* config.sub: Update to version 2011-03-23.
[deliverable/binutils-gdb.git] / gold / x86_64.cc
index 4853603fdb96e414789c9e2937e71eb0ae0a3381..5ba15c45d0e2512e37674fd565321bce04c81842 100644 (file)
@@ -309,7 +309,7 @@ class Target_x86_64 : public Target_freebsd<64, false>
   do_plt_section_for_local(const Relobj*, unsigned int) const
   { return this->plt_section(); }
 
-  // Adjust -fstack-split code which calls non-stack-split code.
+  // Adjust -fsplit-stack code which calls non-split-stack code.
   void
   do_calls_non_split(Relobj* object, unsigned int shndx,
                     section_offset_type fnoffset, section_size_type fnsize,
@@ -362,6 +362,9 @@ class Target_x86_64 : public Target_freebsd<64, false>
       : issued_non_pic_error_(false)
     { }
 
+    static inline int
+    get_reference_flags(unsigned int r_type);
+
     inline void
     local(Symbol_table* symtab, Layout* layout, Target_x86_64* target,
          Sized_relobj<64, false>* object,
@@ -1236,6 +1239,73 @@ Target_x86_64::optimize_tls_reloc(bool is_final, int r_type)
     }
 }
 
+// Get the Reference_flags for a particular relocation.
+
+int
+Target_x86_64::Scan::get_reference_flags(unsigned int r_type)
+{
+  switch (r_type)
+    {
+    case elfcpp::R_X86_64_NONE:
+    case elfcpp::R_X86_64_GNU_VTINHERIT:
+    case elfcpp::R_X86_64_GNU_VTENTRY:
+    case elfcpp::R_X86_64_GOTPC32:
+    case elfcpp::R_X86_64_GOTPC64:
+      // No symbol reference.
+      return 0;
+
+    case elfcpp::R_X86_64_64:
+    case elfcpp::R_X86_64_32:
+    case elfcpp::R_X86_64_32S:
+    case elfcpp::R_X86_64_16:
+    case elfcpp::R_X86_64_8:
+      return Symbol::ABSOLUTE_REF;
+
+    case elfcpp::R_X86_64_PC64:
+    case elfcpp::R_X86_64_PC32:
+    case elfcpp::R_X86_64_PC16:
+    case elfcpp::R_X86_64_PC8:
+    case elfcpp::R_X86_64_GOTOFF64:
+      return Symbol::RELATIVE_REF;
+
+    case elfcpp::R_X86_64_PLT32:
+    case elfcpp::R_X86_64_PLTOFF64:
+      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
+
+    case elfcpp::R_X86_64_GOT64:
+    case elfcpp::R_X86_64_GOT32:
+    case elfcpp::R_X86_64_GOTPCREL64:
+    case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPLT64:
+      // Absolute in GOT.
+      return Symbol::ABSOLUTE_REF;
+
+    case elfcpp::R_X86_64_TLSGD:            // Global-dynamic
+    case elfcpp::R_X86_64_GOTPC32_TLSDESC:  // Global-dynamic (from ~oliva url)
+    case elfcpp::R_X86_64_TLSDESC_CALL:
+    case elfcpp::R_X86_64_TLSLD:            // Local-dynamic
+    case elfcpp::R_X86_64_DTPOFF32:
+    case elfcpp::R_X86_64_DTPOFF64:
+    case elfcpp::R_X86_64_GOTTPOFF:         // Initial-exec
+    case elfcpp::R_X86_64_TPOFF32:          // Local-exec
+      return Symbol::TLS_REF;
+
+    case elfcpp::R_X86_64_COPY:
+    case elfcpp::R_X86_64_GLOB_DAT:
+    case elfcpp::R_X86_64_JUMP_SLOT:
+    case elfcpp::R_X86_64_RELATIVE:
+    case elfcpp::R_X86_64_IRELATIVE:
+    case elfcpp::R_X86_64_TPOFF64:
+    case elfcpp::R_X86_64_DTPMOD64:
+    case elfcpp::R_X86_64_TLSDESC:
+    case elfcpp::R_X86_64_SIZE32:
+    case elfcpp::R_X86_64_SIZE64:
+    default:
+      // Not expected.  We will give an error later.
+      return 0;
+    }
+}
+
 // Report an unsupported relocation against a local symbol.
 
 void
