summaryrefslogtreecommitdiffstats
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-11-14 16:53:25 +0000
committerIan Lance Taylor <iant@google.com>2007-11-14 16:53:25 +0000
commit9a2d69841557c502021be98221a796ebe253fa09 (patch)
tree0b92ca469f9782810c95cbbc2e2aa5e80273c669 /gold/symtab.cc
parent3e6fe5ae738660d48c8b6a3e0206cbd2d23fa1c5 (diff)
downloadppe42-binutils-9a2d69841557c502021be98221a796ebe253fa09.tar.gz
ppe42-binutils-9a2d69841557c502021be98221a796ebe253fa09.zip
Add heuristics for undefined symbol warnings.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc76
1 files changed, 51 insertions, 25 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index f5e21322b7..539bf328c5 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -1524,7 +1524,8 @@ Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool)
// Write out the global symbols.
void
-Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
+Symbol_table::write_globals(const Input_objects* input_objects,
+ const Stringpool* sympool,
const Stringpool* dynpool, Output_file* of) const
{
if (parameters->get_size() == 32)
@@ -1532,7 +1533,8 @@ Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
if (parameters->is_big_endian())
{
#ifdef HAVE_TARGET_32_BIG
- this->sized_write_globals<32, true>(target, sympool, dynpool, of);
+ this->sized_write_globals<32, true>(input_objects, sympool,
+ dynpool, of);
#else
gold_unreachable();
#endif
@@ -1540,7 +1542,8 @@ Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
else
{
#ifdef HAVE_TARGET_32_LITTLE
- this->sized_write_globals<32, false>(target, sympool, dynpool, of);
+ this->sized_write_globals<32, false>(input_objects, sympool,
+ dynpool, of);
#else
gold_unreachable();
#endif
@@ -1551,7 +1554,8 @@ Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
if (parameters->is_big_endian())
{
#ifdef HAVE_TARGET_64_BIG
- this->sized_write_globals<64, true>(target, sympool, dynpool, of);
+ this->sized_write_globals<64, true>(input_objects, sympool,
+ dynpool, of);
#else
gold_unreachable();
#endif
@@ -1559,7 +1563,8 @@ Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
else
{
#ifdef HAVE_TARGET_64_LITTLE
- this->sized_write_globals<64, false>(target, sympool, dynpool, of);
+ this->sized_write_globals<64, false>(input_objects, sympool,
+ dynpool, of);
#else
gold_unreachable();
#endif
@@ -1573,11 +1578,13 @@ Symbol_table::write_globals(const Target* target, const Stringpool* sympool,
template<int size, bool big_endian>
void
-Symbol_table::sized_write_globals(const Target* target,
+Symbol_table::sized_write_globals(const Input_objects* input_objects,
const Stringpool* sympool,
const Stringpool* dynpool,
Output_file* of) const
{
+ const Target* const target = input_objects->target();
+
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
unsigned int index = this->first_global_index_;
const off_t oview_size = this->output_count_ * sym_size;
@@ -1599,25 +1606,8 @@ Symbol_table::sized_write_globals(const Target* target,
{
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(p->second);
- // Optionally check for unresolved symbols in shared libraries.
- // This is controlled by the --allow-shlib-undefined option. We
- // only warn about libraries for which we have seen all the
- // DT_NEEDED entries. We don't try to track down DT_NEEDED
- // entries which were not seen in this link. If we didn't see a
- // DT_NEEDED entry, we aren't going to be able to reliably
- // report whether the symbol is undefined.
- if (sym->source() == Symbol::FROM_OBJECT
- && sym->object()->is_dynamic()
- && sym->shndx() == elfcpp::SHN_UNDEF
- && sym->binding() != elfcpp::STB_WEAK
- && !parameters->allow_shlib_undefined())
- {
- // A very ugly cast.
- Dynobj* dynobj = static_cast<Dynobj*>(sym->object());
- if (!dynobj->has_unknown_needed_entries())
- gold_error(_("%s: undefined reference to '%s'"),
- sym->object()->name().c_str(), sym->name());
- }
+ // Possibly warn about unresolved symbols in shared libraries.
+ this->warn_about_undefined_dynobj_symbol(input_objects, sym);
unsigned int sym_index = sym->symtab_index();
unsigned int dynsym_index;
@@ -1749,6 +1739,42 @@ Symbol_table::sized_write_symbol(
osym.put_st_shndx(shndx);
}
+// Check for unresolved symbols in shared libraries. This is
+// controlled by the --allow-shlib-undefined option.
+
+// We only warn about libraries for which we have seen all the
+// DT_NEEDED entries. We don't try to track down DT_NEEDED entries
+// which were not seen in this link. If we didn't see a DT_NEEDED
+// entry, we aren't going to be able to reliably report whether the
+// symbol is undefined.
+
+// We also don't warn about libraries found in the system library
+// directory (the directory were we find libc.so); we assume that
+// those libraries are OK. This heuristic avoids problems in
+// GNU/Linux, in which -ldl can have undefined references satisfied by
+// ld-linux.so.
+
+inline void
+Symbol_table::warn_about_undefined_dynobj_symbol(
+ const Input_objects* input_objects,
+ Symbol* sym) const
+{
+ if (sym->source() == Symbol::FROM_OBJECT
+ && sym->object()->is_dynamic()
+ && sym->shndx() == elfcpp::SHN_UNDEF
+ && sym->binding() != elfcpp::STB_WEAK
+ && !parameters->allow_shlib_undefined()
+ && !input_objects->target()->is_defined_by_abi(sym)
+ && !input_objects->found_in_system_library_directory(sym->object()))
+ {
+ // A very ugly cast.
+ Dynobj* dynobj = static_cast<Dynobj*>(sym->object());
+ if (!dynobj->has_unknown_needed_entries())
+ gold_error(_("%s: undefined reference to '%s'"),
+ sym->object()->name().c_str(), sym->name());
+ }
+}
+
// Write out a section symbol. Return the update offset.
void
OpenPOWER on IntegriCloud