aboutsummaryrefslogtreecommitdiff
path: root/elfcpp
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@gmail.com>2017-04-25 19:21:57 -0700
committerCary Coutant <ccoutant@gmail.com>2017-04-25 20:07:52 -0700
commit8c13bcd2209cb776aa2cf7e5016b7884b0aecbf6 (patch)
treedc131c444a7e2a372b057cca03b68bc21ae50f28 /elfcpp
parent4658f12e9c5ec0d2efb04f1688f6cd6bd9f1a47d (diff)
downloadbinutils-users/ccoutant/experimental-relr.zip
binutils-users/ccoutant/experimental-relr.tar.gz
binutils-users/ccoutant/experimental-relr.tar.bz2
Experimental implementation of RELR-style relocations.users/ccoutant/experimental-relr
For x86-64 only. Instead of R_X86_64_RELATIVE relocations, we write the offsets of the relocation targets to a new section, .relr.dyn, with section type SHT_RELR.
Diffstat (limited to 'elfcpp')
-rw-r--r--elfcpp/elfcpp.h49
-rw-r--r--elfcpp/elfcpp_internal.h6
2 files changed, 55 insertions, 0 deletions
diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
index cce40d4..d4c0a63 100644
--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -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>
diff --git a/elfcpp/elfcpp_internal.h b/elfcpp/elfcpp_internal.h
index 14adfde..a1cfcf5 100644
--- a/elfcpp/elfcpp_internal.h
+++ b/elfcpp/elfcpp_internal.h
@@ -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