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