forked from Imagelibrary/binutils-gdb
Fix placement of forced local symbols in the dynamic symbol table.
Gold was not placing forced-local symbols (e.g., hidden visibility) at the front of the dynamic symbol table, or including them in the count of local symbols recorded in the .dynsym section's sh_info field. gold/ * layout.cc (Layout::finalize): Track count of forced-local symbols in .dynsym. (Layout::create_symtab_sections): Add local_dynamic_count parameter; use that instead of sh_info value. (Layout::create_dynamic_symtab): Add pforced_local_dynamic_count parameter; pass it to Symtab::set_dynsym_indexes(). Include forced locals in sh_info value. Pass index of first real global to Dynobj::create_gnu_hash_table() and Dynobj::create_elf_hash_table(). * layout.h (Layout::create_symtab_sections): Add local_dynamic_count parameter. (Layout::create_dynamic_symtab): Add pforced_local_dynamic_count parameter. * symtab.cc (Symbol_table::set_dynsym_indexes): Add pforced_local_count parameter. Process forced-local symbols first and return the count. (Symbol_table::finalize): Update comments. * symtab.h (Symbol_table::set_dynsym_indexes): Add pforced_local_count parameter. (Symbol_table::first_dynamic_global_index_): Update comment. (Symbol_table::dynamic_count_): Update comment. * testsuite/Makefile.am (ifuncmod1.sh): New test case. * testsuite/Makefile.in: Regenerate. * testsuite/ifuncmod1.sh: New shell script.
This commit is contained in:
@@ -2473,18 +2473,42 @@ Symbol_table::add_undefined_symbol_from_command_line(const char* name)
|
||||
}
|
||||
|
||||
// Set the dynamic symbol indexes. INDEX is the index of the first
|
||||
// global dynamic symbol. Pointers to the symbols are stored into the
|
||||
// vector SYMS. The names are added to DYNPOOL. This returns an
|
||||
// updated dynamic symbol index.
|
||||
// global dynamic symbol. Pointers to the global symbols are stored
|
||||
// into the vector SYMS. The names are added to DYNPOOL.
|
||||
// This returns an updated dynamic symbol index.
|
||||
|
||||
unsigned int
|
||||
Symbol_table::set_dynsym_indexes(unsigned int index,
|
||||
unsigned int* pforced_local_count,
|
||||
std::vector<Symbol*>* syms,
|
||||
Stringpool* dynpool,
|
||||
Versions* versions)
|
||||
{
|
||||
std::vector<Symbol*> as_needed_sym;
|
||||
|
||||
// First process all the symbols which have been forced to be local,
|
||||
// as they must appear before all global symbols.
|
||||
unsigned int forced_local_count = 0;
|
||||
for (Forced_locals::iterator p = this->forced_locals_.begin();
|
||||
p != this->forced_locals_.end();
|
||||
++p)
|
||||
{
|
||||
Symbol* sym = *p;
|
||||
gold_assert(sym->is_forced_local());
|
||||
if (sym->has_dynsym_index())
|
||||
continue;
|
||||
if (!sym->should_add_dynsym_entry(this))
|
||||
sym->set_dynsym_index(-1U);
|
||||
else
|
||||
{
|
||||
sym->set_dynsym_index(index);
|
||||
++index;
|
||||
++forced_local_count;
|
||||
dynpool->add(sym->name(), false, NULL);
|
||||
}
|
||||
}
|
||||
*pforced_local_count = forced_local_count;
|
||||
|
||||
// Allow a target to set dynsym indexes.
|
||||
if (parameters->target().has_custom_set_dynsym_indexes())
|
||||
{
|
||||
@@ -2494,6 +2518,8 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
|
||||
++p)
|
||||
{
|
||||
Symbol* sym = p->second;
|
||||
if (sym->is_forced_local())
|
||||
continue;
|
||||
if (!sym->should_add_dynsym_entry(this))
|
||||
sym->set_dynsym_index(-1U);
|
||||
else
|
||||
@@ -2510,6 +2536,9 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
|
||||
{
|
||||
Symbol* sym = p->second;
|
||||
|
||||
if (sym->is_forced_local())
|
||||
continue;
|
||||
|
||||
// Note that SYM may already have a dynamic symbol index, since
|
||||
// some symbols appear more than once in the symbol table, with
|
||||
// and without a version.
|
||||
@@ -2581,7 +2610,12 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
|
||||
// Set the final values for all the symbols. The index of the first
|
||||
// global symbol in the output file is *PLOCAL_SYMCOUNT. Record the
|
||||
// file offset OFF. Add their names to POOL. Return the new file
|
||||
// offset. Update *PLOCAL_SYMCOUNT if necessary.
|
||||
// offset. Update *PLOCAL_SYMCOUNT if necessary. DYNOFF and
|
||||
// DYN_GLOBAL_INDEX refer to the start of the symbols that will be
|
||||
// written from the global symbol table in Symtab::write_globals(),
|
||||
// which will include forced-local symbols. DYN_GLOBAL_INDEX is
|
||||
// not necessarily the same as the sh_info field for the .dynsym
|
||||
// section, which will point to the first real global symbol.
|
||||
|
||||
off_t
|
||||
Symbol_table::finalize(off_t off, off_t dynoff, size_t dyn_global_index,
|
||||
|
||||
Reference in New Issue
Block a user