[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