Add -Wshadow to the gcc command line options used when compiling the binutils.
[deliverable/binutils-gdb.git] / gold / sparc.cc
index 2812fe1437049a331dbbd9c805d2534348055c39..43c6e34b0b9ccb09bde296df9e7cee4604eaea7d 100644 (file)
@@ -1,6 +1,6 @@
 // sparc.cc -- sparc target support for gold.
 
-// Copyright 2008 Free Software Foundation, Inc.
+// Copyright 2008, 2009 Free Software Foundation, Inc.
 // Written by David S. Miller <davem@davemloft.net>.
 
 // This file is part of gold.
 #include "symtab.h"
 #include "layout.h"
 #include "output.h"
+#include "copy-relocs.h"
 #include "target.h"
 #include "target-reloc.h"
 #include "target-select.h"
 #include "tls.h"
 #include "errors.h"
+#include "gc.h"
 
 namespace
 {
@@ -57,15 +59,29 @@ class Target_sparc : public Sized_target<size, big_endian>
   Target_sparc()
     : Sized_target<size, big_endian>(&sparc_info),
       got_(NULL), plt_(NULL), rela_dyn_(NULL),
-      copy_relocs_(NULL), dynbss_(NULL), got_mod_index_offset_(-1U),
-      tls_get_addr_sym_(NULL)
+      copy_relocs_(elfcpp::R_SPARC_COPY), dynbss_(NULL),
+      got_mod_index_offset_(-1U), tls_get_addr_sym_(NULL)
   {
   }
 
+  // Process the relocations to determine unreferenced sections for 
+  // garbage collection.
+  void
+  gc_process_relocs(Symbol_table* symtab,
+                   Layout* layout,
+                   Sized_relobj<size, big_endian>* object,
+                   unsigned int data_shndx,
+                   unsigned int sh_type,
+                   const unsigned char* prelocs,
+                   size_t reloc_count,
+                   Output_section* output_section,
+                   bool needs_special_offset_handling,
+                   size_t local_symbol_count,
+                   const unsigned char* plocal_symbols);
+
   // Scan the relocations to look for symbol adjustments.
   void
-  scan_relocs(const General_options& options,
-             Symbol_table* symtab,
+  scan_relocs(Symbol_table* symtab,
              Layout* layout,
              Sized_relobj<size, big_endian>* object,
              unsigned int data_shndx,
@@ -78,7 +94,7 @@ class Target_sparc : public Sized_target<size, big_endian>
              const unsigned char* plocal_symbols);
   // Finalize the sections.
   void
-  do_finalize_sections(Layout*);
+  do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
 
   // Return the value to use for a dynamic which requires special
   // treatment.
@@ -95,12 +111,12 @@ class Target_sparc : public Sized_target<size, big_endian>
                   bool needs_special_offset_handling,
                   unsigned char* view,
                   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
-                  section_size_type view_size);
+                  section_size_type view_size,
+                  const Reloc_symbol_changes*);
 
   // Scan the relocs during a relocatable link.
   void
-  scan_relocatable_relocs(const General_options& options,
-                         Symbol_table* symtab,
+  scan_relocatable_relocs(Symbol_table* symtab,
                          Layout* layout,
                          Sized_relobj<size, big_endian>* object,
                          unsigned int data_shndx,
@@ -129,7 +145,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)
@@ -138,6 +154,11 @@ class Target_sparc : public Sized_target<size, big_endian>
     return strcmp(sym->name(), "___tls_get_addr") == 0;
   }
 
+  // Return whether there is a GOT section.
+  bool
+  has_got_section() const
+  { return this->got_ != NULL; }
+
   // Return the size of the GOT section.
   section_size_type
   got_size()
@@ -149,11 +170,15 @@ class Target_sparc : public Sized_target<size, big_endian>
  private:
 
   // The class which scans relocations.
-  struct Scan
+  class Scan
   {
+  public:
+    Scan()
+      : issued_non_pic_error_(false)
+    { }
+
     inline void
-    local(const General_options& options, Symbol_table* symtab,
-         Layout* layout, Target_sparc* target,
+    local(Symbol_table* symtab, Layout* layout, Target_sparc* target,
          Sized_relobj<size, big_endian>* object,
          unsigned int data_shndx,
          Output_section* output_section,
@@ -161,14 +186,14 @@ class Target_sparc : public Sized_target<size, big_endian>
          const elfcpp::Sym<size, big_endian>& lsym);
 
     inline void
-    global(const General_options& options, Symbol_table* symtab,
-          Layout* layout, Target_sparc* target,
+    global(Symbol_table* symtab, Layout* layout, Target_sparc* target,
           Sized_relobj<size, big_endian>* object,
           unsigned int data_shndx,
           Output_section* output_section,
           const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
           Symbol* gsym);
 
+  private:
     static void
     unsupported_reloc_local(Sized_relobj<size, big_endian>*,
                            unsigned int r_type);
@@ -180,6 +205,12 @@ class Target_sparc : public Sized_target<size, big_endian>
     static void
     generate_tls_call(Symbol_table* symtab, Layout* layout,
                      Target_sparc* target);
+
+    void
+    check_non_pic(Relobj*, unsigned int r_type);
+
+    // Whether we have issued an error about a non-PIC compilation.
+    bool issued_non_pic_error_;
   };
 
   // The class which implements relocation.
@@ -203,7 +234,8 @@ class Target_sparc : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_sparc*,
-            size_t relnum, const elfcpp::Rela<size, big_endian>&,
+            Output_section*, size_t relnum,
+            const elfcpp::Rela<size, big_endian>&,
             unsigned int r_type, const Sized_symbol<size>*,
             const Symbol_value<size>*,
             unsigned char*,
@@ -270,22 +302,18 @@ class Target_sparc : public Sized_target<size, big_endian>
   Reloc_section*
   rela_dyn_section(Layout*);
 
-  // Return true if the symbol may need a COPY relocation.
-  // References from an executable object to non-function symbols
-  // defined in a dynamic object may need a COPY relocation.
-  bool
-  may_need_copy_reloc(Symbol* gsym)
-  {
-    return (!parameters->options().shared()
-            && gsym->is_from_dynobj()
-            && gsym->type() != elfcpp::STT_FUNC);
-  }
-
   // Copy a relocation against a global symbol.
   void
-  copy_reloc(const General_options*, Symbol_table*, Layout*,
-            Sized_relobj<size, big_endian>*, unsigned int,
-            Output_section*, Symbol*, const elfcpp::Rela<size, big_endian>&);
+  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)
+  {
+    this->copy_relocs_.copy_reloc(symtab, layout,
+                                 symtab->get_sized_symbol<size>(sym),
+                                 object, shndx, output_section,
+                                 reloc, this->rela_dyn_section(layout));
+  }
 
   // Information about this specific target which we pass to the
   // general Target structure.
@@ -306,7 +334,7 @@ class Target_sparc : public Sized_target<size, big_endian>
   // The dynamic reloc section.
   Reloc_section* rela_dyn_;
   // Relocs saved to avoid a COPY reloc.
-  Copy_relocs<size, big_endian>* copy_relocs_;
+  Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
   // Space for variables copied with a COPY reloc.
   Output_data_space* dynbss_;
   // Offset of the GOT entry for the TLS module index;
@@ -329,7 +357,13 @@ Target::Target_info Target_sparc<32, true>::sparc_info =
   "/usr/lib/ld.so.1",  // dynamic_linker
   0x00010000,          // default_text_segment_address
   64 * 1024,           // abi_pagesize (overridable by -z max-page-size)
-  8 * 1024             // common_pagesize (overridable by -z common-page-size)
+  8 * 1024,            // common_pagesize (overridable by -z common-page-size)
+  elfcpp::SHN_UNDEF,   // small_common_shndx
+  elfcpp::SHN_UNDEF,   // large_common_shndx
+  0,                   // small_common_section_flags
+  0,                   // large_common_section_flags
+  NULL,                        // attributes_section
+  NULL                 // attributes_vendor
 };
 
 template<>
