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