aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/i386.cc4
-rw-r--r--gold/layout.cc8
-rw-r--r--gold/object.cc7
-rw-r--r--gold/object.h38
-rw-r--r--gold/options.cc5
-rw-r--r--gold/options.h10
-rw-r--r--gold/parameters.cc3
-rw-r--r--gold/parameters.h7
-rw-r--r--gold/reloc.cc235
-rw-r--r--gold/reloc.h3
-rw-r--r--gold/target-reloc.h10
-rw-r--r--gold/x86_64.cc4
12 files changed, 293 insertions, 41 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index 0655f13..6b805bd 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -2297,7 +2297,7 @@ Target_i386::scan_relocatable_relocs(const General_options& options,
typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
Relocatable_size_for_reloc> Scan_relocatable_relocs;
- gold::scan_relocatable_relocs<32, false, Target_i386, elfcpp::SHT_REL,
+ gold::scan_relocatable_relocs<32, false, elfcpp::SHT_REL,
Scan_relocatable_relocs>(
options,
symtab,
@@ -2332,7 +2332,7 @@ Target_i386::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_REL);
- gold::relocate_for_relocatable<32, false, Target_i386, elfcpp::SHT_REL>(
+ gold::relocate_for_relocatable<32, false, elfcpp::SHT_REL>(
relinfo,
prelocs,
reloc_count,
diff --git a/gold/layout.cc b/gold/layout.cc
index 6685156..e8c6c66 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -155,8 +155,10 @@ Layout::include_section(Sized_relobj<size, big_endian>*, const char* name,
case elfcpp::SHT_RELA:
case elfcpp::SHT_REL:
case elfcpp::SHT_GROUP:
- // For a relocatable link these should be handled elsewhere.
- gold_assert(!parameters->output_is_object());
+ // If we are emitting relocations these should be handled
+ // elsewhere.
+ gold_assert(!parameters->output_is_object()
+ && !parameters->emit_relocs());
return false;
case elfcpp::SHT_PROGBITS:
@@ -370,7 +372,7 @@ Layout::layout_reloc(Sized_relobj<size, big_endian>* object,
Output_section* data_section,
Relocatable_relocs* rr)
{
- gold_assert(parameters->output_is_object());
+ gold_assert(parameters->output_is_object() || parameters->emit_relocs());
int sh_type = shdr.get_sh_type();
diff --git a/gold/object.cc b/gold/object.cc
index 3db6f85..c886717 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -593,8 +593,9 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
// Keep track of which sections to omit.
std::vector<bool> omit(shnum, false);
- // Keep track of reloc sections when doing a relocatable link.
+ // Keep track of reloc sections when emitting relocations.
const bool output_is_object = parameters->output_is_object();
+ const bool emit_relocs = output_is_object || parameters->emit_relocs();
std::vector<unsigned int> reloc_sections;
// Keep track of .eh_frame sections.
@@ -660,7 +661,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
// ones associated with sections which are not being discarded.
// However, we don't know that yet for all sections. So save
// reloc sections and process them later.
- if (output_is_object
+ if (emit_relocs
&& (shdr.get_sh_type() == elfcpp::SHT_REL
|| shdr.get_sh_type() == elfcpp::SHT_RELA))
{
@@ -704,7 +705,7 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
// When doing a relocatable link handle the reloc sections at the
// end.
- if (output_is_object)
+ if (emit_relocs)
this->size_relocatable_relocs();
for (std::vector<unsigned int>::const_iterator p = reloc_sections.begin();
p != reloc_sections.end();
diff --git a/gold/object.h b/gold/object.h
index 4011bdc..80047b0 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -111,6 +111,8 @@ struct Section_relocs
Output_section* output_section;
// Whether this section has special handling for offsets.
bool needs_special_offset_handling;
+ // Whether the data section is allocated (has the SHF_ALLOC flag set).
+ bool is_data_section_allocated;
};
// Relocations in an object file. This is read in read_relocs and
@@ -1312,6 +1314,42 @@ class Sized_relobj : public Relobj
relocate_sections(const General_options& options, const Symbol_table*,
const Layout*, const unsigned char* pshdrs, Views*);
+ // Scan the input relocations for --emit-relocs.
+ void
+ emit_relocs_scan(const General_options&, Symbol_table*, Layout*,
+ const unsigned char* plocal_syms,
+ const Read_relocs_data::Relocs_list::iterator&);
+
+ // Scan the input relocations for --emit-relocs, templatized on the
+ // type of the relocation section.
+ template<int sh_type>
+ void
+ emit_relocs_scan_reltype(const General_options&, Symbol_table*, Layout*,
+ const unsigned char* plocal_syms,
+ const Read_relocs_data::Relocs_list::iterator&,
+ Relocatable_relocs*);
+
+ // Emit the relocs for --emit-relocs.
+ void
+ emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
+ unsigned int sh_type, const unsigned char* prelocs,
+ size_t reloc_count, Output_section*, off_t output_offset,
+ unsigned char* view, Address address,
+ section_size_type view_size,
+ unsigned char* reloc_view, section_size_type reloc_view_size);
+
+ // Emit the relocs for --emit-relocs, templatized on the type of the
+ // relocation section.
+ template<int sh_type>
+ void
+ emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
+ const unsigned char* prelocs, size_t reloc_count,
+ Output_section*, off_t output_offset,
+ unsigned char* view, Address address,
+ section_size_type view_size,
+ unsigned char* reloc_view,
+ section_size_type reloc_view_size);
+
// Initialize input to output maps for section symbols in merged
// sections.
void
diff --git a/gold/options.cc b/gold/options.cc
index 2dbfad8..c65862e 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -530,8 +530,10 @@ options::Command_line_options::options[] =
GENERAL_ARG('\0', "oformat", N_("Set output format (only binary supported)"),
N_("--oformat FORMAT"), EXACTLY_TWO_DASHES,
&General_options::set_oformat),
+ GENERAL_NOARG('q', "emit-relocs", N_("Generate relocations in output"),
+ NULL, TWO_DASHES, &General_options::set_emit_relocs),
GENERAL_NOARG('r', "relocatable", N_("Generate relocatable output"), NULL,
- ONE_DASH, &General_options::set_relocatable),
+ TWO_DASHES, &General_options::set_relocatable),
// -R really means -rpath, but can mean --just-symbols for
// compatibility with GNU ld. -rpath is always -rpath, so we list
// it separately.
@@ -672,6 +674,7 @@ General_options::General_options()
output_file_name_("a.out"),
oformat_(OBJECT_FORMAT_ELF),
oformat_string_(NULL),
+ emit_relocs_(false),
is_relocatable_(false),
strip_(STRIP_NONE),
allow_shlib_undefined_(false),
diff --git a/gold/options.h b/gold/options.h
index 14e1629..c08b391 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -167,6 +167,11 @@ class General_options
Target*
default_target() const;
+ // -q: Whether to emit relocations.
+ bool
+ emit_relocs() const
+ { return this->emit_relocs_; }
+
// -r: Whether we are doing a relocatable link.
bool
relocatable() const
@@ -409,6 +414,10 @@ class General_options
set_oformat(const char*);
void
+ set_emit_relocs(bool value)
+ { this->emit_relocs_ = value; }
+
+ void
set_relocatable(bool value)
{ this->is_relocatable_ = value; }
@@ -615,6 +624,7 @@ class General_options
const char* output_file_name_;
Object_format oformat_;
const char* oformat_string_;
+ bool emit_relocs_;
bool is_relocatable_;
Strip strip_;
bool allow_shlib_undefined_;
diff --git a/gold/parameters.cc b/gold/parameters.cc
index a53908f..56de281 100644
--- a/gold/parameters.cc
+++ b/gold/parameters.cc
@@ -33,7 +33,7 @@ namespace gold
Parameters::Parameters(Errors* errors)
: errors_(errors), threads_(false), output_file_name_(NULL),
- output_file_type_(OUTPUT_INVALID), sysroot_(),
+ output_file_type_(OUTPUT_INVALID), emit_relocs_(false), sysroot_(),
strip_(STRIP_INVALID), allow_shlib_undefined_(false),
symbolic_(false), demangle_(false), detect_odr_violations_(false),
optimization_level_(0), export_dynamic_(false), debug_(0),
@@ -50,6 +50,7 @@ Parameters::set_from_options(const General_options* options)
{
this->threads_ = options->threads();
this->output_file_name_ = options->output_file_name();
+ this->emit_relocs_ = options->emit_relocs();
this->sysroot_ = options->sysroot();
this->allow_shlib_undefined_ = options->allow_shlib_undefined();
this->symbolic_ = options->Bsymbolic();
diff --git a/gold/parameters.h b/gold/parameters.h
index 136fd35..9d3ebb6 100644
--- a/gold/parameters.h
+++ b/gold/parameters.h
@@ -102,6 +102,11 @@ class Parameters
output_is_position_independent() const
{ return output_is_shared(); }
+ // Whether to emit relocations in the output.
+ bool
+ emit_relocs() const
+ { return this->emit_relocs_; }
+
// The target system root directory. This is NULL if there isn't
// one.
const std::string&
@@ -298,6 +303,8 @@ class Parameters
const char* output_file_name_;
// The type of the output file.
Output_file_type output_file_type_;
+ // Whether to emit relocations (-q/--emit-relocs).
+ bool emit_relocs_;
// The target system root directory.
std::string sysroot_;
// Which symbols to strip.
diff --git a/gold/reloc.cc b/gold/reloc.cc
index 1920032..63ebb84 100644
--- a/gold/reloc.cc
+++ b/gold/reloc.cc
@@ -29,6 +29,7 @@
#include "output.h"
#include "merge.h"
#include "object.h"
+#include "target-reloc.h"
#include "reloc.h"
namespace gold
@@ -223,13 +224,14 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
// PLT sections. Relocations for sections which are not
// allocated (typically debugging sections) should not add new
// GOT and PLT entries. So we skip them unless this is a
- // relocatable link.
- if (!parameters->output_is_object())
- {
- typename This::Shdr secshdr(pshdrs + shndx * This::shdr_size);
- if ((secshdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
- continue;
- }
+ // relocatable link or we need to emit relocations.
+ typename This::Shdr secshdr(pshdrs + shndx * This::shdr_size);
+ bool is_section_allocated = ((secshdr.get_sh_flags() & elfcpp::SHF_ALLOC)
+ != 0);
+ if (!is_section_allocated
+ && !parameters->output_is_object()
+ && !parameters->emit_relocs())
+ continue;
if (shdr.get_sh_link() != this->symtab_shndx_)
{
@@ -272,6 +274,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
sr.reloc_count = reloc_count;
sr.output_section = os;
sr.needs_special_offset_handling = map_sections[shndx].offset == -1;
+ sr.is_data_section_allocated = is_section_allocated;
}
// Read the local symbols.
@@ -315,12 +318,20 @@ Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options,
++p)
{
if (!parameters->output_is_object())
- target->scan_relocs(options, symtab, layout, this, p->data_shndx,
- p->sh_type, p->contents->data(), p->reloc_count,
- p->output_section,
- p->needs_special_offset_handling,
- this->local_symbol_count_,
- local_symbols);
+ {
+ // As noted above, when not generating an object file, we
+ // only scan allocated sections. We may see a non-allocated
+ // section here if we are emitting relocs.
+ if (p->is_data_section_allocated)
+ target->scan_relocs(options, symtab, layout, this, p->data_shndx,
+ p->sh_type, p->contents->data(),
+ p->reloc_count, p->output_section,
+ p->needs_special_offset_handling,
+ this->local_symbol_count_,
+ local_symbols);
+ if (parameters->emit_relocs())
+ this->emit_relocs_scan(options, symtab, layout, local_symbols, p);
+ }
else
{
Relocatable_relocs* rr = this->relocatable_relocs(p->reloc_shndx);
@@ -348,6 +359,98 @@ Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options,
}
}
+// This is a strategy class we use when scanning for --emit-relocs.
+
+template<int sh_type>
+class Emit_relocs_strategy
+{
+ public:
+ // A local non-section symbol.
+ inline Relocatable_relocs::Reloc_strategy
+ local_non_section_strategy(unsigned int, Relobj*)
+ { return Relocatable_relocs::RELOC_COPY; }
+
+ // A local section symbol.
+ inline Relocatable_relocs::Reloc_strategy
+ local_section_strategy(unsigned int, Relobj*)
+ {
+ if (sh_type == elfcpp::SHT_RELA)
+ return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
+ else
+ {
+ // The addend is stored in the section contents. Since this
+ // is not a relocatable link, we are going to apply the
+ // relocation contents to the section as usual. This means
+ // that we have no way to record the original addend. If the
+ // original addend is not zero, there is basically no way for
+ // the user to handle this correctly. Caveat emptor.
+ return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
+ }
+ }
+
+ // A global symbol.
+ inline Relocatable_relocs::Reloc_strategy
+ global_strategy(unsigned int, Relobj*, unsigned int)
+ { return Relocatable_relocs::RELOC_COPY; }
+};
+
+// Scan the input relocations for --emit-relocs.
+
+template<int size, bool big_endian>
+void
+Sized_relobj<size, big_endian>::emit_relocs_scan(
+ const General_options& options,
+ Symbol_table* symtab,
+ Layout* layout,
+ const unsigned char* plocal_syms,
+ const Read_relocs_data::Relocs_list::iterator& p)
+{
+ Relocatable_relocs* rr = this->relocatable_relocs(p->reloc_shndx);
+ gold_assert(rr != NULL);
+ rr->set_reloc_count(p->reloc_count);
+
+ if (p->sh_type == elfcpp::SHT_REL)
+ this->emit_relocs_scan_reltype<elfcpp::SHT_REL>(options, symtab, layout,
+ plocal_syms, p, rr);
+ else
+ {
+ gold_assert(p->sh_type == elfcpp::SHT_RELA);
+ this->emit_relocs_scan_reltype<elfcpp::SHT_RELA>(options, symtab,
+ layout, plocal_syms, p,
+ rr);
+ }
+}
+
+// Scan the input relocation for --emit-relocs, templatized on the
+// type of the relocation section.
+
+template<int size, bool big_endian>
+template<int sh_type>
+void
+Sized_relobj<size, big_endian>::emit_relocs_scan_reltype(
+ const General_options& options,
+ Symbol_table* symtab,
+ Layout* layout,
+ const unsigned char* plocal_syms,
+ const Read_relocs_data::Relocs_list::iterator& p,
+ Relocatable_relocs* rr)
+{
+ scan_relocatable_relocs<size, big_endian, sh_type,
+ Emit_relocs_strategy<sh_type> >(
+ options,
+ symtab,
+ layout,
+ this,
+ p->data_shndx,
+ p->contents->data(),
+ p->reloc_count,
+ p->output_section,
+ p->needs_special_offset_handling,
+ this->local_symbol_count_,
+ plocal_syms,
+ rr);
+}
+
// Relocate the input sections and write out the local symbols.
template<int size, bool big_endian>
@@ -452,14 +555,15 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
if (shdr.get_sh_type() == elfcpp::SHT_NOBITS)
continue;
- if (parameters->output_is_object()
+ if ((parameters->output_is_object() || parameters->emit_relocs())
&& (shdr.get_sh_type() == elfcpp::SHT_REL
|| shdr.get_sh_type() == elfcpp::SHT_RELA)
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
{
- // This is a reloc section in a relocatable link. We don't
- // need to read the input file. The size and file offset
- // are stored in the Relocatable_relocs structure.
+ // This is a reloc section in a relocatable link or when
+ // emitting relocs. We don't need to read the input file.
+ // The size and file offset are stored in the
+ // Relocatable_relocs structure.
Relocatable_relocs* rr = this->relocatable_relocs(i);
gold_assert(rr != NULL);
Output_data* posd = rr->output_data();
@@ -670,15 +774,25 @@ Sized_relobj<size, big_endian>::relocate_sections(
relinfo.reloc_shndx = i;
relinfo.data_shndx = index;
if (!parameters->output_is_object())
- target->relocate_section(&relinfo,
- sh_type,
- prelocs,
- reloc_count,
- os,
- output_offset == -1,
- (*pviews)[index].view,
- (*pviews)[index].address,
- (*pviews)[index].view_size);
+ {
+ target->relocate_section(&relinfo,
+ sh_type,
+ prelocs,
+ reloc_count,
+ os,
+ output_offset == -1,
+ (*pviews)[index].view,
+ (*pviews)[index].address,
+ (*pviews)[index].view_size);
+ if (parameters->emit_relocs())
+ this->emit_relocs(&relinfo, i, sh_type, prelocs, reloc_count,
+ os, output_offset,
+ (*pviews)[index].view,
+ (*pviews)[index].address,
+ (*pviews)[index].view_size,
+ (*pviews)[i].view,
+ (*pviews)[i].view_size);
+ }
else
{
Relocatable_relocs* rr = this->relocatable_relocs(i);
@@ -698,6 +812,75 @@ Sized_relobj<size, big_endian>::relocate_sections(
}
}
+// Emit the relocs for --emit-relocs.
+
+template<int size, bool big_endian>
+void
+Sized_relobj<size, big_endian>::emit_relocs(
+ const Relocate_info<size, big_endian>* relinfo,
+ unsigned int i,
+ unsigned int sh_type,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ Output_section* output_section,
+ off_t offset_in_output_section,
+ unsigned char* view,
+ typename elfcpp::Elf_types<size>::Elf_Addr address,
+ section_size_type view_size,
+ unsigned char* reloc_view,
+ section_size_type reloc_view_size)
+{
+ if (sh_type == elfcpp::SHT_REL)
+ this->emit_relocs_reltype<elfcpp::SHT_REL>(relinfo, i, prelocs,
+ reloc_count, output_section,
+ offset_in_output_section,
+ view, address, view_size,
+ reloc_view, reloc_view_size);
+ else
+ {
+ gold_assert(sh_type == elfcpp::SHT_RELA);
+ this->emit_relocs_reltype<elfcpp::SHT_RELA>(relinfo, i, prelocs,
+ reloc_count, output_section,
+ offset_in_output_section,
+ view, address, view_size,
+ reloc_view, reloc_view_size);
+ }
+}
+
+// Emit the relocs for --emit-relocs, templatized on the type of the
+// relocation section.
+
+template<int size, bool big_endian>
+template<int sh_type>
+void
+Sized_relobj<size, big_endian>::emit_relocs_reltype(
+ const Relocate_info<size, big_endian>* relinfo,
+ unsigned int i,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ Output_section* output_section,
+ off_t offset_in_output_section,
+ unsigned char* view,
+ typename elfcpp::Elf_types<size>::Elf_Addr address,
+ section_size_type view_size,
+ unsigned char* reloc_view,
+ section_size_type reloc_view_size)
+{
+ const Relocatable_relocs* rr = this->relocatable_relocs(i);
+ relocate_for_relocatable<size, big_endian, sh_type>(
+ relinfo,
+ prelocs,
+ reloc_count,
+ output_section,
+ offset_in_output_section,
+ rr,
+ view,
+ address,
+ view_size,
+ reloc_view,
+ reloc_view_size);
+}
+
// Create merge hash tables for the local symbols. These are used to
// speed up relocations.
diff --git a/gold/reloc.h b/gold/reloc.h
index 438e861..fb6c846 100644
--- a/gold/reloc.h
+++ b/gold/reloc.h
@@ -194,6 +194,9 @@ class Relocatable_relocs
// SHT_RELA reloc and the contents of the data section do not need
// to be changed.
RELOC_ADJUST_FOR_SECTION_RELA,
+ // Like RELOC_ADJUST_FOR_SECTION_RELA but the addend should not be
+ // adjusted.
+ RELOC_ADJUST_FOR_SECTION_0,
// Like RELOC_ADJUST_FOR_SECTION_RELA but the contents of the
// section need to be changed. The number indicates the number of
// bytes in the addend in the section contents.
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 3fd96c3..2bc0a1b 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -256,7 +256,7 @@ class Default_scan_relocatable_relocs
switch (classify.get_size_for_reloc(r_type, object))
{
case 0:
- return Relocatable_relocs::RELOC_COPY;
+ return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
case 1:
return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1;
case 2:
@@ -286,7 +286,7 @@ class Default_scan_relocatable_relocs
// local_section_strategy. Most targets should be able to use
// Default_scan_relocatable_relocs as this class.
-template<int size, bool big_endian, typename Target_type, int sh_type,
+template<int size, bool big_endian, int sh_type,
typename Scan_relocatable_reloc>
void
scan_relocatable_relocs(
@@ -365,7 +365,7 @@ scan_relocatable_relocs(
// Relocate relocs during a relocatable link. This is a default
// definition which should work for most targets.
-template<int size, bool big_endian, typename Target_type, int sh_type>
+template<int size, bool big_endian, int sh_type>
void
relocate_for_relocatable(
const Relocate_info<size, big_endian>* relinfo,
@@ -416,6 +416,7 @@ relocate_for_relocatable(
break;
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
+ case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2:
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4:
@@ -503,6 +504,9 @@ relocate_for_relocatable(
}
break;
+ case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
+ break;
+
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
Relocate_functions<size, big_endian>::rel8(padd, object,
psymval);
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 882398f..3ceb798 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -2087,7 +2087,7 @@ Target_x86_64::scan_relocatable_relocs(const General_options& options,
typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_RELA,
Relocatable_size_for_reloc> Scan_relocatable_relocs;
- gold::scan_relocatable_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA,
+ gold::scan_relocatable_relocs<64, false, elfcpp::SHT_RELA,
Scan_relocatable_relocs>(
options,
symtab,
@@ -2122,7 +2122,7 @@ Target_x86_64::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_RELA);
- gold::relocate_for_relocatable<64, false, Target_x86_64, elfcpp::SHT_RELA>(
+ gold::relocate_for_relocatable<64, false, elfcpp::SHT_RELA>(
relinfo,
prelocs,
reloc_count,