Elfxx.h (4398B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef Elfxx_h 6 #define Elfxx_h 7 8 #include "Utils.h" 9 10 #include <elf.h> 11 #include <endian.h> 12 13 /** 14 * Generic ELF macros for the target system 15 */ 16 #ifdef __LP64__ 17 # define Elf_(type) Elf64_##type 18 # define ELFCLASS ELFCLASS64 19 # define ELF_R_TYPE ELF64_R_TYPE 20 # define ELF_R_SYM ELF64_R_SYM 21 # ifndef ELF_ST_BIND 22 # define ELF_ST_BIND ELF64_ST_BIND 23 # endif 24 #else 25 # define Elf_(type) Elf32_##type 26 # define ELFCLASS ELFCLASS32 27 # define ELF_R_TYPE ELF32_R_TYPE 28 # define ELF_R_SYM ELF32_R_SYM 29 # ifndef ELF_ST_BIND 30 # define ELF_ST_BIND ELF32_ST_BIND 31 # endif 32 #endif 33 34 #ifndef __BYTE_ORDER 35 # error Cannot find endianness 36 #endif 37 38 #if __BYTE_ORDER == __LITTLE_ENDIAN 39 # define ELFDATA ELFDATA2LSB 40 #elif __BYTE_ORDER == __BIG_ENDIAN 41 # define ELFDATA ELFDATA2MSB 42 #endif 43 44 #ifdef __linux__ 45 # define ELFOSABI ELFOSABI_LINUX 46 # ifdef EI_ABIVERSION 47 # define ELFABIVERSION 0 48 # endif 49 #else 50 # error Unknown ELF OSABI 51 #endif 52 53 #if defined(__i386__) 54 # define ELFMACHINE EM_386 55 56 // Doing this way probably doesn't scale to other architectures 57 # define R_ABS R_386_32 58 # define R_GLOB_DAT R_386_GLOB_DAT 59 # define R_JMP_SLOT R_386_JMP_SLOT 60 # define R_RELATIVE R_386_RELATIVE 61 # define RELOC(n) DT_REL##n 62 # define UNSUPPORTED_RELOC(n) DT_RELA##n 63 # define STR_RELOC(n) "DT_REL" #n 64 # define Reloc Rel 65 66 #elif defined(__x86_64__) 67 # define ELFMACHINE EM_X86_64 68 69 # define R_ABS R_X86_64_64 70 # define R_GLOB_DAT R_X86_64_GLOB_DAT 71 # define R_JMP_SLOT R_X86_64_JUMP_SLOT 72 # define R_RELATIVE R_X86_64_RELATIVE 73 # define RELOC(n) DT_RELA##n 74 # define UNSUPPORTED_RELOC(n) DT_REL##n 75 # define STR_RELOC(n) "DT_RELA" #n 76 # define Reloc Rela 77 78 #elif defined(__arm__) 79 # define ELFMACHINE EM_ARM 80 81 # ifndef R_ARM_ABS32 82 # define R_ARM_ABS32 2 83 # endif 84 # ifndef R_ARM_GLOB_DAT 85 # define R_ARM_GLOB_DAT 21 86 # endif 87 # ifndef R_ARM_JUMP_SLOT 88 # define R_ARM_JUMP_SLOT 22 89 # endif 90 # ifndef R_ARM_RELATIVE 91 # define R_ARM_RELATIVE 23 92 # endif 93 94 # define R_ABS R_ARM_ABS32 95 # define R_GLOB_DAT R_ARM_GLOB_DAT 96 # define R_JMP_SLOT R_ARM_JUMP_SLOT 97 # define R_RELATIVE R_ARM_RELATIVE 98 # define RELOC(n) DT_REL##n 99 # define UNSUPPORTED_RELOC(n) DT_RELA##n 100 # define STR_RELOC(n) "DT_REL" #n 101 # define Reloc Rel 102 103 #elif defined(__aarch64__) 104 # define ELFMACHINE EM_AARCH64 105 106 # define R_ABS R_AARCH64_ABS64 107 # define R_GLOB_DAT R_AARCH64_GLOB_DAT 108 # define R_JMP_SLOT R_AARCH64_JUMP_SLOT 109 # define R_RELATIVE R_AARCH64_RELATIVE 110 # define RELOC(n) DT_RELA##n 111 # define UNSUPPORTED_RELOC(n) DT_REL##n 112 # define STR_RELOC(n) "DT_RELA" #n 113 # define Reloc Rela 114 115 #else 116 # error Unknown ELF machine type 117 #endif 118 119 namespace Elf { 120 121 /** 122 * Define a few basic Elf Types 123 */ 124 typedef Elf_(Phdr) Phdr; 125 typedef Elf_(Dyn) Dyn; 126 typedef Elf_(Sym) Sym; 127 typedef Elf_(Addr) Addr; 128 typedef Elf_(Word) Word; 129 typedef Elf_(Half) Half; 130 131 /** 132 * Helper class around the standard Elf header struct 133 */ 134 struct Ehdr : public Elf_(Ehdr) { 135 /** 136 * Equivalent to reinterpret_cast<const Ehdr *>(buf), but additionally 137 * checking that this is indeed an Elf header and that the Elf type 138 * corresponds to that of the system 139 */ 140 static const Ehdr* validate(const void* buf); 141 }; 142 143 /** 144 * Elf String table 145 */ 146 class Strtab : public UnsizedArray<const char> { 147 public: 148 /** 149 * Returns the string at the given index in the table 150 */ 151 const char* GetStringAt(off_t index) const { 152 return &UnsizedArray<const char>::operator[](index); 153 } 154 }; 155 156 /** 157 * Helper class around Elf relocation. 158 */ 159 struct Rel 160 : public Elf_(Rel){/** 161 * Returns the addend for the relocation, which is the 162 * value stored at r_offset. 163 */ 164 Addr GetAddend(void* base) 165 const {return *(reinterpret_cast<const Addr*>( 166 reinterpret_cast<const char*>(base) + r_offset)); 167 } // namespace Elf 168 } 169 ; 170 171 /** 172 * Helper class around Elf relocation with addend. 173 */ 174 struct Rela 175 : public Elf_(Rela){/** 176 * Returns the addend for the relocation. 177 */ 178 Addr GetAddend(void* base) const {return r_addend; 179 } 180 } 181 ; 182 183 } /* namespace Elf */ 184 185 #endif /* Elfxx_h */