version 1.1.1.2, 2016/10/26 17:03:18 |
version 1.1.1.3, 2018/04/14 15:37:01 |
|
|
// symtab.cc -- the gold symbol table |
// symtab.cc -- the gold symbol table |
|
|
// Copyright (C) 2006-2015 Free Software Foundation, Inc. |
// Copyright (C) 2006-2016 Free Software Foundation, Inc. |
// Written by Ian Lance Taylor <iant@google.com>. |
// Written by Ian Lance Taylor <iant@google.com>. |
|
|
// This file is part of gold. |
// This file is part of gold. |
Line 80 Symbol::init_fields(const char* name, co |
|
Line 80 Symbol::init_fields(const char* name, co |
|
this->undef_binding_set_ = false; |
this->undef_binding_set_ = false; |
this->undef_binding_weak_ = false; |
this->undef_binding_weak_ = false; |
this->is_predefined_ = false; |
this->is_predefined_ = false; |
|
this->is_protected_ = false; |
} |
} |
|
|
// Return the demangled version of the symbol's name, but only |
// Return the demangled version of the symbol's name, but only |
Line 285 Sized_symbol<size>::init_constant(const |
|
Line 286 Sized_symbol<size>::init_constant(const |
|
template<int size> |
template<int size> |
void |
void |
Sized_symbol<size>::init_undefined(const char* name, const char* version, |
Sized_symbol<size>::init_undefined(const char* name, const char* version, |
elfcpp::STT type, elfcpp::STB binding, |
Value_type value, elfcpp::STT type, |
elfcpp::STV visibility, unsigned char nonvis) |
elfcpp::STB binding, elfcpp::STV visibility, |
|
unsigned char nonvis) |
{ |
{ |
this->init_base_undefined(name, version, type, binding, visibility, nonvis); |
this->init_base_undefined(name, version, type, binding, visibility, nonvis); |
this->value_ = 0; |
this->value_ = value; |
this->symsize_ = 0; |
this->symsize_ = 0; |
} |
} |
|
|
Line 565 Symbol_table::Symbol_table(unsigned int |
|
Line 567 Symbol_table::Symbol_table(unsigned int |
|
: saw_undefined_(0), offset_(0), table_(count), namepool_(), |
: saw_undefined_(0), offset_(0), table_(count), namepool_(), |
forwarders_(), commons_(), tls_commons_(), small_commons_(), |
forwarders_(), commons_(), tls_commons_(), small_commons_(), |
large_commons_(), forced_locals_(), warnings_(), |
large_commons_(), forced_locals_(), warnings_(), |
version_script_(version_script), gc_(NULL), icf_(NULL) |
version_script_(version_script), gc_(NULL), icf_(NULL), |
|
target_symbols_() |
{ |
{ |
namepool_.reserve(count); |
namepool_.reserve(count); |
} |
} |
Line 863 Symbol_table::define_default_version(Siz |
|
Line 866 Symbol_table::define_default_version(Siz |
|
// other is defined in a shared object, then they are different |
// other is defined in a shared object, then they are different |
// symbols. |
// symbols. |
|
|
|
// If the two symbols are from different shared objects, |
|
// they are different symbols. |
|
|
// Otherwise, we just resolve the symbols as though they were |
// Otherwise, we just resolve the symbols as though they were |
// the same. |
// the same. |
|
|
Line 874 Symbol_table::define_default_version(Siz |
|
Line 880 Symbol_table::define_default_version(Siz |
|
else if (pdef->second->visibility() != elfcpp::STV_DEFAULT |
else if (pdef->second->visibility() != elfcpp::STV_DEFAULT |
&& sym->is_from_dynobj()) |
&& sym->is_from_dynobj()) |
; |
; |
|
else if (pdef->second->is_from_dynobj() |
|
&& sym->is_from_dynobj() |
|
&& pdef->second->object() != sym->object()) |
|
; |
else |
else |
{ |
{ |
const Sized_symbol<size>* symdef; |
const Sized_symbol<size>* symdef; |
Line 1058 Symbol_table::add_from_object(Object* ob |
|
Line 1068 Symbol_table::add_from_object(Object* ob |
|
ret = new Sized_symbol<size>(); |
ret = new Sized_symbol<size>(); |
else |
else |
{ |
{ |
ret = target->make_symbol(); |
ret = target->make_symbol(name, sym.get_st_type(), object, |
|
st_shndx, sym.get_st_value()); |
if (ret == NULL) |
if (ret == NULL) |
{ |
{ |
// This means that we don't want a symbol table |
// This means that we don't want a symbol table |
Line 1171 Symbol_table::add_from_relobj( |
|
Line 1182 Symbol_table::add_from_relobj( |
|
|
|
const char* name = sym_names + st_name; |
const char* name = sym_names + st_name; |
|
|
if (strcmp (name, "__gnu_lto_slim") == 0) |
if (!parameters->options().relocatable() |
|
&& strcmp (name, "__gnu_lto_slim") == 0) |
gold_info(_("%s: plugin needed to handle lto object"), |
gold_info(_("%s: plugin needed to handle lto object"), |
relobj->name().c_str()); |
relobj->name().c_str()); |
|
|
Line 1599 Symbol_table::add_from_dynobj( |
|
Line 1611 Symbol_table::add_from_dynobj( |
|
&& res->object() == dynobj) |
&& res->object() == dynobj) |
object_symbols.push_back(res); |
object_symbols.push_back(res); |
|
|
|
// If the symbol has protected visibility in the dynobj, |
|
// mark it as such if it was not overridden. |
|
if (res->source() == Symbol::FROM_OBJECT |
|
&& res->object() == dynobj |
|
&& sym.get_st_visibility() == elfcpp::STV_PROTECTED) |
|
res->set_is_protected(); |
|
|
if (sympointers != NULL) |
if (sympointers != NULL) |
(*sympointers)[i] = res; |
(*sympointers)[i] = res; |
} |
} |
Line 1857 Symbol_table::define_special_symbol(cons |
|
Line 1876 Symbol_table::define_special_symbol(cons |
|
{ |
{ |
Sized_target<size, big_endian>* sized_target = |
Sized_target<size, big_endian>* sized_target = |
parameters->sized_target<size, big_endian>(); |
parameters->sized_target<size, big_endian>(); |
sym = sized_target->make_symbol(); |
sym = sized_target->make_symbol(*pname, elfcpp::STT_NOTYPE, |
|
NULL, elfcpp::SHN_UNDEF, 0); |
if (sym == NULL) |
if (sym == NULL) |
return NULL; |
return NULL; |
} |
} |
Line 2436 Symbol_table::add_undefined_symbol_from_ |
|
Line 2456 Symbol_table::add_undefined_symbol_from_ |
|
|
|
gold_assert(oldsym == NULL); |
gold_assert(oldsym == NULL); |
|
|
sym->init_undefined(name, version, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, |
sym->init_undefined(name, version, 0, elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, |
elfcpp::STV_DEFAULT, 0); |
elfcpp::STV_DEFAULT, 0); |
++this->saw_undefined_; |
++this->saw_undefined_; |
} |
} |
Line 2533 Symbol_table::set_dynsym_indexes(unsigne |
|
Line 2553 Symbol_table::set_dynsym_indexes(unsigne |
|
// symbols. |
// symbols. |
index = versions->finalize(this, index, syms); |
index = versions->finalize(this, index, syms); |
|
|
|
// Process target-specific symbols. |
|
for (std::vector<Symbol*>::iterator p = this->target_symbols_.begin(); |
|
p != this->target_symbols_.end(); |
|
++p) |
|
{ |
|
(*p)->set_dynsym_index(index); |
|
++index; |
|
syms->push_back(*p); |
|
dynpool->add((*p)->name(), false, NULL); |
|
} |
|
|
return index; |
return index; |
} |
} |
|
|
Line 2638 Symbol_table::sized_finalize(off_t off, |
|
Line 2669 Symbol_table::sized_finalize(off_t off, |
|
this->add_to_final_symtab<size>(sym, pool, &index, &off); |
this->add_to_final_symtab<size>(sym, pool, &index, &off); |
} |
} |
|
|
|
// Now do target-specific symbols. |
|
for (std::vector<Symbol*>::iterator p = this->target_symbols_.begin(); |
|
p != this->target_symbols_.end(); |
|
++p) |
|
{ |
|
this->add_to_final_symtab<size>(*p, pool, &index, &off); |
|
} |
|
|
this->output_count_ = index - orig_index; |
this->output_count_ = index - orig_index; |
|
|
return off; |
return off; |
Line 3107 Symbol_table::sized_write_globals(const |
|
Line 3146 Symbol_table::sized_write_globals(const |
|
} |
} |
} |
} |
|
|
|
// Write the target-specific symbols. |
|
for (std::vector<Symbol*>::const_iterator p = this->target_symbols_.begin(); |
|
p != this->target_symbols_.end(); |
|
++p) |
|
{ |
|
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(*p); |
|
|
|
unsigned int sym_index = sym->symtab_index(); |
|
unsigned int dynsym_index; |
|
if (dynamic_view == NULL) |
|
dynsym_index = -1U; |
|
else |
|
dynsym_index = sym->dynsym_index(); |
|
|
|
unsigned int shndx; |
|
switch (sym->source()) |
|
{ |
|
case Symbol::IS_CONSTANT: |
|
shndx = elfcpp::SHN_ABS; |
|
break; |
|
case Symbol::IS_UNDEFINED: |
|
shndx = elfcpp::SHN_UNDEF; |
|
break; |
|
default: |
|
gold_unreachable(); |
|
} |
|
|
|
if (sym_index != -1U) |
|
{ |
|
sym_index -= first_global_index; |
|
gold_assert(sym_index < output_count); |
|
unsigned char* ps = psyms + (sym_index * sym_size); |
|
this->sized_write_symbol<size, big_endian>(sym, sym->value(), shndx, |
|
sym->binding(), sympool, |
|
ps); |
|
} |
|
|
|
if (dynsym_index != -1U) |
|
{ |
|
dynsym_index -= first_dynamic_global_index; |
|
gold_assert(dynsym_index < dynamic_count); |
|
unsigned char* pd = dynamic_view + (dynsym_index * sym_size); |
|
this->sized_write_symbol<size, big_endian>(sym, sym->value(), shndx, |
|
sym->binding(), dynpool, |
|
pd); |
|
} |
|
} |
|
|
of->write_output_view(this->offset_, oview_size, psyms); |
of->write_output_view(this->offset_, oview_size, psyms); |
if (dynamic_view != NULL) |
if (dynamic_view != NULL) |
of->write_output_view(this->dynamic_offset_, dynamic_size, dynamic_view); |
of->write_output_view(this->dynamic_offset_, dynamic_size, dynamic_view); |
Line 3745 Sized_symbol<32>::init_output_data(const |
|
Line 3832 Sized_symbol<32>::init_output_data(const |
|
unsigned char nonvis, |
unsigned char nonvis, |
bool offset_is_from_end, |
bool offset_is_from_end, |
bool is_predefined); |
bool is_predefined); |
|
|
|
template |
|
void |
|
Sized_symbol<32>::init_constant(const char* name, const char* version, |
|
Value_type value, Size_type symsize, |
|
elfcpp::STT type, elfcpp::STB binding, |
|
elfcpp::STV visibility, unsigned char nonvis, |
|
bool is_predefined); |
|
|
|
template |
|
void |
|
Sized_symbol<32>::init_undefined(const char* name, const char* version, |
|
Value_type value, elfcpp::STT type, |
|
elfcpp::STB binding, elfcpp::STV visibility, |
|
unsigned char nonvis); |
#endif |
#endif |
|
|
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) |
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) |
Line 3758 Sized_symbol<64>::init_output_data(const |
|
Line 3860 Sized_symbol<64>::init_output_data(const |
|
unsigned char nonvis, |
unsigned char nonvis, |
bool offset_is_from_end, |
bool offset_is_from_end, |
bool is_predefined); |
bool is_predefined); |
|
|
|
template |
|
void |
|
Sized_symbol<64>::init_constant(const char* name, const char* version, |
|
Value_type value, Size_type symsize, |
|
elfcpp::STT type, elfcpp::STB binding, |
|
elfcpp::STV visibility, unsigned char nonvis, |
|
bool is_predefined); |
|
|
|
template |
|
void |
|
Sized_symbol<64>::init_undefined(const char* name, const char* version, |
|
Value_type value, elfcpp::STT type, |
|
elfcpp::STB binding, elfcpp::STV visibility, |
|
unsigned char nonvis); |
#endif |
#endif |
|
|
#ifdef HAVE_TARGET_32_LITTLE |
#ifdef HAVE_TARGET_32_LITTLE |