[patch ld]: Improve import-table linking and fixes some memory-leaks

xunxun xunxun1982@gmail.com
Sun Feb 19 04:45:00 GMT 2012


于 2012/2/17 4:52, Kai Tietz 写道:
> Hi,
>
> this patch fixes some memory-leaks and speeds-up import-table link.
>
> ChangeLog
>
> 2012-02-16  Kai Tietz<ktietz@redhat.com>
>
> 	* deffilep.y (cmp_import_elem): Sort first by module name.
> 	* pe-dll.c (process_def_file_and_drectve): Free strings
> 	from removed export-element.
> 	(add_bfd_to_link): Optimize loop on import-elements and lower
> 	allocated memory.
> 	(pe_implied_import_dll): Pass NULL instead of 0 for pointer
> 	argument.
>
> Tested for i686-w64-mingw32, x86_64-w64-mingw32, and i686-pc-cygwin.
> Ok for apply?
>
> Regards,
> Kai
>
> Index: deffilep.y
> ===================================================================
> RCS file: /cvs/src/src/ld/deffilep.y,v
> retrieving revision 1.38
> diff -u -p -r1.38 deffilep.y
> --- deffilep.y	13 Feb 2012 20:42:07 -0000	1.38
> +++ deffilep.y	16 Feb 2012 20:44:29 -0000
> @@ -741,13 +741,15 @@ cmp_import_elem (const def_file_import *
>   {
>     int r;
>
> +  if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
> +    return r;
>     if ((r = are_names_equal (ex_name, e->name)) != 0)
>       return r;
>     if ((r = are_names_equal (in_name, e->internal_name)) != 0)
>       return r;
>     if (ord != e->ordinal)
>       return (ord<  e->ordinal ? -1 : 1);
> -  return are_names_equal (module, (e->module ? e->module->name : NULL));
> +  return 0;
>   }
>
>   /* Search the position of the identical element, or returns the position
> Index: pe-dll.c
> ===================================================================
> RCS file: /cvs/src/src/ld/pe-dll.c,v
> retrieving revision 1.140
> diff -u -p -r1.140 pe-dll.c
> --- pe-dll.c	11 Feb 2012 19:25:12 -0000	1.140
> +++ pe-dll.c	16 Feb 2012 20:44:29 -0000
> @@ -834,16 +834,6 @@ process_def_file_and_drectve (bfd *abfd
>     /* Convenience, but watch out for it changing.  */
>     e = pe_def_file->exports;
>
> -  exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
> -  exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
> -
> -  memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
> -  max_ordinal = 0;
> -  min_ordinal = 65536;
> -  count_exported = 0;
> -  count_exported_byname = 0;
> -  count_with_ordinals = 0;
> -
>     for (i = 0, j = 0; i<  NE; i++)
>       {
>         if (i>  0&&  strcmp (e[i].name, e[i - 1].name) == 0)
> @@ -872,6 +862,12 @@ process_def_file_and_drectve (bfd *abfd
>   	  e[j - 1].flag_constant |= e[i].flag_constant;
>   	  e[j - 1].flag_noname |= e[i].flag_noname;
>   	  e[j - 1].flag_data |= e[i].flag_data;
> +	  if (e[i].name)
> +	    free (e[i].name);
> +	  if (e[i].internal_name)
> +	    free (e[i].internal_name);
> +	  if (e[i].its_name)
> +	    free (e[i].its_name);
>   	}
>         else
>   	{
> @@ -882,6 +878,16 @@ process_def_file_and_drectve (bfd *abfd
>       }
>     pe_def_file->num_exports = j;	/* == NE */
>
> +  exported_symbol_offsets = xmalloc (NE * sizeof (bfd_vma));
> +  exported_symbol_sections = xmalloc (NE * sizeof (struct bfd_section *));
> +
> +  memset (exported_symbol_sections, 0, NE * sizeof (struct bfd_section *));
> +  max_ordinal = 0;
> +  min_ordinal = 65536;
> +  count_exported = 0;
> +  count_exported_byname = 0;
> +  count_with_ordinals = 0;
> +
>     for (i = 0; i<  NE; i++)
>       {
>         char *name;
> @@ -2861,99 +2867,101 @@ add_bfd_to_link (bfd *abfd, const char *
>   void
>   pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
>   {
> +  int i, j;
>     def_file_module *module;
> +  def_file_import *imp;
>
>     pe_dll_id_target (bfd_get_target (output_bfd));
>
>     if (!pe_def_file)
>       return;
>
> +  imp = pe_def_file->imports;
> +
>     for (module = pe_def_file->modules; module; module = module->next)
>       {
> -      int i, do_this_dll;
> +      int do_this_dll = 0;
> +
> +      for (i = 0; i<  pe_def_file->num_imports&&  imp[i].module != module; i++)
> +	;
> +      if (i>= pe_def_file->num_imports)
> +        continue;
>
>         dll_filename = module->name;
>         dll_symname = xstrdup (module->name);
> -      for (i = 0; dll_symname[i]; i++)
> -	if (!ISALNUM (dll_symname[i]))
> -	  dll_symname[i] = '_';
> +      for (j = 0; dll_symname[j]; j++)
> +	if (!ISALNUM (dll_symname[j]))
> +	  dll_symname[j] = '_';
> +
> +      for (; i<  pe_def_file->num_imports&&  imp[i].module == module; i++)
> +	{
> +	  def_file_export exp;
> +	  struct bfd_link_hash_entry *blhe;
> +	  int lead_at = (*imp[i].internal_name == '@');
> +	  /* See if we need this import.  */
> +	  size_t len = strlen (imp[i].internal_name);
> +	  char *name = xmalloc (len + 2 + 6);
> +	  bfd_boolean include_jmp_stub = FALSE;
> +	  bfd_boolean is_cdecl = FALSE;
> +	  if (!lead_at&&  strchr (imp[i].internal_name, '@') == NULL)
> +	      is_cdecl = TRUE;
>
> -      do_this_dll = 0;
> +	  if (lead_at)
> +	    sprintf (name, "%s", imp[i].internal_name);
> +	  else
> +	    sprintf (name, "%s%s",U (""), imp[i].internal_name);
>
> -      for (i = 0; i<  pe_def_file->num_imports; i++)
> -	if (pe_def_file->imports[i].module == module)
> -	  {
> -	    def_file_export exp;
> -	    struct bfd_link_hash_entry *blhe;
> -	    int lead_at = (*pe_def_file->imports[i].internal_name == '@');
> -	    /* See if we need this import.  */
> -	    size_t len = strlen (pe_def_file->imports[i].internal_name);
> -	    char *name = xmalloc (len + 2 + 6);
> -	    bfd_boolean include_jmp_stub = FALSE;
> -	    bfd_boolean is_cdecl = FALSE;
> -	    if (!lead_at&&  strchr (pe_def_file->imports[i].internal_name,
> '@') == NULL)
> -	        is_cdecl = TRUE;
> -
> - 	    if (lead_at)
> -	      sprintf (name, "%s",
> -		       pe_def_file->imports[i].internal_name);
> -	    else
> -	      sprintf (name, "%s%s",U (""),
> -		       pe_def_file->imports[i].internal_name);
> -
> -	    blhe = bfd_link_hash_lookup (linfo->hash, name,
> -					 FALSE, FALSE, FALSE);
> -
> -	    /* Include the jump stub for<sym>  only if the<sym>
> -	       is undefined.  */
> -	    if (!blhe || (blhe&&  blhe->type != bfd_link_hash_undefined))
> -	      {
> -		if (lead_at)
> -		  sprintf (name, "%s%s", "__imp_",
> -			   pe_def_file->imports[i].internal_name);
> -		else
> -		  sprintf (name, "%s%s%s", "__imp_", U (""),
> -			   pe_def_file->imports[i].internal_name);
> -
> -		blhe = bfd_link_hash_lookup (linfo->hash, name,
> -					     FALSE, FALSE, FALSE);
> -	      }
> -	    else
> +	  blhe = bfd_link_hash_lookup (linfo->hash, name,
> +				       FALSE, FALSE, FALSE);
> +
> +	  /* Include the jump stub for<sym>  only if the<sym>
> +	     is undefined.  */
> +	  if (!blhe || (blhe&&  blhe->type != bfd_link_hash_undefined))
> +	    {
> +	      if (lead_at)
> +		sprintf (name, "%s%s", "__imp_", imp[i].internal_name);
> +	      else
> +		sprintf (name, "%s%s%s", "__imp_", U (""),
> +			 imp[i].internal_name);
> +
> +	      blhe = bfd_link_hash_lookup (linfo->hash, name,
> +					   FALSE, FALSE, FALSE);
> +	    }
> +	  else
> +	    include_jmp_stub = TRUE;
> +
> +	  if (is_cdecl&&  !blhe)
> +	    {
> +	      sprintf (name, "%s%s",U (""), imp[i].internal_name);
> +	      blhe = pe_find_cdecl_alias_match (name);
>   	      include_jmp_stub = TRUE;
> +	    }
>
> -	    if (is_cdecl&&  !blhe)
> -	      {
> -		sprintf (name, "%s%s",U (""),
> -		         pe_def_file->imports[i].internal_name);
> -		blhe = pe_find_cdecl_alias_match (name);
> -		include_jmp_stub = TRUE;
> -	      }
> -
> -	    free (name);
> -
> -	    if (blhe&&  blhe->type == bfd_link_hash_undefined)
> -	      {
> -		bfd *one;
> -		/* We do.  */
> -		if (!do_this_dll)
> -		  {
> -		    bfd *ar_head = make_head (output_bfd);
> -		    add_bfd_to_link (ar_head, ar_head->filename, linfo);
> -		    do_this_dll = 1;
> -		  }
> -		exp.internal_name = pe_def_file->imports[i].internal_name;
> -		exp.name = pe_def_file->imports[i].name;
> -		exp.its_name = pe_def_file->imports[i].its_name;
> -		exp.ordinal = pe_def_file->imports[i].ordinal;
> -		exp.hint = exp.ordinal>= 0 ? exp.ordinal : 0;
> -		exp.flag_private = 0;
> -		exp.flag_constant = 0;
> -		exp.flag_data = pe_def_file->imports[i].data;
> -		exp.flag_noname = exp.name ? 0 : 1;
> -		one = make_one (&exp, output_bfd, (! exp.flag_data)&&  include_jmp_stub);
> -		add_bfd_to_link (one, one->filename, linfo);
> -	      }
> -	  }
> +	  free (name);
> +
> +	  if (blhe&&  blhe->type == bfd_link_hash_undefined)
> +	    {
> +	      bfd *one;
> +	      /* We do.  */
> +	      if (!do_this_dll)
> +		{
> +		  bfd *ar_head = make_head (output_bfd);
> +		  add_bfd_to_link (ar_head, ar_head->filename, linfo);
> +		  do_this_dll = 1;
> +		}
> +	      exp.internal_name = imp[i].internal_name;
> +	      exp.name = imp[i].name;
> +	      exp.its_name = imp[i].its_name;
> +	      exp.ordinal = imp[i].ordinal;
> +	      exp.hint = exp.ordinal>= 0 ? exp.ordinal : 0;
> +	      exp.flag_private = 0;
> +	      exp.flag_constant = 0;
> +	      exp.flag_data = imp[i].data;
> +	      exp.flag_noname = exp.name ? 0 : 1;
> +	      one = make_one (&exp, output_bfd, (! exp.flag_data)&&
> include_jmp_stub);
> +	      add_bfd_to_link (one, one->filename, linfo);
> +	    }
> +	}
>         if (do_this_dll)
>   	{
>   	  bfd *ar_tail = make_tail (output_bfd);
> @@ -3178,7 +3186,7 @@ pe_implied_import_dll (const char *filen
>   	    || (func_rva>= bss_start&&  func_rva<  bss_end);
>
>   	  imp = def_file_add_import (pe_def_file, erva + name_rva,
> -				     dllname, i, 0, NULL,&is_dup);
> +				     dllname, i, NULL, NULL,&is_dup);
>    	  /* Mark symbol type.  */
>    	  if (!is_dup)
>    	    imp->data = is_data;
Ping ...

-- 
Best Regards,
xunxun



More information about the Binutils mailing list