@@ -346,7 +380,13 @@ Target::Target_info Target_sparc<64, true>::sparc_info =
   "/usr/lib/sparcv9/ld.so.1",  // dynamic_linker
   0x100000,            // default_text_segment_address
   64 * 1024,           // abi_pagesize (overridable by -z max-page-size)
-  8 * 1024             // common_pagesize (overridable by -z common-page-size)
+  8 * 1024,            // common_pagesize (overridable by -z common-page-size)
+  elfcpp::SHN_UNDEF,   // small_common_shndx
+  elfcpp::SHN_UNDEF,   // large_common_shndx
+  0,                   // small_common_section_flags
+  0,                   // large_common_section_flags
+  NULL,                        // attributes_section
+  NULL                 // attributes_vendor
 };
 
 // We have to take care here, even when operating in little-endian
@@ -361,13 +401,13 @@ private:
   rela(unsigned char* view,
        unsigned int right_shift,
        typename elfcpp::Elf_types<valsize>::Elf_Addr dst_mask,
-       typename elfcpp::Swap<size, big_endian>::Valtype value,
+       typename elfcpp::Swap<size, big_endian>::Valtype avalue,
        typename elfcpp::Swap<size, big_endian>::Valtype addend)
   {
     typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
-    Valtype reloc = ((value + addend) >> right_shift);
+    Valtype reloc = ((avalue + addend) >> right_shift);
 
     val &= ~dst_mask;
     reloc &= dst_mask;
@@ -549,10 +589,10 @@ public:
   // R_SPARC_HI22: (Symbol + Addend) >> 10
   static inline void
   hi22(unsigned char* view,
-       typename elfcpp::Elf_types<size>::Elf_Addr value,
+       typename elfcpp::Elf_types<size>::Elf_Addr avalue,
        typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
-    This_insn::template rela<32>(view, 10, 0x003fffff, value, addend);
+    This_insn::template rela<32>(view, 10, 0x003fffff, avalue, addend);
   }
 
   // R_SPARC_HI22: (Symbol + Addend) >> 10
@@ -580,10 +620,10 @@ public:
   // R_SPARC_LO10: (Symbol + Addend) & 0x3ff
   static inline void
   lo10(unsigned char* view,
-       typename elfcpp::Elf_types<size>::Elf_Addr value,
+       typename elfcpp::Elf_types<size>::Elf_Addr avalue,
        typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
-    This_insn::template rela<32>(view, 0, 0x000003ff, value, addend);
+    This_insn::template rela<32>(view, 0, 0x000003ff, avalue, addend);
   }
 
   // R_SPARC_LO10: (Symbol + Addend) & 0x3ff
@@ -642,10 +682,10 @@ public:
   // R_SPARC_13: (Symbol + Addend)
   static inline void
   rela32_13(unsigned char* view,
-           typename elfcpp::Elf_types<size>::Elf_Addr value,
+           typename elfcpp::Elf_types<size>::Elf_Addr avalue,
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
-    This_insn::template rela<32>(view, 0, 0x00001fff, value, addend);
+    This_insn::template rela<32>(view, 0, 0x00001fff, avalue, addend);
   }
 
   // R_SPARC_13: (Symbol + Addend)
@@ -864,22 +904,22 @@ public:
   // R_SPARC_TLS_LDO_HIX22: @dtpoff(Symbol + Addend) >> 10
   static inline void
   ldo_hix22(unsigned char* view,
-           typename elfcpp::Elf_types<size>::Elf_Addr value,
+           typename elfcpp::Elf_types<size>::Elf_Addr avalue,
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
-    This_insn::hi22(view, value, addend);
+    This_insn::hi22(view, avalue, addend);
   }
 
   // R_SPARC_TLS_LDO_LOX10: @dtpoff(Symbol + Addend) & 0x3ff
   static inline void
   ldo_lox10(unsigned char* view,
-           typename elfcpp::Elf_types<size>::Elf_Addr value,
+           typename elfcpp::Elf_types<size>::Elf_Addr avalue,
            typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
     typedef typename elfcpp::Swap<32, true>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<32, true>::readval(wv);
-    Valtype reloc = (value + addend);
+    Valtype reloc = (avalue + addend);
 
     val &= ~0x1fff;
     reloc &= 0x3ff;
@@ -890,13 +930,13 @@ public:
   // R_SPARC_TLS_LE_HIX22: (@tpoff(Symbol + Addend) ^ 0xffffffffffffffff) >> 10
   static inline void
   hix22(unsigned char* view,
-       typename elfcpp::Elf_types<size>::Elf_Addr value,
+       typename elfcpp::Elf_types<size>::Elf_Addr avalue,
        typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
     typedef typename elfcpp::Swap<32, true>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<32, true>::readval(wv);
-    Valtype reloc = (value + addend);
+    Valtype reloc = (avalue + addend);
 
     val &= ~0x3fffff;
 
@@ -934,13 +974,13 @@ public:
   // R_SPARC_TLS_LE_LOX10: (@tpoff(Symbol + Addend) & 0x3ff) | 0x1c00
   static inline void
   lox10(unsigned char* view,
-       typename elfcpp::Elf_types<size>::Elf_Addr value,
+       typename elfcpp::Elf_types<size>::Elf_Addr avalue,
        typename elfcpp::Elf_types<size>::Elf_Addr addend)
   {
     typedef typename elfcpp::Swap<32, true>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<32, true>::readval(wv);
-    Valtype reloc = (value + addend);
+    Valtype reloc = (avalue + addend);
 
     val &= ~0x1fff;
     reloc &= 0x3ff;
@@ -982,9 +1022,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_, false);
+      os->set_is_relro();
 
       // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
       symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
@@ -1007,9 +1050,9 @@ 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_);
+                                     elfcpp::SHF_ALLOC, this->rela_dyn_, true);
     }
   return this->rela_dyn_;
 }
