Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2#ifndef _SCRIPTS_ELF_PARSE_H
3#define _SCRIPTS_ELF_PARSE_H
4
5#include <elf.h>
6
7#include <tools/be_byteshift.h>
8#include <tools/le_byteshift.h>
9
10typedef union {
11 Elf32_Ehdr e32;
12 Elf64_Ehdr e64;
13} Elf_Ehdr;
14
15typedef union {
16 Elf32_Shdr e32;
17 Elf64_Shdr e64;
18} Elf_Shdr;
19
20typedef union {
21 Elf32_Sym e32;
22 Elf64_Sym e64;
23} Elf_Sym;
24
25typedef union {
26 Elf32_Rela e32;
27 Elf64_Rela e64;
28} Elf_Rela;
29
30struct elf_funcs {
31 int (*compare_extable)(const void *a, const void *b);
32 uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
33 uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
34 uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
35 uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
36 uint64_t (*shdr_addr)(Elf_Shdr *shdr);
37 uint64_t (*shdr_offset)(Elf_Shdr *shdr);
38 uint64_t (*shdr_size)(Elf_Shdr *shdr);
39 uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
40 uint32_t (*shdr_link)(Elf_Shdr *shdr);
41 uint32_t (*shdr_name)(Elf_Shdr *shdr);
42 uint32_t (*shdr_type)(Elf_Shdr *shdr);
43 uint8_t (*sym_type)(Elf_Sym *sym);
44 uint32_t (*sym_name)(Elf_Sym *sym);
45 uint64_t (*sym_value)(Elf_Sym *sym);
46 uint16_t (*sym_shndx)(Elf_Sym *sym);
47 uint64_t (*rela_offset)(Elf_Rela *rela);
48 uint64_t (*rela_info)(Elf_Rela *rela);
49 uint64_t (*rela_addend)(Elf_Rela *rela);
50 void (*rela_write_addend)(Elf_Rela *rela, uint64_t val);
51 uint32_t (*r)(const uint32_t *);
52 uint16_t (*r2)(const uint16_t *);
53 uint64_t (*r8)(const uint64_t *);
54 void (*w)(uint32_t, uint32_t *);
55 void (*w8)(uint64_t, uint64_t *);
56};
57
58extern struct elf_funcs elf_parser;
59
60static inline uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
61{
62 return elf_parser.r8(&ehdr->e64.e_shoff);
63}
64
65static inline uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
66{
67 return elf_parser.r(&ehdr->e32.e_shoff);
68}
69
70static inline uint64_t ehdr_shoff(Elf_Ehdr *ehdr)
71{
72 return elf_parser.ehdr_shoff(ehdr);
73}
74
75#define EHDR_HALF(fn_name) \
76static inline uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
77{ \
78 return elf_parser.r2(&ehdr->e64.e_##fn_name); \
79} \
80 \
81static inline uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
82{ \
83 return elf_parser.r2(&ehdr->e32.e_##fn_name); \
84} \
85 \
86static inline uint16_t ehdr_##fn_name(Elf_Ehdr *ehdr) \
87{ \
88 return elf_parser.ehdr_##fn_name(ehdr); \
89}
90
91EHDR_HALF(shentsize)
92EHDR_HALF(shstrndx)
93EHDR_HALF(shnum)
94
95#define SHDR_WORD(fn_name) \
96static inline uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
97{ \
98 return elf_parser.r(&shdr->e64.sh_##fn_name); \
99} \
100 \
101static inline uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
102{ \
103 return elf_parser.r(&shdr->e32.sh_##fn_name); \
104} \
105 \
106static inline uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
107{ \
108 return elf_parser.shdr_##fn_name(shdr); \
109}
110
111#define SHDR_ADDR(fn_name) \
112static inline uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
113{ \
114 return elf_parser.r8(&shdr->e64.sh_##fn_name); \
115} \
116 \
117static inline uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
118{ \
119 return elf_parser.r(&shdr->e32.sh_##fn_name); \
120} \
121 \
122static inline uint64_t shdr_##fn_name(Elf_Shdr *shdr) \
123{ \
124 return elf_parser.shdr_##fn_name(shdr); \
125}
126
127#define SHDR_WORD(fn_name) \
128static inline uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
129{ \
130 return elf_parser.r(&shdr->e64.sh_##fn_name); \
131} \
132 \
133static inline uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
134{ \
135 return elf_parser.r(&shdr->e32.sh_##fn_name); \
136} \
137static inline uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
138{ \
139 return elf_parser.shdr_##fn_name(shdr); \
140}
141
142SHDR_ADDR(addr)
143SHDR_ADDR(offset)
144SHDR_ADDR(size)
145SHDR_ADDR(entsize)
146
147SHDR_WORD(link)
148SHDR_WORD(name)
149SHDR_WORD(type)
150
151#define SYM_ADDR(fn_name) \
152static inline uint64_t sym64_##fn_name(Elf_Sym *sym) \
153{ \
154 return elf_parser.r8(&sym->e64.st_##fn_name); \
155} \
156 \
157static inline uint64_t sym32_##fn_name(Elf_Sym *sym) \
158{ \
159 return elf_parser.r(&sym->e32.st_##fn_name); \
160} \
161 \
162static inline uint64_t sym_##fn_name(Elf_Sym *sym) \
163{ \
164 return elf_parser.sym_##fn_name(sym); \
165}
166
167#define SYM_WORD(fn_name) \
168static inline uint32_t sym64_##fn_name(Elf_Sym *sym) \
169{ \
170 return elf_parser.r(&sym->e64.st_##fn_name); \
171} \
172 \
173static inline uint32_t sym32_##fn_name(Elf_Sym *sym) \
174{ \
175 return elf_parser.r(&sym->e32.st_##fn_name); \
176} \
177 \
178static inline uint32_t sym_##fn_name(Elf_Sym *sym) \
179{ \
180 return elf_parser.sym_##fn_name(sym); \
181}
182
183#define SYM_HALF(fn_name) \
184static inline uint16_t sym64_##fn_name(Elf_Sym *sym) \
185{ \
186 return elf_parser.r2(&sym->e64.st_##fn_name); \
187} \
188 \
189static inline uint16_t sym32_##fn_name(Elf_Sym *sym) \
190{ \
191 return elf_parser.r2(&sym->e32.st_##fn_name); \
192} \
193 \
194static inline uint16_t sym_##fn_name(Elf_Sym *sym) \
195{ \
196 return elf_parser.sym_##fn_name(sym); \
197}
198
199static inline uint8_t sym64_type(Elf_Sym *sym)
200{
201 return ELF64_ST_TYPE(sym->e64.st_info);
202}
203
204static inline uint8_t sym32_type(Elf_Sym *sym)
205{
206 return ELF32_ST_TYPE(sym->e32.st_info);
207}
208
209static inline uint8_t sym_type(Elf_Sym *sym)
210{
211 return elf_parser.sym_type(sym);
212}
213
214SYM_ADDR(value)
215SYM_WORD(name)
216SYM_HALF(shndx)
217
218#define __maybe_unused __attribute__((__unused__))
219
220#define RELA_ADDR(fn_name) \
221static inline uint64_t rela64_##fn_name(Elf_Rela *rela) \
222{ \
223 return elf_parser.r8((uint64_t *)&rela->e64.r_##fn_name); \
224} \
225 \
226static inline uint64_t rela32_##fn_name(Elf_Rela *rela) \
227{ \
228 return elf_parser.r((uint32_t *)&rela->e32.r_##fn_name); \
229} \
230 \
231static inline uint64_t __maybe_unused rela_##fn_name(Elf_Rela *rela) \
232{ \
233 return elf_parser.rela_##fn_name(rela); \
234}
235
236RELA_ADDR(offset)
237RELA_ADDR(info)
238RELA_ADDR(addend)
239
240static inline void rela64_write_addend(Elf_Rela *rela, uint64_t val)
241{
242 elf_parser.w8(val, (uint64_t *)&rela->e64.r_addend);
243}
244
245static inline void rela32_write_addend(Elf_Rela *rela, uint64_t val)
246{
247 elf_parser.w(val, (uint32_t *)&rela->e32.r_addend);
248}
249
250static inline uint32_t rbe(const uint32_t *x)
251{
252 return get_unaligned_be32(x);
253}
254
255static inline uint16_t r2be(const uint16_t *x)
256{
257 return get_unaligned_be16(x);
258}
259
260static inline uint64_t r8be(const uint64_t *x)
261{
262 return get_unaligned_be64(x);
263}
264
265static inline uint32_t rle(const uint32_t *x)
266{
267 return get_unaligned_le32(x);
268}
269
270static inline uint16_t r2le(const uint16_t *x)
271{
272 return get_unaligned_le16(x);
273}
274
275static inline uint64_t r8le(const uint64_t *x)
276{
277 return get_unaligned_le64(x);
278}
279
280static inline void wbe(uint32_t val, uint32_t *x)
281{
282 put_unaligned_be32(val, x);
283}
284
285static inline void wle(uint32_t val, uint32_t *x)
286{
287 put_unaligned_le32(val, x);
288}
289
290static inline void w8be(uint64_t val, uint64_t *x)
291{
292 put_unaligned_be64(val, x);
293}
294
295static inline void w8le(uint64_t val, uint64_t *x)
296{
297 put_unaligned_le64(val, x);
298}
299
300void *elf_map(char const *fname, size_t *size, uint32_t types);
301void elf_unmap(void *addr, size_t size);
302int elf_map_machine(void *addr);
303int elf_map_long_size(void *addr);
304
305#endif /* _SCRIPTS_ELF_PARSE_H */