Fix versions of copied symbols.
This commit is contained in:
parent
60dc88db8b
commit
46fe162319
@ -1190,11 +1190,28 @@ Versions::~Versions()
|
||||
delete *p;
|
||||
}
|
||||
|
||||
// Return the dynamic object which a symbol refers to.
|
||||
|
||||
Dynobj*
|
||||
Versions::get_dynobj_for_sym(const Symbol_table* symtab,
|
||||
const Symbol* sym) const
|
||||
{
|
||||
if (sym->is_copied_from_dynobj())
|
||||
return symtab->get_copy_source(sym);
|
||||
else
|
||||
{
|
||||
Object* object = sym->object();
|
||||
gold_assert(object->is_dynamic());
|
||||
return static_cast<Dynobj*>(object);
|
||||
}
|
||||
}
|
||||
|
||||
// Record version information for a symbol going into the dynamic
|
||||
// symbol table.
|
||||
|
||||
void
|
||||
Versions::record_version(const General_options* options,
|
||||
const Symbol_table* symtab,
|
||||
Stringpool* dynpool, const Symbol* sym)
|
||||
{
|
||||
gold_assert(!this->is_finalized_);
|
||||
@ -1203,7 +1220,7 @@ Versions::record_version(const General_options* options,
|
||||
Stringpool::Key version_key;
|
||||
const char* version = dynpool->add(sym->version(), false, &version_key);
|
||||
|
||||
if (!sym->is_from_dynobj())
|
||||
if (!sym->is_from_dynobj() && !sym->is_copied_from_dynobj())
|
||||
{
|
||||
if (parameters->output_is_shared())
|
||||
this->add_def(options, sym, version, version_key);
|
||||
@ -1211,11 +1228,7 @@ Versions::record_version(const General_options* options,
|
||||
else
|
||||
{
|
||||
// This is a version reference.
|
||||
|
||||
Object* object = sym->object();
|
||||
gold_assert(object->is_dynamic());
|
||||
Dynobj* dynobj = static_cast<Dynobj*>(object);
|
||||
|
||||
Dynobj* dynobj = this->get_dynobj_for_sym(symtab, sym);
|
||||
this->add_need(dynpool, dynobj->soname(), version, version_key);
|
||||
}
|
||||
}
|
||||
@ -1375,14 +1388,15 @@ Versions::finalize(const Target* target, Symbol_table* symtab,
|
||||
// pointers.
|
||||
|
||||
unsigned int
|
||||
Versions::version_index(const Stringpool* dynpool, const Symbol* sym) const
|
||||
Versions::version_index(const Symbol_table* symtab, const Stringpool* dynpool,
|
||||
const Symbol* sym) const
|
||||
{
|
||||
Stringpool::Key version_key;
|
||||
const char* version = dynpool->find(sym->version(), &version_key);
|
||||
gold_assert(version != NULL);
|
||||
|
||||
Key k;
|
||||
if (!sym->is_from_dynobj())
|
||||
if (!sym->is_from_dynobj() && !sym->is_copied_from_dynobj())
|
||||
{
|
||||
if (!parameters->output_is_shared())
|
||||
return elfcpp::VER_NDX_GLOBAL;
|
||||
@ -1390,9 +1404,7 @@ Versions::version_index(const Stringpool* dynpool, const Symbol* sym) const
|
||||
}
|
||||
else
|
||||
{
|
||||
Object* object = sym->object();
|
||||
gold_assert(object->is_dynamic());
|
||||
Dynobj* dynobj = static_cast<Dynobj*>(object);
|
||||
Dynobj* dynobj = this->get_dynobj_for_sym(symtab, sym);
|
||||
|
||||
Stringpool::Key filename_key;
|
||||
const char* filename = dynpool->find(dynobj->soname(), &filename_key);
|
||||
@ -1412,7 +1424,8 @@ Versions::version_index(const Stringpool* dynpool, const Symbol* sym) const
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Versions::symbol_section_contents(const Stringpool* dynpool,
|
||||
Versions::symbol_section_contents(const Symbol_table* symtab,
|
||||
const Stringpool* dynpool,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& syms,
|
||||
unsigned char** pp,
|
||||
@ -1437,7 +1450,7 @@ Versions::symbol_section_contents(const Stringpool* dynpool,
|
||||
if (version == NULL)
|
||||
version_index = elfcpp::VER_NDX_GLOBAL;
|
||||
else
|
||||
version_index = this->version_index(dynpool, *p);
|
||||
version_index = this->version_index(symtab, dynpool, *p);
|
||||
elfcpp::Swap<16, big_endian>::writeval(pbuf + (*p)->dynsym_index() * 2,
|
||||
version_index);
|
||||
}
|
||||
@ -1561,6 +1574,7 @@ class Sized_dynobj<64, true>;
|
||||
template
|
||||
void
|
||||
Versions::symbol_section_contents<32, false>(
|
||||
const Symbol_table*,
|
||||
const Stringpool*,
|
||||
unsigned int,
|
||||
const std::vector<Symbol*>&,
|
||||
@ -1573,6 +1587,7 @@ Versions::symbol_section_contents<32, false>(
|
||||
template
|
||||
void
|
||||
Versions::symbol_section_contents<32, true>(
|
||||
const Symbol_table*,
|
||||
const Stringpool*,
|
||||
unsigned int,
|
||||
const std::vector<Symbol*>&,
|
||||
@ -1585,6 +1600,7 @@ Versions::symbol_section_contents<32, true>(
|
||||
template
|
||||
void
|
||||
Versions::symbol_section_contents<64, false>(
|
||||
const Symbol_table*,
|
||||
const Stringpool*,
|
||||
unsigned int,
|
||||
const std::vector<Symbol*>&,
|
||||
@ -1597,6 +1613,7 @@ Versions::symbol_section_contents<64, false>(
|
||||
template
|
||||
void
|
||||
Versions::symbol_section_contents<64, true>(
|
||||
const Symbol_table*,
|
||||
const Stringpool*,
|
||||
unsigned int,
|
||||
const std::vector<Symbol*>&,
|
||||
|
@ -411,7 +411,8 @@ class Versions
|
||||
// SYM is going into the dynamic symbol table and has a version.
|
||||
// Record the appropriate version information.
|
||||
void
|
||||
record_version(const General_options*, Stringpool*, const Symbol* sym);
|
||||
record_version(const General_options*, const Symbol_table* symtab,
|
||||
Stringpool*, const Symbol* sym);
|
||||
|
||||
// Set the version indexes. DYNSYM_INDEX is the index we should use
|
||||
// for the next dynamic symbol. We add new dynamic symbols to SYMS
|
||||
@ -434,7 +435,8 @@ class Versions
|
||||
// version section (.gnu.version).
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
symbol_section_contents(const Stringpool*, unsigned int local_symcount,
|
||||
symbol_section_contents(const Symbol_table*, const Stringpool*,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& syms,
|
||||
unsigned char**, unsigned int*
|
||||
ACCEPT_SIZE_ENDIAN) const;
|
||||
@ -472,9 +474,14 @@ class Versions
|
||||
add_need(Stringpool*, const char* filename, const char* name,
|
||||
Stringpool::Key);
|
||||
|
||||
// Get the dynamic object to use for SYM.
|
||||
Dynobj*
|
||||
get_dynobj_for_sym(const Symbol_table*, const Symbol* sym) const;
|
||||
|
||||
// Return the version index to use for SYM.
|
||||
unsigned int
|
||||
version_index(const Stringpool*, const Symbol* sym) const;
|
||||
version_index(const Symbol_table*, const Stringpool*,
|
||||
const Symbol* sym) const;
|
||||
|
||||
// We keep a hash table mapping canonicalized name/version pairs to
|
||||
// a version base.
|
||||
|
@ -649,14 +649,9 @@ Target_i386::copy_reloc(const General_options* options,
|
||||
off_t offset = dynbss_size;
|
||||
dynbss->set_space_size(dynbss_size + symsize);
|
||||
|
||||
// Define the symbol in the .dynbss section.
|
||||
symtab->define_in_output_data(this, ssym->name(), ssym->version(),
|
||||
dynbss, offset, symsize, ssym->type(),
|
||||
ssym->binding(), ssym->visibility(),
|
||||
ssym->nonvis(), false, false);
|
||||
symtab->define_with_copy_reloc(this, ssym, dynbss, offset);
|
||||
|
||||
// Add the COPY reloc.
|
||||
ssym->set_needs_dynsym_entry();
|
||||
Reloc_section* rel_dyn = this->rel_dyn_section(layout);
|
||||
rel_dyn->add_global(ssym, elfcpp::R_386_COPY, dynbss, offset);
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
|
||||
|
||||
// Create the version sections. We can't do this until the
|
||||
// dynamic string table is complete.
|
||||
this->create_version_sections(&versions, local_dynamic_count,
|
||||
this->create_version_sections(&versions, symtab, local_dynamic_count,
|
||||
dynamic_symbols, dynstr);
|
||||
}
|
||||
|
||||
@ -1214,6 +1214,7 @@ Layout::create_dynamic_symtab(const Target* target, Symbol_table* symtab,
|
||||
|
||||
void
|
||||
Layout::create_version_sections(const Versions* versions,
|
||||
const Symbol_table* symtab,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& dynamic_symbols,
|
||||
const Output_section* dynstr)
|
||||
@ -1228,7 +1229,7 @@ Layout::create_version_sections(const Versions* versions,
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
this->sized_create_version_sections
|
||||
SELECT_SIZE_ENDIAN_NAME(32, true)(
|
||||
versions, local_symcount, dynamic_symbols, dynstr
|
||||
versions, symtab, local_symcount, dynamic_symbols, dynstr
|
||||
SELECT_SIZE_ENDIAN(32, true));
|
||||
#else
|
||||
gold_unreachable();
|
||||
@ -1239,7 +1240,7 @@ Layout::create_version_sections(const Versions* versions,
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
this->sized_create_version_sections
|
||||
SELECT_SIZE_ENDIAN_NAME(32, false)(
|
||||
versions, local_symcount, dynamic_symbols, dynstr
|
||||
versions, symtab, local_symcount, dynamic_symbols, dynstr
|
||||
SELECT_SIZE_ENDIAN(32, false));
|
||||
#else
|
||||
gold_unreachable();
|
||||
@ -1253,7 +1254,7 @@ Layout::create_version_sections(const Versions* versions,
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
this->sized_create_version_sections
|
||||
SELECT_SIZE_ENDIAN_NAME(64, true)(
|
||||
versions, local_symcount, dynamic_symbols, dynstr
|
||||
versions, symtab, local_symcount, dynamic_symbols, dynstr
|
||||
SELECT_SIZE_ENDIAN(64, true));
|
||||
#else
|
||||
gold_unreachable();
|
||||
@ -1264,7 +1265,7 @@ Layout::create_version_sections(const Versions* versions,
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
this->sized_create_version_sections
|
||||
SELECT_SIZE_ENDIAN_NAME(64, false)(
|
||||
versions, local_symcount, dynamic_symbols, dynstr
|
||||
versions, symtab, local_symcount, dynamic_symbols, dynstr
|
||||
SELECT_SIZE_ENDIAN(64, false));
|
||||
#else
|
||||
gold_unreachable();
|
||||
@ -1281,6 +1282,7 @@ template<int size, bool big_endian>
|
||||
void
|
||||
Layout::sized_create_version_sections(
|
||||
const Versions* versions,
|
||||
const Symbol_table* symtab,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& dynamic_symbols,
|
||||
const Output_section* dynstr
|
||||
@ -1294,7 +1296,7 @@ Layout::sized_create_version_sections(
|
||||
unsigned char* vbuf;
|
||||
unsigned int vsize;
|
||||
versions->symbol_section_contents SELECT_SIZE_ENDIAN_NAME(size, big_endian)(
|
||||
&this->dynpool_, local_symcount, dynamic_symbols, &vbuf, &vsize
|
||||
symtab, &this->dynpool_, local_symcount, dynamic_symbols, &vbuf, &vsize
|
||||
SELECT_SIZE_ENDIAN(size, big_endian));
|
||||
|
||||
Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2);
|
||||
|
@ -257,6 +257,7 @@ class Layout
|
||||
// Create the version sections.
|
||||
void
|
||||
create_version_sections(const Versions*,
|
||||
const Symbol_table*,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& dynamic_symbols,
|
||||
const Output_section* dynstr);
|
||||
@ -264,6 +265,7 @@ class Layout
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
sized_create_version_sections(const Versions* versions,
|
||||
const Symbol_table*,
|
||||
unsigned int local_symcount,
|
||||
const std::vector<Symbol*>& dynamic_symbols,
|
||||
const Output_section* dynstr
|
||||
|
@ -620,6 +620,8 @@ Symbol_table::should_override_with_special(const Symbol* to)
|
||||
void
|
||||
Symbol::override_base_with_special(const Symbol* from)
|
||||
{
|
||||
gold_assert(this->name_ == from->name_ || this->has_alias());
|
||||
|
||||
this->source_ = from->source_;
|
||||
switch (from->source_)
|
||||
{
|
||||
@ -652,6 +654,20 @@ Symbol::override_base_with_special(const Symbol* from)
|
||||
|
||||
// Special symbols are always considered to be regular symbols.
|
||||
this->in_reg_ = true;
|
||||
|
||||
if (from->needs_dynsym_entry_)
|
||||
this->needs_dynsym_entry_ = true;
|
||||
if (from->needs_dynsym_value_)
|
||||
this->needs_dynsym_value_ = true;
|
||||
|
||||
// We shouldn't see these flags. If we do, we need to handle them
|
||||
// somehow.
|
||||
gold_assert(!from->is_target_special_ || this->is_target_special_);
|
||||
gold_assert(!from->is_forwarder_);
|
||||
gold_assert(!from->has_got_offset_);
|
||||
gold_assert(!from->has_plt_offset_);
|
||||
gold_assert(!from->has_warning_);
|
||||
gold_assert(!from->is_copied_from_dynobj_);
|
||||
}
|
||||
|
||||
// Override a symbol with a special symbol.
|
||||
|
@ -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.
|
||||
|
@ -422,6 +422,17 @@ class Symbol
|
||||
set_has_warning()
|
||||
{ this->has_warning_ = true; }
|
||||
|
||||
// Return whether this symbol is defined by a COPY reloc from a
|
||||
// dynamic object.
|
||||
bool
|
||||
is_copied_from_dynobj() const
|
||||
{ return this->is_copied_from_dynobj_; }
|
||||
|
||||
// Mark this symbol as defined by a COPY reloc.
|
||||
void
|
||||
set_is_copied_from_dynobj()
|
||||
{ this->is_copied_from_dynobj_ = true; }
|
||||
|
||||
protected:
|
||||
// Instances of this class should always be created at a specific
|
||||
// size.
|
||||
@ -573,6 +584,9 @@ class Symbol
|
||||
bool needs_dynsym_value_ : 1;
|
||||
// True if there is a warning for this symbol.
|
||||
bool has_warning_ : 1;
|
||||
// True if we are using a COPY reloc for this symbol, so that the
|
||||
// real definition lives in a dynamic object.
|
||||
bool is_copied_from_dynobj_ : 1;
|
||||
};
|
||||
|
||||
// The parts of a symbol which are size specific. Using a template
|
||||
@ -870,6 +884,14 @@ class Symbol_table
|
||||
define_symbols(const Layout*, const Target*, int count,
|
||||
const Define_symbol_in_segment*);
|
||||
|
||||
// Define SYM 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
|
||||
define_with_copy_reloc(const Target*, Sized_symbol<size>* sym,
|
||||
Output_data* posd, uint64_t value);
|
||||
|
||||
// Look up a symbol.
|
||||
Symbol*
|
||||
lookup(const char*, const char* version = NULL) const;
|
||||
@ -915,6 +937,11 @@ class Symbol_table
|
||||
size_t relnum, off_t reloffset) const
|
||||
{ this->warnings_.issue_warning(sym, relinfo, relnum, reloffset); }
|
||||
|
||||
// SYM is defined using a COPY reloc. Return the dynamic object
|
||||
// where the original definition was found.
|
||||
Dynobj*
|
||||
get_copy_source(const Symbol* sym) const;
|
||||
|
||||
// Set the dynamic symbol indexes. INDEX is the index of the first
|
||||
// global dynamic symbol. Pointers to the symbols are stored into
|
||||
// the vector. The names are stored into the Stringpool. This
|
||||
@ -1089,55 +1116,52 @@ class Symbol_table
|
||||
Symbol_table_eq> Symbol_table_type;
|
||||
|
||||
// The type of the list of common symbols.
|
||||
|
||||
typedef std::vector<Symbol*> Commons_type;
|
||||
|
||||
// A map from symbols with COPY relocs to the dynamic objects where
|
||||
// they are defined.
|
||||
typedef Unordered_map<const Symbol*, Dynobj*> Copied_symbol_dynobjs;
|
||||
|
||||
// We increment this every time we see a new undefined symbol, for
|
||||
// use in archive groups.
|
||||
int saw_undefined_;
|
||||
|
||||
// The index of the first global symbol in the output file.
|
||||
unsigned int first_global_index_;
|
||||
|
||||
// The file offset within the output symtab section where we should
|
||||
// write the table.
|
||||
off_t offset_;
|
||||
|
||||
// The number of global symbols we want to write out.
|
||||
size_t output_count_;
|
||||
|
||||
// The file offset of the global dynamic symbols, or 0 if none.
|
||||
off_t dynamic_offset_;
|
||||
|
||||
// The index of the first global dynamic symbol.
|
||||
unsigned int first_dynamic_global_index_;
|
||||
|
||||
// The number of global dynamic symbols, or 0 if none.
|
||||
off_t dynamic_count_;
|
||||
|
||||
// The symbol hash table.
|
||||
Symbol_table_type table_;
|
||||
|
||||
// A pool of symbol names. This is used for all global symbols.
|
||||
// Entries in the hash table point into this pool.
|
||||
Stringpool namepool_;
|
||||
|
||||
// Forwarding symbols.
|
||||
Unordered_map<const Symbol*, Symbol*> forwarders_;
|
||||
|
||||
// Weak aliases. A symbol in this list points to the next alias.
|
||||
// The aliases point to each other in a circular list.
|
||||
Unordered_map<Symbol*, Symbol*> weak_aliases_;
|
||||
|
||||
// We don't expect there to be very many common symbols, so we keep
|
||||
// a list of them. When we find a common symbol we add it to this
|
||||
// list. It is possible that by the time we process the list the
|
||||
// symbol is no longer a common symbol. It may also have become a
|
||||
// forwarder.
|
||||
Commons_type commons_;
|
||||
|
||||
// Manage symbol warnings.
|
||||
Warnings warnings_;
|
||||
// When we emit a COPY reloc for a symbol, we define it in an
|
||||
// Output_data. When it's time to emit version information for it,
|
||||
// we need to know the dynamic object in which we found the original
|
||||
// definition. This maps symbols with COPY relocs to the dynamic
|
||||
// object where they were defined.
|
||||
Copied_symbol_dynobjs copied_symbol_dynobjs_;
|
||||
};
|
||||
|
||||
// We inline get_sized_symbol for efficiency.
|
||||
|
@ -621,14 +621,9 @@ Target_x86_64::copy_reloc(const General_options* options,
|
||||
off_t offset = dynbss_size;
|
||||
dynbss->set_space_size(dynbss_size + symsize);
|
||||
|
||||
// Define the symbol in the .dynbss section.
|
||||
symtab->define_in_output_data(this, ssym->name(), ssym->version(),
|
||||
dynbss, offset, symsize, ssym->type(),
|
||||
ssym->binding(), ssym->visibility(),
|
||||
ssym->nonvis(), false, false);
|
||||
symtab->define_with_copy_reloc(this, ssym, dynbss, offset);
|
||||
|
||||
// Add the COPY reloc.
|
||||
ssym->set_needs_dynsym_entry();
|
||||
Reloc_section* rela_dyn = this->rela_dyn_section(layout);
|
||||
rela_dyn->add_global(ssym, elfcpp::R_X86_64_COPY, dynbss, offset, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user