|
|
|
@ -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 |
|
|
|
|