Line 600... |
Line 600... |
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
Symbol_table::gc_mark_symbol_for_shlib(Symbol* sym)
|
Symbol_table::gc_mark_symbol(Symbol* sym)
|
{
|
|
if (!sym->is_from_dynobj()
|
|
&& sym->is_externally_visible())
|
|
{
|
{
|
//Add the object and section to the work list.
|
//Add the object and section to the work list.
|
Relobj* obj = static_cast<Relobj*>(sym->object());
|
Relobj* obj = static_cast<Relobj*>(sym->object());
|
bool is_ordinary;
|
bool is_ordinary;
|
unsigned int shndx = sym->shndx(&is_ordinary);
|
unsigned int shndx = sym->shndx(&is_ordinary);
|
Line 615... |
Line 612... |
{
|
{
|
gold_assert(this->gc_!= NULL);
|
gold_assert(this->gc_!= NULL);
|
this->gc_->worklist().push(Section_id(obj, shndx));
|
this->gc_->worklist().push(Section_id(obj, shndx));
|
}
|
}
|
}
|
}
|
}
|
|
|
|
// When doing garbage collection, keep symbols that have been seen in
|
// When doing garbage collection, keep symbols that have been seen in
|
// dynamic objects.
|
// dynamic objects.
|
inline void
|
inline void
|
Symbol_table::gc_mark_dyn_syms(Symbol* sym)
|
Symbol_table::gc_mark_dyn_syms(Symbol* sym)
|
{
|
{
|
if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT
|
if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT
|
&& !sym->object()->is_dynamic())
|
&& !sym->object()->is_dynamic())
|
{
|
this->gc_mark_symbol(sym);
|
Relobj* obj = static_cast<Relobj*>(sym->object());
|
|
bool is_ordinary;
|
|
unsigned int shndx = sym->shndx(&is_ordinary);
|
|
if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
|
|
{
|
|
gold_assert(this->gc_ != NULL);
|
|
this->gc_->worklist().push(Section_id(obj, shndx));
|
|
}
|
|
}
|
|
}
|
}
|
|
|
// Make TO a symbol which forwards to FROM.
|
// Make TO a symbol which forwards to FROM.
|
|
|
void
|
void
|
Line 1141... |
Line 1128... |
// IS_DEFAULT_VERSION: is the version default?
|
// IS_DEFAULT_VERSION: is the version default?
|
// IS_FORCED_LOCAL: is the symbol forced local?
|
// IS_FORCED_LOCAL: is the symbol forced local?
|
bool is_default_version = false;
|
bool is_default_version = false;
|
bool is_forced_local = false;
|
bool is_forced_local = false;
|
|
|
|
// FIXME: For incremental links, we don't store version information,
|
|
// so we need to ignore version symbols for now.
|
|
if (parameters->incremental_update() && ver != NULL)
|
|
{
|
|
namelen = ver - name;
|
|
ver = NULL;
|
|
}
|
|
|
if (ver != NULL)
|
if (ver != NULL)
|
{
|
{
|
// The symbol name is of the form foo@VERSION or foo@@VERSION
|
// The symbol name is of the form foo@VERSION or foo@@VERSION
|
namelen = ver - name;
|
namelen = ver - name;
|
++ver;
|
++ver;
|
Line 1241... |
Line 1236... |
is_ordinary, orig_st_shndx);
|
is_ordinary, orig_st_shndx);
|
|
|
if (is_forced_local)
|
if (is_forced_local)
|
this->force_local(res);
|
this->force_local(res);
|
|
|
// If building a shared library using garbage collection, do not
|
// Do not treat this symbol as garbage if this symbol will be
|
// treat externally visible symbols as garbage.
|
// exported to the dynamic symbol table. This is true when
|
|
// building a shared library or using --export-dynamic and
|
|
// the symbol is externally visible.
|
if (parameters->options().gc_sections()
|
if (parameters->options().gc_sections()
|
&& parameters->options().shared())
|
&& res->is_externally_visible()
|
this->gc_mark_symbol_for_shlib(res);
|
&& !res->is_from_dynobj()
|
|
&& (parameters->options().shared()
|
|
|| parameters->options().export_dynamic()))
|
|
this->gc_mark_symbol(res);
|
|
|
if (is_defined_in_discarded_section)
|
if (is_defined_in_discarded_section)
|
res->set_is_defined_in_discarded_section();
|
res->set_is_defined_in_discarded_section();
|
|
|
(*sympointers)[i] = res;
|
(*sympointers)[i] = res;
|
Line 1344... |
Line 1344... |
{
|
{
|
gold_error(_("--just-symbols does not make sense with a shared object"));
|
gold_error(_("--just-symbols does not make sense with a shared object"));
|
return;
|
return;
|
}
|
}
|
|
|
|
// FIXME: For incremental links, we don't store version information,
|
|
// so we need to ignore version symbols for now.
|
|
if (parameters->incremental_update())
|
|
versym = NULL;
|
|
|
if (versym != NULL && versym_size / 2 < count)
|
if (versym != NULL && versym_size / 2 < count)
|
{
|
{
|
dynobj->error(_("too few symbol versions"));
|
dynobj->error(_("too few symbol versions"));
|
return;
|
return;
|
}
|
}
|
Line 1681... |
Line 1686... |
oldsym = this->lookup(*pname, NULL);
|
oldsym = this->lookup(*pname, NULL);
|
if (oldsym == NULL || !oldsym->is_undefined())
|
if (oldsym == NULL || !oldsym->is_undefined())
|
return NULL;
|
return NULL;
|
|
|
*pname = oldsym->name();
|
*pname = oldsym->name();
|
if (!is_default_version)
|
if (is_default_version)
|
|
*pversion = this->namepool_.add(*pversion, true, NULL);
|
|
else
|
*pversion = oldsym->version();
|
*pversion = oldsym->version();
|
}
|
}
|
else
|
else
|
{
|
{
|
// Canonicalize NAME and VERSION.
|
// Canonicalize NAME and VERSION.
|
Line 2805... |
Line 2812... |
|
|
unsigned int shndx;
|
unsigned int shndx;
|
typename elfcpp::Elf_types<size>::Elf_Addr sym_value = sym->value();
|
typename elfcpp::Elf_types<size>::Elf_Addr sym_value = sym->value();
|
typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
|
typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
|
elfcpp::STB binding = sym->binding();
|
elfcpp::STB binding = sym->binding();
|
|
|
|
// If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL.
|
|
if (binding == elfcpp::STB_GNU_UNIQUE
|
|
&& !parameters->options().gnu_unique())
|
|
binding = elfcpp::STB_GLOBAL;
|
|
|
switch (sym->source())
|
switch (sym->source())
|
{
|
{
|
case Symbol::FROM_OBJECT:
|
case Symbol::FROM_OBJECT:
|
{
|
{
|
bool is_ordinary;
|
bool is_ordinary;
|