]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2010-05-26 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Wed, 26 May 2010 03:33:59 +0000 (03:33 +0000)
committerDoug Kwan <dougkwan@google.com>
Wed, 26 May 2010 03:33:59 +0000 (03:33 +0000)
* arm.cc (Arm_scan_relocatable_relocs): New class.
(Target_arm::relocate_special_relocatable): New method.
(Arm_relocate_functions::arm_branch_common): Handle relocatable link.
(Arm_relocate_functions::thumb_branch_common): Same.
(Target_arm::scan_relocatable_relocs): Use Arm_scan_relocatable_relocs
instead of Default_scan_relocatable_relocs.
* target-reloc.h (relocate_for_relocatable): Let target handle
relocation strategy Relocatable_relocs::RELOC_SPECIAL.
* target.h (Sized_target::relocate_special_relocatable): New method.

gold/ChangeLog
gold/arm.cc
gold/target-reloc.h
gold/target.h

index a76baf8b74b7a749beda15ad98dda8a4f349cab3..e2b009d1ea92e947bd7cc490e2d1d0eb508d2745 100644 (file)
@@ -1,3 +1,15 @@
+2010-05-26  Doug Kwan  <dougkwan@google.com>
+
+       * arm.cc (Arm_scan_relocatable_relocs): New class.
+       (Target_arm::relocate_special_relocatable): New method.
+       (Arm_relocate_functions::arm_branch_common): Handle relocatable link.
+       (Arm_relocate_functions::thumb_branch_common): Same.
+       (Target_arm::scan_relocatable_relocs): Use Arm_scan_relocatable_relocs
+       instead of Default_scan_relocatable_relocs.
+       * target-reloc.h (relocate_for_relocatable): Let target handle
+       relocation strategy Relocatable_relocs::RELOC_SPECIAL.
+       * target.h (Sized_target::relocate_special_relocatable): New method.
+
 2010-05-25  Viktor Kutuzov  <vkutuzov@accesssoftek.com>
 
        * timer.cc: Only #include <sys/times.h> if HAVE_TIMES is defined.
index 8bcd5d2225cd68050928ed6158dc5c891d9a8bb9..88102dcf9c60f31f14ef50843ac96c22b1d7e73a 100644 (file)
@@ -1956,6 +1956,79 @@ class Arm_output_data_got : public Output_data_got<32, big_endian>
   std::vector<Static_reloc> static_relocs_;
 };
 
+// The ARM target has many relocation types with odd-sizes or incontigious
+// bits.  The default handling of relocatable relocation cannot process these
+// relocations.  So we have to extend the default code.
+
+template<bool big_endian, int sh_type, typename Classify_reloc>
+class Arm_scan_relocatable_relocs :
+  public Default_scan_relocatable_relocs<sh_type, Classify_reloc>
+{
+ public:
+  // Return the strategy to use for a local symbol which is a section
+  // symbol, given the relocation type.
+  inline Relocatable_relocs::Reloc_strategy
+  local_section_strategy(unsigned int r_type, Relobj*)
+  {
+    if (sh_type == elfcpp::SHT_RELA)
+      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
+    else
+      {
+       if (r_type == elfcpp::R_ARM_TARGET1
+           || r_type == elfcpp::R_ARM_TARGET2)
+         {
+           const Target_arm<big_endian>* arm_target =
+             Target_arm<big_endian>::default_target();
+           r_type = arm_target->get_real_reloc_type(r_type);
+         }
+
+       switch(r_type)
+         {
+         // Relocations that write nothing.  These exclude R_ARM_TARGET1
+         // and R_ARM_TARGET2.
+         case elfcpp::R_ARM_NONE:
+         case elfcpp::R_ARM_V4BX:
+         case elfcpp::R_ARM_TLS_GOTDESC:
+         case elfcpp::R_ARM_TLS_CALL:
+         case elfcpp::R_ARM_TLS_DESCSEQ:
+         case elfcpp::R_ARM_THM_TLS_CALL:
+         case elfcpp::R_ARM_GOTRELAX:
+         case elfcpp::R_ARM_GNU_VTENTRY:
+         case elfcpp::R_ARM_GNU_VTINHERIT:
+         case elfcpp::R_ARM_THM_TLS_DESCSEQ16:
+         case elfcpp::R_ARM_THM_TLS_DESCSEQ32:
+           return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
+         // These should have been converted to something else above.
+         case elfcpp::R_ARM_TARGET1:
+         case elfcpp::R_ARM_TARGET2:
+           gold_unreachable();
+         // Relocations that write full 32 bits.
+         case elfcpp::R_ARM_ABS32:
+         case elfcpp::R_ARM_REL32:
+         case elfcpp::R_ARM_SBREL32:
+         case elfcpp::R_ARM_GOTOFF32:
+         case elfcpp::R_ARM_BASE_PREL:
+         case elfcpp::R_ARM_GOT_BREL:
+         case elfcpp::R_ARM_BASE_ABS:
+         case elfcpp::R_ARM_ABS32_NOI:
+         case elfcpp::R_ARM_REL32_NOI:
+         case elfcpp::R_ARM_PLT32_ABS:
+         case elfcpp::R_ARM_GOT_ABS:
+         case elfcpp::R_ARM_GOT_PREL:
+         case elfcpp::R_ARM_TLS_GD32:
+         case elfcpp::R_ARM_TLS_LDM32:
+         case elfcpp::R_ARM_TLS_LDO32:
+         case elfcpp::R_ARM_TLS_IE32:
+         case elfcpp::R_ARM_TLS_LE32:
+           return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4;
+         default:
+           // For all other static relocations, return RELOC_SPECIAL.
+           return Relocatable_relocs::RELOC_SPECIAL;
+         }
+      }
+  }
+};
+
 // Utilities for manipulating integers of up to 32-bits
 
 namespace utils
