* Makefile.am (spu_ovl.o_c): Add missing line continuations.
[binutils-gdb.git] / gold / x86_64.cc
index f523ae9f26449291a4f238cde54a334b28f6a6d7..69f76a0265f2e51d48c02a214bb870daccad9829 100644 (file)
@@ -139,7 +139,7 @@ class Target_x86_64 : public Sized_target<64, false>
 
   // Return whether SYM is defined by the ABI.
   bool
-  do_is_defined_by_abi(Symbol* sym) const
+  do_is_defined_by_abi(const Symbol* sym) const
   { return strcmp(sym->name(), "__tls_get_addr") == 0; }
 
   // Return the size of the GOT section.
@@ -330,7 +330,7 @@ class Target_x86_64 : public Sized_target<64, false>
   void
   make_plt_entry(Symbol_table*, Layout*, Symbol*);
 
-  // Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+  // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
   void
   define_tls_base_symbol(Symbol_table*, Layout*);
 
@@ -368,7 +368,8 @@ class Target_x86_64 : public Sized_target<64, false>
 
   // Add a potential copy relocation.
   void
-  copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
+  copy_reloc(Symbol_table* symtab, Layout* layout,
+             Sized_relobj<64, false>* object,
             unsigned int shndx, Output_section* output_section,
             Symbol* sym, const elfcpp::Rela<64, false>& reloc)
   {
@@ -446,7 +447,7 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout)
       // create another set of data in the .got section.  Note that we
       // always create a PLT if we create a GOT, although the PLT
       // might be empty.
-      this->got_plt_ = new Output_data_space(8);
+      this->got_plt_ = new Output_data_space(8, "** GOT PLT");
       os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
                                           (elfcpp::SHF_ALLOC
                                            | elfcpp::SHF_WRITE),
@@ -526,6 +527,11 @@ class Output_data_plt_x86_64 : public Output_section_data
   void
   do_adjust_output_section(Output_section* os);
 
+  // Write to a map file.
+  void
+  do_print_to_mapfile(Mapfile* mapfile) const
+  { mapfile->print_output_data(this, _("** PLT")); }
+
  private:
   // The size of an entry in the PLT.
   static const int plt_entry_size = 16;
@@ -790,7 +796,7 @@ Target_x86_64::make_plt_entry(Symbol_table* symtab, Layout* layout,
   this->plt_->add_entry(gsym);
 }
 
-// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
 
 void
 Target_x86_64::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
@@ -801,12 +807,16 @@ Target_x86_64::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
   Output_segment* tls_segment = layout->tls_segment();
   if (tls_segment != NULL)
     {
+      bool is_exec = parameters->options().output_is_executable();
       symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
                                       tls_segment, 0, 0,
                                       elfcpp::STT_TLS,
                                       elfcpp::STB_LOCAL,
                                       elfcpp::STV_HIDDEN, 0,
-                                      Symbol::SEGMENT_END, true);
+                                      (is_exec
+                                       ? Symbol::SEGMENT_END
+                                       : Symbol::SEGMENT_START),
+                                      true);
     }
   this->tls_base_symbol_defined_ = true;
 }
@@ -1659,10 +1669,10 @@ Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
   // Pick the value to use for symbols defined in shared objects.
   Symbol_value<64> symval;
   if (gsym != NULL
-      && (gsym->is_from_dynobj()
-          || (parameters->options().shared()
-              && (gsym->is_undefined() || gsym->is_preemptible())))
-      && gsym->has_plt_offset())
+      && 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))
     {
       symval.set_output_value(target->plt_section()->address()
                              + gsym->plt_offset());
@@ -2048,7 +2058,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
           if (this->saw_tls_block_reloc_)
             value -= tls_segment->memsz();
         }
-      Relocate_functions<64, false>::rela32(view, value, 0);
+      Relocate_functions<64, false>::rela32(view, value, addend);
       break;
 
     case elfcpp::R_X86_64_DTPOFF64:
@@ -2059,7 +2069,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
           if (this->saw_tls_block_reloc_)
             value -= tls_segment->memsz();
         }
-      Relocate_functions<64, false>::rela64(view, value, 0);
+      Relocate_functions<64, false>::rela64(view, value, addend);
       break;
 
     case elfcpp::R_X86_64_GOTTPOFF:         // Initial-exec
@@ -2101,7 +2111,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
 
     case elfcpp::R_X86_64_TPOFF32:          // Local-exec
       value -= tls_segment->memsz();
-      Relocate_functions<64, false>::rela32(view, value, 0);
+      Relocate_functions<64, false>::rela32(view, value, addend);
       break;
     }
 }