* gold.cc (gold_exit): Call plugin cleanup handlers on exit.
[binutils-gdb.git] / gold / sparc.cc
index 60e85241d71cc83c997c35bc676b40f2d188a64a..cca78b794b809d9c425dcbef37bfd31971e3fc73 100644 (file)
@@ -130,7 +130,7 @@ class Target_sparc : public Sized_target<size, big_endian>
                           section_size_type reloc_view_size);
   // 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
   {
     // XXX Really need to support this better...
     if (sym->type() == elfcpp::STT_SPARC_REGISTER)
@@ -296,7 +296,8 @@ class Target_sparc : public Sized_target<size, big_endian>
 
   // Copy a relocation against a global symbol.
   void
-  copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
+  copy_reloc(Symbol_table* symtab, Layout* layout,
+             Sized_relobj<size, big_endian>* object,
             unsigned int shndx, Output_section* output_section,
             Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
   {
@@ -1001,9 +1002,12 @@ Target_sparc<size, big_endian>::got_section(Symbol_table* symtab,
 
       this->got_ = new Output_data_got<size, big_endian>();
 
-      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
-                                     elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
-                                     this->got_);
+      Output_section* os;
+      os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
+                                          (elfcpp::SHF_ALLOC
+                                           | elfcpp::SHF_WRITE),
+                                          this->got_);
+      os->set_is_relro();
 
       // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
       symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
@@ -1026,7 +1030,7 @@ Target_sparc<size, big_endian>::rela_dyn_section(Layout* layout)
   if (this->rela_dyn_ == NULL)
     {
       gold_assert(layout != NULL);
-      this->rela_dyn_ = new Reloc_section();
+      this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
       layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
                                      elfcpp::SHF_ALLOC, this->rela_dyn_);
     }
@@ -1056,6 +1060,11 @@ class Output_data_plt_sparc : public Output_section_data
  protected:
   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 base_plt_entry_size = (size == 32 ? 12 : 32);
@@ -1123,7 +1132,7 @@ template<int size, bool big_endian>
 Output_data_plt_sparc<size, big_endian>::Output_data_plt_sparc(Layout* layout)
   : Output_section_data(size == 32 ? 4 : 8), count_(0)
 {
-  this->rel_ = new Reloc_section();
+  this->rel_ = new Reloc_section(false);
   layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
                                  elfcpp::SHF_ALLOC, this->rel_);
 }
@@ -2323,10 +2332,19 @@ Target_sparc<size, big_endian>::Relocate::relocate(
   // Pick the value to use for symbols defined in shared objects.
   Symbol_value<size> 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_SPARC_DISP8
+                             || r_type == elfcpp::R_SPARC_DISP16
+                             || r_type == elfcpp::R_SPARC_DISP32
+                             || r_type == elfcpp::R_SPARC_DISP64
+                             || r_type == elfcpp::R_SPARC_PC_HH22
+                             || r_type == elfcpp::R_SPARC_PC_HM10
+                             || r_type == elfcpp::R_SPARC_PC_LM22
+                             || r_type == elfcpp::R_SPARC_PC10
+                             || r_type == elfcpp::R_SPARC_PC22
+                             || r_type == elfcpp::R_SPARC_WDISP30
+                             || r_type == elfcpp::R_SPARC_WDISP22
+                             || r_type == elfcpp::R_SPARC_WDISP19
+                             || r_type == elfcpp::R_SPARC_WDISP16))
     {
       elfcpp::Elf_Xword value;