@@ -1037,6 +1080,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);
@@ -1078,6 +1126,25 @@ class Output_data_plt_sparc : public Output_section_data
   unsigned int count_;
 };
 
+// Define the constants as required by C++ standard.
+
+template<int size, bool big_endian>
+const int Output_data_plt_sparc<size, big_endian>::base_plt_entry_size;
+
+template<int size, bool big_endian>
+const unsigned int
+Output_data_plt_sparc<size, big_endian>::plt_entries_per_block;
+
+template<int size, bool big_endian>
+const unsigned int Output_data_plt_sparc<size, big_endian>::plt_insn_chunk_size;
+
+template<int size, bool big_endian>
+const unsigned int
+Output_data_plt_sparc<size, big_endian>::plt_pointer_chunk_size;
+
+template<int size, bool big_endian>
+const unsigned int Output_data_plt_sparc<size, big_endian>::plt_block_size;
+
 // Create the PLT section.  The ordinary .got section is an argument,
 // since we need to refer to the start.
 
@@ -1085,9 +1152,9 @@ 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_);
+                                 elfcpp::SHF_ALLOC, this->rel_, true);
 }
 
 template<int size, bool big_endian>
@@ -1153,10 +1220,10 @@ template<int size, bool big_endian>
 void
 Output_data_plt_sparc<size, big_endian>::do_write(Output_file* of)
 {
-  const off_t offset = this->offset();
+  const off_t off = this->offset();
   const section_size_type oview_size =
     convert_to_section_size_type(this->data_size());
-  unsigned char* const oview = of->get_output_view(offset, oview_size);
+  unsigned char* const oview = of->get_output_view(off, oview_size);
   unsigned char* pov = oview;
 
   memset(pov, 0, base_plt_entry_size * 4);
@@ -1280,7 +1347,7 @@ Output_data_plt_sparc<size, big_endian>::do_write(Output_file* of)
 
   gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
 
-  of->write_output_view(offset, oview_size, oview);
+  of->write_output_view(off, oview_size, oview);
 }
 
 // Create a PLT entry for a global symbol.
@@ -1304,7 +1371,7 @@ Target_sparc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_EXECINSTR
                                       | elfcpp::SHF_WRITE),
-                                     this->plt_);
+                                     this->plt_, false);
 
       // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
       symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
@@ -1346,89 +1413,6 @@ Target_sparc<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
   return this->got_mod_index_offset_;
 }
 
