elf-parse.h 6.9 KB

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