Bug 1874684 - Part 4: Prefer const references instead of copying Instant values....
[gecko.git] / mozglue / linker / Elfxx.h
blob4baf923b557d9ee8546163cd0db044b8d1d4e68d
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 #include "Utils.h"
10 /**
11 * Android system headers have two different elf.h file. The one under linux/
12 * is the most complete on older Android API versions without unified headers.
14 #if defined(ANDROID) && __ANDROID_API__ < 21 && !defined(__ANDROID_API_L__)
15 # include <linux/elf.h>
16 #else
17 # include <elf.h>
18 #endif
19 #include <endian.h>
21 #if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX)
22 # define PT_ARM_EXIDX 0x70000001
23 #endif
25 /**
26 * Generic ELF macros for the target system
28 #ifdef __LP64__
29 # define Elf_(type) Elf64_##type
30 # define ELFCLASS ELFCLASS64
31 # define ELF_R_TYPE ELF64_R_TYPE
32 # define ELF_R_SYM ELF64_R_SYM
33 # ifndef ELF_ST_BIND
34 # define ELF_ST_BIND ELF64_ST_BIND
35 # endif
36 #else
37 # define Elf_(type) Elf32_##type
38 # define ELFCLASS ELFCLASS32
39 # define ELF_R_TYPE ELF32_R_TYPE
40 # define ELF_R_SYM ELF32_R_SYM
41 # ifndef ELF_ST_BIND
42 # define ELF_ST_BIND ELF32_ST_BIND
43 # endif
44 #endif
46 #ifndef __BYTE_ORDER
47 # error Cannot find endianness
48 #endif
50 #if __BYTE_ORDER == __LITTLE_ENDIAN
51 # define ELFDATA ELFDATA2LSB
52 #elif __BYTE_ORDER == __BIG_ENDIAN
53 # define ELFDATA ELFDATA2MSB
54 #endif
56 #ifdef __linux__
57 # define ELFOSABI ELFOSABI_LINUX
58 # ifdef EI_ABIVERSION
59 # define ELFABIVERSION 0
60 # endif
61 #else
62 # error Unknown ELF OSABI
63 #endif
65 #if defined(__i386__)
66 # define ELFMACHINE EM_386
68 // Doing this way probably doesn't scale to other architectures
69 # define R_ABS R_386_32
70 # define R_GLOB_DAT R_386_GLOB_DAT
71 # define R_JMP_SLOT R_386_JMP_SLOT
72 # define R_RELATIVE R_386_RELATIVE
73 # define RELOC(n) DT_REL##n
74 # define UNSUPPORTED_RELOC(n) DT_RELA##n
75 # define STR_RELOC(n) "DT_REL" #n
76 # define Reloc Rel
78 #elif defined(__x86_64__)
79 # define ELFMACHINE EM_X86_64
81 # define R_ABS R_X86_64_64
82 # define R_GLOB_DAT R_X86_64_GLOB_DAT
83 # define R_JMP_SLOT R_X86_64_JUMP_SLOT
84 # define R_RELATIVE R_X86_64_RELATIVE
85 # define RELOC(n) DT_RELA##n
86 # define UNSUPPORTED_RELOC(n) DT_REL##n
87 # define STR_RELOC(n) "DT_RELA" #n
88 # define Reloc Rela
90 #elif defined(__arm__)
91 # define ELFMACHINE EM_ARM
93 # ifndef R_ARM_ABS32
94 # define R_ARM_ABS32 2
95 # endif
96 # ifndef R_ARM_GLOB_DAT
97 # define R_ARM_GLOB_DAT 21
98 # endif
99 # ifndef R_ARM_JUMP_SLOT
100 # define R_ARM_JUMP_SLOT 22
101 # endif
102 # ifndef R_ARM_RELATIVE
103 # define R_ARM_RELATIVE 23
104 # endif
106 # define R_ABS R_ARM_ABS32
107 # define R_GLOB_DAT R_ARM_GLOB_DAT
108 # define R_JMP_SLOT R_ARM_JUMP_SLOT
109 # define R_RELATIVE R_ARM_RELATIVE
110 # define RELOC(n) DT_REL##n
111 # define UNSUPPORTED_RELOC(n) DT_RELA##n
112 # define STR_RELOC(n) "DT_REL" #n
113 # define Reloc Rel
115 #elif defined(__aarch64__)
116 # define ELFMACHINE EM_AARCH64
118 # define R_ABS R_AARCH64_ABS64
119 # define R_GLOB_DAT R_AARCH64_GLOB_DAT
120 # define R_JMP_SLOT R_AARCH64_JUMP_SLOT
121 # define R_RELATIVE R_AARCH64_RELATIVE
122 # define RELOC(n) DT_RELA##n
123 # define UNSUPPORTED_RELOC(n) DT_REL##n
124 # define STR_RELOC(n) "DT_RELA" #n
125 # define Reloc Rela
127 #else
128 # error Unknown ELF machine type
129 #endif
132 * Android system headers don't have all definitions
134 #ifndef STN_UNDEF
135 # define STN_UNDEF 0
136 #endif
137 #ifndef DT_INIT_ARRAY
138 # define DT_INIT_ARRAY 25
139 #endif
140 #ifndef DT_FINI_ARRAY
141 # define DT_FINI_ARRAY 26
142 #endif
143 #ifndef DT_INIT_ARRAYSZ
144 # define DT_INIT_ARRAYSZ 27
145 #endif
146 #ifndef DT_FINI_ARRAYSZ
147 # define DT_FINI_ARRAYSZ 28
148 #endif
149 #ifndef DT_RELACOUNT
150 # define DT_RELACOUNT 0x6ffffff9
151 #endif
152 #ifndef DT_RELCOUNT
153 # define DT_RELCOUNT 0x6ffffffa
154 #endif
155 #ifndef DT_VERSYM
156 # define DT_VERSYM 0x6ffffff0
157 #endif
158 #ifndef DT_VERDEF
159 # define DT_VERDEF 0x6ffffffc
160 #endif
161 #ifndef DT_VERDEFNUM
162 # define DT_VERDEFNUM 0x6ffffffd
163 #endif
164 #ifndef DT_VERNEED
165 # define DT_VERNEED 0x6ffffffe
166 #endif
167 #ifndef DT_VERNEEDNUM
168 # define DT_VERNEEDNUM 0x6fffffff
169 #endif
170 #ifndef DT_FLAGS_1
171 # define DT_FLAGS_1 0x6ffffffb
172 #endif
173 #ifndef DT_FLAGS
174 # define DT_FLAGS 30
175 #endif
176 #ifndef DF_SYMBOLIC
177 # define DF_SYMBOLIC 0x00000002
178 #endif
179 #ifndef DF_TEXTREL
180 # define DF_TEXTREL 0x00000004
181 #endif
183 namespace Elf {
186 * Define a few basic Elf Types
188 typedef Elf_(Phdr) Phdr;
189 typedef Elf_(Dyn) Dyn;
190 typedef Elf_(Sym) Sym;
191 typedef Elf_(Addr) Addr;
192 typedef Elf_(Word) Word;
193 typedef Elf_(Half) Half;
196 * Helper class around the standard Elf header struct
198 struct Ehdr : public Elf_(Ehdr) {
200 * Equivalent to reinterpret_cast<const Ehdr *>(buf), but additionally
201 * checking that this is indeed an Elf header and that the Elf type
202 * corresponds to that of the system
204 static const Ehdr* validate(const void* buf);
208 * Elf String table
210 class Strtab : public UnsizedArray<const char> {
211 public:
213 * Returns the string at the given index in the table
215 const char* GetStringAt(off_t index) const {
216 return &UnsizedArray<const char>::operator[](index);
221 * Helper class around Elf relocation.
223 struct Rel : public Elf_(Rel) {
225 * Returns the addend for the relocation, which is the value stored
226 * at r_offset.
228 Addr GetAddend(void* base) const {
229 return *(reinterpret_cast<const Addr*>(reinterpret_cast<const char*>(base) +
230 r_offset));
235 * Helper class around Elf relocation with addend.
237 struct Rela : public Elf_(Rela) {
239 * Returns the addend for the relocation.
241 Addr GetAddend(void* base) const { return r_addend; }
244 } /* namespace Elf */
246 #endif /* Elfxx_h */