-// Handle a relocation against a non-function symbol defined in a
-// dynamic object.  The traditional way to handle this is to generate
-// a COPY relocation to copy the variable at runtime from the shared
-// object into the executable's data segment.  However, this is
-// undesirable in general, as if the size of the object changes in the
-// dynamic object, the executable will no longer work correctly.  If
-// this relocation is in a writable section, then we can create a
-// dynamic reloc and the dynamic linker will resolve it to the correct
-// address at runtime.  However, we do not want do that if the
-// relocation is in a read-only section, as it would prevent the
-// readonly segment from being shared.  And if we have to eventually
-// generate a COPY reloc, then any dynamic relocations will be
-// useless.  So this means that if this is a writable section, we need
-// to save the relocation until we see whether we have to create a
-// COPY relocation for this symbol for any other relocation.
-
-template<int size, bool big_endian>
-void
-Target_sparc<size, big_endian>::copy_reloc(const General_options* options,
-                                          Symbol_table* symtab,
-                                          Layout* layout,
-                                          Sized_relobj<size, big_endian>* object,
-                                          unsigned int data_shndx,
-                                          Output_section* output_section,
-                                          Symbol* gsym,
-                                          const elfcpp::Rela<size, big_endian>& rel)
-{
-  Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(gsym);
-
-  if (!Copy_relocs<size, big_endian>::need_copy_reloc(options, object,
-                                                     data_shndx, ssym))
-    {
-      // So far we do not need a COPY reloc.  Save this relocation.
-      // If it turns out that we never need a COPY reloc for this
-      // symbol, then we will emit the relocation.
-      if (this->copy_relocs_ == NULL)
-       this->copy_relocs_ = new Copy_relocs<size, big_endian>();
-      this->copy_relocs_->save(ssym, object, data_shndx, output_section, rel);
-    }
-  else
-    {
-      // Allocate space for this symbol in the .bss section.
-
-      typename elfcpp::Elf_types<size>::Elf_WXword symsize = ssym->symsize();
-
-      // There is no defined way to determine the required alignment
-      // of the symbol.  We pick the alignment based on the size.  We
-      // set an arbitrary maximum of 256.
-      unsigned int align;
-      // XXX remove this when bss alignment issue is fixed...
-      for (align = (size == 32 ? 4 : 8); align < 512; align <<= 1)
-       if ((symsize & align) != 0)
-         break;
-
-      if (this->dynbss_ == NULL)
-       {
-         this->dynbss_ = new Output_data_space(align);
-         layout->add_output_section_data(".bss",
-                                         elfcpp::SHT_NOBITS,
-                                         (elfcpp::SHF_ALLOC
-                                          | elfcpp::SHF_WRITE),
-                                         this->dynbss_);
-       }
-
-      Output_data_space* dynbss = this->dynbss_;
-
-      if (align > dynbss->addralign())
-       dynbss->set_space_alignment(align);
-
-      section_size_type dynbss_size =
-       convert_to_section_size_type(dynbss->current_data_size());
-      dynbss_size = align_address(dynbss_size, align);
-      section_size_type offset = dynbss_size;
-      dynbss->set_current_data_size(dynbss_size + symsize);
-
-      symtab->define_with_copy_reloc(ssym, dynbss, offset);
-
-      // Add the COPY reloc.
-      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
-      rela_dyn->add_global(ssym, elfcpp::R_SPARC_COPY, dynbss, offset, 0);
-    }
-}
-
 // Optimize the TLS relocation type based on what we know about the
 // symbol.  IS_FINAL is true if the final address of this symbol is
 // known at link time.
@@ -1474,6 +1458,7 @@ optimize_tls_reloc(bool is_final, int r_type)
     case elfcpp::R_SPARC_TLS_IE_LO10:
     case elfcpp::R_SPARC_TLS_IE_LD:
     case elfcpp::R_SPARC_TLS_IE_LDX:
+    case elfcpp::R_SPARC_TLS_IE_ADD:
       // These are Initial-Exec relocs which get the thread offset
       // from the GOT.  If we know that we are linking against the
       // local symbol, we can switch to Local-Exec, which links the
@@ -1517,12 +1502,103 @@ Target_sparc<size, big_endian>::Scan::unsupported_reloc_local(
             object->name().c_str(), r_type);
 }
 
