mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-04 18:36:32 +00: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:
parent
1c645fec9f
commit
6d2cd2108d
@ -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>
|
||||
|
||||
* 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;
|
||||
}
|
||||
|
||||
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
|
||||
_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
|
||||
{
|
||||
flagword flags;
|
||||
const char *name;
|
||||
const char *name, *p;
|
||||
struct bfd_section_already_linked *l;
|
||||
struct bfd_section_already_linked_hash_entry *already_linked_list;
|
||||
asection *group;
|
||||
@ -9399,7 +9322,13 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * 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)
|
||||
{
|
||||
@ -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
|
||||
section. */
|
||||
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)
|
||||
{
|
||||
/* The section has already been linked. See if we should
|
||||
issue a warning. */
|
||||
issue a warning. */
|
||||
switch (flags & SEC_LINK_DUPLICATES)
|
||||
{
|
||||
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
|
||||
the undiscarded group will be discarded incorrectly later since
|
||||
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;
|
||||
}
|
||||
else
|
||||
/* There is no direct match. But for linkonce section, we should
|
||||
check if there is a match with comdat group member. We always
|
||||
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. */
|
||||
bfd_section_already_linked_table_insert (already_linked_list, sec);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user