aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc51
1 files changed, 30 insertions, 21 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index a410db3..8cf7789 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -15,10 +15,6 @@ namespace gold
// Class Symbol.
-Symbol::~Symbol()
-{
-}
-
// Initialize the fields in the base class Symbol.
template<int size, bool big_endian>
@@ -34,9 +30,10 @@ Symbol::init_base(const char* name, const char* version, Object* object,
this->binding_ = sym.get_st_bind();
this->visibility_ = sym.get_st_visibility();
this->other_ = sym.get_st_nonvis();
- this->special_ = false;
- this->def_ = false;
- this->forwarder_ = false;
+ this->is_special_ = false;
+ this->is_def_ = false;
+ this->is_forwarder_ = false;
+ this->in_dyn_ = object->is_dynamic();
}
// Initialize the fields in Sized_symbol.
@@ -107,11 +104,22 @@ Symbol_table::resolve_forwards(Symbol* from) const
// Resolve a Symbol with another Symbol. This is only used in the
// unusual case where there are references to both an unversioned
// symbol and a symbol with a version, and we then discover that that
-// version is the default version.
+// version is the default version. Because this is unusual, we do
+// this the slow way, by converting back to an ELF symbol.
+template<int size, bool big_endian>
void
-Symbol_table::resolve(Symbol*, const Symbol*)
+Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
{
+ unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
+ elfcpp::Sym_write<size, big_endian> esym(buf);
+ // We don't bother to set the st_name field.
+ esym.put_st_value(from->value());
+ esym.put_st_size(from->symsize());
+ esym.put_st_info(from->binding(), from->type());
+ esym.put_st_other(from->visibility(), from->other());
+ esym.put_st_shndx(from->shnum());
+ Symbol_table::resolve(to, esym.sym(), from->object());
}
// Add one symbol from OBJECT to the symbol table. NAME is symbol
@@ -162,11 +170,11 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
// ins.first->second: the value (Symbol*).
// ins.second: true if new entry was inserted, false if not.
- Symbol* ret;
+ Sized_symbol<size>* ret;
if (!ins.second)
{
// We already have an entry for NAME/VERSION.
- ret = ins.first->second;
+ ret = this->get_sized_symbol<size>(ins.first->second);
assert(ret != NULL);
Symbol_table::resolve(ret, sym, object);
@@ -182,7 +190,9 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
{
// This is the unfortunate case where we already have
// entries for both NAME/VERSION and NAME/NULL.
- Symbol_table::resolve(ret, insdef.first->second);
+ const Sized_symbol<size>* sym2 =
+ this->get_sized_symbol<size>(insdef.first->second);
+ Symbol_table::resolve<size, big_endian>(ret, sym2);
this->make_forwarder(insdef.first->second, ret);
insdef.first->second = ret;
}
@@ -196,18 +206,19 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
{
// We already have an entry for NAME/NULL. Make
// NAME/VERSION point to it.
- ret = insdef.first->second;
+ ret = this->get_sized_symbol<size>(insdef.first->second);
Symbol_table::resolve(ret, sym, object);
ins.first->second = ret;
}
else
{
- Sized_symbol<size>* rs;
Sized_target<size, big_endian>* target = object->sized_target();
- if (target->has_make_symbol())
+ if (!target->has_make_symbol())
+ ret = new Sized_symbol<size>();
+ else
{
- rs = target->make_symbol();
- if (rs == NULL)
+ ret = target->make_symbol();
+ if (ret == NULL)
{
// This means that we don't want a symbol table
// entry after all.
@@ -222,11 +233,9 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
return NULL;
}
}
- else
- rs = new Sized_symbol<size>();
- rs->init(name, version, object, sym);
- ret = rs;
+ ret->init(name, version, object, sym);
+
ins.first->second = ret;
if (def)
{