+// We are about to emit a dynamic relocation of type R_TYPE.  If the
+// dynamic linker does not support it, issue an error.
+
+template<int size, bool big_endian>
+void
+Target_sparc<size, big_endian>::Scan::check_non_pic(Relobj* object, unsigned int r_type)
+{
+  gold_assert(r_type != elfcpp::R_SPARC_NONE);
+
+  if (size == 64)
+    {
+      switch (r_type)
+       {
+         // These are the relocation types supported by glibc for sparc 64-bit.
+       case elfcpp::R_SPARC_RELATIVE:
+       case elfcpp::R_SPARC_COPY:
+       case elfcpp::R_SPARC_64:
+       case elfcpp::R_SPARC_GLOB_DAT:
+       case elfcpp::R_SPARC_JMP_SLOT:
+       case elfcpp::R_SPARC_TLS_DTPMOD64:
+       case elfcpp::R_SPARC_TLS_DTPOFF64:
+       case elfcpp::R_SPARC_TLS_TPOFF64:
+       case elfcpp::R_SPARC_TLS_LE_HIX22:
+       case elfcpp::R_SPARC_TLS_LE_LOX10:
+       case elfcpp::R_SPARC_8:
+       case elfcpp::R_SPARC_16:
+       case elfcpp::R_SPARC_DISP8:
+       case elfcpp::R_SPARC_DISP16:
+       case elfcpp::R_SPARC_DISP32:
+       case elfcpp::R_SPARC_WDISP30:
+       case elfcpp::R_SPARC_LO10:
+       case elfcpp::R_SPARC_HI22:
+       case elfcpp::R_SPARC_OLO10:
+       case elfcpp::R_SPARC_H44:
+       case elfcpp::R_SPARC_M44:
+       case elfcpp::R_SPARC_L44:
+       case elfcpp::R_SPARC_HH22:
+       case elfcpp::R_SPARC_HM10:
+       case elfcpp::R_SPARC_LM22:
+       case elfcpp::R_SPARC_UA16:
+       case elfcpp::R_SPARC_UA32:
+       case elfcpp::R_SPARC_UA64:
+         return;
+
+       default:
+         break;
+       }
+    }
+  else
+    {
+      switch (r_type)
+       {
+         // These are the relocation types supported by glibc for sparc 32-bit.
+       case elfcpp::R_SPARC_RELATIVE:
+       case elfcpp::R_SPARC_COPY:
+       case elfcpp::R_SPARC_GLOB_DAT:
+       case elfcpp::R_SPARC_32:
+       case elfcpp::R_SPARC_JMP_SLOT:
+       case elfcpp::R_SPARC_TLS_DTPMOD32:
+       case elfcpp::R_SPARC_TLS_DTPOFF32:
+       case elfcpp::R_SPARC_TLS_TPOFF32:
+       case elfcpp::R_SPARC_TLS_LE_HIX22:
+       case elfcpp::R_SPARC_TLS_LE_LOX10:
+       case elfcpp::R_SPARC_8:
+       case elfcpp::R_SPARC_16:
+       case elfcpp::R_SPARC_DISP8:
+       case elfcpp::R_SPARC_DISP16:
+       case elfcpp::R_SPARC_DISP32:
+       case elfcpp::R_SPARC_LO10:
+       case elfcpp::R_SPARC_WDISP30:
+       case elfcpp::R_SPARC_HI22:
+       case elfcpp::R_SPARC_UA16:
+       case elfcpp::R_SPARC_UA32:
+         return;
+
+       default:
+         break;
+       }
+    }
+
+  // This prevents us from issuing more than one error per reloc
+  // section.  But we can still wind up issuing more than one
+  // error per object file.
+  if (this->issued_non_pic_error_)
+    return;
+  gold_assert(parameters->options().output_is_position_independent());
+  object->error(_("requires unsupported dynamic reloc; "
+                 "recompile with -fPIC"));
+  this->issued_non_pic_error_ = true;
+  return;
+}
+
 // Scan a relocation for a local symbol.
 
 template<int size, bool big_endian>
 inline void
 Target_sparc<size, big_endian>::Scan::local(
-                       const General_options&,
                        Symbol_table* symtab,
                        Layout* layout,
                        Target_sparc<size, big_endian>* target,
@@ -1590,6 +1666,8 @@ Target_sparc<size, big_endian>::Scan::local(
       if (parameters->options().output_is_position_independent())
         {
           Reloc_section* rela_dyn = target->rela_dyn_section(layout);
+
+         check_non_pic(object, r_type);
           if (lsym.get_st_type() != elfcpp::STT_SECTION)
             {
               unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
@@ -1670,6 +1748,7 @@ Target_sparc<size, big_endian>::Scan::local(
     case elfcpp::R_SPARC_TLS_IE_LO10:
     case elfcpp::R_SPARC_TLS_IE_LD:
     case elfcpp::R_SPARC_TLS_IE_LDX:
+    case elfcpp::R_SPARC_TLS_IE_ADD:
     case elfcpp::R_SPARC_TLS_LE_HIX22: // Local-exec
     case elfcpp::R_SPARC_TLS_LE_LOX10:
       {
@@ -1689,13 +1768,21 @@ Target_sparc<size, big_endian>::Scan::local(
                 Output_data_got<size, big_endian>* got
                     = target->got_section(symtab, layout);
                 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
-                got->add_local_pair_with_rela(object, r_sym, 
-                                             lsym.get_st_shndx(),
-                                             GOT_TYPE_TLS_PAIR,
-                                             target->rela_dyn_section(layout),
-                                             (size == 64 ?
-                                              elfcpp::R_SPARC_TLS_DTPMOD64 :
-                                              elfcpp::R_SPARC_TLS_DTPMOD32), 0);
+               unsigned int shndx = lsym.get_st_shndx();
+               bool is_ordinary;
+               shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
+               if (!is_ordinary)
+                 object->error(_("local symbol %u has bad shndx %u"),
+                               r_sym, shndx);
+               else
+                 got->add_local_pair_with_rela(object, r_sym, 
+                                               lsym.get_st_shndx(),
+                                               GOT_TYPE_TLS_PAIR,
+                                               target->rela_dyn_section(layout),
+                                               (size == 64
+                                                ? elfcpp::R_SPARC_TLS_DTPMOD64
+                                                : elfcpp::R_SPARC_TLS_DTPMOD32),
+                                                0);
                if (r_type == elfcpp::R_SPARC_TLS_GD_CALL)
                  generate_tls_call(symtab, layout, target);
              }
@@ -1728,6 +1815,7 @@ Target_sparc<size, big_endian>::Scan::local(
          case elfcpp::R_SPARC_TLS_IE_LO10:
          case elfcpp::R_SPARC_TLS_IE_LD:
          case elfcpp::R_SPARC_TLS_IE_LDX:
+         case elfcpp::R_SPARC_TLS_IE_ADD:
            layout->set_has_static_tls();
            if (optimized_type == tls::TLSOPT_NONE)
              {
@@ -1812,7 +1900,6 @@ Target_sparc<size, big_endian>::Scan::unsupported_reloc_global(
 template<int size, bool big_endian>
 inline void
 Target_sparc<size, big_endian>::Scan::global(
-                               const General_options& options,
                                Symbol_table* symtab,
                                Layout* layout,
                                Target_sparc<size, big_endian>* target,
@@ -1825,6 +1912,13 @@ Target_sparc<size, big_endian>::Scan::global(
 {
   unsigned int orig_r_type = r_type;
 
+  // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got
+  // section.  We check here to avoid creating a dynamic reloc against
+  // _GLOBAL_OFFSET_TABLE_.
+  if (!target->has_got_section()
+      && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
+    target->got_section(symtab, layout);
+
   r_type &= 0xff;
   switch (r_type)
     {
@@ -1878,15 +1972,16 @@ Target_sparc<size, big_endian>::Scan::global(
          flags |= Symbol::FUNCTION_CALL;
        if (gsym->needs_dynamic_reloc(flags))
          {
-           if (target->may_need_copy_reloc(gsym))
+           if (gsym->may_need_copy_reloc())
              {
-               target->copy_reloc(&options, symtab, layout, object,
+               target->copy_reloc(symtab, layout, object,
                                   data_shndx, output_section, gsym,
                                   reloc);
              }
            else
              {
                Reloc_section* rela_dyn = target->rela_dyn_section(layout);
+               check_non_pic(object, r_type);
                rela_dyn->add_global(gsym, orig_r_type, output_section, object,
                                     data_shndx, reloc.get_r_offset(),
                                     reloc.get_r_addend());
@@ -1933,9 +2028,9 @@ Target_sparc<size, big_endian>::Scan::global(
         // Make a dynamic relocation if necessary.
         if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
           {
-            if (target->may_need_copy_reloc(gsym))
+            if (gsym->may_need_copy_reloc())
               {
-               target->copy_reloc(&options, symtab, layout, object,
+               target->copy_reloc(symtab, layout, object,
                                   data_shndx, output_section, gsym, reloc);
               }
             else if ((r_type == elfcpp::R_SPARC_32
@@ -1952,6 +2047,7 @@ Target_sparc<size, big_endian>::Scan::global(
               {
                 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
 
+               check_non_pic(object, r_type);
                if (gsym->is_from_dynobj()
                    || gsym->is_undefined()
                    || gsym->is_preemptible())
@@ -2021,6 +2117,7 @@ Target_sparc<size, big_endian>::Scan::global(
     case elfcpp::R_SPARC_TLS_IE_LO10:
     case elfcpp::R_SPARC_TLS_IE_LD:
     case elfcpp::R_SPARC_TLS_IE_LDX:
+    case elfcpp::R_SPARC_TLS_IE_ADD:
       {
        const bool is_final = gsym->final_value_is_known();
        const tls::Tls_optimization optimized_type
@@ -2103,6 +2200,7 @@ Target_sparc<size, big_endian>::Scan::global(
          case elfcpp::R_SPARC_TLS_IE_LO10:
          case elfcpp::R_SPARC_TLS_IE_LD:
          case elfcpp::R_SPARC_TLS_IE_LDX:
+         case elfcpp::R_SPARC_TLS_IE_ADD:
            layout->set_has_static_tls();
            if (optimized_type == tls::TLSOPT_NONE)
              {
@@ -2144,12 +2242,45 @@ Target_sparc<size, big_endian>::Scan::global(
     }
 }
 
+// Process relocations for gc.
+
+template<int size, bool big_endian>
+void
+Target_sparc<size, big_endian>::gc_process_relocs(
+                       Symbol_table* symtab,
+                       Layout* layout,
+                       Sized_relobj<size, big_endian>* object,
+                       unsigned int data_shndx,
+                       unsigned int,
+                       const unsigned char* prelocs,
+                       size_t reloc_count,
+                       Output_section* output_section,
+                       bool needs_special_offset_handling,
+                       size_t local_symbol_count,
+                       const unsigned char* plocal_symbols)
+{
+  typedef Target_sparc<size, big_endian> Sparc;
+  typedef typename Target_sparc<size, big_endian>::Scan scan;
+
+  gold::gc_process_relocs<size, big_endian, Sparc, elfcpp::SHT_RELA, scan>(
+    symtab,
+    layout,
+    this,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols);
+}
+
 // Scan relocations for a section.
 
 template<int size, bool big_endian>
 void
 Target_sparc<size, big_endian>::scan_relocs(
-                       const General_options& options,
                        Symbol_table* symtab,
                        Layout* layout,
                        Sized_relobj<size, big_endian>* object,
@@ -2163,7 +2294,7 @@ Target_sparc<size, big_endian>::scan_relocs(
                        const unsigned char* plocal_symbols)
 {
   typedef Target_sparc<size, big_endian> Sparc;
-  typedef typename Target_sparc<size, big_endian>::Scan Scan;
+  typedef typename Target_sparc<size, big_endian>::Scan scan;
 
   if (sh_type == elfcpp::SHT_REL)
     {
@@ -2172,8 +2303,7 @@ Target_sparc<size, big_endian>::scan_relocs(
       return;
     }
 
-  gold::scan_relocs<size, big_endian, Sparc, elfcpp::SHT_RELA, Scan>(
-    options,
+  gold::scan_relocs<size, big_endian, Sparc, elfcpp::SHT_RELA, scan>(
     symtab,
     layout,
     this,
@@ -2191,13 +2321,17 @@ Target_sparc<size, big_endian>::scan_relocs(
 
 template<int size, bool big_endian>
 void
-Target_sparc<size, big_endian>::do_finalize_sections(Layout* layout)
+Target_sparc<size, big_endian>::do_finalize_sections(
+    Layout* layout,
+    const Input_objects*,
+    Symbol_table*)
 {
   // Fill in some more dynamic tags.
   Output_data_dynamic* const odyn = layout->dynamic_data();
   if (odyn != NULL)
     {
-      if (this->plt_ != NULL)
+      if (this->plt_ != NULL
+         && this->plt_->output_section() != NULL)
        {
          const Output_data* od = this->plt_->rel_plt();
          odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
@@ -2207,7 +2341,8 @@ Target_sparc<size, big_endian>::do_finalize_sections(Layout* layout)
          odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_);
        }
 
-      if (this->rela_dyn_ != NULL)
+      if (this->rela_dyn_ != NULL
+         && this->rela_dyn_->output_section() != NULL)
        {
          const Output_data* od = this->rela_dyn_;
          odyn->add_section_address(elfcpp::DT_RELA, od);
@@ -2226,15 +2361,8 @@ Target_sparc<size, big_endian>::do_finalize_sections(Layout* layout)
 
   // Emit any relocs we saved in an attempt to avoid generating COPY
   // relocs.
-  if (this->copy_relocs_ == NULL)
-    return;
-  if (this->copy_relocs_->any_to_emit())
-    {
-      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
-      this->copy_relocs_->emit(rela_dyn);
-    }
-  delete this->copy_relocs_;
-  this->copy_relocs_ = NULL;
+  if (this->copy_relocs_.any_saved_relocs())
+    this->copy_relocs_.emit(this->rela_dyn_section(layout));
 }
 
 // Perform a relocation.
@@ -2244,6 +2372,7 @@ inline bool
 Target_sparc<size, big_endian>::Relocate::relocate(
                        const Relocate_info<size, big_endian>* relinfo,
                        Target_sparc* target,
+                       Output_section*,
                        size_t relnum,
                        const elfcpp::Rela<size, big_endian>& rela,
                        unsigned int r_type,
@@ -2272,16 +2401,25 @@ 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;
+      elfcpp::Elf_Xword avalue;
 
-      value = target->plt_section()->address() + gsym->plt_offset();
+      avalue = target->plt_section()->address() + gsym->plt_offset();
 
-      symval.set_output_value(value);
+      symval.set_output_value(avalue);
 
       psymval = &symval;
     }
@@ -2337,8 +2475,8 @@ Target_sparc<size, big_endian>::Relocate::relocate(
 
     case elfcpp::R_SPARC_32:
       if (!parameters->options().output_is_position_independent())
-             Relocate_functions<size, big_endian>::rela32(view, object,
-                                                          psymval, addend);
+       Relocate_functions<size, big_endian>::rela32(view, object,
+                                                    psymval, addend);
       break;
 
     case elfcpp::R_SPARC_DISP8:
@@ -2547,6 +2685,7 @@ Target_sparc<size, big_endian>::Relocate::relocate(
     case elfcpp::R_SPARC_TLS_IE_LO10:
     case elfcpp::R_SPARC_TLS_IE_LD:
     case elfcpp::R_SPARC_TLS_IE_LDX:
+    case elfcpp::R_SPARC_TLS_IE_ADD:
     case elfcpp::R_SPARC_TLS_LE_HIX22:
     case elfcpp::R_SPARC_TLS_LE_LOX10:
       this->relocate_tls(relinfo, target, relnum, rela,
@@ -2601,7 +2740,7 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
   typedef typename elfcpp::Swap<32, true>::Valtype Insntype;
 
   const elfcpp::Elf_Xword addend = rela.get_r_addend();
-  typename elfcpp::Elf_types<size>::Elf_Addr value = psymval->value(object, 0);
+  typename elfcpp::Elf_types<size>::Elf_Addr avalue = psymval->value(object, 0);
 
   const bool is_final =
     (gsym == NULL
@@ -2621,18 +2760,18 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
          Insntype* wv = reinterpret_cast<Insntype*>(view);
          Insntype val;
 
-         value -= tls_segment->memsz();
+         avalue -= tls_segment->memsz();
 
          switch (r_type)
            {
            case elfcpp::R_SPARC_TLS_GD_HI22:
              // TLS_GD_HI22 --> TLS_LE_HIX22
-             Reloc::hix22(view, value, addend);
+             Reloc::hix22(view, avalue, addend);
              break;
 
            case elfcpp::R_SPARC_TLS_GD_LO10:
              // TLS_GD_LO10 --> TLS_LE_LOX10
-             Reloc::lox10(view, value, addend);
+             Reloc::lox10(view, avalue, addend);
              break;
 
            case elfcpp::R_SPARC_TLS_GD_ADD:
@@ -2656,13 +2795,13 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
           if (gsym != NULL)
             {
               gold_assert(gsym->has_got_offset(got_type));
-              value = gsym->got_offset(got_type);
+              avalue = gsym->got_offset(got_type);
             }
           else
             {
               unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
               gold_assert(object->local_has_got_offset(r_sym, got_type));
-              value = object->local_got_offset(r_sym, got_type);
+              avalue = object->local_got_offset(r_sym, got_type);
             }
           if (optimized_type == tls::TLSOPT_TO_IE)
            {
@@ -2673,12 +2812,12 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
                {
                case elfcpp::R_SPARC_TLS_GD_HI22:
                  // TLS_GD_HI22 --> TLS_IE_HI22
-                 Reloc::hi22(view, value, addend);
+                 Reloc::hi22(view, avalue, addend);
                  break;
 
                case elfcpp::R_SPARC_TLS_GD_LO10:
                  // TLS_GD_LO10 --> TLS_IE_LO10
-                 Reloc::lo10(view, value, addend);
+                 Reloc::lo10(view, avalue, addend);
                  break;
 
                case elfcpp::R_SPARC_TLS_GD_ADD:
@@ -2728,24 +2867,24 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
              switch (r_type)
                {
                case elfcpp::R_SPARC_TLS_GD_HI22:
-                 Reloc::hi22(view, value, addend);
+                 Reloc::hi22(view, avalue, addend);
                  break;
                case elfcpp::R_SPARC_TLS_GD_LO10:
-                 Reloc::lo10(view, value, addend);
+                 Reloc::lo10(view, avalue, addend);
                  break;
                case elfcpp::R_SPARC_TLS_GD_ADD:
                  break;
                case elfcpp::R_SPARC_TLS_GD_CALL:
                  {
                    Symbol_value<size> symval;
-                   elfcpp::Elf_Xword value;
+                   elfcpp::Elf_Xword xvalue;
                    Symbol* tsym;
 
                    tsym = target->tls_get_addr_sym_;
                    gold_assert(tsym);
-                   value = (target->plt_section()->address() +
-                            tsym->plt_offset());
-                   symval.set_output_value(value);
+                   xvalue = (target->plt_section()->address() +
+                             tsym->plt_offset());
+                   symval.set_output_value(xvalue);
                    Reloc::wdisp30(view, object, &symval, addend, address);
                  }
                  break;
@@ -2800,14 +2939,14 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
            case elfcpp::R_SPARC_TLS_LDM_CALL:
              {
                Symbol_value<size> symval;
-               elfcpp::Elf_Xword value;
+               elfcpp::Elf_Xword xvalue;
                Symbol* tsym;
 
                tsym = target->tls_get_addr_sym_;
                gold_assert(tsym);
-               value = (target->plt_section()->address() +
-                        tsym->plt_offset());
-               symval.set_output_value(value);
+               xvalue = (target->plt_section()->address() +
+                         tsym->plt_offset());
+               symval.set_output_value(xvalue);
                Reloc::wdisp30(view, object, &symval, addend, address);
              }
              break;
@@ -2825,20 +2964,20 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
     case elfcpp::R_SPARC_TLS_LDO_HIX22:
       if (optimized_type == tls::TLSOPT_TO_LE)
        {
-         value -= tls_segment->memsz();
-         Reloc::hix22(view, value, addend);
+         avalue -= tls_segment->memsz();
+         Reloc::hix22(view, avalue, addend);
        }
       else
-       Reloc::ldo_hix22(view, value, addend);
+       Reloc::ldo_hix22(view, avalue, addend);
       break;
     case elfcpp::R_SPARC_TLS_LDO_LOX10:
       if (optimized_type == tls::TLSOPT_TO_LE)
        {
-         value -= tls_segment->memsz();
-         Reloc::lox10(view, value, addend);
+         avalue -= tls_segment->memsz();
+         Reloc::lox10(view, avalue, addend);
        }
       else
-       Reloc::ldo_lox10(view, value, addend);
+       Reloc::ldo_lox10(view, avalue, addend);
       break;
     case elfcpp::R_SPARC_TLS_LDO_ADD:
       if (optimized_type == tls::TLSOPT_TO_LE)
@@ -2879,16 +3018,16 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
     case elfcpp::R_SPARC_TLS_IE_LO10:
       if (optimized_type == tls::TLSOPT_TO_LE)
        {
-         value -= tls_segment->memsz();
+         avalue -= tls_segment->memsz();
          switch (r_type)
            {
            case elfcpp::R_SPARC_TLS_IE_HI22:
              // IE_HI22 --> LE_HIX22
-             Reloc::hix22(view, value, addend);
+             Reloc::hix22(view, avalue, addend);
              break;
            case elfcpp::R_SPARC_TLS_IE_LO10:
              // IE_LO10 --> LE_LOX10
-             Reloc::lox10(view, value, addend);
+             Reloc::lox10(view, avalue, addend);
              break;
            }
          break;
@@ -2900,23 +3039,23 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
          if (gsym != NULL)
            {
              gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_OFFSET));
-             value = gsym->got_offset(GOT_TYPE_TLS_OFFSET);
+             avalue = gsym->got_offset(GOT_TYPE_TLS_OFFSET);
            }
          else
            {
              unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
              gold_assert(object->local_has_got_offset(r_sym,
                                                       GOT_TYPE_TLS_OFFSET));
-             value = object->local_got_offset(r_sym,
-                                              GOT_TYPE_TLS_OFFSET);
+             avalue = object->local_got_offset(r_sym,
+                                               GOT_TYPE_TLS_OFFSET);
            }
          switch (r_type)
            {
            case elfcpp::R_SPARC_TLS_IE_HI22:
-             Reloc::hi22(view, value, addend);
+             Reloc::hi22(view, avalue, addend);
              break;
            case elfcpp::R_SPARC_TLS_IE_LO10:
-             Reloc::lo10(view, value, addend);
+             Reloc::lo10(view, avalue, addend);
              break;
            }
          break;
@@ -2926,13 +3065,19 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
                             r_type);
       break;
 
+    case elfcpp::R_SPARC_TLS_IE_ADD:
+      // This seems to be mainly so that we can find the addition
+      // instruction if there is one.  There doesn't seem to be any
+      // actual relocation to apply.
+      break;
+
     case elfcpp::R_SPARC_TLS_LE_HIX22:
       // If we're creating a shared library, a dynamic relocation will
       // have been created for this location, so do not apply it now.
       if (!parameters->options().shared())
        {
-         value -= tls_segment->memsz();
-         Reloc::hix22(view, value, addend);
+         avalue -= tls_segment->memsz();
+         Reloc::hix22(view, avalue, addend);
        }
       break;
 
@@ -2941,8 +3086,8 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
       // have been created for this location, so do not apply it now.
       if (!parameters->options().shared())
        {
-         value -= tls_segment->memsz();
-         Reloc::lox10(view, value, addend);
+         avalue -= tls_segment->memsz();
+         Reloc::lox10(view, avalue, addend);
        }
       break;
     }
@@ -2961,7 +3106,8 @@ Target_sparc<size, big_endian>::relocate_section(
                        bool needs_special_offset_handling,
                        unsigned char* view,
                        typename elfcpp::Elf_types<size>::Elf_Addr address,
-                       section_size_type view_size)
+                       section_size_type view_size,
+                       const Reloc_symbol_changes* reloc_symbol_changes)
 {
   typedef Target_sparc<size, big_endian> Sparc;
   typedef typename Target_sparc<size, big_endian>::Relocate Sparc_relocate;
@@ -2978,7 +3124,8 @@ Target_sparc<size, big_endian>::relocate_section(
     needs_special_offset_handling,
     view,
     address,
-    view_size);
+    view_size,
+    reloc_symbol_changes);
 }
 
 // Return the size of a relocation while scanning during a relocatable
@@ -3000,7 +3147,6 @@ Target_sparc<size, big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
 template<int size, bool big_endian>
 void
 Target_sparc<size, big_endian>::scan_relocatable_relocs(
-                       const General_options& options,
                        Symbol_table* symtab,
                        Layout* layout,
                        Sized_relobj<size, big_endian>* object,
@@ -3021,7 +3167,6 @@ Target_sparc<size, big_endian>::scan_relocatable_relocs(
 
   gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_RELA,
       Scan_relocatable_relocs>(
-    options,
     symtab,
     layout,
     object,
@@ -3093,20 +3238,18 @@ public:
                      (size == 64 ? "elf64-sparc" : "elf32-sparc"))
   { }
 
-  Target* instantiated_target_;
-
-  Target* do_recognize(int machine, int, int)
+  Target* do_recognize(int amachine, int, int)
   {
     switch (size)
       {
       case 64:
-       if (machine != elfcpp::EM_SPARCV9)
+       if (amachine != elfcpp::EM_SPARCV9)
          return NULL;
        break;
 
       case 32:
-       if (machine != elfcpp::EM_SPARC
-           && machine != elfcpp::EM_SPARC32PLUS)
+       if (amachine != elfcpp::EM_SPARC
+           && amachine != elfcpp::EM_SPARC32PLUS)
          return NULL;
        break;
 
@@ -3114,15 +3257,11 @@ public:
        return NULL;
       }
 
-    return do_instantiate_target();
+    return this->instantiate_target();
   }
 
   Target* do_instantiate_target()
-  {
-    if (this->instantiated_target_ == NULL)
-      this->instantiated_target_ = new Target_sparc<size, big_endian>();
-    return this->instantiated_target_;
-  }
+  { return new Target_sparc<size, big_endian>(); }
 };
 
 Target_selector_sparc<32, true> target_selector_sparc32;
This page took 0.045528 seconds and 4 git commands to generate.