Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #ifndef Elfxx_h |
michael@0 | 6 | #define Elfxx_h |
michael@0 | 7 | |
michael@0 | 8 | /** |
michael@0 | 9 | * Android system headers have two different elf.h file. The one under linux/ |
michael@0 | 10 | * is the most complete. |
michael@0 | 11 | */ |
michael@0 | 12 | #ifdef ANDROID |
michael@0 | 13 | #include <linux/elf.h> |
michael@0 | 14 | #else |
michael@0 | 15 | #include <elf.h> |
michael@0 | 16 | #endif |
michael@0 | 17 | #include <endian.h> |
michael@0 | 18 | |
michael@0 | 19 | #if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX) |
michael@0 | 20 | #define PT_ARM_EXIDX 0x70000001 |
michael@0 | 21 | #endif |
michael@0 | 22 | |
michael@0 | 23 | /** |
michael@0 | 24 | * Generic ELF macros for the target system |
michael@0 | 25 | */ |
michael@0 | 26 | #ifdef __LP64__ |
michael@0 | 27 | #define Elf_(type) Elf64_ ## type |
michael@0 | 28 | #define ELFCLASS ELFCLASS64 |
michael@0 | 29 | #define ELF_R_TYPE ELF64_R_TYPE |
michael@0 | 30 | #define ELF_R_SYM ELF64_R_SYM |
michael@0 | 31 | #ifndef ELF_ST_BIND |
michael@0 | 32 | #define ELF_ST_BIND ELF64_ST_BIND |
michael@0 | 33 | #endif |
michael@0 | 34 | #else |
michael@0 | 35 | #define Elf_(type) Elf32_ ## type |
michael@0 | 36 | #define ELFCLASS ELFCLASS32 |
michael@0 | 37 | #define ELF_R_TYPE ELF32_R_TYPE |
michael@0 | 38 | #define ELF_R_SYM ELF32_R_SYM |
michael@0 | 39 | #ifndef ELF_ST_BIND |
michael@0 | 40 | #define ELF_ST_BIND ELF32_ST_BIND |
michael@0 | 41 | #endif |
michael@0 | 42 | #endif |
michael@0 | 43 | |
michael@0 | 44 | #ifndef __BYTE_ORDER |
michael@0 | 45 | #error Cannot find endianness |
michael@0 | 46 | #endif |
michael@0 | 47 | |
michael@0 | 48 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
michael@0 | 49 | #define ELFDATA ELFDATA2LSB |
michael@0 | 50 | #elif __BYTE_ORDER == __BIG_ENDIAN |
michael@0 | 51 | #define ELFDATA ELFDATA2MSB |
michael@0 | 52 | #endif |
michael@0 | 53 | |
michael@0 | 54 | #ifdef __linux__ |
michael@0 | 55 | #define ELFOSABI ELFOSABI_LINUX |
michael@0 | 56 | #ifdef EI_ABIVERSION |
michael@0 | 57 | #define ELFABIVERSION 0 |
michael@0 | 58 | #endif |
michael@0 | 59 | #else |
michael@0 | 60 | #error Unknown ELF OSABI |
michael@0 | 61 | #endif |
michael@0 | 62 | |
michael@0 | 63 | #if defined(__i386__) |
michael@0 | 64 | #define ELFMACHINE EM_386 |
michael@0 | 65 | |
michael@0 | 66 | // Doing this way probably doesn't scale to other architectures |
michael@0 | 67 | #define R_ABS R_386_32 |
michael@0 | 68 | #define R_GLOB_DAT R_386_GLOB_DAT |
michael@0 | 69 | #define R_JMP_SLOT R_386_JMP_SLOT |
michael@0 | 70 | #define R_RELATIVE R_386_RELATIVE |
michael@0 | 71 | #define RELOC(n) DT_REL ## n |
michael@0 | 72 | #define UNSUPPORTED_RELOC(n) DT_RELA ## n |
michael@0 | 73 | #define STR_RELOC(n) "DT_REL" # n |
michael@0 | 74 | #define Reloc Rel |
michael@0 | 75 | |
michael@0 | 76 | #elif defined(__x86_64__) |
michael@0 | 77 | #define ELFMACHINE EM_X86_64 |
michael@0 | 78 | |
michael@0 | 79 | #define R_ABS R_X86_64_64 |
michael@0 | 80 | #define R_GLOB_DAT R_X86_64_GLOB_DAT |
michael@0 | 81 | #define R_JMP_SLOT R_X86_64_JUMP_SLOT |
michael@0 | 82 | #define R_RELATIVE R_X86_64_RELATIVE |
michael@0 | 83 | #define RELOC(n) DT_RELA ## n |
michael@0 | 84 | #define UNSUPPORTED_RELOC(n) DT_REL ## n |
michael@0 | 85 | #define STR_RELOC(n) "DT_RELA" # n |
michael@0 | 86 | #define Reloc Rela |
michael@0 | 87 | |
michael@0 | 88 | #elif defined(__arm__) |
michael@0 | 89 | #define ELFMACHINE EM_ARM |
michael@0 | 90 | |
michael@0 | 91 | #ifndef R_ARM_ABS32 |
michael@0 | 92 | #define R_ARM_ABS32 2 |
michael@0 | 93 | #endif |
michael@0 | 94 | #ifndef R_ARM_GLOB_DAT |
michael@0 | 95 | #define R_ARM_GLOB_DAT 21 |
michael@0 | 96 | #endif |
michael@0 | 97 | #ifndef R_ARM_JUMP_SLOT |
michael@0 | 98 | #define R_ARM_JUMP_SLOT 22 |
michael@0 | 99 | #endif |
michael@0 | 100 | #ifndef R_ARM_RELATIVE |
michael@0 | 101 | #define R_ARM_RELATIVE 23 |
michael@0 | 102 | #endif |
michael@0 | 103 | |
michael@0 | 104 | #define R_ABS R_ARM_ABS32 |
michael@0 | 105 | #define R_GLOB_DAT R_ARM_GLOB_DAT |
michael@0 | 106 | #define R_JMP_SLOT R_ARM_JUMP_SLOT |
michael@0 | 107 | #define R_RELATIVE R_ARM_RELATIVE |
michael@0 | 108 | #define RELOC(n) DT_REL ## n |
michael@0 | 109 | #define UNSUPPORTED_RELOC(n) DT_RELA ## n |
michael@0 | 110 | #define STR_RELOC(n) "DT_REL" # n |
michael@0 | 111 | #define Reloc Rel |
michael@0 | 112 | |
michael@0 | 113 | #else |
michael@0 | 114 | #error Unknown ELF machine type |
michael@0 | 115 | #endif |
michael@0 | 116 | |
michael@0 | 117 | /** |
michael@0 | 118 | * Android system headers don't have all definitions |
michael@0 | 119 | */ |
michael@0 | 120 | #ifndef STN_UNDEF |
michael@0 | 121 | #define STN_UNDEF 0 |
michael@0 | 122 | #endif |
michael@0 | 123 | #ifndef DT_INIT_ARRAY |
michael@0 | 124 | #define DT_INIT_ARRAY 25 |
michael@0 | 125 | #endif |
michael@0 | 126 | #ifndef DT_FINI_ARRAY |
michael@0 | 127 | #define DT_FINI_ARRAY 26 |
michael@0 | 128 | #endif |
michael@0 | 129 | #ifndef DT_INIT_ARRAYSZ |
michael@0 | 130 | #define DT_INIT_ARRAYSZ 27 |
michael@0 | 131 | #endif |
michael@0 | 132 | #ifndef DT_FINI_ARRAYSZ |
michael@0 | 133 | #define DT_FINI_ARRAYSZ 28 |
michael@0 | 134 | #endif |
michael@0 | 135 | #ifndef DT_RELACOUNT |
michael@0 | 136 | #define DT_RELACOUNT 0x6ffffff9 |
michael@0 | 137 | #endif |
michael@0 | 138 | #ifndef DT_RELCOUNT |
michael@0 | 139 | #define DT_RELCOUNT 0x6ffffffa |
michael@0 | 140 | #endif |
michael@0 | 141 | #ifndef DT_VERSYM |
michael@0 | 142 | #define DT_VERSYM 0x6ffffff0 |
michael@0 | 143 | #endif |
michael@0 | 144 | #ifndef DT_VERDEF |
michael@0 | 145 | #define DT_VERDEF 0x6ffffffc |
michael@0 | 146 | #endif |
michael@0 | 147 | #ifndef DT_VERDEFNUM |
michael@0 | 148 | #define DT_VERDEFNUM 0x6ffffffd |
michael@0 | 149 | #endif |
michael@0 | 150 | #ifndef DT_VERNEED |
michael@0 | 151 | #define DT_VERNEED 0x6ffffffe |
michael@0 | 152 | #endif |
michael@0 | 153 | #ifndef DT_VERNEEDNUM |
michael@0 | 154 | #define DT_VERNEEDNUM 0x6fffffff |
michael@0 | 155 | #endif |
michael@0 | 156 | #ifndef DT_FLAGS_1 |
michael@0 | 157 | #define DT_FLAGS_1 0x6ffffffb |
michael@0 | 158 | #endif |
michael@0 | 159 | #ifndef DT_FLAGS |
michael@0 | 160 | #define DT_FLAGS 30 |
michael@0 | 161 | #endif |
michael@0 | 162 | #ifndef DF_SYMBOLIC |
michael@0 | 163 | #define DF_SYMBOLIC 0x00000002 |
michael@0 | 164 | #endif |
michael@0 | 165 | #ifndef DF_TEXTREL |
michael@0 | 166 | #define DF_TEXTREL 0x00000004 |
michael@0 | 167 | #endif |
michael@0 | 168 | |
michael@0 | 169 | namespace Elf { |
michael@0 | 170 | |
michael@0 | 171 | /** |
michael@0 | 172 | * Define a few basic Elf Types |
michael@0 | 173 | */ |
michael@0 | 174 | typedef Elf_(Phdr) Phdr; |
michael@0 | 175 | typedef Elf_(Dyn) Dyn; |
michael@0 | 176 | typedef Elf_(Sym) Sym; |
michael@0 | 177 | typedef Elf_(Addr) Addr; |
michael@0 | 178 | typedef Elf_(Word) Word; |
michael@0 | 179 | typedef Elf_(Half) Half; |
michael@0 | 180 | |
michael@0 | 181 | /** |
michael@0 | 182 | * Helper class around the standard Elf header struct |
michael@0 | 183 | */ |
michael@0 | 184 | struct Ehdr: public Elf_(Ehdr) |
michael@0 | 185 | { |
michael@0 | 186 | /** |
michael@0 | 187 | * Equivalent to reinterpret_cast<const Ehdr *>(buf), but additionally |
michael@0 | 188 | * checking that this is indeed an Elf header and that the Elf type |
michael@0 | 189 | * corresponds to that of the system |
michael@0 | 190 | */ |
michael@0 | 191 | static const Ehdr *validate(const void *buf); |
michael@0 | 192 | }; |
michael@0 | 193 | |
michael@0 | 194 | /** |
michael@0 | 195 | * Elf String table |
michael@0 | 196 | */ |
michael@0 | 197 | class Strtab: public UnsizedArray<const char> |
michael@0 | 198 | { |
michael@0 | 199 | public: |
michael@0 | 200 | /** |
michael@0 | 201 | * Returns the string at the given index in the table |
michael@0 | 202 | */ |
michael@0 | 203 | const char *GetStringAt(off_t index) const |
michael@0 | 204 | { |
michael@0 | 205 | return &UnsizedArray<const char>::operator[](index); |
michael@0 | 206 | } |
michael@0 | 207 | }; |
michael@0 | 208 | |
michael@0 | 209 | /** |
michael@0 | 210 | * Helper class around Elf relocation. |
michael@0 | 211 | */ |
michael@0 | 212 | struct Rel: public Elf_(Rel) |
michael@0 | 213 | { |
michael@0 | 214 | /** |
michael@0 | 215 | * Returns the addend for the relocation, which is the value stored |
michael@0 | 216 | * at r_offset. |
michael@0 | 217 | */ |
michael@0 | 218 | Addr GetAddend(void *base) const |
michael@0 | 219 | { |
michael@0 | 220 | return *(reinterpret_cast<const Addr *>( |
michael@0 | 221 | reinterpret_cast<const char *>(base) + r_offset)); |
michael@0 | 222 | } |
michael@0 | 223 | }; |
michael@0 | 224 | |
michael@0 | 225 | /** |
michael@0 | 226 | * Helper class around Elf relocation with addend. |
michael@0 | 227 | */ |
michael@0 | 228 | struct Rela: public Elf_(Rela) |
michael@0 | 229 | { |
michael@0 | 230 | /** |
michael@0 | 231 | * Returns the addend for the relocation. |
michael@0 | 232 | */ |
michael@0 | 233 | Addr GetAddend(void *base) const |
michael@0 | 234 | { |
michael@0 | 235 | return r_addend; |
michael@0 | 236 | } |
michael@0 | 237 | }; |
michael@0 | 238 | |
michael@0 | 239 | } /* namespace Elf */ |
michael@0 | 240 | |
michael@0 | 241 | #endif /* Elfxx_h */ |