gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / tilegx.cc
index 037bf5458045f6940c7f192237cfadcc0be5ea49..f2c1038b045982f5d77b7ca01eab8322f04f1b95 100644 (file)
@@ -1,6 +1,6 @@
 // tilegx.cc -- tilegx target support for gold.
 
-// Copyright 2012 Free Software Foundation, Inc.
+// Copyright (C) 2012-2020 Free Software Foundation, Inc.
 // Written by Jiong Wang (jiwang@tilera.com)
 
 // This file is part of gold.
@@ -239,7 +239,7 @@ class Target_tilegx : public Sized_target<size, big_endian>
       got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
       global_offset_table_(NULL), tilegx_dynamic_(NULL), rela_dyn_(NULL),
       rela_irelative_(NULL), copy_relocs_(elfcpp::R_TILEGX_COPY),
-      dynbss_(NULL), got_mod_index_offset_(-1U),
+      got_mod_index_offset_(-1U),
       tls_get_addr_sym_defined_(false)
   { }
 
@@ -308,6 +308,21 @@ class Target_tilegx : public Sized_target<size, big_endian>
                           const unsigned char* plocal_symbols,
                           Relocatable_relocs*);
 
+  // Scan the relocs for --emit-relocs.
+  void
+  emit_relocs_scan(Symbol_table* symtab,
+                  Layout* layout,
+                  Sized_relobj_file<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_syms,
+                  Relocatable_relocs* rr);
+
   // Relocate a section during a relocatable link.
   void
   relocate_relocs(
@@ -316,8 +331,7 @@ class Target_tilegx : public Sized_target<size, big_endian>
       const unsigned char* prelocs,
       size_t reloc_count,
       Output_section* output_section,
-      off_t offset_in_output_section,
-      const Relocatable_relocs*,
+      typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
       section_size_type view_size,
@@ -517,22 +531,11 @@ class Target_tilegx : public Sized_target<size, big_endian>
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<size, big_endian>*, Target_tilegx*,
-             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*, typename elfcpp::Elf_types<size>::Elf_Addr,
-             section_size_type);
-  };
-
-  // A class which returns the size required for a relocation type,
-  // used while scanning relocs during a relocatable link.
-  class Relocatable_size_for_reloc
-  {
-   public:
-    unsigned int
-    get_size_for_reloc(unsigned int, Relobj*);
+    relocate(const Relocate_info<size, big_endian>*, unsigned int,
+            Target_tilegx*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
+            unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
+            section_size_type);
   };
 
   // Adjust TLS relocation type based on the options and whether this
@@ -594,10 +597,13 @@ class Target_tilegx : public Sized_target<size, big_endian>
              unsigned int shndx, Output_section* output_section,
              Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
   {
+    unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
     this->copy_relocs_.copy_reloc(symtab, layout,
                                   symtab->get_sized_symbol<size>(sym),
                                   object, shndx, output_section,
-                                  reloc, this->rela_dyn_section(layout));
+                                 r_type, reloc.get_r_offset(),
+                                 reloc.get_r_addend(),
+                                  this->rela_dyn_section(layout));
   }
 
   // Information about this specific target which we pass to the
@@ -650,8 +656,6 @@ class Target_tilegx : public Sized_target<size, big_endian>
   Reloc_section* rela_irelative_;
   // Relocs saved to avoid a COPY reloc.
   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.
   unsigned int got_mod_index_offset_;
   // True if the _tls_get_addr symbol has been defined.
@@ -681,7 +685,10 @@ const Target::Target_info Target_tilegx<64, false>::tilegx_info =
   0,                    // small_common_section_flags
   0,                    // large_common_section_flags
   NULL,                 // attributes_section
-  NULL                  // attributes_vendor
+  NULL,                 // attributes_vendor
+  "_start",            // entry_symbol_name
+  32,                  // hash_entry_size
+  elfcpp::SHT_PROGBITS,        // unwind_section_type
 };
 
 template<>
