gold/
[deliverable/binutils-gdb.git] / gold / x86_64.cc
index 6c379ba0c9abfaab7b28c352bf1362959ac2e16c..4f4d612939b7e3554b6124534cb64add55b0e175 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>.
 
@@ -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,
@@ -1007,7 +1007,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 +1034,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 +2309,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,
@@ -3230,6 +3232,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 +3970,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 +3985,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 +4233,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,
@@ -4587,7 +4599,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 +4626,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.
This page took 0.029809 seconds and 4 git commands to generate.