From Craig Silverstein: New version of x86_64.cc.
authorIan Lance Taylor <iant@google.com>
Mon, 1 Oct 2007 22:21:58 +0000 (22:21 +0000)
committerIan Lance Taylor <iant@google.com>
Mon, 1 Oct 2007 22:21:58 +0000 (22:21 +0000)
gold/x86_64.cc

index e2ad4bb8e7cd7beb3dee41fb0d8df4da1eb38285..4d73eac705d27fa2746daed236ce1a2805c119c9 100644 (file)
@@ -58,8 +58,8 @@ class Output_data_plt_x86_64;
 class Target_x86_64 : public Sized_target<64, false>
 {
  public:
-  // In the x86_64 ABI, it says "The AMD64 ABI architectures uses only
-  // Elf64_Rela relocation entries with explicit addends."
+  // In the x86_64 ABI (p 68), it says "The AMD64 ABI architectures
+  // uses only Elf64_Rela relocation entries with explicit addends."
   typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section;
 
   Target_x86_64()
@@ -696,6 +696,8 @@ Target_x86_64::Scan::local(const General_options&,
   switch (r_type)
     {
     case elfcpp::R_X86_64_NONE:
+    case elfcpp::R_386_GNU_VTINHERIT:
+    case elfcpp::R_386_GNU_VTENTRY:
       break;
 
     case elfcpp::R_X86_64_64:
@@ -714,8 +716,14 @@ Target_x86_64::Scan::local(const General_options&,
     case elfcpp::R_X86_64_PC8:
       break;
 
-    case elfcpp::R_X86_64_GOTOFF64:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPC32:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOT64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTOFF64:
+    case elfcpp::R_X86_64_GOTPC64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTPCREL64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTPLT64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_PLTOFF64:  // TODO(csilvers): correct?
       // We need a GOT section.
       target->got_section(symtab, layout);
       break;
@@ -729,21 +737,27 @@ Target_x86_64::Scan::local(const General_options&,
     case elfcpp::R_X86_64_DTPMOD64:
     case elfcpp::R_X86_64_DTPOFF64:
     case elfcpp::R_X86_64_DTPOFF32:
+    case elfcpp::R_X86_64_GOTTPOFF:  // TODO(csilvers): correct?
     case elfcpp::R_X86_64_TLSDESC:
+    case elfcpp::R_X86_64_GOTPC32_TLSDESC:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSDESC_CALL:  // TODO(csilvers): correct?
       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
              program_name, object->name().c_str(), r_type);
       gold_exit(false);
       break;
 
 #if 0
-    case elfcpp::R_X86_64_TLS_IE:
-    case elfcpp::R_X86_64_TLS_GOTIE:
-    case elfcpp::R_X86_64_TLS_LE:
-    case elfcpp::R_X86_64_TLS_GD:
-    case elfcpp::R_X86_64_TLS_LDM:
-    case elfcpp::R_X86_64_TLS_LDO_64:
-    case elfcpp::R_X86_64_TLS_IE_64:
-    case elfcpp::R_X86_64_TLS_LE_64:
+    case elfcpp::R_X86_64_TLSGD:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSLD:  // TODO(csilvers): correct?
+
+    case elfcpp::R_386_TLS_IE:
+    case elfcpp::R_386_TLS_GOTIE:
+    case elfcpp::R_386_TLS_LE:
+    case elfcpp::R_386_TLS_GD:
+    case elfcpp::R_386_TLS_LDM:
+    case elfcpp::R_386_TLS_LDO_64:
+    case elfcpp::R_386_TLS_IE_64:
+    case elfcpp::R_386_TLS_LE_64:
       {
        bool output_is_shared = parameters->output_is_shared();
        r_type = Target_x86_64::optimize_tls_reloc(!output_is_shared,
@@ -772,17 +786,19 @@ Target_x86_64::Scan::local(const General_options&,
       break;
 #endif
 
-#if 0
     case elfcpp::R_X86_64_GOT32:
     case elfcpp::R_X86_64_PLT32:
-    case elfcpp::R_X86_64_TLS_GD_64:
-    case elfcpp::R_X86_64_TLS_GD_PUSH:
-    case elfcpp::R_X86_64_TLS_GD_CALL:
-    case elfcpp::R_X86_64_TLS_GD_POP:
-    case elfcpp::R_X86_64_TLS_LDM_64:
-    case elfcpp::R_X86_64_TLS_LDM_PUSH:
-    case elfcpp::R_X86_64_TLS_LDM_CALL:
-    case elfcpp::R_X86_64_TLS_LDM_POP:
+    case elfcpp::R_X86_64_SIZE32:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_SIZE64:  // TODO(csilvers): correct?
+#if 0
+    case elfcpp::R_386_TLS_GD_64:
+    case elfcpp::R_386_TLS_GD_PUSH:
+    case elfcpp::R_386_TLS_GD_CALL:
+    case elfcpp::R_386_TLS_GD_POP:
+    case elfcpp::R_386_TLS_LDM_64:
+    case elfcpp::R_386_TLS_LDM_PUSH:
+    case elfcpp::R_386_TLS_LDM_CALL:
+    case elfcpp::R_386_TLS_LDM_POP:
 #endif
     default:
       fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
@@ -808,6 +824,8 @@ Target_x86_64::Scan::global(const General_options& options,
   switch (r_type)
     {
     case elfcpp::R_X86_64_NONE:
+    case elfcpp::R_386_GNU_VTINHERIT:
+    case elfcpp::R_386_GNU_VTENTRY:
       break;
 
     case elfcpp::R_X86_64_64:
@@ -865,57 +883,66 @@ Target_x86_64::Scan::global(const General_options& options,
       target->make_plt_entry(symtab, layout, gsym);
       break;
 
-    case elfcpp::R_X86_64_GOTOFF64:
-    case elfcpp::R_X86_64_GOTPC32:
     case elfcpp::R_X86_64_GOTPCREL:
+    case elfcpp::R_X86_64_GOTPC32:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOT64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTOFF64:
+    case elfcpp::R_X86_64_GOTPC64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTPCREL64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_GOTPLT64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_PLTOFF64:  // TODO(csilvers): correct?
       // We need a GOT section.
       target->got_section(symtab, layout);
       break;
 
-#if 0
     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_TLS_TPOFF:
+    case elfcpp::R_X86_64_TPOFF64:
+    case elfcpp::R_X86_64_TPOFF32:
     case elfcpp::R_X86_64_DTPMOD64:
     case elfcpp::R_X86_64_DTPOFF64:
     case elfcpp::R_X86_64_DTPOFF32:
-    case elfcpp::R_X86_64_TLS_TPOFF64:
-    case elfcpp::R_X86_64_TLS_DESC:
+    case elfcpp::R_X86_64_GOTTPOFF:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSDESC:
+    case elfcpp::R_X86_64_GOTPC32_TLSDESC:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSDESC_CALL:  // TODO(csilvers): correct?
       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
              program_name, object->name().c_str(), r_type);
       gold_exit(false);
       break;
-#endif
 
 #if 0
-    case elfcpp::R_X86_64_TLS_IE:
-    case elfcpp::R_X86_64_TLS_GOTIE:
-    case elfcpp::R_X86_64_TLS_LE:
-    case elfcpp::R_X86_64_TLS_GD:
-    case elfcpp::R_X86_64_TLS_LDM:
-    case elfcpp::R_X86_64_TLS_LDO_64:
-    case elfcpp::R_X86_64_TLS_IE_64:
-    case elfcpp::R_X86_64_TLS_LE_64:
+    case elfcpp::R_X86_64_TLSGD:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSLD:  // TODO(csilvers): correct?
+
+    case elfcpp::R_386_TLS_IE:
+    case elfcpp::R_386_TLS_GOTIE:
+    case elfcpp::R_386_TLS_LE:
+    case elfcpp::R_386_TLS_GD:
+    case elfcpp::R_386_TLS_LDM:
+    case elfcpp::R_386_TLS_LDO_64:
+    case elfcpp::R_386_TLS_IE_64:
+    case elfcpp::R_386_TLS_LE_64:
       {
        const bool is_final = gsym->final_value_is_known();
        r_type = Target_x86_64::optimize_tls_reloc(is_final, r_type);
        switch (r_type)
          {
-         case elfcpp::R_X86_64_TLS_LE:
-         case elfcpp::R_X86_64_TLS_LE_64:
+         case elfcpp::R_386_TLS_LE:
+         case elfcpp::R_386_TLS_LE_64:
            // FIXME: If generating a shared object, we need to copy
            // this relocation into the object.
            gold_assert(!parameters->output_is_shared());
            break;
 
-         case elfcpp::R_X86_64_TLS_IE:
-         case elfcpp::R_X86_64_TLS_GOTIE:
-         case elfcpp::R_X86_64_TLS_GD:
-         case elfcpp::R_X86_64_TLS_LDM:
-         case elfcpp::R_X86_64_TLS_LDO_64:
-         case elfcpp::R_X86_64_TLS_IE_64:
+         case elfcpp::R_386_TLS_IE:
+         case elfcpp::R_386_TLS_GOTIE:
+         case elfcpp::R_386_TLS_GD:
+         case elfcpp::R_386_TLS_LDM:
+         case elfcpp::R_386_TLS_LDO_64:
+         case elfcpp::R_386_TLS_IE_64:
            fprintf(stderr,
                    _("%s: %s: unsupported reloc %u "
                      "against global symbol %s\n"),
@@ -927,15 +954,17 @@ Target_x86_64::Scan::global(const General_options& options,
       break;
 #endif
 
+    case elfcpp::R_X86_64_SIZE32:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_SIZE64:  // TODO(csilvers): correct?
 #if 0
-    case elfcpp::R_X86_64_TLS_GD_64:
-    case elfcpp::R_X86_64_TLS_GD_PUSH:
-    case elfcpp::R_X86_64_TLS_GD_CALL:
-    case elfcpp::R_X86_64_TLS_GD_POP:
-    case elfcpp::R_X86_64_TLS_LDM_64:
-    case elfcpp::R_X86_64_TLS_LDM_PUSH:
-    case elfcpp::R_X86_64_TLS_LDM_CALL:
-    case elfcpp::R_X86_64_TLS_LDM_POP:
+    case elfcpp::R_386_TLS_GD_64:
+    case elfcpp::R_386_TLS_GD_PUSH:
+    case elfcpp::R_386_TLS_GD_CALL:
+    case elfcpp::R_386_TLS_GD_POP:
+    case elfcpp::R_386_TLS_LDM_64:
+    case elfcpp::R_386_TLS_LDM_PUSH:
+    case elfcpp::R_386_TLS_LDM_CALL:
+    case elfcpp::R_386_TLS_LDM_POP:
 #endif
     default:
       fprintf(stderr,
@@ -1078,6 +1107,8 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
   switch (r_type)
     {
     case elfcpp::R_X86_64_NONE:
+    case elfcpp::R_386_GNU_VTINHERIT:
+    case elfcpp::R_386_GNU_VTENTRY:
       break;
 
     case elfcpp::R_X86_64_64:
@@ -1090,12 +1121,10 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
       break;
 
     case elfcpp::R_X86_64_32:
-      // FIXME: Needs error checking.
       Relocate_functions<64, false>::rela32(view, object, psymval, addend);
       break;
 
     case elfcpp::R_X86_64_32S:
-      // FIXME: Needs error checking.
       Relocate_functions<64, false>::rela32(view, object, psymval, addend);
       break;
 
@@ -1136,6 +1165,34 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
       Relocate_functions<64, false>::rela32(view, gsym->got_offset(), addend);
       break;
 
+    case elfcpp::R_X86_64_GOTPC32:
+      {
+        gold_assert(gsym);
+       elfcpp::Elf_types<64>::Elf_Addr value;
+       value = target->got_section(NULL, NULL)->address();
+       Relocate_functions<64, false>::pcrela32(view, value, addend, address);
+      }
+      break;
+
+    case elfcpp::R_X86_64_GOT64:
+      // The ABI doc says "Like GOT64, but indicates a PLT entry is needed."
+      // Since we always add a PLT entry, this is equivalent.
+    case elfcpp::R_X86_64_GOTPLT64:  // TODO(csilvers): correct?
+      // Local GOT offsets not yet supported.
+      gold_assert(gsym);
+      gold_assert(gsym->has_got_offset());
+      Relocate_functions<64, false>::rela64(view, gsym->got_offset(), addend);
+      break;
+
+    case elfcpp::R_X86_64_GOTPC64:
+      {
+        gold_assert(gsym);
+       elfcpp::Elf_types<64>::Elf_Addr value;
+       value = target->got_section(NULL, NULL)->address();
+       Relocate_functions<64, false>::pcrela64(view, value, addend, address);
+      }
+      break;
+
     case elfcpp::R_X86_64_GOTOFF64:
       {
        elfcpp::Elf_types<64>::Elf_Addr value;
@@ -1156,6 +1213,17 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
       }
       break;
 
+    case elfcpp::R_X86_64_GOTPCREL64:
+      {
+        gold_assert(gsym);
+       elfcpp::Elf_types<64>::Elf_Addr value;
+        // FIXME(csilvers): this is probably totally wrong for G + GOT
+       value = (target->got_section(NULL, NULL)->address()
+                 + (gsym->has_got_offset() ? gsym->got_offset() : 0));
+       Relocate_functions<64, false>::pcrela64(view, value, addend, address);
+      }
+      break;
+
     case elfcpp::R_X86_64_COPY:
     case elfcpp::R_X86_64_GLOB_DAT:
     case elfcpp::R_X86_64_JUMP_SLOT:
@@ -1165,7 +1233,10 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
     case elfcpp::R_X86_64_DTPMOD64:
     case elfcpp::R_X86_64_DTPOFF64:
     case elfcpp::R_X86_64_DTPOFF32:
+    case elfcpp::R_X86_64_GOTTPOFF:  // TODO(csilvers): correct?
     case elfcpp::R_X86_64_TLSDESC:
+    case elfcpp::R_X86_64_GOTPC32_TLSDESC:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSDESC_CALL:  // TODO(csilvers): correct?
       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
              program_name,
              relinfo->location(relnum, rel.get_r_offset()).c_str(),
@@ -1174,14 +1245,17 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
       break;
 
 #if 0
-    case elfcpp::R_X86_64_TLS_IE:
-    case elfcpp::R_X86_64_TLS_GOTIE:
-    case elfcpp::R_X86_64_TLS_LE:
-    case elfcpp::R_X86_64_TLS_GD:
-    case elfcpp::R_X86_64_TLS_LDM:
-    case elfcpp::R_X86_64_TLS_LDO_64:
-    case elfcpp::R_X86_64_TLS_IE_64:
-    case elfcpp::R_X86_64_TLS_LE_64:
+    case elfcpp::R_X86_64_TLSGD:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_TLSLD:  // TODO(csilvers): correct?
+
+    case elfcpp::R_386_TLS_IE:
+    case elfcpp::R_386_TLS_GOTIE:
+    case elfcpp::R_386_TLS_LE:
+    case elfcpp::R_386_TLS_GD:
+    case elfcpp::R_386_TLS_LDM:
+    case elfcpp::R_386_TLS_LDO_64:
+    case elfcpp::R_386_TLS_IE_64:
+    case elfcpp::R_386_TLS_LE_64:
       this->relocate_tls(relinfo, relnum, rel, r_type, gsym, psymval, view,
                         address, view_size);
       break;
@@ -1189,15 +1263,18 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
       view_size++;      // this is to make view_size used
 #endif
 
+    case elfcpp::R_X86_64_SIZE32:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_SIZE64:  // TODO(csilvers): correct?
+    case elfcpp::R_X86_64_PLTOFF64:  // TODO(csilvers): implement me!
 #if 0
-    case elfcpp::R_X86_64_TLS_GD_64:
-    case elfcpp::R_X86_64_TLS_GD_PUSH:
-    case elfcpp::R_X86_64_TLS_GD_CALL:
-    case elfcpp::R_X86_64_TLS_GD_POP:
-    case elfcpp::R_X86_64_TLS_LDM_64:
-    case elfcpp::R_X86_64_TLS_LDM_PUSH:
-    case elfcpp::R_X86_64_TLS_LDM_CALL:
-    case elfcpp::R_X86_64_TLS_LDM_POP:
+    case elfcpp::R_386_TLS_GD_64:
+    case elfcpp::R_386_TLS_GD_PUSH:
+    case elfcpp::R_386_TLS_GD_CALL:
+    case elfcpp::R_386_TLS_GD_POP:
+    case elfcpp::R_386_TLS_LDM_64:
+    case elfcpp::R_386_TLS_LDM_PUSH:
+    case elfcpp::R_386_TLS_LDM_CALL:
+    case elfcpp::R_386_TLS_LDM_POP:
 #endif
     default:
       fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),