OSDN Git Service

Assignments in linker scripts override definitions from object files.
authoriant <iant>
Wed, 13 Feb 2008 01:20:38 +0000 (01:20 +0000)
committeriant <iant>
Wed, 13 Feb 2008 01:20:38 +0000 (01:20 +0000)
gold/dynobj.cc
gold/script.cc
gold/symtab.cc
gold/symtab.h

index b07a530..780e0c9 100644 (file)
@@ -1437,7 +1437,7 @@ Versions::finalize(Symbol_table* symtab, unsigned int dynsym_index,
                                                    elfcpp::STT_OBJECT,
                                                    elfcpp::STB_GLOBAL,
                                                    elfcpp::STV_DEFAULT, 0,
-                                                   false);
+                                                   false, false);
          vsym->set_needs_dynsym_entry();
           vsym->set_dynsym_index(dynsym_index);
          ++dynsym_index;
index 128acae..3213115 100644 (file)
@@ -895,6 +895,10 @@ class Script_unblock : public Task
 // necessarily evaluate the expression until all ordinary symbols have
 // been finalized.
 
+// The GNU linker lets symbol assignments in the linker script
+// silently override defined symbols in object files.  We are
+// compatible.  FIXME: Should we issue a warning?
+
 void
 Symbol_assignment::add_to_table(Symbol_table* symtab)
 {
@@ -907,7 +911,8 @@ Symbol_assignment::add_to_table(Symbol_table* symtab)
                                          elfcpp::STB_GLOBAL,
                                          vis,
                                          0, // nonvis
-                                         this->provide_);
+                                         this->provide_,
+                                          true); // force_override
 }
 
 // Finalize a symbol value.
index 86d8b11..86b69b4 100644 (file)
@@ -1332,14 +1332,16 @@ Symbol_table::define_as_constant(const char* name,
                                 elfcpp::STB binding,
                                 elfcpp::STV visibility,
                                 unsigned char nonvis,
-                                bool only_if_ref)
+                                bool only_if_ref,
+                                 bool force_override)
 {
   if (parameters->get_size() == 32)
     {
 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
       return this->do_define_as_constant<32>(name, version, value,
                                              symsize, type, binding,
-                                             visibility, nonvis, only_if_ref);
+                                             visibility, nonvis, only_if_ref,
+                                             force_override);
 #else
       gold_unreachable();
 #endif
@@ -1349,7 +1351,8 @@ Symbol_table::define_as_constant(const char* name,
 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
       return this->do_define_as_constant<64>(name, version, value,
                                              symsize, type, binding,
-                                             visibility, nonvis, only_if_ref);
+                                             visibility, nonvis, only_if_ref,
+                                             force_override);
 #else
       gold_unreachable();
 #endif
@@ -1371,7 +1374,8 @@ Symbol_table::do_define_as_constant(
     elfcpp::STB binding,
     elfcpp::STV visibility,
     unsigned char nonvis,
-    bool only_if_ref)
+    bool only_if_ref,
+    bool force_override)
 {
   Sized_symbol<size>* sym;
   Sized_symbol<size>* oldsym;
@@ -1411,7 +1415,7 @@ Symbol_table::do_define_as_constant(
       return sym;
     }
 
-  if (Symbol_table::should_override_with_special(oldsym))
+  if (force_override || Symbol_table::should_override_with_special(oldsym))
     this->override_with_special(oldsym, sym);
   delete sym;
   return oldsym;
@@ -1436,7 +1440,8 @@ Symbol_table::define_symbols(const Layout* layout, int count,
       else
        this->define_as_constant(p->name, NULL, 0, p->size, p->type,
                                 p->binding, p->visibility, p->nonvis,
-                                only_if_ref || p->only_if_ref);
+                                only_if_ref || p->only_if_ref,
+                                 false);
     }
 }
 
@@ -1461,7 +1466,8 @@ Symbol_table::define_symbols(const Layout* layout, int count,
       else
        this->define_as_constant(p->name, NULL, 0, p->size, p->type,
                                 p->binding, p->visibility, p->nonvis,
-                                only_if_ref || p->only_if_ref);
+                                only_if_ref || p->only_if_ref,
+                                 false);
     }
 }
 
index b2417f6..8da7a78 100644 (file)
@@ -1078,7 +1078,8 @@ class Symbol_table
   define_as_constant(const char* name, const char* version,
                     uint64_t value, uint64_t symsize, elfcpp::STT type,
                     elfcpp::STB binding, elfcpp::STV visibility,
-                    unsigned char nonvis, bool only_if_ref);
+                    unsigned char nonvis, bool only_if_ref,
+                     bool force_override);
 
   // Define a set of symbols in output sections.  If ONLY_IF_REF is
   // true, only define them if they are referenced.
@@ -1294,7 +1295,7 @@ class Symbol_table
     typename elfcpp::Elf_types<size>::Elf_WXword ssize,
     elfcpp::STT type, elfcpp::STB binding,
     elfcpp::STV visibility, unsigned char nonvis,
-    bool only_if_ref);
+    bool only_if_ref, bool force_override);
 
   // Allocate the common symbols, sized version.
   template<int size>