mozglue/linker/Elfxx.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

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 */

mercurial