Elfxx.h 4.7 KB

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