aboutsummaryrefslogtreecommitdiff
path: root/gold/resolve.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-10-14 15:35:27 +0000
committerIan Lance Taylor <iant@google.com>2007-10-14 15:35:27 +0000
commitaeddab66fe1cca5222b8f26dba6f05aa766d5c9e (patch)
tree73b472220a14dc021d736cd98eb40a379c7453b3 /gold/resolve.cc
parentad435a24655b0c6a0247862c084f8d205b5d6ecc (diff)
downloadfsf-binutils-gdb-aeddab66fe1cca5222b8f26dba6f05aa766d5c9e.zip
fsf-binutils-gdb-aeddab66fe1cca5222b8f26dba6f05aa766d5c9e.tar.gz
fsf-binutils-gdb-aeddab66fe1cca5222b8f26dba6f05aa766d5c9e.tar.bz2
Keep track of weak aliases, so that overriding environ works.
Diffstat (limited to 'gold/resolve.cc')
-rw-r--r--gold/resolve.cc65
1 files changed, 62 insertions, 3 deletions
diff --git a/gold/resolve.cc b/gold/resolve.cc
index b890ed0..8836a3a 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -71,6 +71,35 @@ Sized_symbol<size>::override(const elfcpp::Sym<size, big_endian>& sym,
this->symsize_ = sym.get_st_size();
}
+// Override TOSYM with symbol FROMSYM, defined in OBJECT, with version
+// VERSION. This handles all aliases of TOSYM.
+
+template<int size, bool big_endian>
+void
+Symbol_table::override(Sized_symbol<size>* tosym,
+ const elfcpp::Sym<size, big_endian>& fromsym,
+ Object* object, const char* version)
+{
+ tosym->override(fromsym, object, version);
+ if (tosym->has_alias())
+ {
+ Symbol* sym = this->weak_aliases_[tosym];
+ gold_assert(sym != NULL);
+ Sized_symbol<size>* ssym;
+ ssym = this->get_sized_symbol SELECT_SIZE_NAME(size) (sym
+ SELECT_SIZE(size));
+ do
+ {
+ ssym->override(fromsym, object, version);
+ sym = this->weak_aliases_[ssym];
+ gold_assert(sym != NULL);
+ ssym = this->get_sized_symbol SELECT_SIZE_NAME(size) (
+ sym SELECT_SIZE(size));
+ }
+ while (ssym != tosym);
+ }
+}
+
// The resolve functions build a little code for each symbol.
// Bit 0: 0 for global, 1 for weak.
// Bit 1: 0 for regular object, 1 for shared object
@@ -175,7 +204,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
{
typename Sized_symbol<size>::Size_type tosize = to->symsize();
- to->override(sym, object, version);
+ this->override(to, sym, object, version);
if (adjust_common_sizes && tosize > to->symsize())
to->set_symsize(tosize);
@@ -636,6 +665,34 @@ Sized_symbol<size>::override_with_special(const Sized_symbol<size>* from)
this->symsize_ = from->symsize_;
}
+// Override TOSYM with the special symbol FROMSYM. This handles all
+// aliases of TOSYM.
+
+template<int size>
+void
+Symbol_table::override_with_special(Sized_symbol<size>* tosym,
+ const Sized_symbol<size>* fromsym)
+{
+ tosym->override_with_special(fromsym);
+ if (tosym->has_alias())
+ {
+ Symbol* sym = this->weak_aliases_[tosym];
+ gold_assert(sym != NULL);
+ Sized_symbol<size>* ssym;
+ ssym = this->get_sized_symbol SELECT_SIZE_NAME(size) (sym
+ SELECT_SIZE(size));
+ do
+ {
+ ssym->override_with_special(fromsym);
+ sym = this->weak_aliases_[ssym];
+ gold_assert(sym != NULL);
+ ssym = this->get_sized_symbol SELECT_SIZE_NAME(size) (
+ sym SELECT_SIZE(size));
+ }
+ while (ssym != tosym);
+ }
+}
+
// Instantiate the templates we need. We could use the configure
// script to restrict this to only the ones needed for implemented
// targets.
@@ -683,13 +740,15 @@ Symbol_table::resolve<64, true>(
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
template
void
-Sized_symbol<32>::override_with_special(const Sized_symbol<32>*);
+Symbol_table::override_with_special<32>(Sized_symbol<32>*,
+ const Sized_symbol<32>*);
#endif
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
template
void
-Sized_symbol<64>::override_with_special(const Sized_symbol<64>*);
+Symbol_table::override_with_special<64>(Sized_symbol<64>*,
+ const Sized_symbol<64>*);
#endif
} // End namespace gold.