From: Ian Lance Taylor Date: Fri, 8 Feb 2008 22:49:22 +0000 (+0000) Subject: From Cary Coutant: fix handling of undefined symbols in shared X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8fc19601e8cc9e67bbc39c41fd368df15dcc20aa;p=binutils-gdb.git From Cary Coutant: fix handling of undefined symbols in shared libraries. --- diff --git a/gold/i386.cc b/gold/i386.cc index 3bcfa4c6ec1..d6e42f46501 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -1207,7 +1207,9 @@ Target_i386::Scan::global(const General_options& options, // If this symbol is not fully resolved, we need to add a // GOT entry with a dynamic relocation. Reloc_section* rel_dyn = target->rel_dyn_section(layout); - if (gsym->is_from_dynobj() || gsym->is_preemptible()) + if (gsym->is_from_dynobj() + || gsym->is_undefined() + || gsym->is_preemptible()) got->add_global_with_rel(gsym, rel_dyn, elfcpp::R_386_GLOB_DAT); else { @@ -1543,7 +1545,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, if (gsym != NULL && (gsym->is_from_dynobj() || (parameters->output_is_shared() - && gsym->is_preemptible())) + && (gsym->is_undefined() || gsym->is_preemptible()))) && gsym->has_plt_offset() && (!is_nonpic || !parameters->output_is_shared())) { diff --git a/gold/symtab.h b/gold/symtab.h index b60256e90a1..4d258408710 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -462,6 +462,10 @@ class Symbol // another object is preemptible. gold_assert(!this->is_from_dynobj()); + // It doesn't make sense to ask whether an undefined symbol + // is preemptible. + gold_assert(!this->is_undefined()); + return (this->visibility_ != elfcpp::STV_INTERNAL && this->visibility_ != elfcpp::STV_HIDDEN && this->visibility_ != elfcpp::STV_PROTECTED @@ -472,12 +476,16 @@ class Symbol // Return true if this symbol is a function that needs a PLT entry. // If the symbol is defined in a dynamic object or if it is subject - // to pre-emption, we need to make a PLT entry. + // to pre-emption, we need to make a PLT entry. If we're doing a + // static link, we don't create PLT entries. bool needs_plt_entry() const { - return (this->type() == elfcpp::STT_FUNC - && (this->is_from_dynobj() || this->is_preemptible())); + return (!parameters->doing_static_link() + && this->type() == elfcpp::STT_FUNC + && (this->is_from_dynobj() + || this->is_undefined() + || this->is_preemptible())); } // When determining whether a reference to a symbol needs a dynamic @@ -500,6 +508,10 @@ class Symbol bool needs_dynamic_reloc(int flags) const { + // No dynamic relocations in a static link! + if (parameters->doing_static_link()) + return false; + // An absolute reference within a position-independent output file // will need a dynamic relocation. if ((flags & ABSOLUTE_REF) @@ -522,7 +534,9 @@ class Symbol // A reference to a symbol defined in a dynamic object or to a // symbol that is preemptible will need a dynamic relocation. - if (this->is_from_dynobj() || this->is_preemptible()) + if (this->is_from_dynobj() + || this->is_undefined() + || this->is_preemptible()) return true; // For all other cases, return FALSE. @@ -545,7 +559,9 @@ class Symbol // A reference to a symbol defined in a dynamic object or to a // symbol that is preemptible can not use a RELATIVE relocaiton. - if (this->is_from_dynobj() || this->is_preemptible()) + if (this->is_from_dynobj() + || this->is_undefined() + || this->is_preemptible()) return false; // For all other cases, return TRUE. diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 51a8d84a5b1..54357fdaebe 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -1144,7 +1144,9 @@ Target_x86_64::Scan::global(const General_options& options, // If this symbol is not fully resolved, we need to add a // dynamic relocation for it. Reloc_section* rela_dyn = target->rela_dyn_section(layout); - if (gsym->is_from_dynobj() || gsym->is_preemptible()) + if (gsym->is_from_dynobj() + || gsym->is_undefined() + || gsym->is_preemptible()) got->add_global_with_rela(gsym, rela_dyn, elfcpp::R_X86_64_GLOB_DAT); else @@ -1426,7 +1428,7 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo, if (gsym != NULL && (gsym->is_from_dynobj() || (parameters->output_is_shared() - && gsym->is_preemptible())) + && (gsym->is_undefined() || gsym->is_preemptible()))) && gsym->has_plt_offset()) { symval.set_output_value(target->plt_section()->address()