ARMEHABIPrinter.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. //===--- ARMEHABIPrinter.h - ARM EHABI Unwind Information Printer ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
  10. #define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
  11. #include "Error.h"
  12. #include "StreamWriter.h"
  13. #include "llvm/ADT/STLExtras.h"
  14. #include "llvm/Object/ELF.h"
  15. #include "llvm/Object/ELFTypes.h"
  16. #include "llvm/Support/ARMEHABI.h"
  17. #include "llvm/Support/Debug.h"
  18. #include "llvm/Support/Endian.h"
  19. #include "llvm/Support/Format.h"
  20. #include "llvm/Support/type_traits.h"
  21. namespace llvm {
  22. namespace ARM {
  23. namespace EHABI {
  24. class OpcodeDecoder {
  25. StreamWriter &SW;
  26. raw_ostream &OS;
  27. struct RingEntry {
  28. uint8_t Mask;
  29. uint8_t Value;
  30. void (OpcodeDecoder::*Routine)(const uint8_t *Opcodes, unsigned &OI);
  31. };
  32. static const RingEntry Ring[];
  33. void Decode_00xxxxxx(const uint8_t *Opcodes, unsigned &OI);
  34. void Decode_01xxxxxx(const uint8_t *Opcodes, unsigned &OI);
  35. void Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes, unsigned &OI);
  36. void Decode_10011101(const uint8_t *Opcodes, unsigned &OI);
  37. void Decode_10011111(const uint8_t *Opcodes, unsigned &OI);
  38. void Decode_1001nnnn(const uint8_t *Opcodes, unsigned &OI);
  39. void Decode_10100nnn(const uint8_t *Opcodes, unsigned &OI);
  40. void Decode_10101nnn(const uint8_t *Opcodes, unsigned &OI);
  41. void Decode_10110000(const uint8_t *Opcodes, unsigned &OI);
  42. void Decode_10110001_0000iiii(const uint8_t *Opcodes, unsigned &OI);
  43. void Decode_10110010_uleb128(const uint8_t *Opcodes, unsigned &OI);
  44. void Decode_10110011_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  45. void Decode_101101nn(const uint8_t *Opcodes, unsigned &OI);
  46. void Decode_10111nnn(const uint8_t *Opcodes, unsigned &OI);
  47. void Decode_11000110_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  48. void Decode_11000111_0000iiii(const uint8_t *Opcodes, unsigned &OI);
  49. void Decode_11001000_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  50. void Decode_11001001_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  51. void Decode_11001yyy(const uint8_t *Opcodes, unsigned &OI);
  52. void Decode_11000nnn(const uint8_t *Opcodes, unsigned &OI);
  53. void Decode_11010nnn(const uint8_t *Opcodes, unsigned &OI);
  54. void Decode_11xxxyyy(const uint8_t *Opcodes, unsigned &OI);
  55. void PrintGPR(uint16_t GPRMask);
  56. void PrintRegisters(uint32_t Mask, StringRef Prefix);
  57. public:
  58. OpcodeDecoder(StreamWriter &SW) : SW(SW), OS(SW.getOStream()) {}
  59. void Decode(const uint8_t *Opcodes, off_t Offset, size_t Length);
  60. };
  61. const OpcodeDecoder::RingEntry OpcodeDecoder::Ring[] = {
  62. { 0xc0, 0x00, &OpcodeDecoder::Decode_00xxxxxx },
  63. { 0xc0, 0x40, &OpcodeDecoder::Decode_01xxxxxx },
  64. { 0xf0, 0x80, &OpcodeDecoder::Decode_1000iiii_iiiiiiii },
  65. { 0xff, 0x9d, &OpcodeDecoder::Decode_10011101 },
  66. { 0xff, 0x9f, &OpcodeDecoder::Decode_10011111 },
  67. { 0xf0, 0x90, &OpcodeDecoder::Decode_1001nnnn },
  68. { 0xf8, 0xa0, &OpcodeDecoder::Decode_10100nnn },
  69. { 0xf8, 0xa8, &OpcodeDecoder::Decode_10101nnn },
  70. { 0xff, 0xb0, &OpcodeDecoder::Decode_10110000 },
  71. { 0xff, 0xb1, &OpcodeDecoder::Decode_10110001_0000iiii },
  72. { 0xff, 0xb2, &OpcodeDecoder::Decode_10110010_uleb128 },
  73. { 0xff, 0xb3, &OpcodeDecoder::Decode_10110011_sssscccc },
  74. { 0xfc, 0xb4, &OpcodeDecoder::Decode_101101nn },
  75. { 0xf8, 0xb8, &OpcodeDecoder::Decode_10111nnn },
  76. { 0xff, 0xc6, &OpcodeDecoder::Decode_11000110_sssscccc },
  77. { 0xff, 0xc7, &OpcodeDecoder::Decode_11000111_0000iiii },
  78. { 0xff, 0xc8, &OpcodeDecoder::Decode_11001000_sssscccc },
  79. { 0xff, 0xc9, &OpcodeDecoder::Decode_11001001_sssscccc },
  80. { 0xc8, 0xc8, &OpcodeDecoder::Decode_11001yyy },
  81. { 0xf8, 0xc0, &OpcodeDecoder::Decode_11000nnn },
  82. { 0xf8, 0xd0, &OpcodeDecoder::Decode_11010nnn },
  83. { 0xc0, 0xc0, &OpcodeDecoder::Decode_11xxxyyy },
  84. };
  85. void OpcodeDecoder::Decode_00xxxxxx(const uint8_t *Opcodes, unsigned &OI) {
  86. uint8_t Opcode = Opcodes[OI++ ^ 3];
  87. SW.startLine() << format("0x%02X ; vsp = vsp + %u\n", Opcode,
  88. ((Opcode & 0x3f) << 2) + 4);
  89. }
  90. void OpcodeDecoder::Decode_01xxxxxx(const uint8_t *Opcodes, unsigned &OI) {
  91. uint8_t Opcode = Opcodes[OI++ ^ 3];
  92. SW.startLine() << format("0x%02X ; vsp = vsp - %u\n", Opcode,
  93. ((Opcode & 0x3f) << 2) + 4);
  94. }
  95. void OpcodeDecoder::Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes,
  96. unsigned &OI) {
  97. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  98. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  99. uint16_t GPRMask = (Opcode1 << 4) | ((Opcode0 & 0x0f) << 12);
  100. SW.startLine()
  101. << format("0x%02X 0x%02X ; %s",
  102. Opcode0, Opcode1, GPRMask ? "pop " : "refuse to unwind");
  103. if (GPRMask)
  104. PrintGPR(GPRMask);
  105. OS << '\n';
  106. }
  107. void OpcodeDecoder::Decode_10011101(const uint8_t *Opcodes, unsigned &OI) {
  108. uint8_t Opcode = Opcodes[OI++ ^ 3];
  109. SW.startLine() << format("0x%02X ; reserved (ARM MOVrr)\n", Opcode);
  110. }
  111. void OpcodeDecoder::Decode_10011111(const uint8_t *Opcodes, unsigned &OI) {
  112. uint8_t Opcode = Opcodes[OI++ ^ 3];
  113. SW.startLine() << format("0x%02X ; reserved (WiMMX MOVrr)\n", Opcode);
  114. }
  115. void OpcodeDecoder::Decode_1001nnnn(const uint8_t *Opcodes, unsigned &OI) {
  116. uint8_t Opcode = Opcodes[OI++ ^ 3];
  117. SW.startLine() << format("0x%02X ; vsp = r%u\n", Opcode, (Opcode & 0x0f));
  118. }
  119. void OpcodeDecoder::Decode_10100nnn(const uint8_t *Opcodes, unsigned &OI) {
  120. uint8_t Opcode = Opcodes[OI++ ^ 3];
  121. SW.startLine() << format("0x%02X ; pop ", Opcode);
  122. PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4));
  123. OS << '\n';
  124. }
  125. void OpcodeDecoder::Decode_10101nnn(const uint8_t *Opcodes, unsigned &OI) {
  126. uint8_t Opcode = Opcodes[OI++ ^ 3];
  127. SW.startLine() << format("0x%02X ; pop ", Opcode);
  128. PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4) | (1 << 14));
  129. OS << '\n';
  130. }
  131. void OpcodeDecoder::Decode_10110000(const uint8_t *Opcodes, unsigned &OI) {
  132. uint8_t Opcode = Opcodes[OI++ ^ 3];
  133. SW.startLine() << format("0x%02X ; finish\n", Opcode);
  134. }
  135. void OpcodeDecoder::Decode_10110001_0000iiii(const uint8_t *Opcodes,
  136. unsigned &OI) {
  137. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  138. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  139. SW.startLine()
  140. << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1,
  141. ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop ");
  142. if (((Opcode1 & 0xf0) == 0x00) && Opcode1)
  143. PrintGPR((Opcode1 & 0x0f));
  144. OS << '\n';
  145. }
  146. void OpcodeDecoder::Decode_10110010_uleb128(const uint8_t *Opcodes,
  147. unsigned &OI) {
  148. uint8_t Opcode = Opcodes[OI++ ^ 3];
  149. SW.startLine() << format("0x%02X ", Opcode);
  150. SmallVector<uint8_t, 4> ULEB;
  151. do { ULEB.push_back(Opcodes[OI ^ 3]); } while (Opcodes[OI++ ^ 3] & 0x80);
  152. for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI)
  153. OS << format("0x%02X ", ULEB[BI]);
  154. uint64_t Value = 0;
  155. for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI)
  156. Value = Value | ((ULEB[BI] & 0x7f) << (7 * BI));
  157. OS << format("; vsp = vsp + %" PRIu64 "\n", 0x204 + (Value << 2));
  158. }
  159. void OpcodeDecoder::Decode_10110011_sssscccc(const uint8_t *Opcodes,
  160. unsigned &OI) {
  161. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  162. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  163. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  164. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  165. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  166. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  167. OS << '\n';
  168. }
  169. void OpcodeDecoder::Decode_101101nn(const uint8_t *Opcodes, unsigned &OI) {
  170. uint8_t Opcode = Opcodes[OI++ ^ 3];
  171. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  172. }
  173. void OpcodeDecoder::Decode_10111nnn(const uint8_t *Opcodes, unsigned &OI) {
  174. uint8_t Opcode = Opcodes[OI++ ^ 3];
  175. SW.startLine() << format("0x%02X ; pop ", Opcode);
  176. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d");
  177. OS << '\n';
  178. }
  179. void OpcodeDecoder::Decode_11000110_sssscccc(const uint8_t *Opcodes,
  180. unsigned &OI) {
  181. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  182. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  183. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  184. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  185. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  186. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "wR");
  187. OS << '\n';
  188. }
  189. void OpcodeDecoder::Decode_11000111_0000iiii(const uint8_t *Opcodes,
  190. unsigned &OI) {
  191. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  192. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  193. SW.startLine()
  194. << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1,
  195. ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop ");
  196. if ((Opcode1 & 0xf0) == 0x00 && Opcode1)
  197. PrintRegisters(Opcode1 & 0x0f, "wCGR");
  198. OS << '\n';
  199. }
  200. void OpcodeDecoder::Decode_11001000_sssscccc(const uint8_t *Opcodes,
  201. unsigned &OI) {
  202. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  203. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  204. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  205. uint8_t Start = 16 + ((Opcode1 & 0xf0) >> 4);
  206. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  207. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  208. OS << '\n';
  209. }
  210. void OpcodeDecoder::Decode_11001001_sssscccc(const uint8_t *Opcodes,
  211. unsigned &OI) {
  212. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  213. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  214. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  215. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  216. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  217. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  218. OS << '\n';
  219. }
  220. void OpcodeDecoder::Decode_11001yyy(const uint8_t *Opcodes, unsigned &OI) {
  221. uint8_t Opcode = Opcodes[OI++ ^ 3];
  222. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  223. }
  224. void OpcodeDecoder::Decode_11000nnn(const uint8_t *Opcodes, unsigned &OI) {
  225. uint8_t Opcode = Opcodes[OI++ ^ 3];
  226. SW.startLine() << format("0x%02X ; pop ", Opcode);
  227. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 10), "wR");
  228. OS << '\n';
  229. }
  230. void OpcodeDecoder::Decode_11010nnn(const uint8_t *Opcodes, unsigned &OI) {
  231. uint8_t Opcode = Opcodes[OI++ ^ 3];
  232. SW.startLine() << format("0x%02X ; pop ", Opcode);
  233. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d");
  234. OS << '\n';
  235. }
  236. void OpcodeDecoder::Decode_11xxxyyy(const uint8_t *Opcodes, unsigned &OI) {
  237. uint8_t Opcode = Opcodes[OI++ ^ 3];
  238. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  239. }
  240. void OpcodeDecoder::PrintGPR(uint16_t GPRMask) {
  241. static const char *GPRRegisterNames[16] = {
  242. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
  243. "fp", "ip", "sp", "lr", "pc"
  244. };
  245. OS << '{';
  246. bool Comma = false;
  247. for (unsigned RI = 0, RE = 17; RI < RE; ++RI) {
  248. if (GPRMask & (1 << RI)) {
  249. if (Comma)
  250. OS << ", ";
  251. OS << GPRRegisterNames[RI];
  252. Comma = true;
  253. }
  254. }
  255. OS << '}';
  256. }
  257. void OpcodeDecoder::PrintRegisters(uint32_t VFPMask, StringRef Prefix) {
  258. OS << '{';
  259. bool Comma = false;
  260. for (unsigned RI = 0, RE = 32; RI < RE; ++RI) {
  261. if (VFPMask & (1 << RI)) {
  262. if (Comma)
  263. OS << ", ";
  264. OS << Prefix << RI;
  265. Comma = true;
  266. }
  267. }
  268. OS << '}';
  269. }
  270. void OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset, size_t Length) {
  271. for (unsigned OCI = Offset; OCI < Length + Offset; ) {
  272. bool Decoded = false;
  273. for (unsigned REI = 0, REE = array_lengthof(Ring);
  274. REI != REE && !Decoded; ++REI) {
  275. if ((Opcodes[OCI ^ 3] & Ring[REI].Mask) == Ring[REI].Value) {
  276. (this->*Ring[REI].Routine)(Opcodes, OCI);
  277. Decoded = true;
  278. break;
  279. }
  280. }
  281. if (!Decoded)
  282. SW.startLine() << format("0x%02X ; reserved\n", Opcodes[OCI++ ^ 3]);
  283. }
  284. }
  285. template <typename ET>
  286. class PrinterContext {
  287. StreamWriter &SW;
  288. const object::ELFFile<ET> *ELF;
  289. typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym;
  290. typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
  291. typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator;
  292. static const size_t IndexTableEntrySize;
  293. static uint64_t PREL31(uint32_t Address, uint32_t Place) {
  294. uint64_t Location = Address & 0x7fffffff;
  295. if (Location & 0x04000000)
  296. Location |= (uint64_t) ~0x7fffffff;
  297. return Location + Place;
  298. }
  299. ErrorOr<StringRef> FunctionAtAddress(unsigned Section, uint64_t Address) const;
  300. const Elf_Shdr *FindExceptionTable(unsigned IndexTableIndex,
  301. off_t IndexTableOffset) const;
  302. void PrintIndexTable(unsigned SectionIndex, const Elf_Shdr *IT) const;
  303. void PrintExceptionTable(const Elf_Shdr *IT, const Elf_Shdr *EHT,
  304. uint64_t TableEntryOffset) const;
  305. void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
  306. public:
  307. PrinterContext(StreamWriter &Writer, const object::ELFFile<ET> *File)
  308. : SW(Writer), ELF(File) {}
  309. void PrintUnwindInformation() const;
  310. };
  311. template <typename ET>
  312. const size_t PrinterContext<ET>::IndexTableEntrySize = 8;
  313. template <typename ET>
  314. ErrorOr<StringRef>
  315. PrinterContext<ET>::FunctionAtAddress(unsigned Section,
  316. uint64_t Address) const {
  317. for (const Elf_Sym &Sym : ELF->symbols())
  318. if (Sym.st_shndx == Section && Sym.st_value == Address &&
  319. Sym.getType() == ELF::STT_FUNC)
  320. return ELF->getSymbolName(&Sym, false);
  321. return readobj_error::unknown_symbol;
  322. }
  323. template <typename ET>
  324. const typename object::ELFFile<ET>::Elf_Shdr *
  325. PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
  326. off_t IndexTableOffset) const {
  327. /// Iterate through the sections, searching for the relocation section
  328. /// associated with the unwind index table section specified by
  329. /// IndexSectionIndex. Iterate the associated section searching for the
  330. /// relocation associated with the index table entry specified by
  331. /// IndexTableOffset. The symbol is the section symbol for the exception
  332. /// handling table. Use this symbol to recover the actual exception handling
  333. /// table.
  334. for (const Elf_Shdr &Sec : ELF->sections()) {
  335. if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) {
  336. for (Elf_Rel_iterator RI = ELF->rel_begin(&Sec), RE = ELF->rel_end(&Sec);
  337. RI != RE; ++RI) {
  338. if (RI->r_offset == static_cast<unsigned>(IndexTableOffset)) {
  339. typename object::ELFFile<ET>::Elf_Rela RelA;
  340. RelA.r_offset = RI->r_offset;
  341. RelA.r_info = RI->r_info;
  342. RelA.r_addend = 0;
  343. std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
  344. ELF->getRelocationSymbol(&Sec, &RelA);
  345. ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second);
  346. if (std::error_code EC = Ret.getError())
  347. report_fatal_error(EC.message());
  348. return *Ret;
  349. }
  350. }
  351. }
  352. }
  353. return nullptr;
  354. }
  355. template <typename ET>
  356. void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT,
  357. const Elf_Shdr *EHT,
  358. uint64_t TableEntryOffset) const {
  359. ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(EHT);
  360. if (!Contents)
  361. return;
  362. /// ARM EHABI Section 6.2 - The generic model
  363. ///
  364. /// An exception-handling table entry for the generic model is laid out as:
  365. ///
  366. /// 3 3
  367. /// 1 0 0
  368. /// +-+------------------------------+
  369. /// |0| personality routine offset |
  370. /// +-+------------------------------+
  371. /// | personality routine data ... |
  372. ///
  373. ///
  374. /// ARM EHABI Section 6.3 - The ARM-defined compact model
  375. ///
  376. /// An exception-handling table entry for the compact model looks like:
  377. ///
  378. /// 3 3 2 2 2 2
  379. /// 1 0 8 7 4 3 0
  380. /// +-+---+----+-----------------------+
  381. /// |1| 0 | Ix | data for pers routine |
  382. /// +-+---+----+-----------------------+
  383. /// | more personality routine data |
  384. const support::ulittle32_t Word =
  385. *reinterpret_cast<const support::ulittle32_t *>(Contents->data() + TableEntryOffset);
  386. if (Word & 0x80000000) {
  387. SW.printString("Model", StringRef("Compact"));
  388. unsigned PersonalityIndex = (Word & 0x0f000000) >> 24;
  389. SW.printNumber("PersonalityIndex", PersonalityIndex);
  390. switch (PersonalityIndex) {
  391. case AEABI_UNWIND_CPP_PR0:
  392. PrintOpcodes(Contents->data() + TableEntryOffset, 3, 1);
  393. break;
  394. case AEABI_UNWIND_CPP_PR1:
  395. case AEABI_UNWIND_CPP_PR2:
  396. unsigned AdditionalWords = (Word & 0x00ff0000) >> 16;
  397. PrintOpcodes(Contents->data() + TableEntryOffset, 2 + 4 * AdditionalWords,
  398. 2);
  399. break;
  400. }
  401. } else {
  402. SW.printString("Model", StringRef("Generic"));
  403. uint64_t Address = PREL31(Word, EHT->sh_addr);
  404. SW.printHex("PersonalityRoutineAddress", Address);
  405. if (ErrorOr<StringRef> Name = FunctionAtAddress(EHT->sh_link, Address))
  406. SW.printString("PersonalityRoutineName", *Name);
  407. }
  408. }
  409. template <typename ET>
  410. void PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry,
  411. size_t Length, off_t Offset) const {
  412. ListScope OCC(SW, "Opcodes");
  413. OpcodeDecoder(OCC.W).Decode(Entry, Offset, Length);
  414. }
  415. template <typename ET>
  416. void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
  417. const Elf_Shdr *IT) const {
  418. ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(IT);
  419. if (!Contents)
  420. return;
  421. /// ARM EHABI Section 5 - Index Table Entries
  422. /// * The first word contains a PREL31 offset to the start of a function with
  423. /// bit 31 clear
  424. /// * The second word contains one of:
  425. /// - The PREL31 offset of the start of the table entry for the function,
  426. /// with bit 31 clear
  427. /// - The exception-handling table entry itself with bit 31 set
  428. /// - The special bit pattern EXIDX_CANTUNWIND, indicating that associated
  429. /// frames cannot be unwound
  430. const support::ulittle32_t *Data =
  431. reinterpret_cast<const support::ulittle32_t *>(Contents->data());
  432. const unsigned Entries = IT->sh_size / IndexTableEntrySize;
  433. ListScope E(SW, "Entries");
  434. for (unsigned Entry = 0; Entry < Entries; ++Entry) {
  435. DictScope E(SW, "Entry");
  436. const support::ulittle32_t Word0 =
  437. Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 0];
  438. const support::ulittle32_t Word1 =
  439. Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 1];
  440. if (Word0 & 0x80000000) {
  441. errs() << "corrupt unwind data in section " << SectionIndex << "\n";
  442. continue;
  443. }
  444. const uint64_t Offset = PREL31(Word0, IT->sh_addr);
  445. SW.printHex("FunctionAddress", Offset);
  446. if (ErrorOr<StringRef> Name = FunctionAtAddress(IT->sh_link, Offset))
  447. SW.printString("FunctionName", *Name);
  448. if (Word1 == EXIDX_CANTUNWIND) {
  449. SW.printString("Model", StringRef("CantUnwind"));
  450. continue;
  451. }
  452. if (Word1 & 0x80000000) {
  453. SW.printString("Model", StringRef("Compact (Inline)"));
  454. unsigned PersonalityIndex = (Word1 & 0x0f000000) >> 24;
  455. SW.printNumber("PersonalityIndex", PersonalityIndex);
  456. PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1);
  457. } else {
  458. const Elf_Shdr *EHT =
  459. FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
  460. if (ErrorOr<StringRef> Name = ELF->getSectionName(EHT))
  461. SW.printString("ExceptionHandlingTable", *Name);
  462. uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr);
  463. SW.printHex("TableEntryOffset", TableEntryOffset);
  464. PrintExceptionTable(IT, EHT, TableEntryOffset);
  465. }
  466. }
  467. }
  468. template <typename ET>
  469. void PrinterContext<ET>::PrintUnwindInformation() const {
  470. DictScope UI(SW, "UnwindInformation");
  471. int SectionIndex = 0;
  472. for (const Elf_Shdr &Sec : ELF->sections()) {
  473. if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
  474. DictScope UIT(SW, "UnwindIndexTable");
  475. SW.printNumber("SectionIndex", SectionIndex);
  476. if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec))
  477. SW.printString("SectionName", *SectionName);
  478. SW.printHex("SectionOffset", Sec.sh_offset);
  479. PrintIndexTable(SectionIndex, &Sec);
  480. }
  481. ++SectionIndex;
  482. }
  483. }
  484. }
  485. }
  486. }
  487. #endif