@@ -707,7 +714,10 @@ const Target::Target_info Target_tilegx<32, false>::tilegx_info =
   0,                    // small_common_section_flags
   0,                    // large_common_section_flags
   NULL,                 // attributes_section
-  NULL                  // attributes_vendor
+  NULL,                 // attributes_vendor
+  "_start",            // entry_symbol_name
+  32,                  // hash_entry_size
+  elfcpp::SHT_PROGBITS,        // unwind_section_type
 };
 
 template<>
@@ -733,7 +743,10 @@ const Target::Target_info Target_tilegx<64, true>::tilegx_info =
   0,                    // small_common_section_flags
   0,                    // large_common_section_flags
   NULL,                 // attributes_section
-  NULL                  // attributes_vendor
+  NULL,                 // attributes_vendor
+  "_start",            // entry_symbol_name
+  32,                  // hash_entry_size
+  elfcpp::SHT_PROGBITS,        // unwind_section_type
 };
 
 template<>
@@ -759,7 +772,10 @@ const Target::Target_info Target_tilegx<32, true>::tilegx_info =
   0,                    // small_common_section_flags
   0,                    // large_common_section_flags
   NULL,                 // attributes_section
-  NULL                  // attributes_vendor
+  NULL,                  // attributes_vendor
+  "_start",            // entry_symbol_name
+  32,                  // hash_entry_size
+  elfcpp::SHT_PROGBITS,        // unwind_section_type
 };
 
 // tilegx relocation handlers
@@ -780,7 +796,7 @@ public:
     // right shift operand by this number of bits.
     unsigned char srshift;
 
-    // the offset to apply relocation. 
+    // the offset to apply relocation.
     unsigned char doffset;
 
     // set to 1 for pc-relative relocation.
@@ -899,7 +915,7 @@ private:
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
     Valtype reloc = 0;
-    if (size == 32) 
+    if (size == 32)
       reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
                >> srshift;
     else
@@ -927,7 +943,7 @@ private:
       Valtype;
     unsigned char* wv = view;
     Valtype reloc = 0;
-    if (size == 32) 
+    if (size == 32)
       reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
                >> srshift;
     else
@@ -954,7 +970,7 @@ private:
     Valtype* wv = reinterpret_cast<Valtype*>(view);
     Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
     Valtype reloc = 0;
-    if (size == 32) 
+    if (size == 32)
       reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address)
                >> srshift;
     else
@@ -1043,7 +1059,7 @@ public:
                 const Symbol_value<size>* psymval,
                 typename elfcpp::Elf_types<size>::Elf_Addr addend,
                 Tilegx_howto &r_howto)
