Cache result of scan for __start_* and __stop_* sections

include/
	* bfdlink.h (struct bfd_link_hash_entry): Add "section" field to
	undef.  Formatting.
bfd/
	* elflink.c (_bfd_elf_is_start_stop): New function.
	(_bfd_elf_gc_mark_rsec): Use it.
	* elf-bfd.h (_bfd_elf_is_start_stop): Declare.
This commit is contained in:
Alan Modra 2016-04-27 12:53:05 +09:30
parent 28cc9170c3
commit a6a4679fc0
5 changed files with 83 additions and 26 deletions

View File

@ -1,3 +1,9 @@
2016-04-27 Alan Modra <amodra@gmail.com>
* elflink.c (_bfd_elf_is_start_stop): New function.
(_bfd_elf_gc_mark_rsec): Use it.
* elf-bfd.h (_bfd_elf_is_start_stop): Declare.
2016-04-26 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
* elf32-rx.c (rx_set_section_contents): Avoid arithmetic on void *.

View File

@ -2336,6 +2336,9 @@ extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
extern bfd_boolean bfd_elf_gc_common_final_link
(bfd *, struct bfd_link_info *);
extern asection *_bfd_elf_is_start_stop
(const struct bfd_link_info *, struct elf_link_hash_entry *);
extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
(bfd_vma, void *);

View File

@ -12230,6 +12230,55 @@ _bfd_elf_gc_mark_hook (asection *sec,
return NULL;
}
/* For undefined __start_<name> and __stop_<name> symbols, return the
first input section matching <name>. Return NULL otherwise. */
asection *
_bfd_elf_is_start_stop (const struct bfd_link_info *info,
struct elf_link_hash_entry *h)
{
asection *s;
const char *sec_name;
if (h->root.type != bfd_link_hash_undefined
&& h->root.type != bfd_link_hash_undefweak)
return NULL;
s = h->root.u.undef.section;
if (s != NULL)
{
if (s == (asection *) 0 - 1)
return NULL;
return s;
}
sec_name = NULL;
if (strncmp (h->root.root.string, "__start_", 8) == 0)
sec_name = h->root.root.string + 8;
else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
sec_name = h->root.root.string + 7;
if (sec_name != NULL && *sec_name != '\0')
{
bfd *i;
for (i = info->input_bfds; i != NULL; i = i->link.next)
{
s = bfd_get_section_by_name (i, sec_name);
if (s != NULL)
{
h->root.u.undef.section = s;
break;
}
}
}
if (s == NULL)
h->root.u.undef.section = (asection *) 0 - 1;
return s;
}
/* COOKIE->rel describes a relocation against section SEC, which is
a section we've decided to keep. Return the section that contains
the relocation symbol, or NULL if no section contains it. */
@ -12268,34 +12317,19 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
if (h->u.weakdef != NULL)
h->u.weakdef->mark = 1;
if (start_stop != NULL
&& (h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak))
if (start_stop != NULL)
{
/* To work around a glibc bug, mark all XXX input sections
when there is an as yet undefined reference to __start_XXX
or __stop_XXX symbols. The linker will later define such
symbols for orphan input sections that have a name
representable as a C identifier. */
const char *sec_name = NULL;
if (strncmp (h->root.root.string, "__start_", 8) == 0)
sec_name = h->root.root.string + 8;
else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
sec_name = h->root.root.string + 7;
asection *s = _bfd_elf_is_start_stop (info, h);
if (sec_name != NULL && *sec_name != '\0')
if (s != NULL)
{
bfd *i;
for (i = info->input_bfds; i != NULL; i = i->link.next)
{
asection *s = bfd_get_section_by_name (i, sec_name);
if (s != NULL && !s->gc_mark)
{
*start_stop = TRUE;
return s;
}
}
*start_stop = !s->gc_mark;
return s;
}
}

View File

@ -1,3 +1,8 @@
2016-04-27 Alan Modra <amodra@gmail.com>
* bfdlink.h (struct bfd_link_hash_entry): Add "section" field to
undef. Formatting.
2016-04-21 Nick Clifton <nickc@redhat.com>
* bfdlink.h: Add prototype for bfd_link_check_relocs.

View File

@ -135,21 +135,29 @@ struct bfd_link_hash_entry
automatically be non-NULL since the symbol will have been on the
undefined symbol list. */
struct bfd_link_hash_entry *next;
bfd *abfd; /* BFD symbol was found in. */
/* BFD symbol was found in. */
bfd *abfd;
/* For __start_<name> and __stop_<name> symbols, the first
input section matching the name. */
asection *section;
} undef;
/* bfd_link_hash_defined, bfd_link_hash_defweak. */
struct
{
struct bfd_link_hash_entry *next;
asection *section; /* Symbol section. */
bfd_vma value; /* Symbol value. */
/* Symbol section. */
asection *section;
/* Symbol value. */
bfd_vma value;
} def;
/* bfd_link_hash_indirect, bfd_link_hash_warning. */
struct
{
struct bfd_link_hash_entry *next;
struct bfd_link_hash_entry *link; /* Real symbol. */
const char *warning; /* Warning (bfd_link_hash_warning only). */
/* Real symbol. */
struct bfd_link_hash_entry *link;
/* Warning message (bfd_link_hash_warning only). */
const char *warning;
} i;
/* bfd_link_hash_common. */
struct
@ -165,7 +173,8 @@ struct bfd_link_hash_entry
the union; this structure is a major space user in the
linker. */
struct bfd_link_hash_common_entry *p;
bfd_size_type size; /* Common symbol size. */
/* Common symbol size. */
bfd_size_type size;
} c;
} u;
};