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.
This commit is contained in:
parent
6177242a84
commit
43e1669b2d
@ -1,3 +1,18 @@
|
||||
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.
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 *);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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. */
|
||||
|
||||
23
bfd/linker.c
23
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. */
|
||||
|
||||
@ -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 *,
|
||||
|
||||
@ -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
|
||||
|
||||
12
ld/plugin.c
12
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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user