-  { 
+  {
     This::template rela<64>(view, object, psymval, addend,
                             (elfcpp::Elf_Xword)(r_howto.srshift),
                             (elfcpp::Elf_Xword)(r_howto.doffset),
@@ -1057,7 +1073,7 @@ public:
                       typename elfcpp::Elf_types<size>::Elf_Addr addend,
                       typename elfcpp::Elf_types<size>::Elf_Addr address,
                       Tilegx_howto &r_howto)
-  { 
+  {
     This::template pcrela<64>(view, object, psymval, addend, address,
                               (elfcpp::Elf_Xword)(r_howto.srshift),
                               (elfcpp::Elf_Xword)(r_howto.doffset),
@@ -1071,7 +1087,7 @@ public:
                          typename elfcpp::Elf_types<size>::Elf_Addr addend,
                          typename elfcpp::Elf_types<size>::Elf_Addr address,
                          unsigned int r_type)
-  { 
+  {
 
     elfcpp::Elf_Xword doffset1 = 0llu;
     elfcpp::Elf_Xword doffset2 = 0llu;
@@ -1111,8 +1127,8 @@ public:
   static inline void
   tls_relax(unsigned char* view, unsigned int r_type,
             tls::Tls_optimization opt_t)
-  { 
+  {
+
     const uint64_t TILEGX_X_MOVE_R0_R0 = 0x283bf8005107f000llu;
     const uint64_t TILEGX_Y_MOVE_R0_R0 = 0xae05f800540bf000llu;
     const uint64_t TILEGX_X_LD         = 0x286ae80000000000llu;
@@ -1176,7 +1192,7 @@ public:
           // LE: 1. copy dest operand into the first source operand
           //     2. change the opcode to "move"
           reloc = (val & 0x3Fllu) << 6;
-          reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK); 
+          reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK);
           val &= ~R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK;
         } else
           gold_unreachable();
@@ -1228,7 +1244,7 @@ public:
         break;
       case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD:
         if (opt_t == tls::TLSOPT_NONE) {
-          // GD see comments for optimize_tls_reloc 
+          // GD see comments for optimize_tls_reloc
           reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK;
           val &= ~TILEGX_X0_RRR_SRCB_MASK;
         } else if (opt_t == tls::TLSOPT_TO_IE
@@ -1890,7 +1906,7 @@ Target_tilegx<size, big_endian>::got_section(Symbol_table* symtab,
                                         false, false);
 
         this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD);
-      } else 
+      } else
         // for executable, just set the first entry to zero.
         this->got_->set_current_data_size(size / 8);
 
@@ -2022,7 +2038,7 @@ Output_data_plt_tilegx<size, big_endian>::add_entry(Symbol_table* symtab,
       plt_index = *pcount;
 
       // TILEGX .plt section layout
-      // 
+      //
       //  ----
       //   plt_header
       //  ----
@@ -2030,9 +2046,9 @@ Output_data_plt_tilegx<size, big_endian>::add_entry(Symbol_table* symtab,
       //  ----
       //   ...
       //  ----
-      //  
+      //
       // TILEGX .got.plt section layout
-      // 
+      //
       //  ----
       //  reserv1
       //  ----
@@ -2041,7 +2057,7 @@ Output_data_plt_tilegx<size, big_endian>::add_entry(Symbol_table* symtab,
       //   entries for normal function
       //  ----
       //   ...
-      //  ---- 
+      //  ----
       //   entries for ifunc
       //  ----
       //   ...
@@ -2194,7 +2210,7 @@ Output_data_plt_tilegx<size, big_endian>::address_for_global(
   if (gsym->type() == elfcpp::STT_GNU_IFUNC
       && gsym->can_use_relative_reloc(false))
     offset = (this->count_ + 1) * this->get_plt_entry_size();
-  return this->address() + offset;
+  return this->address() + offset + gsym->plt_offset();
 }
 
 // Return the PLT address to use for a local symbol.  These are always
@@ -2202,10 +2218,13 @@ Output_data_plt_tilegx<size, big_endian>::address_for_global(
 
 template<int size, bool big_endian>
 uint64_t
-Output_data_plt_tilegx<size, big_endian>::address_for_local(const Relobj*,
-                                                            unsigned int)
+Output_data_plt_tilegx<size, big_endian>::address_for_local(
+    const Relobj* object,
+    unsigned int r_sym)
 {
-  return this->address() + (this->count_ + 1) * this->get_plt_entry_size();
+  return (this->address()
+         + (this->count_ + 1) * this->get_plt_entry_size()
+         + object->local_plt_offset(r_sym));
 }
 
 // Set the final size.
@@ -2512,7 +2531,7 @@ Target_tilegx<size, big_endian>::make_plt_section(Symbol_table* symtab,
       this->got_section(symtab, layout);
 
       // Ensure that .rela.dyn always appears before .rela.plt,
-      // becuase on TILE-Gx, .rela.dyn needs to include .rela.plt
+      // because on TILE-Gx, .rela.dyn needs to include .rela.plt
       // in it's range.
       this->rela_dyn_section(layout);
 
@@ -2871,8 +2890,8 @@ Target_tilegx<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
 //       move        r0,  r0                     Y0/Y1/X0/X1
 //       move        r0,  r0                     Y0/Y1/X0/X1
 //       add         adr, r0, tp                 Y0/Y1/X0/X1
-//     
-//     
+//
+//
 //   compiler IE reference
 //    |
 //    V
@@ -3120,7 +3139,7 @@ Target_tilegx<size, big_endian>::Scan::unsupported_reloc_local(
 }
 
 // We are about to emit a dynamic relocation of type R_TYPE.  If the
-// dynamic linker does not support it, issue an error. 
+// dynamic linker does not support it, issue an error.
 template<int size, bool big_endian>
 void
 Target_tilegx<size, big_endian>::Scan::check_non_pic(Relobj* object,
@@ -3293,7 +3312,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
                                                     data_shndx,
                                                     reloc.get_r_offset(),
                                                     reloc.get_r_addend());
-             
+
             }
         }
       break;
@@ -3360,7 +3379,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
             // tilegx dynamic linker will not update local got entry,
             // so, if we are generating a shared object, we need to add a
             // dynamic relocation for this symbol's GOT entry to inform
-            // dynamic linker plus the load base explictly.
+            // dynamic linker plus the load base explicitly.
             if (parameters->options().output_is_position_independent())
               {
                unsigned int got_offset
@@ -3416,7 +3435,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
                //
                // R_TILEGX_TLS_GD_CALL implicitly reference __tls_get_addr,
                // while all other target, x86/arm/mips/powerpc/sparc
-               // generate tls relocation against __tls_get_addr explictly,
+               // generate tls relocation against __tls_get_addr explicitly,
                // so for TILEGX, we need the following hack.
                if (opt_t == tls::TLSOPT_NONE) {
                  if (!target->tls_get_addr_sym_defined_) {
@@ -3447,7 +3466,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
                break;
 
              // GD: requires two GOT entry for module index and offset
-             // IE: requires one GOT entry for tp-relative offset 
+             // IE: requires one GOT entry for tp-relative offset
              // LE: shouldn't happen for global symbol
              case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
              case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
@@ -3470,7 +3489,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
                                    r_sym, shndx);
                    else
                      got->add_local_pair_with_rel(object, r_sym, shndx,
-                                           GOT_TYPE_TLS_PAIR, 
+                                           GOT_TYPE_TLS_PAIR,
                                            target->rela_dyn_section(layout),
                                            size == 32
                                            ? elfcpp::R_TILEGX_TLS_DTPMOD32
@@ -3490,7 +3509,7 @@ Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab,
                                             ? elfcpp::R_TILEGX_TLS_TPOFF32
                                             : elfcpp::R_TILEGX_TLS_TPOFF64,
                                             got, off, 0);
-                  } else if (opt_t != tls::TLSOPT_TO_LE) 
+                  } else if (opt_t != tls::TLSOPT_TO_LE)
                     // only TO_LE is allowed for local symbol
                     unsupported_reloc_local(object, r_type);
                }
@@ -3753,7 +3772,8 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
         // Make a dynamic relocation if necessary.
         if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
           {
-            if (gsym->may_need_copy_reloc())
+           if (!parameters->options().output_is_position_independent()
+               && gsym->may_need_copy_reloc())
               {
                 target->copy_reloc(symtab, layout, object,
                                    data_shndx, output_section, gsym, reloc);
@@ -3827,7 +3847,8 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
         // Make a dynamic relocation if necessary.
         if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
           {
-            if (gsym->may_need_copy_reloc())
+           if (parameters->options().output_is_executable()
+               && gsym->may_need_copy_reloc())
               {
                 target->copy_reloc(symtab, layout, object,
                                    data_shndx, output_section, gsym, reloc);
@@ -4007,7 +4028,7 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
                                          symtab->lookup("__tls_get_addr"));
                 }
                 break;
-          
+
               // only make effect when applying relocation
               case elfcpp::R_TILEGX_TLS_IE_LOAD:
               case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD:
@@ -4019,9 +4040,9 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
               case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD:
               case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD:
                 break;
-          
+
               // GD: requires two GOT entry for module index and offset
-              // IE: requires one GOT entry for tp-relative offset 
+              // IE: requires one GOT entry for tp-relative offset
               // LE: shouldn't happen for global symbol
               case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD:
               case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD:
@@ -4055,7 +4076,7 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
                     unsupported_reloc_global(object, r_type, gsym);
                 }
                 break;
-          
+
               // IE
               case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE:
               case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE:
@@ -4078,7 +4099,7 @@ Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab,
                     unsupported_reloc_global(object, r_type, gsym);
                 }
                 break;
-          
+
               // LE
               case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE:
               case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE:
@@ -4143,26 +4164,26 @@ Target_tilegx<size, big_endian>::gc_process_relocs(Symbol_table* symtab,
 {
   typedef Target_tilegx<size, big_endian> Tilegx;
   typedef typename Target_tilegx<size, big_endian>::Scan Scan;
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
 
   if (sh_type == elfcpp::SHT_REL)
     {
       return;
     }
 
-   gold::gc_process_relocs<size, big_endian,
-                           Tilegx, elfcpp::SHT_RELA, Scan,
-      typename Target_tilegx<size, big_endian>::Relocatable_size_for_reloc>(
-          symtab,
-          layout,
-          this,
-          object,
-          data_shndx,
-          prelocs,
-          reloc_count,
-          output_section,
-          needs_special_offset_handling,
-          local_symbol_count,
-          plocal_symbols);
+   gold::gc_process_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>(
+     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.
 
@@ -4182,6 +4203,8 @@ Target_tilegx<size, big_endian>::scan_relocs(Symbol_table* symtab,
 {
   typedef Target_tilegx<size, big_endian> Tilegx;
   typedef typename Target_tilegx<size, big_endian>::Scan Scan;
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
 
   if (sh_type == elfcpp::SHT_REL)
     {
@@ -4190,7 +4213,7 @@ Target_tilegx<size, big_endian>::scan_relocs(Symbol_table* symtab,
       return;
     }
 
-  gold::scan_relocs<size, big_endian, Tilegx, elfcpp::SHT_RELA, Scan>(
+  gold::scan_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>(
     symtab,
     layout,
     this,
@@ -4256,6 +4279,13 @@ Target_tilegx<size, big_endian>::do_finalize_sections(
     {
       uint64_t data_size = this->got_->current_data_size();
       symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
+
+      // If the .got section is more than 0x8000 bytes, we add
+      // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
+      // bit relocations have a greater chance of working.
+      if (data_size >= 0x8000)
+        symtab->get_sized_symbol<size>(sym)->set_value(
+          symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
     }
 
   if (parameters->doing_static_link()
@@ -4306,20 +4336,25 @@ template<int size, bool big_endian>
 inline bool
 Target_tilegx<size, big_endian>::Relocate::relocate(
     const Relocate_info<size, big_endian>* relinfo,
+    unsigned int,
     Target_tilegx<size, big_endian>* target,
     Output_section*,
     size_t relnum,
-    const elfcpp::Rela<size, big_endian>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type)
 {
+  if (view == NULL)
+    return true;
+
   typedef Tilegx_relocate_functions<size, big_endian> TilegxReloc;
   typename TilegxReloc::Tilegx_howto r_howto;
 
+  const elfcpp::Rela<size, big_endian> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   const Sized_relobj_file<size, big_endian>* object = relinfo->object;
 
   // Pick the value to use for symbols defined in the PLT.
@@ -4327,8 +4362,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
   if (gsym != NULL
       && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
     {
-      symval.set_output_value(target->plt_address_for_global(gsym)
-                              + gsym->plt_offset());
+      symval.set_output_value(target->plt_address_for_global(gsym));
       psymval = &symval;
     }
   else if (gsym == NULL && psymval->is_ifunc_symbol())
@@ -4336,8 +4370,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
       unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
       if (object->local_has_plt_offset(r_sym))
         {
-          symval.set_output_value(target->plt_address_for_local(object, r_sym)
-                                  + object->local_plt_offset(r_sym));
+          symval.set_output_value(target->plt_address_for_local(object, r_sym));
           psymval = &symval;
         }
     }
@@ -4347,7 +4380,10 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
   // Get the GOT offset if needed.
   // For tilegx, the GOT pointer points to the start of the GOT section.
   bool have_got_offset = false;
-  unsigned int got_offset = 0;
+  int got_offset = 0;
+  int got_base = target->got_ != NULL
+                 ? target->got_->current_data_size() >= 0x8000 ? 0x8000 : 0
+                 : 0;
   unsigned int got_type = GOT_TYPE_STANDARD;
   bool always_apply_relocation = false;
   switch (r_type)
@@ -4361,13 +4397,14 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
       if (gsym != NULL)
         {
           gold_assert(gsym->has_got_offset(got_type));
-          got_offset = gsym->got_offset(got_type);
+          got_offset = gsym->got_offset(got_type) - got_base;
         }
       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));
-          got_offset = object->local_got_offset(r_sym, got_type);
+          got_offset =
+            object->local_got_offset(r_sym, got_type) - got_base;
         }
       have_got_offset = true;
       break;
@@ -4395,6 +4432,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
       psymval = &symval;
       always_apply_relocation = true;
       addend = 0;
+      // Fall through.
 
     // when under PIC mode, these relocations are deferred to rtld
     case elfcpp::R_TILEGX_IMM16_X0_HW0:
@@ -4546,8 +4584,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
                 if (opt_t == tls::TLSOPT_NONE) {
                   Symbol *tls_sym = relinfo->symtab->lookup("__tls_get_addr");
                   symval.set_output_value(
-                    target->plt_address_for_global(tls_sym)
-                     + tls_sym->plt_offset());
+                    target->plt_address_for_global(tls_sym));
                   psymval = &symval;
                   TilegxReloc::imm_x_pcrel_general(view, object, psymval,
                                                    addend, address, r_howto);
@@ -4586,16 +4623,18 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
                 got_type = GOT_TYPE_TLS_OFFSET;
                 have_got_offset = true;
               }
+             // Fall through.
             do_update_value:
               if (have_got_offset) {
                 if (gsym != NULL) {
                   gold_assert(gsym->has_got_offset(got_type));
-                  got_offset = gsym->got_offset(got_type);
+                  got_offset = gsym->got_offset(got_type) - got_base;
                 } 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));
-                  got_offset = object->local_got_offset(r_sym, got_type);
+                  got_offset =
+                    object->local_got_offset(r_sym, got_type) - got_base;
                 }
               }
 
@@ -4614,16 +4653,14 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
               } // else if (opt_t == tls::TLSOPT_TO_LE)
                 //   both GD/IE are turned into LE, which
                 //   is absolute relocation.
-                // 
-                //  |  go through
-                //  |  
-                //  V
+                // Fall through.
+
             // LE
-            // 
+            //
             // tp
             // |
             // V
-            //  t_var1 | t_var2 | t_var3 | ... 
+            //  t_var1 | t_var2 | t_var3 | ...
             //  --------------------------------------------------
             //
             //  so offset to tp should be negative, we get offset
@@ -4644,7 +4681,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
                               || issue_undefined_symbol_error(gsym));
                   return false;
                 }
-                
+
                 typename elfcpp::Elf_types<size>::Elf_Addr value
                   = psymval->value(relinfo->object, 0);
                 symval.set_output_value(value);
@@ -4718,11 +4755,13 @@ Target_tilegx<size, big_endian>::relocate_section(
 {
   typedef Target_tilegx<size, big_endian> Tilegx;
   typedef typename Target_tilegx<size, big_endian>::Relocate Tilegx_relocate;
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
 
   gold_assert(sh_type == elfcpp::SHT_RELA);
 
-  gold::relocate_section<size, big_endian, Tilegx,
-                         elfcpp::SHT_RELA, Tilegx_relocate>(
+  gold::relocate_section<size, big_endian, Tilegx, Tilegx_relocate,
+                        gold::Default_comdat_behavior, Classify_reloc>(
     relinfo,
     this,
     prelocs,
@@ -4763,24 +4802,50 @@ Target_tilegx<size, big_endian>::apply_relocation(
     view_size);
 }
 
-// Return the size of a relocation while scanning during a relocatable
-// link.
+// Scan the relocs during a relocatable link.
 
 template<int size, bool big_endian>
-unsigned int
-Target_tilegx<size,big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
-  unsigned int, Relobj*)
+void
+Target_tilegx<size, big_endian>::scan_relocatable_relocs(
+    Symbol_table* symtab,
+    Layout* layout,
+    Sized_relobj_file<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,
+    Relocatable_relocs* rr)
 {
-  // We are always SHT_RELA, so we should never get here.
-  gold_unreachable();
-  return 0;
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
+  typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
+      Scan_relocatable_relocs;
+
+  gold_assert(sh_type == elfcpp::SHT_RELA);
+
+  gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
+    symtab,
+    layout,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols,
+    rr);
 }
 
-// Scan the relocs during a relocatable link.
+// Scan the relocs for --emit-relocs.
 
 template<int size, bool big_endian>
 void
-Target_tilegx<size, big_endian>::scan_relocatable_relocs(
+Target_tilegx<size, big_endian>::emit_relocs_scan(
     Symbol_table* symtab,
     Layout* layout,
     Sized_relobj_file<size, big_endian>* object,
@@ -4791,16 +4856,17 @@ Target_tilegx<size, big_endian>::scan_relocatable_relocs(
     Output_section* output_section,
     bool needs_special_offset_handling,
     size_t local_symbol_count,
-    const unsigned char* plocal_symbols,
+    const unsigned char* plocal_syms,
     Relocatable_relocs* rr)
 {
-  gold_assert(sh_type == elfcpp::SHT_RELA);
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
+  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
+      Emit_relocs_strategy;
 
-  typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_RELA,
-    Relocatable_size_for_reloc> Scan_relocatable_relocs;
+  gold_assert(sh_type == elfcpp::SHT_RELA);
 
-  gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_RELA,
-      Scan_relocatable_relocs>(
+  gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
     symtab,
     layout,
     object,
@@ -4810,7 +4876,7 @@ Target_tilegx<size, big_endian>::scan_relocatable_relocs(
     output_section,
     needs_special_offset_handling,
     local_symbol_count,
-    plocal_symbols,
+    plocal_syms,
     rr);
 }
 
@@ -4824,23 +4890,24 @@ Target_tilegx<size, big_endian>::relocate_relocs(
     const unsigned char* prelocs,
     size_t reloc_count,
     Output_section* output_section,
-    off_t offset_in_output_section,
-    const Relocatable_relocs* rr,
+    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
     unsigned char* reloc_view,
     section_size_type reloc_view_size)
 {
+  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
+      Classify_reloc;
+
   gold_assert(sh_type == elfcpp::SHT_RELA);
 
-  gold::relocate_relocs<size, big_endian, elfcpp::SHT_RELA>(
+  gold::relocate_relocs<size, big_endian, Classify_reloc>(
     relinfo,
     prelocs,
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
@@ -4858,7 +4925,7 @@ uint64_t
 Target_tilegx<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
 {
   gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
-  return this->plt_address_for_global(gsym) + gsym->plt_offset();
+  return this->plt_address_for_global(gsym);
 }
 
 // Return the value to use for the base of a DW_EH_PE_datarel offset
@@ -4877,7 +4944,7 @@ Target_tilegx<size, big_endian>::do_ehframe_datarel_base() const
   return ssym->value();
 }
 
-// The selector for tilegx object files. 
+// The selector for tilegx object files.
 
 template<int size, bool big_endian>
 class Target_selector_tilegx : public Target_selector
This page took 0.034375 seconds and 4 git commands to generate.