diff options
author | Alan Modra <amodra@gmail.com> | 2011-08-17 00:39:41 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2011-08-17 00:39:41 +0000 |
commit | c77ec7261473e7a12a1af46c585caca4bb597b4f (patch) | |
tree | fe75ecc5e02d7b2bcd737b8ce8bccd8b14259809 /bfd/linker.c | |
parent | 142a8c5dcf3f3949d5d2228b894e169ffec28df4 (diff) | |
download | gdb-c77ec7261473e7a12a1af46c585caca4bb597b4f.zip gdb-c77ec7261473e7a12a1af46c585caca4bb597b4f.tar.gz gdb-c77ec7261473e7a12a1af46c585caca4bb597b4f.tar.bz2 |
PR ld/12762
bfd/
* bfd-in.h (struct bfd_section_already_linked): Forward declare.
(_bfd_handle_already_linked): Declare.
* coff-alpha.c (_bfd_ecoff_section_already_linked): Define as
_bfd_coff_section_already_linked.
* coff-mips.c (_bfd_ecoff_section_already_linked): Likewise.
* coffcode.h (coff_section_already_linked): Likewise.
* cofflink.c (coff_link_add_symbols): Revert 2011-07-09 changes.
* elf-bfd.h: Likewise.
* libbfd-in.h: Likewise.
* targets.c: Likewise.
* linker.c (bfd_section_already_linked): Likewise.
(bfd_section_already_linked_table_lookup): Likewise.
(bfd_section_already_linked_table_insert): Likewise.
(_bfd_generic_section_already_linked): Likewise. Call
_bfd_handle_already_linked.
(_bfd_handle_already_linked): New function, split out from..
* elflink.c (_bfd_elf_section_already_linked): ..here. Revert
2011-07-09 changes. Avoid unnecessary strcmp when matching
already_linked_list entries. Match plugin linkonce section.
(section_signature): Delete.
* coffgen.c (_bfd_coff_section_already_linked): New function.
* libcoff-in.h (_bfd_coff_section_already_linked): Declare.
* libbfd.h: Regenerate.
* libcoff.h: Regenerate.
* bfd-in2.h: Regenerate.
ld/
* ldlang.c (section_already_linked): Revert 2011-07-09 changes.
* plugin.c: Likewise.
(asymbol_from_plugin_symbol): Create linkonce section for syms
with comdat_key.
Diffstat (limited to 'bfd/linker.c')
-rw-r--r-- | bfd/linker.c | 250 |
1 files changed, 114 insertions, 136 deletions
diff --git a/bfd/linker.c b/bfd/linker.c index b3ccefd..e443862 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -2889,15 +2889,15 @@ FUNCTION SYNOPSIS bfd_boolean bfd_section_already_linked (bfd *abfd, - struct already_linked *data, + asection *sec, struct bfd_link_info *info); DESCRIPTION Check if @var{data} has been already linked during a reloceatable or final link. Return TRUE if it has. -.#define bfd_section_already_linked(abfd, data, info) \ -. BFD_SEND (abfd, _section_already_linked, (abfd, data, info)) +.#define bfd_section_already_linked(abfd, sec, info) \ +. BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) . */ @@ -2940,7 +2940,7 @@ bfd_section_already_linked_table_lookup (const char *name) bfd_boolean bfd_section_already_linked_table_insert (struct bfd_section_already_linked_hash_entry *already_linked_list, - struct already_linked *data) + asection *sec) { struct bfd_section_already_linked *l; @@ -2950,7 +2950,7 @@ bfd_section_already_linked_table_insert bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l); if (l == NULL) return FALSE; - l->linked = *data; + l->sec = sec; l->next = already_linked_list->entry; already_linked_list->entry = l; return TRUE; @@ -2988,159 +2988,137 @@ bfd_section_already_linked_table_free (void) bfd_hash_table_free (&_bfd_section_already_linked_table); } -/* This is used on non-ELF inputs. */ +/* Report warnings as appropriate for duplicate section SEC. + Return FALSE if we decide to keep SEC after all. */ bfd_boolean -_bfd_generic_section_already_linked (bfd *abfd, - struct already_linked *linked, - struct bfd_link_info *info) +_bfd_handle_already_linked (asection *sec, + struct bfd_section_already_linked *l, + struct bfd_link_info *info) { - flagword flags; - const char *name; - struct bfd_section_already_linked *l; - struct bfd_section_already_linked_hash_entry *already_linked_list; - struct coff_comdat_info *s_comdat; - asection *sec; - - name = linked->comdat_key; - if (name) - { - sec = NULL; - flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - s_comdat = NULL; - } - else + switch (sec->flags & SEC_LINK_DUPLICATES) { - sec = linked->u.sec; - flags = sec->flags; - if ((flags & SEC_LINK_ONCE) == 0) - return FALSE; + default: + abort (); - s_comdat = bfd_coff_get_comdat_section (abfd, sec); + case SEC_LINK_DUPLICATES_DISCARD: + /* If we found an LTO IR match for this comdat group on + the first pass, replace it with the LTO output on the + second pass. We can't simply choose real object + files over IR because the first pass may contain a + mix of LTO and normal objects and we must keep the + first match, be it IR or real. */ + if (info->loading_lto_outputs + && (l->sec->owner->flags & BFD_PLUGIN) != 0) + { + l->sec = sec; + return FALSE; + } + break; - /* FIXME: When doing a relocatable link, we may have trouble - copying relocations in other sections that refer to local symbols - in the section being discarded. Those relocations will have to - be converted somehow; as of this writing I'm not sure that any of - the backends handle that correctly. + case SEC_LINK_DUPLICATES_ONE_ONLY: + info->callbacks->einfo + (_("%B: ignoring duplicate section `%A'\n"), + sec->owner, sec); + break; - It is tempting to instead not discard link once sections when - doing a relocatable link (technically, they should be discarded - whenever we are building constructors). However, that fails, - because the linker winds up combining all the link once sections - into a single large link once section, which defeats the purpose - of having link once sections in the first place. */ + case SEC_LINK_DUPLICATES_SAME_SIZE: + if ((l->sec->owner->flags & BFD_PLUGIN) != 0) + ; + else if (sec->size != l->sec->size) + info->callbacks->einfo + (_("%B: duplicate section `%A' has different size\n"), + sec->owner, sec); + break; - name = bfd_get_section_name (abfd, sec); + case SEC_LINK_DUPLICATES_SAME_CONTENTS: + if ((l->sec->owner->flags & BFD_PLUGIN) != 0) + ; + else if (sec->size != l->sec->size) + info->callbacks->einfo + (_("%B: duplicate section `%A' has different size\n"), + sec->owner, sec); + else if (sec->size != 0) + { + bfd_byte *sec_contents, *l_sec_contents = NULL; + + if (!bfd_malloc_and_get_section (sec->owner, sec, &sec_contents)) + info->callbacks->einfo + (_("%B: could not read contents of section `%A'\n"), + sec->owner, sec); + else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec, + &l_sec_contents)) + info->callbacks->einfo + (_("%B: could not read contents of section `%A'\n"), + l->sec->owner, l->sec); + else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) + info->callbacks->einfo + (_("%B: duplicate section `%A' has different contents\n"), + sec->owner, sec); + + if (sec_contents) + free (sec_contents); + if (l_sec_contents) + free (l_sec_contents); + } + break; } - already_linked_list = bfd_section_already_linked_table_lookup (name); + /* Set the output_section field so that lang_add_section + does not create a lang_input_section structure for this + section. Since there might be a symbol in the section + being discarded, we must retain a pointer to the section + which we are really going to use. */ + sec->output_section = bfd_abs_section_ptr; + sec->kept_section = l->sec; + return TRUE; +} - for (l = already_linked_list->entry; l != NULL; l = l->next) - { - bfd_boolean skip = FALSE; - bfd *l_owner; - flagword l_flags; - struct coff_comdat_info *l_comdat; - asection *l_sec; +/* This is used on non-ELF inputs. */ - if (l->linked.comdat_key) - { - l_sec = NULL; - l_owner = l->linked.u.abfd; - l_comdat = NULL; - l_flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - } - else - { - l_sec = l->linked.u.sec; - l_owner = l_sec->owner; - l_flags = l_sec->flags; - l_comdat = bfd_coff_get_comdat_section (l_sec->owner, l_sec); - } +bfd_boolean +_bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + struct bfd_link_info *info) +{ + const char *name; + struct bfd_section_already_linked *l; + struct bfd_section_already_linked_hash_entry *already_linked_list; - /* We may have 3 different sections on the list: group section, - comdat section and linkonce section. SEC may be a linkonce or - comdat section. We always ignore group section. For non-COFF - inputs, we also ignore comdat section. + if ((sec->flags & SEC_LINK_ONCE) == 0) + return FALSE; - FIXME: Is that safe to match a linkonce section with a comdat - section for COFF inputs? */ - if ((l_flags & SEC_GROUP) != 0) - skip = TRUE; - else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) - { - if (s_comdat != NULL - && l_comdat != NULL - && strcmp (s_comdat->name, l_comdat->name) != 0) - skip = TRUE; - } - else if (l_comdat != NULL) - skip = TRUE; + /* The generic linker doesn't handle section groups. */ + if ((sec->flags & SEC_GROUP) != 0) + return FALSE; - if (!skip) - { - /* The section has already been linked. See if we should - issue a warning. */ - switch (flags & SEC_LINK_DUPLICATES) - { - default: - abort (); - - case SEC_LINK_DUPLICATES_DISCARD: - /* If we found an LTO IR match for this comdat group on - the first pass, replace it with the LTO output on the - second pass. We can't simply choose real object - files over IR because the first pass may contain a - mix of LTO and normal objects and we must keep the - first match, be it IR or real. */ - if (info->loading_lto_outputs - && (l_owner->flags & BFD_PLUGIN) != 0) - { - l->linked = *linked; - return FALSE; - } - break; + /* FIXME: When doing a relocatable link, we may have trouble + copying relocations in other sections that refer to local symbols + in the section being discarded. Those relocations will have to + be converted somehow; as of this writing I'm not sure that any of + the backends handle that correctly. - case SEC_LINK_DUPLICATES_ONE_ONLY: - (*_bfd_error_handler) - (_("%B: warning: ignoring duplicate section `%A'\n"), - abfd, sec); - break; + It is tempting to instead not discard link once sections when + doing a relocatable link (technically, they should be discarded + whenever we are building constructors). However, that fails, + because the linker winds up combining all the link once sections + into a single large link once section, which defeats the purpose + of having link once sections in the first place. */ - case SEC_LINK_DUPLICATES_SAME_CONTENTS: - /* FIXME: We should really dig out the contents of both - sections and memcmp them. The COFF/PE spec says that - the Microsoft linker does not implement this - correctly, so I'm not going to bother doing it - either. */ - /* Fall through. */ - case SEC_LINK_DUPLICATES_SAME_SIZE: - if (sec->size != l_sec->size) - (*_bfd_error_handler) - (_("%B: warning: duplicate section `%A' has different size\n"), - abfd, sec); - break; - } + name = bfd_get_section_name (abfd, sec); - if (sec) - { - /* Set the output_section field so that lang_add_section - does not create a lang_input_section structure for this - section. Since there might be a symbol in the section - being discarded, we must retain a pointer to the section - which we are really going to use. */ - sec->output_section = bfd_abs_section_ptr; - sec->kept_section = l_sec; - } + already_linked_list = bfd_section_already_linked_table_lookup (name); - return TRUE; - } + l = already_linked_list->entry; + if (l != NULL) + { + /* The section has already been linked. See if we should + issue a warning. */ + return _bfd_handle_already_linked (sec, l, info); } /* This is the first section with this name. Record it. */ - if (! bfd_section_already_linked_table_insert (already_linked_list, - linked)) + if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) info->callbacks->einfo (_("%F%P: already_linked_table: %E\n")); return FALSE; } |