Add PowerPC64 ELFv2 tests.
[deliverable/binutils-gdb.git] / gold / x86_64.cc
index 6c379ba0c9abfaab7b28c352bf1362959ac2e16c..b95d2ed8f2da67bbc071e81a0a2a4d584c3ccb09 100644 (file)
@@ -1,6 +1,6 @@
 // x86_64.cc -- x86_64 target support for gold.
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
 // Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
@@ -396,7 +396,7 @@ class Target_x86_64 : public Sized_target<size, false>
       got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
       got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL),
       rela_irelative_(NULL), copy_relocs_(elfcpp::R_X86_64_COPY),
-      dynbss_(NULL), got_mod_index_offset_(-1U), tlsdesc_reloc_info_(),
+      got_mod_index_offset_(-1U), tlsdesc_reloc_info_(),
       tls_base_symbol_defined_(false)
   { }
 
@@ -477,7 +477,7 @@ class Target_x86_64 : public Sized_target<size, false>
       const unsigned char* prelocs,
       size_t reloc_count,
       Output_section* output_section,
-      off_t offset_in_output_section,
+      typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
       const Relocatable_relocs*,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
@@ -972,8 +972,6 @@ class Target_x86_64 : public Sized_target<size, false>
   Reloc_section* rela_irelative_;
   // Relocs saved to avoid a COPY reloc.
   Copy_relocs<elfcpp::SHT_RELA, size, false> copy_relocs_;
-  // Space for variables copied with a COPY reloc.
-  Output_data_space* dynbss_;
   // Offset of the GOT entry for the TLS module index.
   unsigned int got_mod_index_offset_;
   // We handle R_X86_64_TLSDESC against a local symbol as a target
@@ -1007,7 +1005,8 @@ const Target::Target_info Target_x86_64<64>::x86_64_info =
   0,                   // small_common_section_flags
   elfcpp::SHF_X86_64_LARGE,    // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 template<>
@@ -1033,7 +1032,8 @@ const Target::Target_info Target_x86_64<32>::x86_64_info =
   0,                   // small_common_section_flags
   elfcpp::SHF_X86_64_LARGE,    // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 // This is called when a new output section is created.  This is where
@@ -2307,7 +2307,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
          unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
          Reloc_section* rela_dyn = target->rela_dyn_section(layout);
          rela_dyn->add_local_relative(object, r_sym,
-                                      (size == 32 
+                                      (size == 32
                                        ? elfcpp::R_X86_64_RELATIVE64
                                        : elfcpp::R_X86_64_RELATIVE),
                                       output_section, data_shndx,
@@ -2740,7 +2740,8 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
                                                       reloc.get_r_offset(),
                                                       reloc.get_r_addend());
              }
-           else if (r_type == elfcpp::R_X86_64_64
+           else if (((size == 64 && r_type == elfcpp::R_X86_64_64)
+                     || (size == 32 && r_type == elfcpp::R_X86_64_32))
                     && gsym->can_use_relative_reloc(false))
              {
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
@@ -3230,6 +3231,9 @@ Target_x86_64<size>::Relocate::relocate(
        }
     }
 
+  if (view == NULL)
+    return true;
+
   const Sized_relobj_file<size, false>* object = relinfo->object;
 
   // Pick the value to use for symbols defined in the PLT.
@@ -3965,8 +3969,12 @@ Target_x86_64<size>::Relocate::tls_ld_to_le(
     section_size_type view_size)
 {
   // leaq foo@tlsld(%rip),%rdi; call __tls_get_addr@plt;
+  // For SIZE == 64:
   // ... leq foo@dtpoff(%rax),%reg
   // ==> .word 0x6666; .byte 0x66; movq %fs:0,%rax ... leaq x@tpoff(%rax),%rdx
+  // For SIZE == 32:
+  // ... leq foo@dtpoff(%rax),%reg
+  // ==> nopl 0x0(%rax); movl %fs:0,%eax ... leaq x@tpoff(%rax),%rdx
 
   tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -3);
   tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 9);
@@ -3976,7 +3984,10 @@ Target_x86_64<size>::Relocate::tls_ld_to_le(
 
   tls::check_tls(relinfo, relnum, rela.get_r_offset(), view[4] == 0xe8);
 
-  memcpy(view - 3, "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0\0", 12);
+  if (size == 64)
+    memcpy(view - 3, "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0\0", 12);
+  else
+    memcpy(view - 3, "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0\0", 12);
 
   // The next reloc should be a PLT32 reloc against __tls_get_addr.
   // We can skip it.
@@ -4221,7 +4232,7 @@ Target_x86_64<size>::relocate_relocs(
     const unsigned char* prelocs,
     size_t reloc_count,
     Output_section* output_section,
-    off_t offset_in_output_section,
+    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
     const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
@@ -4560,6 +4571,9 @@ class Target_x86_64_nacl : public Target_x86_64<size>
                                                 plt_count);
   }
 
+  virtual std::string
+  do_code_fill(section_size_type length) const;
+
  private:
   static const Target::Target_info x86_64_nacl_info;
 };
@@ -4587,7 +4601,8 @@ const Target::Target_info Target_x86_64_nacl<64>::x86_64_nacl_info =
   0,                   // small_common_section_flags
   elfcpp::SHF_X86_64_LARGE,    // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 template<>
@@ -4613,7 +4628,8 @@ const Target::Target_info Target_x86_64_nacl<32>::x86_64_nacl_info =
   0,                   // small_common_section_flags
   elfcpp::SHF_X86_64_LARGE,    // large_common_section_flags
   NULL,                        // attributes_section
-  NULL                 // attributes_vendor
+  NULL,                        // attributes_vendor
+  "_start"             // entry_symbol_name
 };
 
 #define        NACLMASK        0xe0            // 32-byte alignment mask.
@@ -4784,6 +4800,16 @@ Output_data_plt_x86_64_nacl<size>::plt_eh_frame_fde[plt_eh_frame_fde_size] =
   elfcpp::DW_CFA_nop
 };
 
+// Return a string used to fill a code section with nops.
+// For NaCl, long NOPs are only valid if they do not cross
+// bundle alignment boundaries, so keep it simple with one-byte NOPs.
+template<int size>
+std::string
+Target_x86_64_nacl<size>::do_code_fill(section_size_type length) const
+{
+  return std::string(length, static_cast<char>(0x90));
+}
+
 // The selector for x86_64-nacl object files.
 
 template<int size>
This page took 0.026143 seconds and 4 git commands to generate.