at master 7.0 kB view raw
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 */