ARMEHABIPrinter.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. //===--- ARMEHABIPrinter.h - ARM EHABI Unwind Information Printer ----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
  9. #define LLVM_TOOLS_LLVM_READOBJ_ARMEHABIPRINTER_H
  10. #include "llvm-readobj.h"
  11. #include "llvm/ADT/STLExtras.h"
  12. #include "llvm/Object/ELF.h"
  13. #include "llvm/Object/ELFTypes.h"
  14. #include "llvm/Support/ARMEHABI.h"
  15. #include "llvm/Support/Debug.h"
  16. #include "llvm/Support/Endian.h"
  17. #include "llvm/Support/Format.h"
  18. #include "llvm/Support/ScopedPrinter.h"
  19. #include "llvm/Support/type_traits.h"
  20. namespace llvm {
  21. namespace ARM {
  22. namespace EHABI {
  23. class OpcodeDecoder {
  24. ScopedPrinter &SW;
  25. raw_ostream &OS;
  26. struct RingEntry {
  27. uint8_t Mask;
  28. uint8_t Value;
  29. void (OpcodeDecoder::*Routine)(const uint8_t *Opcodes, unsigned &OI);
  30. };
  31. static ArrayRef<RingEntry> ring();
  32. void Decode_00xxxxxx(const uint8_t *Opcodes, unsigned &OI);
  33. void Decode_01xxxxxx(const uint8_t *Opcodes, unsigned &OI);
  34. void Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes, unsigned &OI);
  35. void Decode_10011101(const uint8_t *Opcodes, unsigned &OI);
  36. void Decode_10011111(const uint8_t *Opcodes, unsigned &OI);
  37. void Decode_1001nnnn(const uint8_t *Opcodes, unsigned &OI);
  38. void Decode_10100nnn(const uint8_t *Opcodes, unsigned &OI);
  39. void Decode_10101nnn(const uint8_t *Opcodes, unsigned &OI);
  40. void Decode_10110000(const uint8_t *Opcodes, unsigned &OI);
  41. void Decode_10110001_0000iiii(const uint8_t *Opcodes, unsigned &OI);
  42. void Decode_10110010_uleb128(const uint8_t *Opcodes, unsigned &OI);
  43. void Decode_10110011_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  44. void Decode_101101nn(const uint8_t *Opcodes, unsigned &OI);
  45. void Decode_10111nnn(const uint8_t *Opcodes, unsigned &OI);
  46. void Decode_11000110_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  47. void Decode_11000111_0000iiii(const uint8_t *Opcodes, unsigned &OI);
  48. void Decode_11001000_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  49. void Decode_11001001_sssscccc(const uint8_t *Opcodes, unsigned &OI);
  50. void Decode_11001yyy(const uint8_t *Opcodes, unsigned &OI);
  51. void Decode_11000nnn(const uint8_t *Opcodes, unsigned &OI);
  52. void Decode_11010nnn(const uint8_t *Opcodes, unsigned &OI);
  53. void Decode_11xxxyyy(const uint8_t *Opcodes, unsigned &OI);
  54. void PrintGPR(uint16_t GPRMask);
  55. void PrintRegisters(uint32_t Mask, StringRef Prefix);
  56. public:
  57. OpcodeDecoder(ScopedPrinter &SW) : SW(SW), OS(SW.getOStream()) {}
  58. void Decode(const uint8_t *Opcodes, off_t Offset, size_t Length);
  59. };
  60. inline ArrayRef<OpcodeDecoder::RingEntry> OpcodeDecoder::ring() {
  61. static const OpcodeDecoder::RingEntry 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. return makeArrayRef(Ring);
  86. }
  87. inline void OpcodeDecoder::Decode_00xxxxxx(const uint8_t *Opcodes,
  88. unsigned &OI) {
  89. uint8_t Opcode = Opcodes[OI++ ^ 3];
  90. SW.startLine() << format("0x%02X ; vsp = vsp + %u\n", Opcode,
  91. ((Opcode & 0x3f) << 2) + 4);
  92. }
  93. inline void OpcodeDecoder::Decode_01xxxxxx(const uint8_t *Opcodes,
  94. unsigned &OI) {
  95. uint8_t Opcode = Opcodes[OI++ ^ 3];
  96. SW.startLine() << format("0x%02X ; vsp = vsp - %u\n", Opcode,
  97. ((Opcode & 0x3f) << 2) + 4);
  98. }
  99. inline void OpcodeDecoder::Decode_1000iiii_iiiiiiii(const uint8_t *Opcodes,
  100. unsigned &OI) {
  101. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  102. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  103. uint16_t GPRMask = (Opcode1 << 4) | ((Opcode0 & 0x0f) << 12);
  104. SW.startLine()
  105. << format("0x%02X 0x%02X ; %s",
  106. Opcode0, Opcode1, GPRMask ? "pop " : "refuse to unwind");
  107. if (GPRMask)
  108. PrintGPR(GPRMask);
  109. OS << '\n';
  110. }
  111. inline void OpcodeDecoder::Decode_10011101(const uint8_t *Opcodes,
  112. unsigned &OI) {
  113. uint8_t Opcode = Opcodes[OI++ ^ 3];
  114. SW.startLine() << format("0x%02X ; reserved (ARM MOVrr)\n", Opcode);
  115. }
  116. inline void OpcodeDecoder::Decode_10011111(const uint8_t *Opcodes,
  117. unsigned &OI) {
  118. uint8_t Opcode = Opcodes[OI++ ^ 3];
  119. SW.startLine() << format("0x%02X ; reserved (WiMMX MOVrr)\n", Opcode);
  120. }
  121. inline void OpcodeDecoder::Decode_1001nnnn(const uint8_t *Opcodes,
  122. unsigned &OI) {
  123. uint8_t Opcode = Opcodes[OI++ ^ 3];
  124. SW.startLine() << format("0x%02X ; vsp = r%u\n", Opcode, (Opcode & 0x0f));
  125. }
  126. inline void OpcodeDecoder::Decode_10100nnn(const uint8_t *Opcodes,
  127. unsigned &OI) {
  128. uint8_t Opcode = Opcodes[OI++ ^ 3];
  129. SW.startLine() << format("0x%02X ; pop ", Opcode);
  130. PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4));
  131. OS << '\n';
  132. }
  133. inline void OpcodeDecoder::Decode_10101nnn(const uint8_t *Opcodes,
  134. unsigned &OI) {
  135. uint8_t Opcode = Opcodes[OI++ ^ 3];
  136. SW.startLine() << format("0x%02X ; pop ", Opcode);
  137. PrintGPR((((1 << ((Opcode & 0x7) + 1)) - 1) << 4) | (1 << 14));
  138. OS << '\n';
  139. }
  140. inline void OpcodeDecoder::Decode_10110000(const uint8_t *Opcodes,
  141. unsigned &OI) {
  142. uint8_t Opcode = Opcodes[OI++ ^ 3];
  143. SW.startLine() << format("0x%02X ; finish\n", Opcode);
  144. }
  145. inline void OpcodeDecoder::Decode_10110001_0000iiii(const uint8_t *Opcodes,
  146. unsigned &OI) {
  147. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  148. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  149. SW.startLine()
  150. << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1,
  151. ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop ");
  152. if (((Opcode1 & 0xf0) == 0x00) && Opcode1)
  153. PrintGPR((Opcode1 & 0x0f));
  154. OS << '\n';
  155. }
  156. inline void OpcodeDecoder::Decode_10110010_uleb128(const uint8_t *Opcodes,
  157. unsigned &OI) {
  158. uint8_t Opcode = Opcodes[OI++ ^ 3];
  159. SW.startLine() << format("0x%02X ", Opcode);
  160. SmallVector<uint8_t, 4> ULEB;
  161. do { ULEB.push_back(Opcodes[OI ^ 3]); } while (Opcodes[OI++ ^ 3] & 0x80);
  162. for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI)
  163. OS << format("0x%02X ", ULEB[BI]);
  164. uint64_t Value = 0;
  165. for (unsigned BI = 0, BE = ULEB.size(); BI != BE; ++BI)
  166. Value = Value | ((ULEB[BI] & 0x7f) << (7 * BI));
  167. OS << format("; vsp = vsp + %" PRIu64 "\n", 0x204 + (Value << 2));
  168. }
  169. inline void OpcodeDecoder::Decode_10110011_sssscccc(const uint8_t *Opcodes,
  170. unsigned &OI) {
  171. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  172. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  173. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  174. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  175. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  176. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  177. OS << '\n';
  178. }
  179. inline void OpcodeDecoder::Decode_101101nn(const uint8_t *Opcodes,
  180. unsigned &OI) {
  181. uint8_t Opcode = Opcodes[OI++ ^ 3];
  182. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  183. }
  184. inline void OpcodeDecoder::Decode_10111nnn(const uint8_t *Opcodes,
  185. unsigned &OI) {
  186. uint8_t Opcode = Opcodes[OI++ ^ 3];
  187. SW.startLine() << format("0x%02X ; pop ", Opcode);
  188. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d");
  189. OS << '\n';
  190. }
  191. inline void OpcodeDecoder::Decode_11000110_sssscccc(const uint8_t *Opcodes,
  192. unsigned &OI) {
  193. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  194. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  195. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  196. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  197. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  198. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "wR");
  199. OS << '\n';
  200. }
  201. inline void OpcodeDecoder::Decode_11000111_0000iiii(const uint8_t *Opcodes,
  202. unsigned &OI) {
  203. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  204. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  205. SW.startLine()
  206. << format("0x%02X 0x%02X ; %s", Opcode0, Opcode1,
  207. ((Opcode1 & 0xf0) || Opcode1 == 0x00) ? "spare" : "pop ");
  208. if ((Opcode1 & 0xf0) == 0x00 && Opcode1)
  209. PrintRegisters(Opcode1 & 0x0f, "wCGR");
  210. OS << '\n';
  211. }
  212. inline void OpcodeDecoder::Decode_11001000_sssscccc(const uint8_t *Opcodes,
  213. unsigned &OI) {
  214. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  215. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  216. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  217. uint8_t Start = 16 + ((Opcode1 & 0xf0) >> 4);
  218. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  219. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  220. OS << '\n';
  221. }
  222. inline void OpcodeDecoder::Decode_11001001_sssscccc(const uint8_t *Opcodes,
  223. unsigned &OI) {
  224. uint8_t Opcode0 = Opcodes[OI++ ^ 3];
  225. uint8_t Opcode1 = Opcodes[OI++ ^ 3];
  226. SW.startLine() << format("0x%02X 0x%02X ; pop ", Opcode0, Opcode1);
  227. uint8_t Start = ((Opcode1 & 0xf0) >> 4);
  228. uint8_t Count = ((Opcode1 & 0x0f) >> 0);
  229. PrintRegisters((((1 << (Count + 1)) - 1) << Start), "d");
  230. OS << '\n';
  231. }
  232. inline void OpcodeDecoder::Decode_11001yyy(const uint8_t *Opcodes,
  233. unsigned &OI) {
  234. uint8_t Opcode = Opcodes[OI++ ^ 3];
  235. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  236. }
  237. inline void OpcodeDecoder::Decode_11000nnn(const uint8_t *Opcodes,
  238. unsigned &OI) {
  239. uint8_t Opcode = Opcodes[OI++ ^ 3];
  240. SW.startLine() << format("0x%02X ; pop ", Opcode);
  241. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 10), "wR");
  242. OS << '\n';
  243. }
  244. inline void OpcodeDecoder::Decode_11010nnn(const uint8_t *Opcodes,
  245. unsigned &OI) {
  246. uint8_t Opcode = Opcodes[OI++ ^ 3];
  247. SW.startLine() << format("0x%02X ; pop ", Opcode);
  248. PrintRegisters((((1 << ((Opcode & 0x07) + 1)) - 1) << 8), "d");
  249. OS << '\n';
  250. }
  251. inline void OpcodeDecoder::Decode_11xxxyyy(const uint8_t *Opcodes,
  252. unsigned &OI) {
  253. uint8_t Opcode = Opcodes[OI++ ^ 3];
  254. SW.startLine() << format("0x%02X ; spare\n", Opcode);
  255. }
  256. inline void OpcodeDecoder::PrintGPR(uint16_t GPRMask) {
  257. static const char *GPRRegisterNames[16] = {
  258. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
  259. "fp", "ip", "sp", "lr", "pc"
  260. };
  261. OS << '{';
  262. bool Comma = false;
  263. for (unsigned RI = 0, RE = 17; RI < RE; ++RI) {
  264. if (GPRMask & (1 << RI)) {
  265. if (Comma)
  266. OS << ", ";
  267. OS << GPRRegisterNames[RI];
  268. Comma = true;
  269. }
  270. }
  271. OS << '}';
  272. }
  273. inline void OpcodeDecoder::PrintRegisters(uint32_t VFPMask, StringRef Prefix) {
  274. OS << '{';
  275. bool Comma = false;
  276. for (unsigned RI = 0, RE = 32; RI < RE; ++RI) {
  277. if (VFPMask & (1 << RI)) {
  278. if (Comma)
  279. OS << ", ";
  280. OS << Prefix << RI;
  281. Comma = true;
  282. }
  283. }
  284. OS << '}';
  285. }
  286. inline void OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset,
  287. size_t Length) {
  288. for (unsigned OCI = Offset; OCI < Length + Offset; ) {
  289. bool Decoded = false;
  290. for (const auto &RE : ring()) {
  291. if ((Opcodes[OCI ^ 3] & RE.Mask) == RE.Value) {
  292. (this->*RE.Routine)(Opcodes, OCI);
  293. Decoded = true;
  294. break;
  295. }
  296. }
  297. if (!Decoded)
  298. SW.startLine() << format("0x%02X ; reserved\n", Opcodes[OCI++ ^ 3]);
  299. }
  300. }
  301. template <typename ET>
  302. class PrinterContext {
  303. typedef typename ET::Sym Elf_Sym;
  304. typedef typename ET::Shdr Elf_Shdr;
  305. typedef typename ET::Rel Elf_Rel;
  306. typedef typename ET::Word Elf_Word;
  307. ScopedPrinter &SW;
  308. const object::ELFFile<ET> &ELF;
  309. StringRef FileName;
  310. const Elf_Shdr *Symtab;
  311. ArrayRef<Elf_Word> ShndxTable;
  312. static const size_t IndexTableEntrySize;
  313. static uint64_t PREL31(uint32_t Address, uint32_t Place) {
  314. uint64_t Location = Address & 0x7fffffff;
  315. if (Location & 0x40000000)
  316. Location |= (uint64_t) ~0x7fffffff;
  317. return Location + Place;
  318. }
  319. ErrorOr<StringRef> FunctionAtAddress(uint64_t Address,
  320. Optional<unsigned> SectionIndex) const;
  321. const Elf_Shdr *FindExceptionTable(unsigned IndexTableIndex,
  322. off_t IndexTableOffset) const;
  323. void PrintIndexTable(unsigned SectionIndex, const Elf_Shdr *IT) const;
  324. void PrintExceptionTable(const Elf_Shdr &EHT,
  325. uint64_t TableEntryOffset) const;
  326. void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
  327. public:
  328. PrinterContext(ScopedPrinter &SW, const object::ELFFile<ET> &ELF,
  329. StringRef FileName, const Elf_Shdr *Symtab)
  330. : SW(SW), ELF(ELF), FileName(FileName), Symtab(Symtab) {}
  331. void PrintUnwindInformation() const;
  332. };
  333. template <typename ET>
  334. const size_t PrinterContext<ET>::IndexTableEntrySize = 8;
  335. template <typename ET>
  336. ErrorOr<StringRef>
  337. PrinterContext<ET>::FunctionAtAddress(uint64_t Address,
  338. Optional<unsigned> SectionIndex) const {
  339. if (!Symtab)
  340. return inconvertibleErrorCode();
  341. auto StrTableOrErr = ELF.getStringTableForSymtab(*Symtab);
  342. if (!StrTableOrErr)
  343. reportError(StrTableOrErr.takeError(), FileName);
  344. StringRef StrTable = *StrTableOrErr;
  345. for (const Elf_Sym &Sym : unwrapOrError(FileName, ELF.symbols(Symtab))) {
  346. if (SectionIndex && *SectionIndex != Sym.st_shndx)
  347. continue;
  348. if (Sym.st_value == Address && Sym.getType() == ELF::STT_FUNC) {
  349. auto NameOrErr = Sym.getName(StrTable);
  350. if (!NameOrErr) {
  351. // TODO: Actually report errors helpfully.
  352. consumeError(NameOrErr.takeError());
  353. return inconvertibleErrorCode();
  354. }
  355. return *NameOrErr;
  356. }
  357. }
  358. return inconvertibleErrorCode();
  359. }
  360. template <typename ET>
  361. const typename ET::Shdr *
  362. PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
  363. off_t IndexTableOffset) const {
  364. /// Iterate through the sections, searching for the relocation section
  365. /// associated with the unwind index table section specified by
  366. /// IndexSectionIndex. Iterate the associated section searching for the
  367. /// relocation associated with the index table entry specified by
  368. /// IndexTableOffset. The symbol is the section symbol for the exception
  369. /// handling table. Use this symbol to recover the actual exception handling
  370. /// table.
  371. for (const Elf_Shdr &Sec : unwrapOrError(FileName, ELF.sections())) {
  372. if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex)
  373. continue;
  374. auto SymTabOrErr = ELF.getSection(Sec.sh_link);
  375. if (!SymTabOrErr)
  376. reportError(SymTabOrErr.takeError(), FileName);
  377. const Elf_Shdr *SymTab = *SymTabOrErr;
  378. for (const Elf_Rel &R : unwrapOrError(FileName, ELF.rels(Sec))) {
  379. if (R.r_offset != static_cast<unsigned>(IndexTableOffset))
  380. continue;
  381. typename ET::Rela RelA;
  382. RelA.r_offset = R.r_offset;
  383. RelA.r_info = R.r_info;
  384. RelA.r_addend = 0;
  385. const Elf_Sym *Symbol =
  386. unwrapOrError(FileName, ELF.getRelocationSymbol(RelA, SymTab));
  387. auto Ret = ELF.getSection(*Symbol, SymTab, ShndxTable);
  388. if (!Ret)
  389. report_fatal_error(errorToErrorCode(Ret.takeError()).message());
  390. return *Ret;
  391. }
  392. }
  393. return nullptr;
  394. }
  395. template <typename ET>
  396. static const typename ET::Shdr *
  397. findSectionContainingAddress(const object::ELFFile<ET> &Obj, StringRef FileName,
  398. uint64_t Address) {
  399. for (const typename ET::Shdr &Sec : unwrapOrError(FileName, Obj.sections()))
  400. if (Address >= Sec.sh_addr && Address < Sec.sh_addr + Sec.sh_size)
  401. return &Sec;
  402. return nullptr;
  403. }
  404. template <typename ET>
  405. void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr &EHT,
  406. uint64_t TableEntryOffset) const {
  407. // TODO: handle failure.
  408. Expected<ArrayRef<uint8_t>> Contents = ELF.getSectionContents(EHT);
  409. if (!Contents)
  410. return;
  411. /// ARM EHABI Section 6.2 - The generic model
  412. ///
  413. /// An exception-handling table entry for the generic model is laid out as:
  414. ///
  415. /// 3 3
  416. /// 1 0 0
  417. /// +-+------------------------------+
  418. /// |0| personality routine offset |
  419. /// +-+------------------------------+
  420. /// | personality routine data ... |
  421. ///
  422. ///
  423. /// ARM EHABI Section 6.3 - The ARM-defined compact model
  424. ///
  425. /// An exception-handling table entry for the compact model looks like:
  426. ///
  427. /// 3 3 2 2 2 2
  428. /// 1 0 8 7 4 3 0
  429. /// +-+---+----+-----------------------+
  430. /// |1| 0 | Ix | data for pers routine |
  431. /// +-+---+----+-----------------------+
  432. /// | more personality routine data |
  433. const support::ulittle32_t Word =
  434. *reinterpret_cast<const support::ulittle32_t *>(Contents->data() + TableEntryOffset);
  435. if (Word & 0x80000000) {
  436. SW.printString("Model", StringRef("Compact"));
  437. unsigned PersonalityIndex = (Word & 0x0f000000) >> 24;
  438. SW.printNumber("PersonalityIndex", PersonalityIndex);
  439. switch (PersonalityIndex) {
  440. case AEABI_UNWIND_CPP_PR0:
  441. PrintOpcodes(Contents->data() + TableEntryOffset, 3, 1);
  442. break;
  443. case AEABI_UNWIND_CPP_PR1:
  444. case AEABI_UNWIND_CPP_PR2:
  445. unsigned AdditionalWords = (Word & 0x00ff0000) >> 16;
  446. PrintOpcodes(Contents->data() + TableEntryOffset, 2 + 4 * AdditionalWords,
  447. 2);
  448. break;
  449. }
  450. } else {
  451. SW.printString("Model", StringRef("Generic"));
  452. const bool IsRelocatable = ELF.getHeader().e_type == ELF::ET_REL;
  453. uint64_t Address = IsRelocatable
  454. ? PREL31(Word, EHT.sh_addr)
  455. : PREL31(Word, EHT.sh_addr + TableEntryOffset);
  456. SW.printHex("PersonalityRoutineAddress", Address);
  457. Optional<unsigned> SecIndex =
  458. IsRelocatable ? Optional<unsigned>(EHT.sh_link) : None;
  459. if (ErrorOr<StringRef> Name = FunctionAtAddress(Address, SecIndex))
  460. SW.printString("PersonalityRoutineName", *Name);
  461. }
  462. }
  463. template <typename ET>
  464. void PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry,
  465. size_t Length, off_t Offset) const {
  466. ListScope OCC(SW, "Opcodes");
  467. OpcodeDecoder(OCC.W).Decode(Entry, Offset, Length);
  468. }
  469. template <typename ET>
  470. void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
  471. const Elf_Shdr *IT) const {
  472. // TODO: handle failure.
  473. Expected<ArrayRef<uint8_t>> Contents = ELF.getSectionContents(*IT);
  474. if (!Contents)
  475. return;
  476. /// ARM EHABI Section 5 - Index Table Entries
  477. /// * The first word contains a PREL31 offset to the start of a function with
  478. /// bit 31 clear
  479. /// * The second word contains one of:
  480. /// - The PREL31 offset of the start of the table entry for the function,
  481. /// with bit 31 clear
  482. /// - The exception-handling table entry itself with bit 31 set
  483. /// - The special bit pattern EXIDX_CANTUNWIND, indicating that associated
  484. /// frames cannot be unwound
  485. const support::ulittle32_t *Data =
  486. reinterpret_cast<const support::ulittle32_t *>(Contents->data());
  487. const unsigned Entries = IT->sh_size / IndexTableEntrySize;
  488. const bool IsRelocatable = ELF.getHeader().e_type == ELF::ET_REL;
  489. ListScope E(SW, "Entries");
  490. for (unsigned Entry = 0; Entry < Entries; ++Entry) {
  491. DictScope E(SW, "Entry");
  492. const support::ulittle32_t Word0 =
  493. Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 0];
  494. const support::ulittle32_t Word1 =
  495. Data[Entry * (IndexTableEntrySize / sizeof(*Data)) + 1];
  496. if (Word0 & 0x80000000) {
  497. errs() << "corrupt unwind data in section " << SectionIndex << "\n";
  498. continue;
  499. }
  500. // FIXME: For a relocatable object ideally we might want to:
  501. // 1) Find a relocation for the offset of Word0.
  502. // 2) Verify this relocation is of an expected type (R_ARM_PREL31) and
  503. // verify the symbol index.
  504. // 3) Resolve the relocation using it's symbol value, addend etc.
  505. // Currently the code assumes that Word0 contains an addend of a
  506. // R_ARM_PREL31 REL relocation that references a section symbol. RELA
  507. // relocations are not supported and it works because addresses of sections
  508. // are nulls in relocatable objects.
  509. //
  510. // For a non-relocatable object, Word0 contains a place-relative signed
  511. // offset to the referenced entity.
  512. const uint64_t Address =
  513. IsRelocatable
  514. ? PREL31(Word0, IT->sh_addr)
  515. : PREL31(Word0, IT->sh_addr + Entry * IndexTableEntrySize);
  516. SW.printHex("FunctionAddress", Address);
  517. // In a relocatable output we might have many .ARM.exidx sections linked to
  518. // their code sections via the sh_link field. For a non-relocatable ELF file
  519. // the sh_link field is not reliable, because we have one .ARM.exidx section
  520. // normally, but might have many code sections.
  521. Optional<unsigned> SecIndex =
  522. IsRelocatable ? Optional<unsigned>(IT->sh_link) : None;
  523. if (ErrorOr<StringRef> Name = FunctionAtAddress(Address, SecIndex))
  524. SW.printString("FunctionName", *Name);
  525. if (Word1 == EXIDX_CANTUNWIND) {
  526. SW.printString("Model", StringRef("CantUnwind"));
  527. continue;
  528. }
  529. if (Word1 & 0x80000000) {
  530. SW.printString("Model", StringRef("Compact (Inline)"));
  531. unsigned PersonalityIndex = (Word1 & 0x0f000000) >> 24;
  532. SW.printNumber("PersonalityIndex", PersonalityIndex);
  533. PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1);
  534. } else {
  535. const Elf_Shdr *EHT;
  536. uint64_t TableEntryAddress;
  537. if (IsRelocatable) {
  538. TableEntryAddress = PREL31(Word1, IT->sh_addr);
  539. EHT = FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
  540. } else {
  541. TableEntryAddress =
  542. PREL31(Word1, IT->sh_addr + Entry * IndexTableEntrySize + 4);
  543. EHT = findSectionContainingAddress(ELF, FileName, TableEntryAddress);
  544. }
  545. if (EHT)
  546. // TODO: handle failure.
  547. if (Expected<StringRef> Name = ELF.getSectionName(*EHT))
  548. SW.printString("ExceptionHandlingTable", *Name);
  549. SW.printHex(IsRelocatable ? "TableEntryOffset" : "TableEntryAddress",
  550. TableEntryAddress);
  551. if (EHT) {
  552. if (IsRelocatable)
  553. PrintExceptionTable(*EHT, TableEntryAddress);
  554. else
  555. PrintExceptionTable(*EHT, TableEntryAddress - EHT->sh_addr);
  556. }
  557. }
  558. }
  559. }
  560. template <typename ET>
  561. void PrinterContext<ET>::PrintUnwindInformation() const {
  562. DictScope UI(SW, "UnwindInformation");
  563. int SectionIndex = 0;
  564. for (const Elf_Shdr &Sec : unwrapOrError(FileName, ELF.sections())) {
  565. if (Sec.sh_type == ELF::SHT_ARM_EXIDX) {
  566. DictScope UIT(SW, "UnwindIndexTable");
  567. SW.printNumber("SectionIndex", SectionIndex);
  568. // TODO: handle failure.
  569. if (Expected<StringRef> SectionName = ELF.getSectionName(Sec))
  570. SW.printString("SectionName", *SectionName);
  571. SW.printHex("SectionOffset", Sec.sh_offset);
  572. PrintIndexTable(SectionIndex, &Sec);
  573. }
  574. ++SectionIndex;
  575. }
  576. }
  577. }
  578. }
  579. }
  580. #endif