aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/gold.h22
-rw-r--r--gold/object.h12
-rw-r--r--gold/resolve.cc11
-rw-r--r--gold/stringpool.h6
-rw-r--r--gold/symtab.cc54
-rw-r--r--gold/symtab.h7
-rw-r--r--gold/target.h10
7 files changed, 105 insertions, 17 deletions
diff --git a/gold/gold.h b/gold/gold.h
index 20095eb..03737a2 100644
--- a/gold/gold.h
+++ b/gold/gold.h
@@ -39,10 +39,32 @@
#include <ext/hash_map>
#include <ext/hash_set>
+#include <string>
#define Unordered_set __gnu_cxx::hash_set
#define Unordered_map __gnu_cxx::hash_map
+namespace __gnu_cxx
+{
+
+template<>
+struct hash<std::string>
+{
+ size_t
+ operator()(std::string s) const
+ { return __stl_hash_string(s.c_str()); }
+};
+
+template<typename T>
+struct hash<T*>
+{
+ size_t
+ operator()(T* p) const
+ { return reinterpret_cast<size_t>(p); }
+};
+
+}
+
#else
// The fallback is to just use set and map.
diff --git a/gold/object.h b/gold/object.h
index 7c27b7b..36cf949 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -92,8 +92,6 @@ class Object
template<int size, bool big_endian>
Sized_target<size, big_endian>*
sized_target();
-#else
- virtual Target* sized_target() = 0;
#endif
// Read the symbol and relocation information.
@@ -248,7 +246,13 @@ class Sized_object : public Object
// Return the appropriate Sized_target structure.
Sized_target<size, big_endian>*
sized_target()
- { return this->Object::sized_target<size, big_endian>(); }
+ {
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
+ return this->Object::sized_target<size, big_endian>();
+#else
+ return static_cast<Sized_target<size, big_endian>*>(this->target());
+#endif
+ }
private:
// This object may not be copied.
@@ -290,7 +294,7 @@ class Input_objects
{
public:
Input_objects()
- : object_list_()
+ : object_list_(), any_dynamic_(false)
{ }
// The type of the list of input objects.
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 4a9b355..8252f5b 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -52,7 +52,16 @@ Symbol_table::resolve(Sized_symbol<size>* to,
{
if (object->target()->has_resolve())
{
- object->sized_target<size, big_endian>()->resolve(to, sym, object);
+ Sized_target<size, big_endian>* sized_target;
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
+ sized_target = object->sized_target<size, big_endian>();
+#else
+ Target* target = object->target();
+ assert(target->get_size() == size);
+ assert(target->is_big_endian() ? big_endian : !big_endian);
+ sized_target = static_cast<Sized_target<size, big_endian>*>(target);
+#endif
+ sized_target->resolve(to, sym, object);
return;
}
diff --git a/gold/stringpool.h b/gold/stringpool.h
index 873c26a..79632e0 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -58,9 +58,15 @@ class Stringpool
{ return strcmp(p1, p2) == 0; }
};
+#ifdef HAVE_TR1_UNORDERED_SET
typedef Unordered_set<const char*, Stringpool_hash, Stringpool_eq,
std::allocator<const char*>,
true> String_set_type;
+#else
+ typedef Unordered_set<const char*, Stringpool_hash, Stringpool_eq,
+ std::allocator<const char*> > String_set_type;
+#endif
+
String_set_type string_set_;
std::list<stringdata*> strings_;
};
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 8538c42..189032d 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -107,6 +107,8 @@ Symbol_table::resolve_forwards(Symbol* from) const
// version is the default version. Because this is unusual, we do
// this the slow way, by converting back to an ELF symbol.
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
+
template<int size, bool big_endian>
void
Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
@@ -122,6 +124,40 @@ Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
Symbol_table::resolve(to, esym.sym(), from->object());
}
+#else
+
+template<int size>
+void
+Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
+ bool big_endian)
+{
+ unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
+ if (big_endian)
+ {
+ elfcpp::Sym_write<size, true> 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());
+ }
+ else
+ {
+ elfcpp::Sym_write<size, false> 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());
+ }
+}
+
+#endif
+
// Add one symbol from OBJECT to the symbol table. NAME is symbol
// name and VERSION is the version; both are canonicalized. DEF is
// whether this is the default version.
@@ -174,7 +210,12 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
if (!ins.second)
{
// We already have an entry for NAME/VERSION.
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
ret = this->get_sized_symbol<size>(ins.first->second);
+#else
+ assert(size == this->get_size());
+ ret = static_cast<Sized_symbol<size>*>(ins.first->second);
+#endif
assert(ret != NULL);
Symbol_table::resolve(ret, sym, object);
@@ -190,9 +231,14 @@ 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.
- const Sized_symbol<size>* sym2 =
- this->get_sized_symbol<size>(insdef.first->second);
+ const Sized_symbol<size>* sym2;
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
+ sym2 = this->get_sized_symbol<size>(insdef.first->second);
Symbol_table::resolve<size, big_endian>(ret, sym2);
+#else
+ sym2 = static_cast<Sized_symbol<size>*>(insdef.first->second);
+ Symbol_table::resolve(ret, sym2, big_endian);
+#endif
this->make_forwarder(insdef.first->second, ret);
insdef.first->second = ret;
}
@@ -206,7 +252,11 @@ 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.
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
ret = this->get_sized_symbol<size>(insdef.first->second);
+#else
+ ret = static_cast<Sized_symbol<size>*>(insdef.first->second);
+#endif
Symbol_table::resolve(ret, sym, object);
ins.first->second = ret;
}
diff --git a/gold/symtab.h b/gold/symtab.h
index f5d2a7b..09aff03 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -265,9 +265,16 @@ class Symbol_table
const elfcpp::Sym<size, big_endian>& sym,
Object*);
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
template<int size, bool big_endian>
static void
resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
+#else
+ template<int size>
+ static void
+ resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
+ bool big_endian);
+#endif
// The type of the symbol hash table.
diff --git a/gold/target.h b/gold/target.h
index 236185b..161c75d 100644
--- a/gold/target.h
+++ b/gold/target.h
@@ -50,16 +50,6 @@ class Target
has_resolve() const
{ return this->has_resolve_; }
- // Resolve a symbol. This is called when we see a symbol with a
- // target specific binding (STB_LOOS through STB_HIOS or STB_LOPROC
- // through STB_HIPROC). TO is a pre-existing symbol. SYM is the
- // new symbol, seen in OBJECT. This returns true on success, false
- // if the symbol can not be resolved.
- template<int size, bool big_endian>
- bool
- resolve(Sized_symbol<size>* to, const elfcpp::Sym<size, big_endian>& sym,
- Object* object);
-
protected:
Target(int size, bool is_big_endian, bool has_make_symbol, bool has_resolve)
: size_(size),