diff options
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r-- | gold/symtab.cc | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc index d97fbdd3586..32c97fbc349 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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, |