From 02d002477b60cff9f0f5abbd5fc27e2889b13421 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 20 Apr 2011 00:22:08 +0000 Subject: PR ld/12365 bfd/ * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols in their own common section. * elflink.c (elf_link_add_object_symbols): Likewise. * linker.c (generic_link_check_archive_element): Don't lose flags if common section is pre-existing. (_bfd_generic_link_add_one_symbol): Likewise. ld/ * ldfile.c (ldfile_try_open_bfd): Move code creating and switching to plugin IR BFD.. * ldmain.c (add_archive_element): ..and similar code here.. * plugin.c (plugin_maybe_claim): ..to here. New function. (plugin_call_claim_file): Make static. (asymbol_from_plugin_symbol): Set ELF st_shndx for common syms. (plugin_multiple_common): New function. (plugin_call_all_symbols_read): Hook in plugin_multiple_common. * plugin.h (plugin_call_claim_file): Don't declare. (plugin_maybe_claim): Declare. --- bfd/ChangeLog | 10 ++++++++++ bfd/elfcode.h | 16 +++++++++++++++- bfd/elflink.c | 27 ++++++++++++++++++++------- bfd/linker.c | 10 +++++----- 4 files changed, 50 insertions(+), 13 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0d532e8..582e98f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,16 @@ 2011-04-20 Alan Modra PR ld/12365 + * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols + in their own common section. + * elflink.c (elf_link_add_object_symbols): Likewise. + * linker.c (generic_link_check_archive_element): Don't lose flags + if common section is pre-existing. + (_bfd_generic_link_add_one_symbol): Likewise. + +2011-04-20 Alan Modra + + PR ld/12365 * elflink.c (_bfd_elf_merge_symbol): Update multiple_common calls. * linker.c (_bfd_generic_link_add_one_symbol): Likewise. Call multiple_definition regardless of allow_multiple_definition. diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 28b6b90..d8833df 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1,6 +1,6 @@ /* ELF executable support for BFD. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support, from information published @@ -1282,6 +1282,20 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) else if (isym->st_shndx == SHN_COMMON) { sym->symbol.section = bfd_com_section_ptr; + if ((abfd->flags & BFD_PLUGIN) != 0) + { + asection *xc = bfd_get_section_by_name (abfd, "COMMON"); + + if (xc == NULL) + { + flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP + | SEC_EXCLUDE); + xc = bfd_make_section_with_flags (abfd, "COMMON", flags); + if (xc == NULL) + goto error_return; + } + sym->symbol.section = xc; + } /* Elf puts the alignment into the `value' field, and the size into the `size' field. BFD wants to see the size in the value field, and doesn't care (at the diff --git a/bfd/elflink.c b/bfd/elflink.c index f0ad579..110bb66 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3937,18 +3937,31 @@ error_free_dyn: goto error_free_vers; if (isym->st_shndx == SHN_COMMON - && ELF_ST_TYPE (isym->st_info) == STT_TLS - && !info->relocatable) + && (abfd->flags & BFD_PLUGIN) != 0) + { + asection *xc = bfd_get_section_by_name (abfd, "COMMON"); + + if (xc == NULL) + { + flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP + | SEC_EXCLUDE); + xc = bfd_make_section_with_flags (abfd, "COMMON", sflags); + if (xc == NULL) + goto error_free_vers; + } + sec = xc; + } + else if (isym->st_shndx == SHN_COMMON + && ELF_ST_TYPE (isym->st_info) == STT_TLS + && !info->relocatable) { asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon"); if (tcomm == NULL) { - tcomm = bfd_make_section_with_flags (abfd, ".tcommon", - (SEC_ALLOC - | SEC_IS_COMMON - | SEC_LINKER_CREATED - | SEC_THREAD_LOCAL)); + flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON + | SEC_LINKER_CREATED); + tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags); if (tcomm == NULL) goto error_free_vers; } diff --git a/bfd/linker.c b/bfd/linker.c index 8c577f2..9f2bac3 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1296,7 +1296,7 @@ generic_link_check_archive_element (bfd *abfd, else h->u.c.p->section = bfd_make_section_old_way (symbfd, p->section->name); - h->u.c.p->section->flags = SEC_ALLOC; + h->u.c.p->section->flags |= SEC_ALLOC; } else { @@ -1756,13 +1756,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, if (section == bfd_com_section_ptr) { h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.p->section->flags = SEC_ALLOC; + h->u.c.p->section->flags |= SEC_ALLOC; } else if (section->owner != abfd) { h->u.c.p->section = bfd_make_section_old_way (abfd, section->name); - h->u.c.p->section->flags = SEC_ALLOC; + h->u.c.p->section->flags |= SEC_ALLOC; } else h->u.c.p->section = section; @@ -1803,13 +1803,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, { h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.p->section->flags = SEC_ALLOC; + h->u.c.p->section->flags |= SEC_ALLOC; } else if (section->owner != abfd) { h->u.c.p->section = bfd_make_section_old_way (abfd, section->name); - h->u.c.p->section->flags = SEC_ALLOC; + h->u.c.p->section->flags |= SEC_ALLOC; } else h->u.c.p->section = section; -- cgit v1.1