PR22150, ld keeps a version reference for gc'd symbols

elf_gc_sweep_symbol should run after verdefs are calculated, since
the verdef code creates symbols for the versions.  However,
elf_gc_sweep_symbol needs to run before verrefs so as to not emit
useless verrefs for symbols that are gc'd.

I've also removed a _bfd_elf_link_renumber_dynsyms calls added by
Maciej after I fussed about it when reviewing.  On further examination
the call appears to be unnecessary.  Looking at renumber_dynsyms also
made me realize that the test to exclude .gnu.version has been wrong
since 2016-04-26 (git commit d5486c4372), so fix that too.

	PR 22150
	* elflink.c (bfd_elf_size_dynamic_sections): Garbage collect
	symbols before calculating verrefs.  Don't renumber dynsyms
	after gc.  Exclude .gnu.version when zero or one dynsym.
	Localize some vars and reindent.
This commit is contained in:
Alan Modra 2017-09-19 11:59:30 +09:30
parent ab502e635e
commit 3d13f3e9bd
2 changed files with 122 additions and 121 deletions

View File

@ -1,3 +1,11 @@
2017-09-19 Alan Modra <amodra@gmail.com>
PR 22150
* elflink.c (bfd_elf_size_dynamic_sections): Garbage collect
symbols before calculating verrefs. Don't renumber dynsyms
after gc. Exclude .gnu.version when zero or one dynsym.
Localize some vars and reindent.
2017-09-18 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22148

View File

@ -6006,19 +6006,18 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
struct elf_info_failed asvinfo;
struct bfd_elf_version_tree *t;
struct bfd_elf_version_expr *d;
struct elf_info_failed eif;
bfd_boolean all_defined;
asection *s;
size_t soname_indx;
eif.info = info;
eif.failed = FALSE;
/* If we are supposed to export all symbols into the dynamic symbol
table (this is not the normal case), then do so. */
if (info->export_dynamic
|| (bfd_link_executable (info) && info->dynamic))
{
struct elf_info_failed eif;
eif.info = info;
eif.failed = FALSE;
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_export_symbol,
&eif);
@ -6102,7 +6101,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
if (!info->allow_undefined_version)
{
/* Check if all global versions have a definition. */
all_defined = TRUE;
bfd_boolean all_defined = TRUE;
for (t = info->version_info; t != NULL; t = t->next)
for (d = t->globals.list; d != NULL; d = d->next)
if (d->literal && !d->symver && !d->script)
@ -6355,13 +6354,31 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
elf_tdata (output_bfd)->cverdefs = cdefs;
}
}
bed = get_elf_backend_data (output_bfd);
if (info->gc_sections && bed->can_gc_sections)
{
struct elf_gc_sweep_symbol_info sweep_info;
/* Remove the symbols that were in the swept sections from the
dynamic symbol table. */
sweep_info.info = info;
sweep_info.hide_symbol = bed->elf_backend_hide_symbol;
elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol,
&sweep_info);
}
if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
{
asection *s;
struct elf_find_verdep_info sinfo;
/* Work out the size of the version reference section. */
s = bfd_get_linker_section (dynobj, ".gnu.version_r");
BFD_ASSERT (s != NULL);
{
struct elf_find_verdep_info sinfo;
sinfo.info = info;
sinfo.vers = elf_tdata (output_bfd)->cverdefs;
@ -6460,30 +6477,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
elf_tdata (output_bfd)->cverrefs = crefs;
}
}
}
bed = get_elf_backend_data (output_bfd);
if (info->gc_sections && bed->can_gc_sections)
{
struct elf_gc_sweep_symbol_info sweep_info;
unsigned long section_sym_count;
/* Remove the symbols that were in the swept sections from the
dynamic symbol table. GCFIXME: Anyone know how to get them
out of the static symbol table as well? */
sweep_info.info = info;
sweep_info.hide_symbol = bed->elf_backend_hide_symbol;
elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol,
&sweep_info);
/* We need to reassign dynsym indices now that symbols may have
been removed. See the call in `bfd_elf_size_dynsym_hash_dynstr'
for the details of the conditions used here. */
if (elf_hash_table (info)->dynamic_sections_created
|| bed->always_renumber_dynsyms)
_bfd_elf_link_renumber_dynsyms (output_bfd, info, &section_sym_count);
}
/* Any syms created from now on start with -1 in
got.refcount/offset and plt.refcount/offset. */
@ -6792,7 +6785,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
if ((elf_tdata (output_bfd)->cverrefs == 0
&& elf_tdata (output_bfd)->cverdefs == 0)
|| _bfd_elf_link_renumber_dynsyms (output_bfd, info,
&section_sym_count) == 0)
&section_sym_count) <= 1)
{
asection *s;