mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
* elflink.c (struct already_linked_section): Removed.
(try_match_symbols_in_sections, already_linked): Removed. (_bfd_elf_section_already_linked): Skip ^\.gnu\.linkonce\.[^.]*\. prefix of section names when finding already_linked_table chain. Compare section names. Instead of calling already_linked, do it inline and only for sections in the same already_linked_list.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2004-10-15 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elflink.c (struct already_linked_section): Removed.
|
||||||
|
(try_match_symbols_in_sections, already_linked): Removed.
|
||||||
|
(_bfd_elf_section_already_linked): Skip ^\.gnu\.linkonce\.[^.]*\.
|
||||||
|
prefix of section names when finding already_linked_table
|
||||||
|
chain. Compare section names. Instead of calling already_linked,
|
||||||
|
do it inline and only for sections in the same already_linked_list.
|
||||||
|
|
||||||
2004-10-15 Alan Modra <amodra@bigpond.net.au>
|
2004-10-15 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info"
|
* elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info"
|
||||||
|
120
bfd/elflink.c
120
bfd/elflink.c
@ -9268,88 +9268,11 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct already_linked_section
|
|
||||||
{
|
|
||||||
asection *sec;
|
|
||||||
asection *linked;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Check if the member of a single member comdat group matches a
|
|
||||||
linkonce section and vice versa. */
|
|
||||||
static bfd_boolean
|
|
||||||
try_match_symbols_in_sections
|
|
||||||
(struct bfd_section_already_linked_hash_entry *h, void *info)
|
|
||||||
{
|
|
||||||
struct bfd_section_already_linked *l;
|
|
||||||
struct already_linked_section *s
|
|
||||||
= (struct already_linked_section *) info;
|
|
||||||
|
|
||||||
if (elf_sec_group (s->sec) == NULL)
|
|
||||||
{
|
|
||||||
/* It is a linkonce section. Try to match it with the member of a
|
|
||||||
single member comdat group. */
|
|
||||||
for (l = h->entry; l != NULL; l = l->next)
|
|
||||||
if ((l->sec->flags & SEC_GROUP))
|
|
||||||
{
|
|
||||||
asection *first = elf_next_in_group (l->sec);
|
|
||||||
|
|
||||||
if (first != NULL
|
|
||||||
&& elf_next_in_group (first) == first
|
|
||||||
&& bfd_elf_match_symbols_in_sections (first, s->sec))
|
|
||||||
{
|
|
||||||
s->linked = first;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is the member of a single member comdat group. Try to match
|
|
||||||
it with a linkonce section. */
|
|
||||||
for (l = h->entry; l != NULL; l = l->next)
|
|
||||||
if ((l->sec->flags & SEC_GROUP) == 0
|
|
||||||
&& bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
|
|
||||||
&& bfd_elf_match_symbols_in_sections (l->sec, s->sec))
|
|
||||||
{
|
|
||||||
s->linked = l->sec;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bfd_boolean
|
|
||||||
already_linked (asection *sec, asection *group)
|
|
||||||
{
|
|
||||||
struct already_linked_section result;
|
|
||||||
|
|
||||||
result.sec = sec;
|
|
||||||
result.linked = NULL;
|
|
||||||
|
|
||||||
bfd_section_already_linked_table_traverse
|
|
||||||
(try_match_symbols_in_sections, &result);
|
|
||||||
|
|
||||||
if (result.linked)
|
|
||||||
{
|
|
||||||
sec->output_section = bfd_abs_section_ptr;
|
|
||||||
sec->kept_section = result.linked;
|
|
||||||
|
|
||||||
/* Also discard the group section. */
|
|
||||||
if (group)
|
|
||||||
group->output_section = bfd_abs_section_ptr;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
||||||
{
|
{
|
||||||
flagword flags;
|
flagword flags;
|
||||||
const char *name;
|
const char *name, *p;
|
||||||
struct bfd_section_already_linked *l;
|
struct bfd_section_already_linked *l;
|
||||||
struct bfd_section_already_linked_hash_entry *already_linked_list;
|
struct bfd_section_already_linked_hash_entry *already_linked_list;
|
||||||
asection *group;
|
asection *group;
|
||||||
@ -9399,7 +9322,13 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
|||||||
|
|
||||||
name = bfd_get_section_name (abfd, sec);
|
name = bfd_get_section_name (abfd, sec);
|
||||||
|
|
||||||
already_linked_list = bfd_section_already_linked_table_lookup (name);
|
if (strncmp (name, ".gnu.linkonce.", sizeof (".gnu.linkonce.") - 1) == 0
|
||||||
|
&& (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
|
||||||
|
p++;
|
||||||
|
else
|
||||||
|
p = name;
|
||||||
|
|
||||||
|
already_linked_list = bfd_section_already_linked_table_lookup (p);
|
||||||
|
|
||||||
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
@ -9409,10 +9338,11 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
|||||||
a linkonce section with a linkonce section, and ignore comdat
|
a linkonce section with a linkonce section, and ignore comdat
|
||||||
section. */
|
section. */
|
||||||
if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
|
if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
|
||||||
|
&& strcmp (name, l->sec->name) == 0
|
||||||
&& bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
|
&& bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
|
||||||
{
|
{
|
||||||
/* The section has already been linked. See if we should
|
/* The section has already been linked. See if we should
|
||||||
issue a warning. */
|
issue a warning. */
|
||||||
switch (flags & SEC_LINK_DUPLICATES)
|
switch (flags & SEC_LINK_DUPLICATES)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
@ -9501,15 +9431,39 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
|||||||
section. We only record the discarded comdat group. Otherwise
|
section. We only record the discarded comdat group. Otherwise
|
||||||
the undiscarded group will be discarded incorrectly later since
|
the undiscarded group will be discarded incorrectly later since
|
||||||
itself has been recorded. */
|
itself has been recorded. */
|
||||||
if (! already_linked (elf_next_in_group (sec), group))
|
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
||||||
|
if ((l->sec->flags & SEC_GROUP) == 0
|
||||||
|
&& bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
|
||||||
|
&& bfd_elf_match_symbols_in_sections (l->sec,
|
||||||
|
elf_next_in_group (sec)))
|
||||||
|
{
|
||||||
|
elf_next_in_group (sec)->output_section = bfd_abs_section_ptr;
|
||||||
|
elf_next_in_group (sec)->kept_section = l->sec;
|
||||||
|
group->output_section = bfd_abs_section_ptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l == NULL)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* There is no direct match. But for linkonce section, we should
|
/* There is no direct match. But for linkonce section, we should
|
||||||
check if there is a match with comdat group member. We always
|
check if there is a match with comdat group member. We always
|
||||||
record the linkonce section, discarded or not. */
|
record the linkonce section, discarded or not. */
|
||||||
already_linked (sec, group);
|
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
||||||
|
if (l->sec->flags & SEC_GROUP)
|
||||||
|
{
|
||||||
|
asection *first = elf_next_in_group (l->sec);
|
||||||
|
|
||||||
|
if (first != NULL
|
||||||
|
&& elf_next_in_group (first) == first
|
||||||
|
&& bfd_elf_match_symbols_in_sections (first, sec))
|
||||||
|
{
|
||||||
|
sec->output_section = bfd_abs_section_ptr;
|
||||||
|
sec->kept_section = l->sec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This is the first section with this name. Record it. */
|
/* This is the first section with this name. Record it. */
|
||||||
bfd_section_already_linked_table_insert (already_linked_list, sec);
|
bfd_section_already_linked_table_insert (already_linked_list, sec);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user