aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-04-20 00:22:08 +0000
committerAlan Modra <amodra@gmail.com>2011-04-20 00:22:08 +0000
commit02d002477b60cff9f0f5abbd5fc27e2889b13421 (patch)
treeddb5245de932bf699df9cd2dda541ad9c96eef26 /bfd
parent24f58f47de96a6c061fc6eeb37a699c03dde970a (diff)
downloadfsf-binutils-gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.zip
fsf-binutils-gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.tar.gz
fsf-binutils-gdb-02d002477b60cff9f0f5abbd5fc27e2889b13421.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elfcode.h16
-rw-r--r--bfd/elflink.c27
-rw-r--r--bfd/linker.c10
4 files changed, 50 insertions, 13 deletions
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 <amodra@gmail.com>
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 <amodra@gmail.com>
+
+ 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;