diff options
author | Ian Lance Taylor <iant@google.com> | 2007-10-22 23:08:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-10-22 23:08:22 +0000 |
commit | 46fe162319cc0ad598f8aa74495ccde823349da2 (patch) | |
tree | 89aa9522a5133a2ee339f480d29f069908315988 /gold/symtab.cc | |
parent | 60dc88db8bb295650876632bce467ba703fea555 (diff) | |
download | gdb-46fe162319cc0ad598f8aa74495ccde823349da2.zip gdb-46fe162319cc0ad598f8aa74495ccde823349da2.tar.gz gdb-46fe162319cc0ad598f8aa74495ccde823349da2.tar.bz2 |
Fix versions of copied symbols.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r-- | gold/symtab.cc | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc index 3eee9be..1f120dd 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -66,6 +66,7 @@ Symbol::init_fields(const char* name, const char* version, this->has_got_offset_ = false; this->has_plt_offset_ = false; this->has_warning_ = false; + this->is_copied_from_dynobj_ = false; } // Initialize the fields in the base class Symbol for SYM in OBJECT. @@ -1223,6 +1224,70 @@ Symbol_table::define_symbols(const Layout* layout, const Target* target, } } +// Define CSYM using a COPY reloc. POSD is the Output_data where the +// symbol should be defined--typically a .dyn.bss section. VALUE is +// the offset within POSD. + +template<int size> +void +Symbol_table::define_with_copy_reloc(const Target* target, + Sized_symbol<size>* csym, + Output_data* posd, uint64_t value) +{ + gold_assert(csym->is_from_dynobj()); + gold_assert(!csym->is_copied_from_dynobj()); + Object* object = csym->object(); + gold_assert(object->is_dynamic()); + Dynobj* dynobj = static_cast<Dynobj*>(object); + + // Our copied variable has to override any variable in a shared + // library. + elfcpp::STB binding = csym->binding(); + if (binding == elfcpp::STB_WEAK) + binding = elfcpp::STB_GLOBAL; + + this->define_in_output_data(target, csym->name(), csym->version(), + posd, value, csym->symsize(), + csym->type(), binding, + csym->visibility(), csym->nonvis(), + false, false); + + csym->set_is_copied_from_dynobj(); + csym->set_needs_dynsym_entry(); + + this->copied_symbol_dynobjs_[csym] = dynobj; + + // We have now defined all aliases, but we have not entered them all + // in the copied_symbol_dynobjs_ map. + if (csym->has_alias()) + { + Symbol* sym = csym; + while (true) + { + sym = this->weak_aliases_[sym]; + if (sym == csym) + break; + gold_assert(sym->output_data() == posd); + + sym->set_is_copied_from_dynobj(); + this->copied_symbol_dynobjs_[sym] = dynobj; + } + } +} + +// SYM is defined using a COPY reloc. Return the dynamic object where +// the original definition was found. + +Dynobj* +Symbol_table::get_copy_source(const Symbol* sym) const +{ + gold_assert(sym->is_copied_from_dynobj()); + Copied_symbol_dynobjs::const_iterator p = + this->copied_symbol_dynobjs_.find(sym); + gold_assert(p != this->copied_symbol_dynobjs_.end()); + return p->second; +} + // 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 @@ -1257,7 +1322,7 @@ Symbol_table::set_dynsym_indexes(const General_options* options, // Record any version information. if (sym->version() != NULL) - versions->record_version(options, dynpool, sym); + versions->record_version(options, this, dynpool, sym); } } @@ -1901,6 +1966,22 @@ Symbol_table::add_from_dynobj<64, true>( const std::vector<const char*>* version_map); #endif +#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) +template +void +Symbol_table::define_with_copy_reloc<32>(const Target* target, + Sized_symbol<32>* sym, + Output_data* posd, uint64_t value); +#endif + +#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) +template +void +Symbol_table::define_with_copy_reloc<64>(const Target* target, + Sized_symbol<64>* sym, + Output_data* posd, uint64_t value); +#endif + #ifdef HAVE_TARGET_32_LITTLE template void @@ -1933,5 +2014,4 @@ Warnings::issue_warning<64, true>(const Symbol* sym, size_t relnum, off_t reloffset) const; #endif - } // End namespace gold. |