|
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 /** |
|
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> |
|
18 |
|
19 #if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX) |
|
20 #define PT_ARM_EXIDX 0x70000001 |
|
21 #endif |
|
22 |
|
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 |
|
43 |
|
44 #ifndef __BYTE_ORDER |
|
45 #error Cannot find endianness |
|
46 #endif |
|
47 |
|
48 #if __BYTE_ORDER == __LITTLE_ENDIAN |
|
49 #define ELFDATA ELFDATA2LSB |
|
50 #elif __BYTE_ORDER == __BIG_ENDIAN |
|
51 #define ELFDATA ELFDATA2MSB |
|
52 #endif |
|
53 |
|
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 |
|
62 |
|
63 #if defined(__i386__) |
|
64 #define ELFMACHINE EM_386 |
|
65 |
|
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 |
|
75 |
|
76 #elif defined(__x86_64__) |
|
77 #define ELFMACHINE EM_X86_64 |
|
78 |
|
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 |
|
87 |
|
88 #elif defined(__arm__) |
|
89 #define ELFMACHINE EM_ARM |
|
90 |
|
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 |
|
103 |
|
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 |
|
112 |
|
113 #else |
|
114 #error Unknown ELF machine type |
|
115 #endif |
|
116 |
|
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 |
|
168 |
|
169 namespace Elf { |
|
170 |
|
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; |
|
180 |
|
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 }; |
|
193 |
|
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 }; |
|
208 |
|
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 }; |
|
224 |
|
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 }; |
|
238 |
|
239 } /* namespace Elf */ |
|
240 |
|
241 #endif /* Elfxx_h */ |