aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-08-05 03:17:12 +0000
committerAlan Modra <amodra@gmail.com>2011-08-05 03:17:12 +0000
commit43e1669b2d187f4b2e4ecdf98a5aac8e9fb10bfd (patch)
tree68647f2f6ce1d2294bd05d4e4ca671d5943b6eee
parent6177242a84b9139f50d23a2b86ac68da6183e10c (diff)
downloadgdb-43e1669b2d187f4b2e4ecdf98a5aac8e9fb10bfd.zip
gdb-43e1669b2d187f4b2e4ecdf98a5aac8e9fb10bfd.tar.gz
gdb-43e1669b2d187f4b2e4ecdf98a5aac8e9fb10bfd.tar.bz2
PR ld/12762
bfd/ * elflink.c (_bfd_elf_section_already_linked): Return matched status. Remove COFF comdat section handling. * linker.c (_bfd_generic_section_already_linked): Return matched status. Don't set SEC_GROUP in l_flags for plugin entries. (bfd_section_already_linked): Update prototype. * targets.c (_section_already_linked): Likewise. * elf-bfd.h (_bfd_elf_section_already_linked): Likewise. * libbfd-in.h (_bfd_generic_section_already_linked): Likewise. (_bfd_nolink_section_already_linked): Update. * libbfd.h: Regenerate. * bfd-in2.h: Regenerate. ld/ * plugin.c (add_symbols): Exclude comdat_key symbols from symbol table if already seen.
-rw-r--r--bfd/ChangeLog15
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elflink.c29
-rw-r--r--bfd/libbfd-in.h6
-rw-r--r--bfd/libbfd.h6
-rw-r--r--bfd/linker.c23
-rw-r--r--bfd/targets.c4
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/plugin.c12
10 files changed, 67 insertions, 42 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f6ccd54..82defd9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,20 @@
2011-08-05 Alan Modra <amodra@gmail.com>
+ PR ld/12762
+ * elflink.c (_bfd_elf_section_already_linked): Return matched
+ status. Remove COFF comdat section handling.
+ * linker.c (_bfd_generic_section_already_linked): Return matched
+ status. Don't set SEC_GROUP in l_flags for plugin entries.
+ (bfd_section_already_linked): Update prototype.
+ * targets.c (_section_already_linked): Likewise.
+ * elf-bfd.h (_bfd_elf_section_already_linked): Likewise.
+ * libbfd-in.h (_bfd_generic_section_already_linked): Likewise.
+ (_bfd_nolink_section_already_linked): Update.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2011-08-05 Alan Modra <amodra@gmail.com>
+
* elf32-ppc.c: Include dwarf2.h.
(struct ppc_elf_link_hash_table): Add glink_eh_frame.
(ppc_elf_create_glink): Create .eh_frame section.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ac8145d..af13ca4 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6107,8 +6107,8 @@ typedef struct bfd_target
/* Check if SEC has been already linked during a reloceatable or
final link. */
- void (*_section_already_linked) (bfd *, struct already_linked *,
- struct bfd_link_info *);
+ bfd_boolean (*_section_already_linked) (bfd *, struct already_linked *,
+ struct bfd_link_info *);
/* Define a common symbol. */
bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
@@ -6177,7 +6177,7 @@ bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
#define bfd_link_split_section(abfd, sec) \
BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
-void bfd_section_already_linked (bfd *abfd,
+bfd_boolean bfd_section_already_linked (bfd *abfd,
struct already_linked *data,
struct bfd_link_info *info);
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index e6ea580..2c80f67 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1802,7 +1802,7 @@ extern bfd_boolean _bfd_elf_match_sections_by_type
extern bfd_boolean bfd_elf_is_group_section
(bfd *, const struct bfd_section *);
struct already_linked;
-extern void _bfd_elf_section_already_linked
+extern bfd_boolean _bfd_elf_section_already_linked
(bfd *, struct already_linked *, struct bfd_link_info *);
extern void bfd_elf_set_group_contents
(bfd *, asection *, void *);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 2e592f5..53765b6 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12515,7 +12515,7 @@ section_signature (asection *sec)
return sec->name;
}
-void
+bfd_boolean
_bfd_elf_section_already_linked (bfd *abfd,
struct already_linked *linked,
struct bfd_link_info *info)
@@ -12525,6 +12525,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
struct bfd_section_already_linked *l;
struct bfd_section_already_linked_hash_entry *already_linked_list;
asection *sec, *l_sec;
+ bfd_boolean matched;
p = name = linked->comdat_key;
if (name)
@@ -12536,20 +12537,20 @@ _bfd_elf_section_already_linked (bfd *abfd,
{
sec = linked->u.sec;
if (sec->output_section == bfd_abs_section_ptr)
- return;
+ return FALSE;
flags = sec->flags;
/* Return if it isn't a linkonce section. A comdat group section
also has SEC_LINK_ONCE set. */
if ((flags & SEC_LINK_ONCE) == 0)
- return;
+ return FALSE;
/* Don't put group member sections on our list of already linked
sections. They are handled as a group via their group section.
*/
if (elf_sec_group (sec) != NULL)
- return;
+ return FALSE;
/* FIXME: When doing a relocatable link, we may have trouble
copying relocations in other sections that refer to local symbols
@@ -12582,7 +12583,6 @@ _bfd_elf_section_already_linked (bfd *abfd,
for (l = already_linked_list->entry; l != NULL; l = l->next)
{
- bfd_boolean l_coff_comdat_sec;
flagword l_flags;
bfd *l_owner;
const char *l_name = l->linked.comdat_key;
@@ -12593,23 +12593,19 @@ _bfd_elf_section_already_linked (bfd *abfd,
l_flags = (SEC_GROUP
| SEC_LINK_ONCE
| SEC_LINK_DUPLICATES_DISCARD);
- l_coff_comdat_sec = FALSE;
}
else
{
l_sec = l->linked.u.sec;
l_owner = l_sec->owner;
l_flags = l_sec->flags;
- l_coff_comdat_sec
- = !!bfd_coff_get_comdat_section (l_sec->owner, l_sec);
l_name = section_signature (l_sec);
}
/* We may have 2 different types of sections on the list: group
sections and linkonce sections. Match like sections. */
if ((flags & SEC_GROUP) == (l_flags & SEC_GROUP)
- && strcmp (name, l_name) == 0
- && !l_coff_comdat_sec)
+ && strcmp (name, l_name) == 0)
{
/* The section has already been linked. See if we should
issue a warning. */
@@ -12629,7 +12625,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
&& (l_owner->flags & BFD_PLUGIN) != 0)
{
l->linked = *linked;
- return;
+ return FALSE;
}
break;
@@ -12711,10 +12707,11 @@ _bfd_elf_section_already_linked (bfd *abfd,
}
}
- return;
+ return TRUE;
}
}
+ matched = FALSE;
if (sec)
{
/* A single member comdat group section may be discarded by a
@@ -12742,6 +12739,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
first->output_section = bfd_abs_section_ptr;
first->kept_section = l_sec;
sec->output_section = bfd_abs_section_ptr;
+ matched = TRUE;
break;
}
}
@@ -12767,6 +12765,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
{
sec->output_section = bfd_abs_section_ptr;
sec->kept_section = first;
+ matched = TRUE;
break;
}
}
@@ -12799,7 +12798,10 @@ _bfd_elf_section_already_linked (bfd *abfd,
&& CONST_STRNEQ (l_sec->name, ".gnu.linkonce.t."))
{
if (abfd != l_sec->owner)
- sec->output_section = bfd_abs_section_ptr;
+ {
+ sec->output_section = bfd_abs_section_ptr;
+ matched = TRUE;
+ }
break;
}
}
@@ -12810,6 +12812,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
if (! bfd_section_already_linked_table_insert (already_linked_list,
linked))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return matched;
}
bfd_boolean
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 0c98b47..db39f3c 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -481,8 +481,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nolink_bfd_link_split_section \
((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
#define _bfd_nolink_section_already_linked \
- ((void (*) (bfd *, struct already_linked*, \
- struct bfd_link_info *)) bfd_void)
+ ((bfd_boolean (*) (bfd *, struct already_linked*, \
+ struct bfd_link_info *)) bfd_false)
#define _bfd_nolink_bfd_define_common_symbol \
((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
struct bfd_link_hash_entry *)) bfd_false)
@@ -602,7 +602,7 @@ extern bfd_boolean _bfd_generic_final_link
extern bfd_boolean _bfd_generic_link_split_section
(bfd *, struct bfd_section *);
-extern void _bfd_generic_section_already_linked
+extern bfd_boolean _bfd_generic_section_already_linked
(bfd *, struct already_linked *, struct bfd_link_info *);
/* Generic reloc_link_order processing routine. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 33069b0..71188dc 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -486,8 +486,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nolink_bfd_link_split_section \
((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
#define _bfd_nolink_section_already_linked \
- ((void (*) (bfd *, struct already_linked*, \
- struct bfd_link_info *)) bfd_void)
+ ((bfd_boolean (*) (bfd *, struct already_linked*, \
+ struct bfd_link_info *)) bfd_false)
#define _bfd_nolink_bfd_define_common_symbol \
((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
struct bfd_link_hash_entry *)) bfd_false)
@@ -607,7 +607,7 @@ extern bfd_boolean _bfd_generic_final_link
extern bfd_boolean _bfd_generic_link_split_section
(bfd *, struct bfd_section *);
-extern void _bfd_generic_section_already_linked
+extern bfd_boolean _bfd_generic_section_already_linked
(bfd *, struct already_linked *, struct bfd_link_info *);
/* Generic reloc_link_order processing routine. */
diff --git a/bfd/linker.c b/bfd/linker.c
index 8700c05..b3ccefd 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -2888,13 +2888,13 @@ FUNCTION
bfd_section_already_linked
SYNOPSIS
- void bfd_section_already_linked (bfd *abfd,
- struct already_linked *data,
- struct bfd_link_info *info);
+ bfd_boolean bfd_section_already_linked (bfd *abfd,
+ struct already_linked *data,
+ struct bfd_link_info *info);
DESCRIPTION
Check if @var{data} has been already linked during a reloceatable
- or final link.
+ 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))
@@ -2990,7 +2990,7 @@ bfd_section_already_linked_table_free (void)
/* This is used on non-ELF inputs. */
-void
+bfd_boolean
_bfd_generic_section_already_linked (bfd *abfd,
struct already_linked *linked,
struct bfd_link_info *info)
@@ -3006,7 +3006,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
if (name)
{
sec = NULL;
- flags = SEC_GROUP | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
s_comdat = NULL;
}
else
@@ -3014,7 +3014,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
sec = linked->u.sec;
flags = sec->flags;
if ((flags & SEC_LINK_ONCE) == 0)
- return;
+ return FALSE;
s_comdat = bfd_coff_get_comdat_section (abfd, sec);
@@ -3049,9 +3049,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
l_sec = NULL;
l_owner = l->linked.u.abfd;
l_comdat = NULL;
- l_flags = (SEC_GROUP
- | SEC_LINK_ONCE
- | SEC_LINK_DUPLICATES_DISCARD);
+ l_flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
}
else
{
@@ -3100,7 +3098,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
&& (l_owner->flags & BFD_PLUGIN) != 0)
{
l->linked = *linked;
- return;
+ return FALSE;
}
break;
@@ -3136,7 +3134,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
sec->kept_section = l_sec;
}
- return;
+ return TRUE;
}
}
@@ -3144,6 +3142,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
if (! bfd_section_already_linked_table_insert (already_linked_list,
linked))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return FALSE;
}
/* Convert symbols in excluded output sections to use a kept section. */
diff --git a/bfd/targets.c b/bfd/targets.c
index c34ce69..3dfa145 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -512,8 +512,8 @@ BFD_JUMP_TABLE macros.
.
. {* Check if SEC has been already linked during a reloceatable or
. final link. *}
-. void (*_section_already_linked) (bfd *, struct already_linked *,
-. struct bfd_link_info *);
+. bfd_boolean (*_section_already_linked) (bfd *, struct already_linked *,
+. struct bfd_link_info *);
.
. {* Define a common symbol. *}
. bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 2b217b5..bb23c7a 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2011-08-05 Alan Modra <amodra@gmail.com>
+
+ PR ld/12762
+ * plugin.c (add_symbols): Exclude comdat_key symbols from symbol
+ table if already seen.
+
2011-08-04 H.J. Lu <hongjiu.lu@intel.com>
* ldmain.c (main): Replace remove_output with ld_cleanup in
diff --git a/ld/plugin.c b/ld/plugin.c
index 0a0ee0c..5ba1fca 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -380,10 +380,11 @@ add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
{
asymbol **symptrs;
bfd *abfd = handle;
- int n;
+ int n, k;
+
ASSERT (called_plugin);
symptrs = xmalloc (nsyms * sizeof *symptrs);
- for (n = 0; n < nsyms; n++)
+ for (n = 0, k = 0; n < nsyms; n++)
{
enum ld_plugin_status rv;
asymbol *bfdsym;
@@ -393,15 +394,16 @@ add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
struct already_linked linked;
linked.comdat_key = xstrdup (syms[n].comdat_key);
linked.u.abfd = abfd;
- bfd_section_already_linked (abfd, &linked, &link_info);
+ if (bfd_section_already_linked (abfd, &linked, &link_info))
+ continue;
}
bfdsym = bfd_make_empty_symbol (abfd);
- symptrs[n] = bfdsym;
+ symptrs[k++] = bfdsym;
rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n);
if (rv != LDPS_OK)
return rv;
}
- bfd_set_symtab (abfd, symptrs, nsyms);
+ bfd_set_symtab (abfd, symptrs, k);
return LDPS_OK;
}