@@ -1259,7 +1329,8 @@ Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type)
 {
   switch (r_type)
     {
-      // These are the relocation types supported by glibc for x86_64.
+      // These are the relocation types supported by glibc for x86_64
+      // which should always work.
     case elfcpp::R_X86_64_RELATIVE:
     case elfcpp::R_X86_64_IRELATIVE:
     case elfcpp::R_X86_64_GLOB_DAT:
@@ -1268,9 +1339,18 @@ Target_x86_64::Scan::check_non_pic(Relobj* object, unsigned int r_type)
     case elfcpp::R_X86_64_DTPOFF64:
     case elfcpp::R_X86_64_TPOFF64:
     case elfcpp::R_X86_64_64:
+    case elfcpp::R_X86_64_COPY:
+      return;
+
+      // glibc supports these reloc types, but they can overflow.
     case elfcpp::R_X86_64_32:
     case elfcpp::R_X86_64_PC32:
-    case elfcpp::R_X86_64_COPY:
+      if (this->issued_non_pic_error_)
+       return;
+      gold_assert(parameters->options().output_is_position_independent());
+      object->error(_("requires dynamic reloc which may overflow at runtime; "
+                     "recompile with -fPIC"));
+      this->issued_non_pic_error_ = true;
       return;
 
     default:
@@ -1297,63 +1377,11 @@ bool
 Target_x86_64::Scan::reloc_needs_plt_for_ifunc(Sized_relobj<64, false>* object,
                                               unsigned int r_type)
 {
-  switch (r_type)
-    {
-    case elfcpp::R_X86_64_NONE:
-    case elfcpp::R_X86_64_GNU_VTINHERIT:
-    case elfcpp::R_X86_64_GNU_VTENTRY:
-      return false;
-
-    case elfcpp::R_X86_64_64:
-    case elfcpp::R_X86_64_32:
-    case elfcpp::R_X86_64_32S:
-    case elfcpp::R_X86_64_16:
-    case elfcpp::R_X86_64_8:
-    case elfcpp::R_X86_64_PC64:
-    case elfcpp::R_X86_64_PC32:
-    case elfcpp::R_X86_64_PC16:
-    case elfcpp::R_X86_64_PC8:
-    case elfcpp::R_X86_64_PLT32:
-    case elfcpp::R_X86_64_GOTPC32:
-    case elfcpp::R_X86_64_GOTOFF64:
-    case elfcpp::R_X86_64_GOTPC64:
-    case elfcpp::R_X86_64_PLTOFF64:
-    case elfcpp::R_X86_64_GOT64:
-    case elfcpp::R_X86_64_GOT32:
-    case elfcpp::R_X86_64_GOTPCREL64:
-    case elfcpp::R_X86_64_GOTPCREL:
-    case elfcpp::R_X86_64_GOTPLT64:
-      return true;
-
-    case elfcpp::R_X86_64_COPY:
-    case elfcpp::R_X86_64_GLOB_DAT:
-    case elfcpp::R_X86_64_JUMP_SLOT:
-    case elfcpp::R_X86_64_RELATIVE:
-    case elfcpp::R_X86_64_IRELATIVE:
-    case elfcpp::R_X86_64_TPOFF64:
-    case elfcpp::R_X86_64_DTPMOD64:
-    case elfcpp::R_X86_64_TLSDESC:
-      // We will give an error later.
-      return false;
-
-    case elfcpp::R_X86_64_TLSGD:
-    case elfcpp::R_X86_64_GOTPC32_TLSDESC:
-    case elfcpp::R_X86_64_TLSDESC_CALL:
-    case elfcpp::R_X86_64_TLSLD:
-    case elfcpp::R_X86_64_DTPOFF32:
-    case elfcpp::R_X86_64_DTPOFF64:
-    case elfcpp::R_X86_64_GOTTPOFF:
-    case elfcpp::R_X86_64_TPOFF32:
-      gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
-                object->name().c_str(), r_type);
-      return false;
-
-    case elfcpp::R_X86_64_SIZE32:
-    case elfcpp::R_X86_64_SIZE64:
-    default:
-      // We will give an error later.
-      return false;
-    }
+  int flags = Scan::get_reference_flags(r_type);
+  if (flags & Symbol::TLS_REF)
+    gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
+               object->name().c_str(), r_type);
+  return flags != 0;
 }
 
 // Scan a relocation for a local symbol.
@@ -1779,7 +1807,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
               gsym->set_needs_dynsym_value();
           }
         // Make a dynamic relocation if necessary.
-        if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
+        if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
           {
             if (gsym->may_need_copy_reloc())
               {
@@ -1836,10 +1864,7 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
         if (gsym->needs_plt_entry())
           target->make_plt_entry(symtab, layout, gsym);
         // Make a dynamic relocation if necessary.
-        int flags = Symbol::NON_PIC_REF;
-        if (gsym->is_func())
-          flags |= Symbol::FUNCTION_CALL;
-        if (gsym->needs_dynamic_reloc(flags))
+        if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
           {
             if (gsym->may_need_copy_reloc())
               {
@@ -2242,10 +2267,7 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
   // Pick the value to use for symbols defined in the PLT.
   Symbol_value<64> symval;
   if (gsym != NULL
-      && gsym->use_plt_offset(r_type == elfcpp::R_X86_64_PC64
-                             || r_type == elfcpp::R_X86_64_PC32
-                             || r_type == elfcpp::R_X86_64_PC16
-                             || r_type == elfcpp::R_X86_64_PC8))
+      && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
     {
       symval.set_output_value(target->plt_section()->address()
                              + gsym->plt_offset());
@@ -3226,7 +3248,7 @@ Target_x86_64::do_reloc_addend(void* arg, unsigned int r_type,
 }
 
 // FNOFFSET in section SHNDX in OBJECT is the start of a function
-// compiled with -fstack-split.  The function calls non-stack-split
+// compiled with -fsplit-stack.  The function calls non-split-stack
 // code.  We have to change the function so that it always ensures
 // that it has enough stack space to run some random function.
 
This page took 0.033434 seconds and 4 git commands to generate.