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