mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
1 Commits
gdb-15.1-r
...
users/ccou
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c13bcd220 |
@@ -358,6 +358,7 @@ enum SHT
|
||||
SHT_PREINIT_ARRAY = 16,
|
||||
SHT_GROUP = 17,
|
||||
SHT_SYMTAB_SHNDX = 18,
|
||||
SHT_RELR = 19, // Experimental
|
||||
SHT_LOOS = 0x60000000,
|
||||
SHT_HIOS = 0x6fffffff,
|
||||
SHT_LOPROC = 0x70000000,
|
||||
@@ -719,6 +720,11 @@ enum DT
|
||||
|
||||
DT_PREINIT_ARRAY = 32,
|
||||
DT_PREINIT_ARRAYSZ = 33,
|
||||
DT_SYMTAB_SHNDX = 34,
|
||||
DT_RELRSZ = 35, // Experimental
|
||||
DT_RELR = 36, // Experimental
|
||||
DT_RELRENT = 37, // Experimental
|
||||
|
||||
DT_LOOS = 0x6000000d,
|
||||
DT_HIOS = 0x6ffff000,
|
||||
DT_LOPROC = 0x70000000,
|
||||
@@ -1021,6 +1027,7 @@ struct Elf_sizes
|
||||
// Sizes of ELF reloc entries.
|
||||
static const int rel_size = sizeof(internal::Rel_data<size>);
|
||||
static const int rela_size = sizeof(internal::Rela_data<size>);
|
||||
static const int relr_size = sizeof(internal::Relr_data<size>);
|
||||
// Size of ELF dynamic entry.
|
||||
static const int dyn_size = sizeof(internal::Dyn_data<size>);
|
||||
// Size of ELF version structures.
|
||||
@@ -1666,6 +1673,48 @@ class Rela_write
|
||||
internal::Rela_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor class for an ELF Relr relocation.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Relr
|
||||
{
|
||||
public:
|
||||
Relr(const unsigned char* p)
|
||||
: p_(reinterpret_cast<const internal::Relr_data<size>*>(p))
|
||||
{ }
|
||||
|
||||
template<typename File>
|
||||
Relr(File* file, typename File::Location loc)
|
||||
: p_(reinterpret_cast<const internal::Relr_data<size>*>(
|
||||
file->view(loc.file_offset, loc.data_size).data()))
|
||||
{ }
|
||||
|
||||
typename Elf_types<size>::Elf_Addr
|
||||
get_r_offset() const
|
||||
{ return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
|
||||
|
||||
private:
|
||||
const internal::Relr_data<size>* p_;
|
||||
};
|
||||
|
||||
// Writer class for an ELF Relr relocation.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Relr_write
|
||||
{
|
||||
public:
|
||||
Relr_write(unsigned char* p)
|
||||
: p_(reinterpret_cast<internal::Relr_data<size>*>(p))
|
||||
{ }
|
||||
|
||||
void
|
||||
put_r_offset(typename Elf_types<size>::Elf_Addr v)
|
||||
{ this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
private:
|
||||
internal::Relr_data<size>* p_;
|
||||
};
|
||||
|
||||
// MIPS-64 has a non-standard relocation layout.
|
||||
|
||||
template<bool big_endian>
|
||||
|
||||
@@ -180,6 +180,12 @@ struct Rela_data
|
||||
typename Elf_types<size>::Elf_Swxword r_addend;
|
||||
};
|
||||
|
||||
template<int size>
|
||||
struct Relr_data
|
||||
{
|
||||
typename Elf_types<size>::Elf_Addr r_offset;
|
||||
};
|
||||
|
||||
// MIPS-64 has a non-standard layout for relocations.
|
||||
|
||||
struct Mips64_rel_data
|
||||
|
||||
@@ -4710,7 +4710,8 @@ void
|
||||
Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
const Output_data* plt_rel,
|
||||
const Output_data_reloc_generic* dyn_rel,
|
||||
bool add_debug, bool dynrel_includes_plt)
|
||||
bool add_debug, bool dynrel_includes_plt,
|
||||
const Output_data_reloc_generic* dyn_relr)
|
||||
{
|
||||
Output_data_dynamic* odyn = this->dynamic_data_;
|
||||
if (odyn == NULL)
|
||||
@@ -4783,6 +4784,14 @@ Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
}
|
||||
}
|
||||
|
||||
if (dyn_relr != NULL && dyn_relr->output_section() != NULL)
|
||||
{
|
||||
const int size = parameters->target().get_size();
|
||||
odyn->add_section_address(elfcpp::DT_RELR, dyn_relr->output_section());
|
||||
odyn->add_section_size(elfcpp::DT_RELRSZ, dyn_relr->output_section());
|
||||
odyn->add_constant(elfcpp::DT_RELRENT, size / 8);
|
||||
}
|
||||
|
||||
if (add_debug && !parameters->options().shared())
|
||||
{
|
||||
// The value of the DT_DEBUG tag is filled in by the dynamic
|
||||
|
||||
@@ -900,7 +900,8 @@ class Layout
|
||||
add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
|
||||
const Output_data* plt_rel,
|
||||
const Output_data_reloc_generic* dyn_rel,
|
||||
bool add_debug, bool dynrel_includes_plt);
|
||||
bool add_debug, bool dynrel_includes_plt,
|
||||
const Output_data_reloc_generic* dyn_relr = NULL);
|
||||
|
||||
// Add a target-specific dynamic tag with constant value.
|
||||
void
|
||||
|
||||
@@ -834,6 +834,10 @@ class General_options
|
||||
N_("Exclude libraries from automatic export"),
|
||||
N_(("lib,lib ...")));
|
||||
|
||||
DEFINE_bool(experimental_use_relr, options::TWO_DASHES, '\0', false,
|
||||
N_("(x86-64 only) Generate RELR dynamic relocations"),
|
||||
N_("Do not generate RELR dynamic relocations"));
|
||||
|
||||
DEFINE_bool(export_dynamic, options::TWO_DASHES, 'E', false,
|
||||
N_("Export all dynamic symbols"),
|
||||
N_("Do not export all dynamic symbols"));
|
||||
|
||||
@@ -1224,6 +1224,17 @@ Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>::write(
|
||||
orel.put_r_addend(addend);
|
||||
}
|
||||
|
||||
// Write out a Relr relocation.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
void
|
||||
Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>::write(
|
||||
unsigned char* pov) const
|
||||
{
|
||||
elfcpp::Relr_write<size, big_endian> orel(pov);
|
||||
orel.put_r_offset(this->rel_.get_address());
|
||||
}
|
||||
|
||||
// Output_data_reloc_base methods.
|
||||
|
||||
// Adjust the output section.
|
||||
@@ -1237,6 +1248,8 @@ Output_data_reloc_base<sh_type, dynamic, size, big_endian>
|
||||
os->set_entsize(elfcpp::Elf_sizes<size>::rel_size);
|
||||
else if (sh_type == elfcpp::SHT_RELA)
|
||||
os->set_entsize(elfcpp::Elf_sizes<size>::rela_size);
|
||||
else if (sh_type == elfcpp::SHT_RELR)
|
||||
os->set_entsize(elfcpp::Elf_sizes<size>::relr_size);
|
||||
else
|
||||
gold_unreachable();
|
||||
|
||||
@@ -5526,6 +5539,26 @@ template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, true, 64, true>;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELR, true, 32, false>;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELR, true, 32, true>;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELR, true, 64, false>;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELR, true, 64, true>;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
template
|
||||
class Output_relocatable_relocs<elfcpp::SHT_REL, 32, false>;
|
||||
|
||||
219
gold/output.h
219
gold/output.h
@@ -1500,6 +1500,104 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
Addend addend_;
|
||||
};
|
||||
|
||||
// The SHT_RELR version of Output_reloc<>. This is a relative reloc,
|
||||
// and holds nothing but an offset. Rather than duplicate all the fields
|
||||
// of the SHT_REL version except for the symbol and relocation type, we
|
||||
// simply use an SHT_REL as a proxy.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>
|
||||
{
|
||||
public:
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||
|
||||
// An uninitialized entry.
|
||||
Output_reloc()
|
||||
: rel_()
|
||||
{ }
|
||||
|
||||
// A reloc against a global symbol.
|
||||
|
||||
Output_reloc(Symbol* gsym, Output_data* od, Address address)
|
||||
: rel_(gsym, 0, od, address, true, true, false)
|
||||
{ }
|
||||
|
||||
Output_reloc(Symbol* gsym, Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
: rel_(gsym, 0, relobj, shndx, address, true, true, false)
|
||||
{ }
|
||||
|
||||
// A reloc against a local symbol.
|
||||
|
||||
Output_reloc(Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int local_sym_index, Output_data* od, Address address,
|
||||
bool is_section_symbol)
|
||||
: rel_(relobj, local_sym_index, 0, od, address, true,
|
||||
true, is_section_symbol, false)
|
||||
{ }
|
||||
|
||||
Output_reloc(Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int local_sym_index, unsigned int shndx,
|
||||
Address address, bool is_section_symbol)
|
||||
: rel_(relobj, local_sym_index, 0, shndx, address, true,
|
||||
true, is_section_symbol, false)
|
||||
{ }
|
||||
|
||||
// A reloc against the STT_SECTION symbol of an output section.
|
||||
|
||||
Output_reloc(Output_section* os, Output_data* od, Address address)
|
||||
: rel_(os, 0, od, address, true)
|
||||
{ }
|
||||
|
||||
Output_reloc(Output_section* os, Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
: rel_(os, 0, relobj, shndx, address, true)
|
||||
{ }
|
||||
|
||||
// A relative relocation with no symbol.
|
||||
|
||||
Output_reloc(Output_data* od, Address address)
|
||||
: rel_(0, od, address, true)
|
||||
{ }
|
||||
|
||||
Output_reloc(Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
: rel_(0, relobj, shndx, address, true)
|
||||
{ }
|
||||
|
||||
// Return whether this is a RELATIVE relocation.
|
||||
bool
|
||||
is_relative() const
|
||||
{ return true; }
|
||||
|
||||
// Return whether this is a relocation which should not use
|
||||
// a symbol, but which obtains its addend from a symbol.
|
||||
bool
|
||||
is_symbolless() const
|
||||
{ return true; }
|
||||
|
||||
// If this relocation is against an input section, return the
|
||||
// relocatable object containing the input section.
|
||||
Sized_relobj<size, big_endian>*
|
||||
get_relobj() const
|
||||
{ return this->rel_.get_relobj(); }
|
||||
|
||||
// Write the reloc entry to an output view.
|
||||
void
|
||||
write(unsigned char* pov) const;
|
||||
|
||||
// Return whether this reloc should be sorted before the argument
|
||||
// when sorting dynamic relocs.
|
||||
bool
|
||||
sort_before(const Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>&
|
||||
r2) const
|
||||
{ return this->rel_.compare(r2.rel_) < 0; }
|
||||
|
||||
private:
|
||||
// The basic reloc.
|
||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
|
||||
};
|
||||
|
||||
// Output_data_reloc_generic is a non-template base class for
|
||||
// Output_data_reloc_base. This gives the generic code a way to hold
|
||||
// a pointer to a reloc section.
|
||||
@@ -2344,6 +2442,127 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
}
|
||||
};
|
||||
|
||||
// The SHT_RELR version of Output_data_reloc.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_data_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>
|
||||
: public Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size, big_endian>
|
||||
{
|
||||
private:
|
||||
typedef Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size,
|
||||
big_endian> Base;
|
||||
|
||||
public:
|
||||
typedef typename Base::Output_reloc_type Output_reloc_type;
|
||||
typedef typename Output_reloc_type::Address Address;
|
||||
|
||||
Output_data_reloc()
|
||||
: Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size, big_endian>(false)
|
||||
{ }
|
||||
|
||||
void
|
||||
add_global_generic(Symbol*, unsigned int, Output_data*, uint64_t, uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
void
|
||||
add_global_generic(Symbol*, unsigned int, Output_data*, Relobj*,
|
||||
unsigned int, uint64_t, uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a global symbol. The final relocation
|
||||
// will not reference the symbol.
|
||||
|
||||
void
|
||||
add_global_relative(Symbol* gsym, Output_data* od, Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(gsym, od, address));
|
||||
}
|
||||
|
||||
void
|
||||
add_global_relative(Symbol* gsym, Output_data* od,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(gsym, relobj, shndx, address));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj*, unsigned int, unsigned int, Output_data*, uint64_t,
|
||||
uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj*, unsigned int, unsigned int, Output_data*,
|
||||
unsigned int, uint64_t, uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a local symbol.
|
||||
|
||||
void
|
||||
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int local_sym_index, Output_data* od,
|
||||
Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(relobj, local_sym_index, od, address,
|
||||
false));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int local_sym_index, Output_data* od,
|
||||
unsigned int shndx, Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(relobj, local_sym_index, shndx, address,
|
||||
false));
|
||||
}
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section*, unsigned int, Output_data*,
|
||||
uint64_t, uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section*, unsigned int, Output_data*,
|
||||
Relobj*, unsigned int, uint64_t, uint64_t)
|
||||
{
|
||||
gold_unreachable();
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against an output section symbol.
|
||||
|
||||
void
|
||||
add_output_section_relative(Output_section* os, Output_data* od,
|
||||
Address address)
|
||||
{ this->add(od, Output_reloc_type(os, od, address)); }
|
||||
|
||||
void
|
||||
add_output_section_relative(Output_section* os, Output_data* od,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
{ this->add(od, Output_reloc_type(os, relobj, shndx, address)); }
|
||||
|
||||
// Add a relative relocation
|
||||
|
||||
void
|
||||
add_relative(Output_data* od, Address address)
|
||||
{ this->add(od, Output_reloc_type(od, address)); }
|
||||
|
||||
void
|
||||
add_relative(Output_data* od, Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
{ this->add(od, Output_reloc_type(relobj, shndx, address)); }
|
||||
};
|
||||
|
||||
// Output_relocatable_relocs represents a relocation section in a
|
||||
// relocatable link. The actual data is written out in the target
|
||||
// hook relocate_relocs. This just saves space for it.
|
||||
|
||||
@@ -79,6 +79,27 @@ struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
|
||||
{ p->put_r_addend(val); }
|
||||
};
|
||||
|
||||
template<int size, bool big_endian>
|
||||
struct Reloc_types<elfcpp::SHT_RELR, size, big_endian>
|
||||
{
|
||||
typedef typename elfcpp::Relr<size, big_endian> Reloc;
|
||||
typedef typename elfcpp::Relr_write<size, big_endian> Reloc_write;
|
||||
static const int reloc_size = elfcpp::Elf_sizes<size>::relr_size;
|
||||
|
||||
static inline typename elfcpp::Elf_types<size>::Elf_Swxword
|
||||
get_reloc_addend(const Reloc*)
|
||||
{ gold_unreachable(); }
|
||||
|
||||
static inline typename elfcpp::Elf_types<size>::Elf_Swxword
|
||||
get_reloc_addend_noerror(const Reloc*)
|
||||
{ return 0; }
|
||||
|
||||
static inline void
|
||||
set_reloc_addend(Reloc_write*,
|
||||
typename elfcpp::Elf_types<size>::Elf_Swxword)
|
||||
{ gold_unreachable(); }
|
||||
};
|
||||
|
||||
}; // End namespace gold.
|
||||
|
||||
#endif // !defined(GOLD_RELOC_TYPE_SH)
|
||||
|
||||
135
gold/x86_64.cc
135
gold/x86_64.cc
@@ -584,13 +584,15 @@ class Target_x86_64 : public Sized_target<size, false>
|
||||
// uses only Elf64_Rela relocation entries with explicit addends."
|
||||
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, false> Reloc_section;
|
||||
|
||||
typedef Output_data_reloc<elfcpp::SHT_RELR, true, size, false> Relr_section;
|
||||
|
||||
Target_x86_64(const Target::Target_info* info = &x86_64_info)
|
||||
: Sized_target<size, false>(info),
|
||||
got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
|
||||
got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL),
|
||||
rela_irelative_(NULL), copy_relocs_(elfcpp::R_X86_64_COPY),
|
||||
got_mod_index_offset_(-1U), tlsdesc_reloc_info_(),
|
||||
tls_base_symbol_defined_(false)
|
||||
rela_irelative_(NULL), relr_dyn_(NULL),
|
||||
copy_relocs_(elfcpp::R_X86_64_COPY), got_mod_index_offset_(-1U),
|
||||
tlsdesc_reloc_info_(), tls_base_symbol_defined_(false)
|
||||
{ }
|
||||
|
||||
// Hook for a new output section.
|
||||
@@ -1172,6 +1174,10 @@ class Target_x86_64 : public Sized_target<size, false>
|
||||
Reloc_section*
|
||||
rela_irelative_section(Layout*);
|
||||
|
||||
// Get the RELR dynamic reloc section, creating it if necessary.
|
||||
Relr_section*
|
||||
relr_dyn_section(Layout*);
|
||||
|
||||
// Add a potential copy relocation.
|
||||
void
|
||||
copy_reloc(Symbol_table* symtab, Layout* layout,
|
||||
@@ -1235,6 +1241,8 @@ class Target_x86_64 : public Sized_target<size, false>
|
||||
Reloc_section* rela_dyn_;
|
||||
// The section to use for IRELATIVE relocs.
|
||||
Reloc_section* rela_irelative_;
|
||||
// The RELR dynamic reloc section.
|
||||
Relr_section* relr_dyn_;
|
||||
// Relocs saved to avoid a COPY reloc.
|
||||
Copy_relocs<elfcpp::SHT_RELA, size, false> copy_relocs_;
|
||||
// Offset of the GOT entry for the TLS module index.
|
||||
@@ -1431,6 +1439,23 @@ Target_x86_64<size>::rela_irelative_section(Layout* layout)
|
||||
return this->rela_irelative_;
|
||||
}
|
||||
|
||||
// Get the RELR dynamic reloc section, creating it if necessary.
|
||||
|
||||
template<int size>
|
||||
typename Target_x86_64<size>::Relr_section*
|
||||
Target_x86_64<size>::relr_dyn_section(Layout* layout)
|
||||
{
|
||||
if (this->relr_dyn_ == NULL)
|
||||
{
|
||||
gold_assert(layout != NULL);
|
||||
this->relr_dyn_ = new Relr_section();
|
||||
layout->add_output_section_data(".relr.dyn", elfcpp::SHT_RELR,
|
||||
elfcpp::SHF_ALLOC, this->relr_dyn_,
|
||||
ORDER_DYNAMIC_RELOCS, false);
|
||||
}
|
||||
return this->relr_dyn_;
|
||||
}
|
||||
|
||||
// Write the first three reserved words of the .got.plt section.
|
||||
// The remainder of the section is written while writing the PLT
|
||||
// in Output_data_plt_i386::do_write.
|
||||
@@ -2966,14 +2991,25 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
|
||||
if (parameters->options().output_is_position_independent())
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
(size == 32
|
||||
? elfcpp::R_X86_64_RELATIVE64
|
||||
: elfcpp::R_X86_64_RELATIVE),
|
||||
output_section, data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), is_ifunc);
|
||||
if (size == 64
|
||||
&& !is_ifunc
|
||||
&& parameters->options().experimental_use_relr())
|
||||
{
|
||||
Relr_section* relr_dyn = target->relr_dyn_section(layout);
|
||||
relr_dyn->add_local_relative(object, r_sym, output_section,
|
||||
data_shndx, reloc.get_r_offset());
|
||||
}
|
||||
else
|
||||
{
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
(size == 32
|
||||
? elfcpp::R_X86_64_RELATIVE64
|
||||
: elfcpp::R_X86_64_RELATIVE),
|
||||
output_section, data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), is_ifunc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2991,12 +3027,22 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
|
||||
if (size == 32 && r_type == elfcpp::R_X86_64_32)
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
output_section, data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), is_ifunc);
|
||||
if (!is_ifunc && parameters->options().experimental_use_relr())
|
||||
{
|
||||
Relr_section* relr_dyn = target->relr_dyn_section(layout);
|
||||
relr_dyn->add_local_relative(object, r_sym, output_section,
|
||||
data_shndx,
|
||||
reloc.get_r_offset());
|
||||
}
|
||||
else
|
||||
{
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
output_section, data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), is_ifunc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3099,15 +3145,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
|
||||
{
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
// R_X86_64_RELATIVE assumes a 64-bit relocation.
|
||||
if (r_type != elfcpp::R_X86_64_GOT32)
|
||||
{
|
||||
unsigned int got_offset =
|
||||
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
got, got_offset, 0, is_ifunc);
|
||||
}
|
||||
else
|
||||
if (r_type == elfcpp::R_X86_64_GOT32)
|
||||
{
|
||||
this->check_non_pic(object, r_type, NULL);
|
||||
|
||||
@@ -3116,6 +3154,24 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
|
||||
object, r_sym, r_type, got,
|
||||
object->local_got_offset(r_sym, GOT_TYPE_STANDARD), 0);
|
||||
}
|
||||
else if (size == 64
|
||||
&& !is_ifunc
|
||||
&& parameters->options().experimental_use_relr())
|
||||
{
|
||||
Relr_section* relr_dyn = target->relr_dyn_section(layout);
|
||||
unsigned int got_offset =
|
||||
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
|
||||
relr_dyn->add_local_relative(object, r_sym, got,
|
||||
got_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int got_offset =
|
||||
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
|
||||
rela_dyn->add_local_relative(object, r_sym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
got, got_offset, 0, is_ifunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
// For GOTPLT64, we'd normally want a PLT section, but since
|
||||
@@ -3478,12 +3534,24 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
|
||||
|| (size == 32 && r_type == elfcpp::R_X86_64_32))
|
||||
&& gsym->can_use_relative_reloc(false))
|
||||
{
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_RELATIVE,
|
||||
output_section, object,
|
||||
data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), false);
|
||||
if (parameters->options().experimental_use_relr())
|
||||
{
|
||||
Relr_section* relr_dyn = target->relr_dyn_section(layout);
|
||||
relr_dyn->add_global_relative(gsym,
|
||||
output_section, object,
|
||||
data_shndx,
|
||||
reloc.get_r_offset());
|
||||
}
|
||||
else
|
||||
{
|
||||
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
||||
rela_dyn->add_global_relative(gsym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
output_section, object,
|
||||
data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend(), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3886,7 +3954,8 @@ Target_x86_64<size>::do_finalize_sections(
|
||||
? NULL
|
||||
: this->plt_->rela_plt());
|
||||
layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
|
||||
this->rela_dyn_, true, false);
|
||||
this->rela_dyn_, true, false,
|
||||
this->relr_dyn_);
|
||||
|
||||
// Fill in some more dynamic tags.
|
||||
Output_data_dynamic* const odyn = layout->dynamic_data();
|
||||
|
||||
Reference in New Issue
Block a user