@@ -2189,6 +2262,21 @@ class Target_arm : public Sized_target<32, big_endian>
                           unsigned char* reloc_view,
                           section_size_type reloc_view_size);
 
+  // Perform target-specific processing in a relocatable link.  This is
+  // only used if we use the relocation strategy RELOC_SPECIAL.
+  void
+  relocate_special_relocatable(const Relocate_info<32, big_endian>* relinfo,
+                              unsigned int sh_type,
+                              const unsigned char* preloc_in,
+                              size_t relnum,
+                              Output_section* output_section,
+                              off_t offset_in_output_section,
+                              unsigned char* view,
+                              typename elfcpp::Elf_types<32>::Elf_Addr
+                                view_address,
+                              section_size_type view_size,
+                              unsigned char* preloc_out);
   // Return whether SYM is defined by the ABI.
   bool
   do_is_defined_by_abi(Symbol* sym) const
@@ -3725,6 +3813,7 @@ Arm_relocate_functions<big_endian>::arm_branch_common(
     Target_arm<big_endian>::default_target();
   if (is_weakly_undefined_without_plt)
     {
+      gold_assert(!parameters->options().relocatable());
       Valtype cond = val & 0xf0000000U;
       if (arm_target->may_use_arm_nop())
        val = cond | 0x0320f000;
@@ -3742,8 +3831,11 @@ Arm_relocate_functions<big_endian>::arm_branch_common(
   // to switch mode.
   bool may_use_blx = arm_target->may_use_blx();
   Reloc_stub* stub = NULL;
-  if (utils::has_overflow<26>(branch_offset)
-      || ((thumb_bit != 0) && !(may_use_blx && r_type == elfcpp::R_ARM_CALL)))
+
+  if (!parameters->options().relocatable()
+      && (utils::has_overflow<26>(branch_offset)
+         || ((thumb_bit != 0)
+             && !(may_use_blx && r_type == elfcpp::R_ARM_CALL))))
     {
       Valtype unadjusted_branch_target = psymval->value(object, 0);
 
@@ -3850,6 +3942,7 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
     Target_arm<big_endian>::default_target();
   if (is_weakly_undefined_without_plt)
     {
+      gold_assert(!parameters->options().relocatable());
       if (arm_target->may_use_thumb2_nop())
        {
          elfcpp::Swap<16, big_endian>::writeval(wv, 0xf3af);
@@ -3876,11 +3969,12 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
   // We need a stub if the branch offset is too large or if we need
   // to switch mode.
   bool thumb2 = arm_target->using_thumb2();
-  if ((!thumb2 && utils::has_overflow<23>(branch_offset))
-      || (thumb2 && utils::has_overflow<25>(branch_offset))
-      || ((thumb_bit == 0)
-          && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx)
-             || r_type == elfcpp::R_ARM_THM_JUMP24)))
+  if (!parameters->options().relocatable()
+      && ((!thumb2 && utils::has_overflow<23>(branch_offset))
+         || (thumb2 && utils::has_overflow<25>(branch_offset))
+         || ((thumb_bit == 0)
+             && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx)
+                 || r_type == elfcpp::R_ARM_THM_JUMP24))))
     {
       Arm_address unadjusted_branch_target = psymval->value(object, 0);
 
@@ -8919,7 +9013,7 @@ Target_arm<big_endian>::scan_relocatable_relocs(
 {
   gold_assert(sh_type == elfcpp::SHT_REL);
 
-  typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
+  typedef Arm_scan_relocatable_relocs<big_endian, elfcpp::SHT_REL,
     Relocatable_size_for_reloc> Scan_relocatable_relocs;
 
   gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
@@ -8971,6 +9065,291 @@ Target_arm<big_endian>::relocate_for_relocatable(
     reloc_view_size);
 }
 
+// Perform target-specific processing in a relocatable link.  This is
+// only used if we use the relocation strategy RELOC_SPECIAL.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::relocate_special_relocatable(
+    const Relocate_info<32, big_endian>* relinfo,
+    unsigned int sh_type,
+    const unsigned char* preloc_in,
+    size_t relnum,
+    Output_section* output_section,
+    off_t offset_in_output_section,
+    unsigned char* view,
+    elfcpp::Elf_types<32>::Elf_Addr view_address,
+    section_size_type,
+    unsigned char* preloc_out)
+{
+  // We can only handle REL type relocation sections.
+  gold_assert(sh_type == elfcpp::SHT_REL);
+
+  typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc Reltype;
+  typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc_write
+    Reltype_write;
+  const Arm_address invalid_address = static_cast<Arm_address>(0) - 1;
+
+  const Arm_relobj<big_endian>* object =
+    Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
+  const unsigned int local_count = object->local_symbol_count();
+
+  Reltype reloc(preloc_in);
+  Reltype_write reloc_write(preloc_out);
+
+  elfcpp::Elf_types<32>::Elf_WXword r_info = reloc.get_r_info();
+  const unsigned int r_sym = elfcpp::elf_r_sym<32>(r_info);
+  const unsigned int r_type = elfcpp::elf_r_type<32>(r_info);
+
+  const Arm_reloc_property* arp =
+    arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
+  gold_assert(arp != NULL);
+
+  // Get the new symbol index.
+  // We only use RELOC_SPECIAL strategy in local relocations.
+  gold_assert(r_sym < local_count);
+
+  // We are adjusting a section symbol.  We need to find
+  // the symbol table index of the section symbol for
+  // the output section corresponding to input section
+  // in which this symbol is defined.
+  bool is_ordinary;
+  unsigned int shndx = object->local_symbol_input_shndx(r_sym, &is_ordinary);
+  gold_assert(is_ordinary);
+  Output_section* os = object->output_section(shndx);
+  gold_assert(os != NULL);
+  gold_assert(os->needs_symtab_index());
+  unsigned int new_symndx = os->symtab_index();
+
+  // Get the new offset--the location in the output section where
+  // this relocation should be applied.
+
+  Arm_address offset = reloc.get_r_offset();
+  Arm_address new_offset;
+  if (offset_in_output_section != invalid_address)
+    new_offset = offset + offset_in_output_section;
+  else
+    {
+      section_offset_type sot_offset =
+          convert_types<section_offset_type, Arm_address>(offset);
+      section_offset_type new_sot_offset =
+          output_section->output_offset(object, relinfo->data_shndx,
+                                        sot_offset);
+      gold_assert(new_sot_offset != -1);
+      new_offset = new_sot_offset;
+    }
+
+  // In an object file, r_offset is an offset within the section.
+  // In an executable or dynamic object, generated by
+  // --emit-relocs, r_offset is an absolute address.
+  if (!parameters->options().relocatable())
+    {
+      new_offset += view_address;
+      if (offset_in_output_section != invalid_address)
+        new_offset -= offset_in_output_section;
+    }
+
+  reloc_write.put_r_offset(new_offset);
+  reloc_write.put_r_info(elfcpp::elf_r_info<32>(new_symndx, r_type));
+
+  // Handle the reloc addend.
+  // The relocation uses a section symbol in the input file.
+  // We are adjusting it to use a section symbol in the output
+  // file.  The input section symbol refers to some address in
+  // the input section.  We need the relocation in the output
+  // file to refer to that same address.  This adjustment to
+  // the addend is the same calculation we use for a simple
+  // absolute relocation for the input section symbol.
+
+  const Symbol_value<32>* psymval = object->local_symbol(r_sym);
+
+  // Handle THUMB bit.
+  Symbol_value<32> symval;
+  Arm_address thumb_bit =
+     object->local_symbol_is_thumb_function(r_sym) ? 1 : 0;
+  if (thumb_bit != 0
+      && arp->uses_thumb_bit() 
+      && ((psymval->value(object, 0) & 1) != 0))
+    {
+      Arm_address stripped_value =
+       psymval->value(object, 0) & ~static_cast<Arm_address>(1);
+      symval.set_output_value(stripped_value);
+      psymval = &symval;
+    } 
+
+  unsigned char* paddend = view + offset;
+  typename Arm_relocate_functions<big_endian>::Status reloc_status =
+       Arm_relocate_functions<big_endian>::STATUS_OKAY;
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_ABS8:
+      reloc_status = Arm_relocate_functions<big_endian>::abs8(paddend, object,
+                                                             psymval);
+      break;
+
+    case elfcpp::R_ARM_ABS12:
+      reloc_status = Arm_relocate_functions<big_endian>::abs12(paddend, object,
+                                                              psymval);
+      break;
+
+    case elfcpp::R_ARM_ABS16:
+      reloc_status = Arm_relocate_functions<big_endian>::abs16(paddend, object,
+                                                              psymval);
+      break;
+
+    case elfcpp::R_ARM_THM_ABS5:
+      reloc_status = Arm_relocate_functions<big_endian>::thm_abs5(paddend,
+                                                                 object,
+                                                                 psymval);
+      break;
+
+    case elfcpp::R_ARM_MOVW_ABS_NC:
+    case elfcpp::R_ARM_MOVW_PREL_NC:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVW_BREL:
+      reloc_status = Arm_relocate_functions<big_endian>::movw(
+         paddend, object, psymval, 0, thumb_bit, arp->checks_overflow());
+      break;
+
+    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
+    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
+      reloc_status = Arm_relocate_functions<big_endian>::thm_movw(
+         paddend, object, psymval, 0, thumb_bit, arp->checks_overflow());
+      break;
+
+    case elfcpp::R_ARM_THM_CALL:
+    case elfcpp::R_ARM_THM_XPC22:
+    case elfcpp::R_ARM_THM_JUMP24:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thumb_branch_common(
+           r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit,
+           false);
+      break;
+
+    case elfcpp::R_ARM_PLT32:
+    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_JUMP24:
+    case elfcpp::R_ARM_XPC25:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::arm_branch_common(
+           r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit,
+           false);
+      break;
+
+    case elfcpp::R_ARM_THM_JUMP19:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_jump19(paddend, object,
+                                                      psymval, 0, thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_THM_JUMP6:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_jump6(paddend, object, psymval,
+                                                     0);
+      break;
+
+    case elfcpp::R_ARM_THM_JUMP8:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_jump8(paddend, object, psymval,
+                                                     0);
+      break;
+
+    case elfcpp::R_ARM_THM_JUMP11:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_jump11(paddend, object, psymval,
+                                                      0);
+      break;
+
+    case elfcpp::R_ARM_PREL31:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::prel31(paddend, object, psymval, 0,
+                                                  thumb_bit);
+      break;
+
+    case elfcpp::R_ARM_THM_PC8:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_pc8(paddend, object, psymval,
+                                                   0);
+      break;
+
+    case elfcpp::R_ARM_THM_PC12:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_pc12(paddend, object, psymval,
+                                                    0);
+      break;
+
+    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
+      reloc_status =
+       Arm_relocate_functions<big_endian>::thm_alu11(paddend, object, psymval,
+                                                     0, thumb_bit);
+      break;
+
+    // These relocation truncate relocation results so we cannot handle them
+    // in a relocatable link.
+    case elfcpp::R_ARM_MOVT_ABS:
+    case elfcpp::R_ARM_THM_MOVT_ABS:
+    case elfcpp::R_ARM_MOVT_PREL:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVT_PREL:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_ALU_PC_G0_NC:
+    case elfcpp::R_ARM_ALU_PC_G0:
+    case elfcpp::R_ARM_ALU_PC_G1_NC:
+    case elfcpp::R_ARM_ALU_PC_G1:
+    case elfcpp::R_ARM_ALU_PC_G2:
+    case elfcpp::R_ARM_ALU_SB_G0_NC:
+    case elfcpp::R_ARM_ALU_SB_G0:
+    case elfcpp::R_ARM_ALU_SB_G1_NC:
+    case elfcpp::R_ARM_ALU_SB_G1:
+    case elfcpp::R_ARM_ALU_SB_G2:
+    case elfcpp::R_ARM_LDR_PC_G0:
+    case elfcpp::R_ARM_LDR_PC_G1:
+    case elfcpp::R_ARM_LDR_PC_G2:
+    case elfcpp::R_ARM_LDR_SB_G0:
+    case elfcpp::R_ARM_LDR_SB_G1:
+    case elfcpp::R_ARM_LDR_SB_G2:
+    case elfcpp::R_ARM_LDRS_PC_G0:
+    case elfcpp::R_ARM_LDRS_PC_G1:
+    case elfcpp::R_ARM_LDRS_PC_G2:
+    case elfcpp::R_ARM_LDRS_SB_G0:
+    case elfcpp::R_ARM_LDRS_SB_G1:
+    case elfcpp::R_ARM_LDRS_SB_G2:
+    case elfcpp::R_ARM_LDC_PC_G0:
+    case elfcpp::R_ARM_LDC_PC_G1:
+    case elfcpp::R_ARM_LDC_PC_G2:
+    case elfcpp::R_ARM_LDC_SB_G0:
+    case elfcpp::R_ARM_LDC_SB_G1:
+    case elfcpp::R_ARM_LDC_SB_G2:
+      gold_error(_("cannot handle %s in a relocatable link"),
+                arp->name().c_str());
+      break;
+
+    default:
+      gold_unreachable();
+    }
+
+  // Report any errors.
+  switch (reloc_status)
+    {
+    case Arm_relocate_functions<big_endian>::STATUS_OKAY:
+      break;
+    case Arm_relocate_functions<big_endian>::STATUS_OVERFLOW:
+      gold_error_at_location(relinfo, relnum, reloc.get_r_offset(),
+                            _("relocation overflow in %s"),
+                            arp->name().c_str());
+      break;
+    case Arm_relocate_functions<big_endian>::STATUS_BAD_RELOC:
+      gold_error_at_location(relinfo, relnum, reloc.get_r_offset(),
+       _("unexpected opcode while processing relocation %s"),
+       arp->name().c_str());
+      break;
+    default:
+      gold_unreachable();
+    }
+}
+
 // Return the value to use for a dynamic symbol which requires special
 // treatment.  This is how we support equality comparisons of function
 // pointers across shared library boundaries, as described in the
index 04854d2d60eeb4d7f0ad480e54f53d6ece4f28eb..34c13e8173d8192ac0255236f0e163a92df4c8c4 100644 (file)
@@ -515,7 +515,7 @@ relocate_for_relocatable(
     const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
-    section_size_type,
+    section_size_type view_size,
     unsigned char* reloc_view,
     section_size_type reloc_view_size)
 {
@@ -537,6 +537,19 @@ relocate_for_relocatable(
       if (strategy == Relocatable_relocs::RELOC_DISCARD)
        continue;
 
+      if (strategy == Relocatable_relocs::RELOC_SPECIAL)
+       {
+         // Target wants to handle this relocation.
+         Sized_target<size, big_endian>* target =
+           parameters->sized_target<size, big_endian>();
+         target->relocate_special_relocatable(relinfo, sh_type, prelocs,
+                                              i, output_section,
+                                              offset_in_output_section,
+                                              view, view_address,
+                                              view_size, pwrite);
+         pwrite += reloc_size;
+         continue;
+       }
       Reltype reloc(prelocs);
       Reltype_write reloc_write(pwrite);
 
index f2fdcc9cbbd54bdf80b416079086258f04b588c4..a0ec0b3f60d145d399a648ac0b4159c1091426b7 100644 (file)
@@ -687,7 +687,37 @@ class Sized_target : public Target
                           section_size_type view_size,
                           unsigned char* reloc_view,
                           section_size_type reloc_view_size) = 0;
+  // Perform target-specific processing in a relocatable link.  This is
+  // only used if we use the relocation strategy RELOC_SPECIAL.
+  // RELINFO points to a Relocation_info structure. SH_TYPE is the relocation
+  // section type. PRELOC_IN points to the original relocation.  RELNUM is
+  // the index number of the relocation in the relocation section.
+  // OUTPUT_SECTION is the output section to which the relocation is applied.
+  // OFFSET_IN_OUTPUT_SECTION is the offset of the relocation input section
+  // within the output section.  VIEW points to the output view of the
+  // output section.  VIEW_ADDRESS is output address of the view.  VIEW_SIZE
+  // is the size of the output view and PRELOC_OUT points to the new
+  // relocation in the output object.
+  //
+  // A target only needs to override this if the generic code in
+  // target-reloc.h cannot handle some relocation types.
 
+  virtual void
+  relocate_special_relocatable(const Relocate_info<size, big_endian>*
+                               /*relinfo */,
+                              unsigned int /* sh_type */,
+                              const unsigned char* /* preloc_in */,
+                              size_t /* relnum */,
+                              Output_section* /* output_section */,
+                              off_t /* offset_in_output_section */,
+                              unsigned char* /* view */,
+                              typename elfcpp::Elf_types<size>::Elf_Addr
+                                /* view_address */,
+                              section_size_type /* view_size */,
+                              unsigned char* /* preloc_out*/)
+  { gold_unreachable(); }
  protected:
   Sized_target(const Target::Target_info* pti)
     : Target(pti)