aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2008-02-08 22:49:22 +0000
committerIan Lance Taylor <iant@google.com>2008-02-08 22:49:22 +0000
commit8fc19601e8cc9e67bbc39c41fd368df15dcc20aa (patch)
tree508721bdc307d3a9917507013f648fb79e4fcd0f
parent8da2a1df1661ca37851fd21c1dda16d433a5811a (diff)
downloadgdb-8fc19601e8cc9e67bbc39c41fd368df15dcc20aa.zip
gdb-8fc19601e8cc9e67bbc39c41fd368df15dcc20aa.tar.gz
gdb-8fc19601e8cc9e67bbc39c41fd368df15dcc20aa.tar.bz2
From Cary Coutant: fix handling of undefined symbols in shared
libraries.
-rw-r--r--gold/i386.cc6
-rw-r--r--gold/symtab.h26
-rw-r--r--gold/x86_64.cc6
3 files changed, 29 insertions, 9 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index 3bcfa4c..d6e42f4 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 b60256e..4d25840 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 51a8d84..54357fd 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()