diff options
author | Alan Modra <amodra@gmail.com> | 2008-10-03 09:40:49 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2008-10-03 09:40:49 +0000 |
commit | bcacc0f587e22ba46333d9377e7e9e4576c90f74 (patch) | |
tree | 0035a6958c007460d3837b1e245b5f89edeb3661 /ld | |
parent | 81ab4297b7f533d6750f073cad0fe6169f567e85 (diff) | |
download | gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.zip gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.tar.gz gdb-bcacc0f587e22ba46333d9377e7e9e4576c90f74.tar.bz2 |
bfd/
* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when
the signature symbol is global.
* elflink.c (elf_link_input_bfd): Ensure group signature symbol
is output when ld -r. Set group sh_info when local.
* linker.c (default_indirect_link_order): Handle group sections
specially.
ld/
* ldemul.c (ldemul_place_orphan): Add "name" param.
* ldemul.h (ldemul_place_orphan): Update prototype.
(struct ld_emulation_xfer_struct <place_orphan>): Likewise.
* ldlang.c (lang_place_orphans): Generate unique section names here..
* emultempl/elf32.em (place_orphan): ..rather than here. Don't
directly use an existing output section statement that has no
bfd section.
* emultempl/pe.em (place_orphan): Likewise.
* emultempl/pep.em (place_orphan): Likewise.
* emultempl/beos.em (place_orphan): Adjust.
* emultempl/spuelf.em (spu_place_special_section): Adjust
place_orphan call.
* emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function.
(LDEMUL_AFTER_OPEN): Define.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 17 | ||||
-rw-r--r-- | ld/emultempl/beos.em | 5 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 59 | ||||
-rw-r--r-- | ld/emultempl/genelf.em | 20 | ||||
-rw-r--r-- | ld/emultempl/pe.em | 30 | ||||
-rw-r--r-- | ld/emultempl/pep.em | 30 | ||||
-rw-r--r-- | ld/emultempl/spuelf.em | 7 | ||||
-rw-r--r-- | ld/ldemul.c | 4 | ||||
-rw-r--r-- | ld/ldemul.h | 4 | ||||
-rw-r--r-- | ld/ldlang.c | 25 |
10 files changed, 97 insertions, 104 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 25debe5..f957395 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,20 @@ +2008-10-03 Alan Modra <amodra@bigpond.net.au> + + * ldemul.c (ldemul_place_orphan): Add "name" param. + * ldemul.h (ldemul_place_orphan): Update prototype. + (struct ld_emulation_xfer_struct <place_orphan>): Likewise. + * ldlang.c (lang_place_orphans): Generate unique section names here.. + * emultempl/elf32.em (place_orphan): ..rather than here. Don't + directly use an existing output section statement that has no + bfd section. + * emultempl/pe.em (place_orphan): Likewise. + * emultempl/pep.em (place_orphan): Likewise. + * emultempl/beos.em (place_orphan): Adjust. + * emultempl/spuelf.em (spu_place_special_section): Adjust + place_orphan call. + * emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function. + (LDEMUL_AFTER_OPEN): Define. + 2008-09-30 Joseph Myers <joseph@codesourcery.com> * emulparams/elf64ppc.sh (OTHER_GOT_RELOC_SECTIONS): Add .rela.opd diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em index fac0c89..997f3a6 100644 --- a/ld/emultempl/beos.em +++ b/ld/emultempl/beos.em @@ -665,9 +665,8 @@ gld_${EMULATION_NAME}_before_allocation (void) which are not mentioned in the linker script. */ static bfd_boolean -gld${EMULATION_NAME}_place_orphan (asection *s) +gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname) { - const char *secname; char *output_secname, *ps; lang_output_section_statement_type *os; lang_statement_union_type *l; @@ -682,8 +681,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s) if (link_info.relocatable) return FALSE; - secname = bfd_get_section_name (s->owner, s); - /* Everything from the '\$' on gets deleted so don't allow '\$' as the first character. */ if (*secname == '\$') diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index be9d78d..65ad4f1 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -62,7 +62,7 @@ fragment <<EOF static void gld${EMULATION_NAME}_before_parse (void); static void gld${EMULATION_NAME}_after_open (void); static void gld${EMULATION_NAME}_before_allocation (void); -static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s); +static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *, const char *); static void gld${EMULATION_NAME}_finish (void); EOF @@ -1635,7 +1635,7 @@ output_rel_find (asection *sec, int isdyn) sections in the right segment. */ static bfd_boolean -gld${EMULATION_NAME}_place_orphan (asection *s) +gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname) { static struct orphan_save hold[] = { @@ -1673,15 +1673,12 @@ gld${EMULATION_NAME}_place_orphan (asection *s) }; static int orphan_init_done = 0; struct orphan_save *place; - const char *secname; lang_output_section_statement_type *after; lang_output_section_statement_type *os; int isdyn = 0; int iself = s->owner->xvec->flavour == bfd_target_elf_flavour; unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL; - secname = bfd_get_section_name (s->owner, s); - if (! link_info.relocatable && link_info.combreloc && (s->flags & SEC_ALLOC)) @@ -1707,28 +1704,24 @@ gld${EMULATION_NAME}_place_orphan (asection *s) } } - if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s))) + /* Look through the script to see where to place this section. */ + os = lang_output_section_find (secname); + + if (os != NULL + && os->bfd_section != NULL + && (os->bfd_section->flags == 0 + || (_bfd_elf_match_sections_by_type (link_info.output_bfd, + os->bfd_section, s->owner, s) + && ((s->flags ^ os->bfd_section->flags) + & (SEC_LOAD | SEC_ALLOC)) == 0))) { - /* Look through the script to see where to place this section. */ - os = lang_output_section_find (secname); - - if (os != NULL - && (os->bfd_section == NULL - || os->bfd_section->flags == 0 - || (_bfd_elf_match_sections_by_type (link_info.output_bfd, - os->bfd_section, - s->owner, s) - && ((s->flags ^ os->bfd_section->flags) - & (SEC_LOAD | SEC_ALLOC)) == 0))) - { - /* We already have an output section statement with this - name, and its bfd section, if any, has compatible flags. - If the section already exists but does not have any flags - set, then it has been created by the linker, probably as a - result of a --section-start command line switch. */ - lang_add_section (&os->children, s, os); - return TRUE; - } + /* We already have an output section statement with this + name, and its bfd section has compatible flags. + If the section already exists but does not have any flags + set, then it has been created by the linker, probably as a + result of a --section-start command line switch. */ + lang_add_section (&os->children, s, os); + return TRUE; } if (!orphan_init_done) @@ -1748,7 +1741,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s) sections into the .text section to get them out of the way. */ if (link_info.executable && ! link_info.relocatable - && CONST_STRNEQ (secname, ".gnu.warning.") + && CONST_STRNEQ (s->name, ".gnu.warning.") && hold[orphan_text].os != NULL) { lang_add_section (&hold[orphan_text].os->children, s, @@ -1803,18 +1796,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s) after = &lang_output_section_statement.head->output_section_statement; } - /* Choose a unique name for the section. This will be needed if the - same section name appears in the input file with different - loadable or allocatable characteristics. */ - if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL) - { - static int count = 1; - secname = bfd_get_unique_section_name (link_info.output_bfd, - secname, &count); - if (secname == NULL) - einfo ("%F%P: place_orphan failed: %E\n"); - } - lang_insert_orphan (s, secname, after, place, NULL, NULL); return TRUE; diff --git a/ld/emultempl/genelf.em b/ld/emultempl/genelf.em index e44bb9b..e6e8841 100644 --- a/ld/emultempl/genelf.em +++ b/ld/emultempl/genelf.em @@ -34,7 +34,27 @@ gld${EMULATION_NAME}_finish (void) gld${EMULATION_NAME}_map_segments (FALSE); finish_default (); } + +static void +gld${EMULATION_NAME}_after_open (void) +{ + bfd *ibfd; + asection *sec; + asymbol **syms; + + if (link_info.relocatable) + for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + if ((syms = bfd_get_outsymbols (ibfd)) != NULL + && bfd_get_flavour (ibfd) == bfd_target_elf_flavour) + for (sec = ibfd->sections; sec != NULL; sec = sec->next) + if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP) + { + struct bfd_elf_section_data *sec_data = elf_section_data (sec); + elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1]; + } +} EOF # Put these extra routines in ld_${EMULATION_NAME}_emulation # LDEMUL_FINISH=gld${EMULATION_NAME}_finish +LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index cec399a..89c521d 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -1613,24 +1613,20 @@ gld_${EMULATION_NAME}_finish (void) sort_sections. */ static bfd_boolean -gld_${EMULATION_NAME}_place_orphan (asection *s) +gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname) { - const char *secname; - const char *orig_secname; + const char *orig_secname = secname; char *dollar = NULL; lang_output_section_statement_type *os; lang_statement_list_type add_child; - secname = bfd_get_section_name (s->owner, s); - /* Look through the script to see where to place this section. */ - orig_secname = secname; if (!link_info.relocatable && (dollar = strchr (secname, '$')) != NULL) { - size_t len = dollar - orig_secname; + size_t len = dollar - secname; char *newname = xmalloc (len + 1); - memcpy (newname, orig_secname, len); + memcpy (newname, secname, len); newname[len] = '\0'; secname = newname; } @@ -1640,13 +1636,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s) lang_list_init (&add_child); if (os != NULL - && (os->bfd_section == NULL - || os->bfd_section->flags == 0 + && os->bfd_section != NULL + && (os->bfd_section->flags == 0 || ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)) { /* We already have an output section statement with this - name, and its bfd section, if any, has compatible flags. + name, and its bfd section has compatible flags. If the section already exists but does not have any flags set, then it has been created by the linker, probably as a result of a --section-start command line switch. */ @@ -1723,18 +1719,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s) ->output_section_statement); } - /* Choose a unique name for the section. This will be needed if the - same section name appears in the input file with different - loadable or allocatable characteristics. */ - if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL) - { - static int count = 1; - secname = bfd_get_unique_section_name (link_info.output_bfd, - secname, &count); - if (secname == NULL) - einfo ("%F%P: place_orphan failed: %E\n"); - } - /* All sections in an executable must be aligned to a page boundary. */ address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__")); os = lang_insert_orphan (s, secname, after, place, address, &add_child); diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 0b9bf40..4afac02 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -1372,24 +1372,20 @@ gld_${EMULATION_NAME}_finish (void) sort_sections. */ static bfd_boolean -gld_${EMULATION_NAME}_place_orphan (asection *s) +gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname) { - const char *secname; - const char *orig_secname; + const char *orig_secname = secname; char *dollar = NULL; lang_output_section_statement_type *os; lang_statement_list_type add_child; - secname = bfd_get_section_name (s->owner, s); - /* Look through the script to see where to place this section. */ - orig_secname = secname; if (!link_info.relocatable && (dollar = strchr (secname, '$')) != NULL) { - size_t len = dollar - orig_secname; + size_t len = dollar - secname; char *newname = xmalloc (len + 1); - memcpy (newname, orig_secname, len); + memcpy (newname, secname, len); newname[len] = '\0'; secname = newname; } @@ -1399,13 +1395,13 @@ gld_${EMULATION_NAME}_place_orphan (asection *s) lang_list_init (&add_child); if (os != NULL - && (os->bfd_section == NULL - || os->bfd_section->flags == 0 + && os->bfd_section != NULL + && (os->bfd_section->flags == 0 || ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)) { /* We already have an output section statement with this - name, and its bfd section, if any, has compatible flags. + name, and its bfd section has compatible flags. If the section already exists but does not have any flags set, then it has been created by the linker, probably as a result of a --section-start command line switch. */ @@ -1482,18 +1478,6 @@ gld_${EMULATION_NAME}_place_orphan (asection *s) ->output_section_statement); } - /* Choose a unique name for the section. This will be needed if the - same section name appears in the input file with different - loadable or allocatable characteristics. */ - if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL) - { - static int count = 1; - secname = bfd_get_unique_section_name (link_info.output_bfd, - secname, &count); - if (secname == NULL) - einfo ("%F%P: place_orphan failed: %E\n"); - } - /* All sections in an executable must be aligned to a page boundary. */ address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__")); os = lang_insert_orphan (s, secname, after, place, address, &add_child); diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index 116a0cc..bc2f6b5 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -114,12 +114,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name) os = lang_output_section_find (o != NULL ? o->name : output_name); if (os == NULL) - { - const char *save = s->name; - s->name = output_name; - gld${EMULATION_NAME}_place_orphan (s); - s->name = save; - } + gld${EMULATION_NAME}_place_orphan (s, output_name); else if (o != NULL && os->children.head != NULL) { lang_statement_list_type add; diff --git a/ld/ldemul.c b/ld/ldemul.c index 6b86ddf..68e1de2 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -120,10 +120,10 @@ ldemul_open_dynamic_archive (const char *arch, search_dirs_type *search, } bfd_boolean -ldemul_place_orphan (asection *s) +ldemul_place_orphan (asection *s, const char *name) { if (ld_emulation->place_orphan) - return (*ld_emulation->place_orphan) (s); + return (*ld_emulation->place_orphan) (s, name); return FALSE; } diff --git a/ld/ldemul.h b/ld/ldemul.h index cc81728..6c95a9d 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -59,7 +59,7 @@ extern void ldemul_set_symbols extern void ldemul_create_output_section_statements (void); extern bfd_boolean ldemul_place_orphan - (asection *); + (asection *, const char *); extern bfd_boolean ldemul_parse_args (int, char **); extern void ldemul_add_options @@ -152,7 +152,7 @@ typedef struct ld_emulation_xfer_struct { the default action should be taken. This field may be NULL, in which case the default action will always be taken. */ bfd_boolean (*place_orphan) - (asection *); + (asection *, const char *); /* Run after assigning parsing with the args, but before reading the script. Used to initialize symbols used in the script. */ diff --git a/ld/ldlang.c b/ld/ldlang.c index b1b8806..44fb136 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -5652,14 +5652,29 @@ lang_place_orphans (void) default_common_section); } } - else if (ldemul_place_orphan (s)) - ; else { - lang_output_section_statement_type *os; + const char *name = s->name; - os = lang_output_section_statement_lookup (s->name, 0, TRUE); - lang_add_section (&os->children, s, os); + if ((config.unique_orphan_sections + || unique_section_p (s)) + && bfd_get_section_by_name (link_info.output_bfd, + name) != NULL) + { + static int count = 1; + name = bfd_get_unique_section_name (link_info.output_bfd, + name, &count); + if (name == NULL) + einfo ("%F%P: place_orphan failed: %E\n"); + } + + if (!ldemul_place_orphan (s, name)) + { + lang_output_section_statement_type *os; + os = lang_output_section_statement_lookup (name, 0, + TRUE); + lang_add_section (&os->children, s, os); + } } } } |