From 24ef1aa73ed312282bd1a755b3ac94681c9f1544 Mon Sep 17 00:00:00 2001 From: Guy Martin Date: Mon, 20 Jan 2014 14:16:16 +1030 Subject: [PATCH] Fix duplicate output section statement lookup Tie output section statements to their associated output section via output section userdata. This allows us to avoid hash lookups which are slower and fail when multiple output sections have the same name. * ldlang.h (lang_output_section_get): Define. * ldlang.c (lang_output_section_get): Likewise. (init_os): Set the output_section userdata to the output section statement. * emultempl/hppaelf.em: Use lang_output_section_get instead of lang_output_section_find where applicable. * emultempl/aarch64elf.em: Likewise. * emultempl/aix.em: Likewise. * emultempl/armelf.em: Likewise. * emultempl/m68hc1xelf.em: Likewise. * emultempl/metagelf.em: Likewise. * emultempl/mipself.em: Likewise. * emultempl/ppc64elf.em: Likewise. * emultempl/spuelf.em: Likewise. --- ld/ChangeLog | 18 ++++++++++++++++++ ld/emultempl/aarch64elf.em | 4 +--- ld/emultempl/aix.em | 2 +- ld/emultempl/armelf.em | 4 +--- ld/emultempl/hppaelf.em | 4 +--- ld/emultempl/m68hc1xelf.em | 4 +--- ld/emultempl/metagelf.em | 4 +--- ld/emultempl/mipself.em | 5 +---- ld/emultempl/ppc64elf.em | 4 +--- ld/emultempl/spuelf.em | 5 +++-- ld/ldlang.c | 12 ++++++++++++ ld/ldlang.h | 2 ++ 12 files changed, 43 insertions(+), 25 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index ee26f64889..a022cba570 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,21 @@ +2014-01-20 Guy Martin + Alan Modra + + * ldlang.h (lang_output_section_get): Define. + * ldlang.c (lang_output_section_get): Likewise. + (init_os): Set the output_section userdata to the output + section statement. + * emultempl/hppaelf.em: Use lang_output_section_get instead of + lang_output_section_find where applicable. + * emultempl/aarch64elf.em: Likewise. + * emultempl/aix.em: Likewise. + * emultempl/armelf.em: Likewise. + * emultempl/m68hc1xelf.em: Likewise. + * emultempl/metagelf.em: Likewise. + * emultempl/mipself.em: Likewise. + * emultempl/ppc64elf.em: Likewise. + * emultempl/spuelf.em: Likewise. + 2014-01-17 Alan Modra * genscripts.sh (COMPILE_IN): Don't set if already set. diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em index b3279bf885..b631feb9fb 100644 --- a/ld/emultempl/aarch64elf.em +++ b/ld/emultempl/aarch64elf.em @@ -159,7 +159,6 @@ elf${ELFSIZE}_aarch64_add_stub_section (const char *stub_sec_name, asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -173,8 +172,7 @@ elf${ELFSIZE}_aarch64_add_stub_section (const char *stub_sec_name, bfd_set_section_alignment (stub_file->the_bfd, stub_sec, 3); output_section = input_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); info.input_section = input_section; lang_list_init (&info.add); diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index 084bb66445..d0801334d0 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -854,7 +854,7 @@ gld${EMULATION_NAME}_before_allocation (void) /* Remove this section from the list of the output section. This assumes we know what the script looks like. */ is = NULL; - os = lang_output_section_find (sec->output_section->name); + os = lang_output_section_get (sec->output_section); if (os == NULL) einfo ("%P%F: can't find output section %s\n", sec->output_section->name); diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index eee6af1259..85e924fcb2 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -189,7 +189,6 @@ elf32_arm_add_stub_section (const char * stub_sec_name, asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -203,8 +202,7 @@ elf32_arm_add_stub_section (const char * stub_sec_name, bfd_set_section_alignment (stub_file->the_bfd, stub_sec, alignment_power); output_section = input_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); info.input_section = input_section; lang_list_init (&info.add); diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em index 65c1ea5e87..1b7e384f30 100644 --- a/ld/emultempl/hppaelf.em +++ b/ld/emultempl/hppaelf.em @@ -178,7 +178,6 @@ hppaelf_add_stub_section (const char *stub_sec_name, asection *input_section) asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -190,8 +189,7 @@ hppaelf_add_stub_section (const char *stub_sec_name, asection *input_section) goto err_ret; output_section = input_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); info.input_section = input_section; lang_list_init (&info.add); diff --git a/ld/emultempl/m68hc1xelf.em b/ld/emultempl/m68hc1xelf.em index 594b193ca8..4e1360f1d9 100644 --- a/ld/emultempl/m68hc1xelf.em +++ b/ld/emultempl/m68hc1xelf.em @@ -250,7 +250,6 @@ m68hc11elf_add_stub_section (const char *stub_sec_name, asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -262,8 +261,7 @@ m68hc11elf_add_stub_section (const char *stub_sec_name, goto err_ret; output_section = tramp_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); /* Try to put the new section at the same place as an existing .tramp section. Such .tramp section exists in most cases and diff --git a/ld/emultempl/metagelf.em b/ld/emultempl/metagelf.em index 21e3e942ed..7760f814bd 100644 --- a/ld/emultempl/metagelf.em +++ b/ld/emultempl/metagelf.em @@ -154,7 +154,6 @@ metagelf_add_stub_section (const char *stub_sec_name, asection *input_section) asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -166,8 +165,7 @@ metagelf_add_stub_section (const char *stub_sec_name, asection *input_section) goto err_ret; output_section = input_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); info.input_section = input_section; lang_list_init (&info.add); diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em index 3c6ec9fdb9..02043b7bbf 100644 --- a/ld/emultempl/mipself.em +++ b/ld/emultempl/mipself.em @@ -136,7 +136,6 @@ mips_add_stub_section (const char *stub_sec_name, asection *input_section, { asection *stub_sec; flagword flags; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -176,9 +175,7 @@ mips_add_stub_section (const char *stub_sec_name, asection *input_section, if (!bfd_set_section_flags (stub_bfd, stub_sec, flags)) goto err_ret; - /* Create an output section statement. */ - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); /* Initialize a statement list that contains only the new statement. */ lang_list_init (&info.add); diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index f2085d7dcf..c126297883 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -378,7 +378,6 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section) asection *stub_sec; flagword flags; asection *output_section; - const char *secname; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -392,8 +391,7 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section) goto err_ret; output_section = input_section->output_section; - secname = bfd_get_section_name (output_section->owner, output_section); - os = lang_output_section_find (secname); + os = lang_output_section_get (output_section); info.input_section = input_section; lang_list_init (&info.add); diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index e14fa2637d..8feb8bfa7f 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -138,8 +138,9 @@ spu_place_special_section (asection *s, asection *o, const char *output_name) lang_output_section_statement_type *os; if (o != NULL) - output_name = o->name; - os = lang_output_section_find (output_name); + os = lang_output_section_get (o); + else + os = lang_output_section_find (output_name); if (os == NULL) { os = gld${EMULATION_NAME}_place_orphan (s, output_name, 0); diff --git a/ld/ldlang.c b/ld/ldlang.c index 2a6c4c5e2a..f6d713c22d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1376,6 +1376,14 @@ lang_memory_default (asection * section) return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); } +/* Get the output section statement directly from the userdata. */ + +lang_output_section_statement_type * +lang_output_section_get (const asection *output_section) +{ + return get_userdata (output_section); +} + /* Find or create an output_section_statement with the given NAME. If CONSTRAINT is non-zero match one with that constraint, otherwise match any non-negative constraint. If CREATE, always make a @@ -2104,6 +2112,10 @@ init_os (lang_output_section_statement_type *s, flagword flags) s->bfd_section->output_section = s->bfd_section; s->bfd_section->output_offset = 0; + /* Set the userdata of the output section to the output section + statement to avoid lookup. */ + get_userdata (s->bfd_section) = s; + /* If there is a base address, make sure that any sections it might mention are initialized. */ if (s->addr_tree != NULL) diff --git a/ld/ldlang.h b/ld/ldlang.h index 6eb75dcff6..e91153ca03 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -584,6 +584,8 @@ extern lang_input_statement_type *lang_add_input_file (const char *, lang_input_file_enum_type, const char *); extern void lang_add_keepsyms_file (const char *); +extern lang_output_section_statement_type *lang_output_section_get + (const asection *); extern lang_output_section_statement_type *lang_output_section_statement_lookup (const char *, int, bfd_boolean); extern lang_output_section_statement_type *next_matching_output_section_statement -- 2.34.1