From Cary Coutant: fix handling of undefined symbols in shared
authorIan Lance Taylor <iant@google.com>
Fri, 8 Feb 2008 22:49:22 +0000 (22:49 +0000)
committerIan Lance Taylor <iant@google.com>
Fri, 8 Feb 2008 22:49:22 +0000 (22:49 +0000)
libraries.

gold/i386.cc
gold/symtab.h
gold/x86_64.cc

index 3bcfa4c..d6e42f4 100644 (file)
@@ -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()))
     {
index b60256e..4d25840 100644 (file)
@@ -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.
index 51a8d84..54357fd 100644 (file)
@@ -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()