1 //===- DWARFContext.cpp ---------------------------------------------------===// 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 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/BinaryFormat/Dwarf.h" 17 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" 18 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 19 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 20 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h" 21 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 22 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" 23 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 24 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 25 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 26 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 27 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" 28 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 29 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" 30 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 31 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 32 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" 33 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 34 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 35 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" 36 #include "llvm/MC/MCRegisterInfo.h" 37 #include "llvm/Object/Decompressor.h" 38 #include "llvm/Object/MachO.h" 39 #include "llvm/Object/ObjectFile.h" 40 #include "llvm/Object/RelocVisitor.h" 41 #include "llvm/Support/Casting.h" 42 #include "llvm/Support/DataExtractor.h" 43 #include "llvm/Support/Error.h" 44 #include "llvm/Support/Format.h" 45 #include "llvm/Support/MemoryBuffer.h" 46 #include "llvm/Support/Path.h" 47 #include "llvm/Support/TargetRegistry.h" 48 #include "llvm/Support/WithColor.h" 49 #include "llvm/Support/raw_ostream.h" 50 #include <algorithm> 51 #include <cstdint> 52 #include <deque> 53 #include <map> 54 #include <string> 55 #include <utility> 56 #include <vector> 57 58 using namespace llvm; 59 using namespace dwarf; 60 using namespace object; 61 62 #define DEBUG_TYPE "dwarf" 63 64 using DWARFLineTable = DWARFDebugLine::LineTable; 65 using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; 66 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; 67 68 DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj, 69 std::string DWPName) 70 : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {} 71 72 DWARFContext::~DWARFContext() = default; 73 74 /// Dump the UUID load command. 75 static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) { 76 auto *MachO = dyn_cast<MachOObjectFile>(&Obj); 77 if (!MachO) 78 return; 79 for (auto LC : MachO->load_commands()) { 80 raw_ostream::uuid_t UUID; 81 if (LC.C.cmd == MachO::LC_UUID) { 82 if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) { 83 OS << "error: UUID load command is too short.\n"; 84 return; 85 } 86 OS << "UUID: "; 87 memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID)); 88 OS.write_uuid(UUID); 89 Triple T = MachO->getArchTriple(); 90 OS << " (" << T.getArchName() << ')'; 91 OS << ' ' << MachO->getFileName() << '\n'; 92 } 93 } 94 } 95 96 using ContributionCollection = 97 std::vector<Optional<StrOffsetsContributionDescriptor>>; 98 99 // Collect all the contributions to the string offsets table from all units, 100 // sort them by their starting offsets and remove duplicates. 101 static ContributionCollection 102 collectContributionData(DWARFContext::unit_iterator_range Units) { 103 ContributionCollection Contributions; 104 for (const auto &U : Units) 105 Contributions.push_back(U->getStringOffsetsTableContribution()); 106 // Sort the contributions so that any invalid ones are placed at 107 // the start of the contributions vector. This way they are reported 108 // first. 109 llvm::sort(Contributions, 110 [](const Optional<StrOffsetsContributionDescriptor> &L, 111 const Optional<StrOffsetsContributionDescriptor> &R) { 112 if (L && R) 113 return L->Base < R->Base; 114 return R.hasValue(); 115 }); 116 117 // Uniquify contributions, as it is possible that units (specifically 118 // type units in dwo or dwp files) share contributions. We don't want 119 // to report them more than once. 120 Contributions.erase( 121 std::unique(Contributions.begin(), Contributions.end(), 122 [](const Optional<StrOffsetsContributionDescriptor> &L, 123 const Optional<StrOffsetsContributionDescriptor> &R) { 124 if (L && R) 125 return L->Base == R->Base && L->Size == R->Size; 126 return false; 127 }), 128 Contributions.end()); 129 return Contributions; 130 } 131 132 static void dumpDWARFv5StringOffsetsSection( 133 raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, 134 const DWARFSection &StringOffsetsSection, StringRef StringSection, 135 DWARFContext::unit_iterator_range Units, bool LittleEndian) { 136 auto Contributions = collectContributionData(Units); 137 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); 138 DataExtractor StrData(StringSection, LittleEndian, 0); 139 uint64_t SectionSize = StringOffsetsSection.Data.size(); 140 uint32_t Offset = 0; 141 for (auto &Contribution : Contributions) { 142 // Report an ill-formed contribution. 143 if (!Contribution) { 144 OS << "error: invalid contribution to string offsets table in section ." 145 << SectionName << ".\n"; 146 return; 147 } 148 149 dwarf::DwarfFormat Format = Contribution->getFormat(); 150 uint16_t Version = Contribution->getVersion(); 151 uint64_t ContributionHeader = Contribution->Base; 152 // In DWARF v5 there is a contribution header that immediately precedes 153 // the string offsets base (the location we have previously retrieved from 154 // the CU DIE's DW_AT_str_offsets attribute). The header is located either 155 // 8 or 16 bytes before the base, depending on the contribution's format. 156 if (Version >= 5) 157 ContributionHeader -= Format == DWARF32 ? 8 : 16; 158 159 // Detect overlapping contributions. 160 if (Offset > ContributionHeader) { 161 OS << "error: overlapping contributions to string offsets table in " 162 "section ." 163 << SectionName << ".\n"; 164 return; 165 } 166 // Report a gap in the table. 167 if (Offset < ContributionHeader) { 168 OS << format("0x%8.8x: Gap, length = ", Offset); 169 OS << (ContributionHeader - Offset) << "\n"; 170 } 171 OS << format("0x%8.8x: ", (uint32_t)ContributionHeader); 172 // In DWARF v5 the contribution size in the descriptor does not equal 173 // the originally encoded length (it does not contain the length of the 174 // version field and the padding, a total of 4 bytes). Add them back in 175 // for reporting. 176 OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4)) 177 << ", Format = " << (Format == DWARF32 ? "DWARF32" : "DWARF64") 178 << ", Version = " << Version << "\n"; 179 180 Offset = Contribution->Base; 181 unsigned EntrySize = Contribution->getDwarfOffsetByteSize(); 182 while (Offset - Contribution->Base < Contribution->Size) { 183 OS << format("0x%8.8x: ", Offset); 184 // FIXME: We can only extract strings if the offset fits in 32 bits. 185 uint64_t StringOffset = 186 StrOffsetExt.getRelocatedValue(EntrySize, &Offset); 187 // Extract the string if we can and display it. Otherwise just report 188 // the offset. 189 if (StringOffset <= std::numeric_limits<uint32_t>::max()) { 190 uint32_t StringOffset32 = (uint32_t)StringOffset; 191 OS << format("%8.8x ", StringOffset32); 192 const char *S = StrData.getCStr(&StringOffset32); 193 if (S) 194 OS << format("\"%s\"", S); 195 } else 196 OS << format("%16.16" PRIx64 " ", StringOffset); 197 OS << "\n"; 198 } 199 } 200 // Report a gap at the end of the table. 201 if (Offset < SectionSize) { 202 OS << format("0x%8.8x: Gap, length = ", Offset); 203 OS << (SectionSize - Offset) << "\n"; 204 } 205 } 206 207 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted 208 // string offsets section, where each compile or type unit contributes a 209 // number of entries (string offsets), with each contribution preceded by 210 // a header containing size and version number. Alternatively, it may be a 211 // monolithic series of string offsets, as generated by the pre-DWARF v5 212 // implementation of split DWARF. 213 static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, 214 const DWARFObject &Obj, 215 const DWARFSection &StringOffsetsSection, 216 StringRef StringSection, 217 DWARFContext::unit_iterator_range Units, 218 bool LittleEndian, unsigned MaxVersion) { 219 // If we have at least one (compile or type) unit with DWARF v5 or greater, 220 // we assume that the section is formatted like a DWARF v5 string offsets 221 // section. 222 if (MaxVersion >= 5) 223 dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection, 224 StringSection, Units, LittleEndian); 225 else { 226 DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0); 227 uint32_t offset = 0; 228 uint64_t size = StringOffsetsSection.Data.size(); 229 // Ensure that size is a multiple of the size of an entry. 230 if (size & ((uint64_t)(sizeof(uint32_t) - 1))) { 231 OS << "error: size of ." << SectionName << " is not a multiple of " 232 << sizeof(uint32_t) << ".\n"; 233 size &= -(uint64_t)sizeof(uint32_t); 234 } 235 DataExtractor StrData(StringSection, LittleEndian, 0); 236 while (offset < size) { 237 OS << format("0x%8.8x: ", offset); 238 uint32_t StringOffset = strOffsetExt.getU32(&offset); 239 OS << format("%8.8x ", StringOffset); 240 const char *S = StrData.getCStr(&StringOffset); 241 if (S) 242 OS << format("\"%s\"", S); 243 OS << "\n"; 244 } 245 } 246 } 247 248 // Dump the .debug_addr section. 249 static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, 250 DIDumpOptions DumpOpts, uint16_t Version, 251 uint8_t AddrSize) { 252 uint32_t Offset = 0; 253 while (AddrData.isValidOffset(Offset)) { 254 DWARFDebugAddrTable AddrTable; 255 uint32_t TableOffset = Offset; 256 if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize, 257 DWARFContext::dumpWarning)) { 258 WithColor::error() << toString(std::move(Err)) << '\n'; 259 // Keep going after an error, if we can, assuming that the length field 260 // could be read. If it couldn't, stop reading the section. 261 if (!AddrTable.hasValidLength()) 262 break; 263 uint64_t Length = AddrTable.getLength(); 264 Offset = TableOffset + Length; 265 } else { 266 AddrTable.dump(OS, DumpOpts); 267 } 268 } 269 } 270 271 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). 272 static void 273 dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, 274 llvm::function_ref<Optional<SectionedAddress>(uint32_t)> 275 LookupPooledAddress, 276 DIDumpOptions DumpOpts) { 277 uint32_t Offset = 0; 278 while (rnglistData.isValidOffset(Offset)) { 279 llvm::DWARFDebugRnglistTable Rnglists; 280 uint32_t TableOffset = Offset; 281 if (Error Err = Rnglists.extract(rnglistData, &Offset)) { 282 WithColor::error() << toString(std::move(Err)) << '\n'; 283 uint64_t Length = Rnglists.length(); 284 // Keep going after an error, if we can, assuming that the length field 285 // could be read. If it couldn't, stop reading the section. 286 if (Length == 0) 287 break; 288 Offset = TableOffset + Length; 289 } else { 290 Rnglists.dump(OS, LookupPooledAddress, DumpOpts); 291 } 292 } 293 } 294 295 static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, 296 DWARFDataExtractor Data, 297 const MCRegisterInfo *MRI, 298 Optional<uint64_t> DumpOffset) { 299 uint32_t Offset = 0; 300 DWARFDebugLoclists Loclists; 301 302 DWARFListTableHeader Header(".debug_loclists", "locations"); 303 if (Error E = Header.extract(Data, &Offset)) { 304 WithColor::error() << toString(std::move(E)) << '\n'; 305 return; 306 } 307 308 Header.dump(OS, DumpOpts); 309 DataExtractor LocData(Data.getData().drop_front(Offset), 310 Data.isLittleEndian(), Header.getAddrSize()); 311 312 Loclists.parse(LocData, Header.getVersion()); 313 Loclists.dump(OS, 0, MRI, DumpOffset); 314 } 315 316 void DWARFContext::dump( 317 raw_ostream &OS, DIDumpOptions DumpOpts, 318 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { 319 320 uint64_t DumpType = DumpOpts.DumpType; 321 322 StringRef Extension = sys::path::extension(DObj->getFileName()); 323 bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp"); 324 325 // Print UUID header. 326 const auto *ObjFile = DObj->getFile(); 327 if (DumpType & DIDT_UUID) 328 dumpUUID(OS, *ObjFile); 329 330 // Print a header for each explicitly-requested section. 331 // Otherwise just print one for non-empty sections. 332 // Only print empty .dwo section headers when dumping a .dwo file. 333 bool Explicit = DumpType != DIDT_All && !IsDWO; 334 bool ExplicitDWO = Explicit && IsDWO; 335 auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID, 336 StringRef Section) -> Optional<uint64_t> * { 337 unsigned Mask = 1U << ID; 338 bool Should = (DumpType & Mask) && (Explicit || !Section.empty()); 339 if (!Should) 340 return nullptr; 341 OS << "\n" << Name << " contents:\n"; 342 return &DumpOffsets[ID]; 343 }; 344 345 // Dump individual sections. 346 if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev, 347 DObj->getAbbrevSection())) 348 getDebugAbbrev()->dump(OS); 349 if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev, 350 DObj->getAbbrevDWOSection())) 351 getDebugAbbrevDWO()->dump(OS); 352 353 auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) { 354 OS << '\n' << Name << " contents:\n"; 355 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo]) 356 for (const auto &U : Units) 357 U->getDIEForOffset(DumpOffset.getValue()) 358 .dump(OS, 0, DumpOpts.noImplicitRecursion()); 359 else 360 for (const auto &U : Units) 361 U->dump(OS, DumpOpts); 362 }; 363 if ((DumpType & DIDT_DebugInfo)) { 364 if (Explicit || getNumCompileUnits()) 365 dumpDebugInfo(".debug_info", info_section_units()); 366 if (ExplicitDWO || getNumDWOCompileUnits()) 367 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units()); 368 } 369 370 auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) { 371 OS << '\n' << Name << " contents:\n"; 372 for (const auto &U : Units) 373 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes]) 374 U->getDIEForOffset(*DumpOffset) 375 .dump(OS, 0, DumpOpts.noImplicitRecursion()); 376 else 377 U->dump(OS, DumpOpts); 378 }; 379 if ((DumpType & DIDT_DebugTypes)) { 380 if (Explicit || getNumTypeUnits()) 381 dumpDebugType(".debug_types", types_section_units()); 382 if (ExplicitDWO || getNumDWOTypeUnits()) 383 dumpDebugType(".debug_types.dwo", dwo_types_section_units()); 384 } 385 386 if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, 387 DObj->getLocSection().Data)) { 388 getDebugLoc()->dump(OS, getRegisterInfo(), *Off); 389 } 390 if (const auto *Off = 391 shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, 392 DObj->getLoclistsSection().Data)) { 393 DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), 394 0); 395 dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off); 396 } 397 if (const auto *Off = 398 shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, 399 DObj->getLocDWOSection().Data)) { 400 getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off); 401 } 402 403 if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, 404 DObj->getDebugFrameSection())) 405 getDebugFrame()->dump(OS, getRegisterInfo(), *Off); 406 407 if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, 408 DObj->getEHFrameSection())) 409 getEHFrame()->dump(OS, getRegisterInfo(), *Off); 410 411 if (DumpType & DIDT_DebugMacro) { 412 if (Explicit || !getDebugMacro()->empty()) { 413 OS << "\n.debug_macinfo contents:\n"; 414 getDebugMacro()->dump(OS); 415 } 416 } 417 418 if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges, 419 DObj->getARangeSection())) { 420 uint32_t offset = 0; 421 DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0); 422 DWARFDebugArangeSet set; 423 while (set.extract(arangesData, &offset)) 424 set.dump(OS); 425 } 426 427 auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser, 428 DIDumpOptions DumpOpts, 429 Optional<uint64_t> DumpOffset) { 430 while (!Parser.done()) { 431 if (DumpOffset && Parser.getOffset() != *DumpOffset) { 432 Parser.skip(dumpWarning); 433 continue; 434 } 435 OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n"; 436 if (DumpOpts.Verbose) { 437 Parser.parseNext(dumpWarning, dumpWarning, &OS); 438 } else { 439 DWARFDebugLine::LineTable LineTable = 440 Parser.parseNext(dumpWarning, dumpWarning); 441 LineTable.dump(OS, DumpOpts); 442 } 443 } 444 }; 445 446 if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine, 447 DObj->getLineSection().Data)) { 448 DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(), 449 0); 450 DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(), 451 type_units()); 452 DumpLineSection(Parser, DumpOpts, *Off); 453 } 454 455 if (const auto *Off = 456 shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine, 457 DObj->getLineDWOSection().Data)) { 458 DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(), 459 isLittleEndian(), 0); 460 DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(), 461 dwo_type_units()); 462 DumpLineSection(Parser, DumpOpts, *Off); 463 } 464 465 if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex, 466 DObj->getCUIndexSection())) { 467 getCUIndex().dump(OS); 468 } 469 470 if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex, 471 DObj->getTUIndexSection())) { 472 getTUIndex().dump(OS); 473 } 474 475 if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr, 476 DObj->getStringSection())) { 477 DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0); 478 uint32_t offset = 0; 479 uint32_t strOffset = 0; 480 while (const char *s = strData.getCStr(&offset)) { 481 OS << format("0x%8.8x: \"%s\"\n", strOffset, s); 482 strOffset = offset; 483 } 484 } 485 if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr, 486 DObj->getStringDWOSection())) { 487 DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0); 488 uint32_t offset = 0; 489 uint32_t strDWOOffset = 0; 490 while (const char *s = strDWOData.getCStr(&offset)) { 491 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); 492 strDWOOffset = offset; 493 } 494 } 495 if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr, 496 DObj->getLineStringSection())) { 497 DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0); 498 uint32_t offset = 0; 499 uint32_t strOffset = 0; 500 while (const char *s = strData.getCStr(&offset)) { 501 OS << format("0x%8.8x: \"", strOffset); 502 OS.write_escaped(s); 503 OS << "\"\n"; 504 strOffset = offset; 505 } 506 } 507 508 if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr, 509 DObj->getAddrSection().Data)) { 510 DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(), 511 isLittleEndian(), 0); 512 dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize()); 513 } 514 515 if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges, 516 DObj->getRangeSection().Data)) { 517 uint8_t savedAddressByteSize = getCUAddrSize(); 518 DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(), 519 isLittleEndian(), savedAddressByteSize); 520 uint32_t offset = 0; 521 DWARFDebugRangeList rangeList; 522 while (rangesData.isValidOffset(offset)) { 523 if (Error E = rangeList.extract(rangesData, &offset)) { 524 WithColor::error() << toString(std::move(E)) << '\n'; 525 break; 526 } 527 rangeList.dump(OS); 528 } 529 } 530 531 auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> { 532 const auto &CUs = compile_units(); 533 auto I = CUs.begin(); 534 if (I == CUs.end()) 535 return None; 536 return (*I)->getAddrOffsetSectionItem(Index); 537 }; 538 539 if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists, 540 DObj->getRnglistsSection().Data)) { 541 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(), 542 isLittleEndian(), 0); 543 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts); 544 } 545 546 if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists, 547 DObj->getRnglistsDWOSection().Data)) { 548 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(), 549 isLittleEndian(), 0); 550 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts); 551 } 552 553 if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames, 554 DObj->getPubNamesSection().Data)) 555 DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false) 556 .dump(OS); 557 558 if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes, 559 DObj->getPubTypesSection().Data)) 560 DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false) 561 .dump(OS); 562 563 if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames, 564 DObj->getGnuPubNamesSection().Data)) 565 DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(), 566 true /* GnuStyle */) 567 .dump(OS); 568 569 if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes, 570 DObj->getGnuPubTypesSection().Data)) 571 DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(), 572 true /* GnuStyle */) 573 .dump(OS); 574 575 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets, 576 DObj->getStringOffsetSection().Data)) 577 dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj, 578 DObj->getStringOffsetSection(), 579 DObj->getStringSection(), normal_units(), 580 isLittleEndian(), getMaxVersion()); 581 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets, 582 DObj->getStringOffsetDWOSection().Data)) 583 dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj, 584 DObj->getStringOffsetDWOSection(), 585 DObj->getStringDWOSection(), dwo_units(), 586 isLittleEndian(), getMaxDWOVersion()); 587 588 if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex, 589 DObj->getGdbIndexSection())) { 590 getGdbIndex().dump(OS); 591 } 592 593 if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames, 594 DObj->getAppleNamesSection().Data)) 595 getAppleNames().dump(OS); 596 597 if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes, 598 DObj->getAppleTypesSection().Data)) 599 getAppleTypes().dump(OS); 600 601 if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces, 602 DObj->getAppleNamespacesSection().Data)) 603 getAppleNamespaces().dump(OS); 604 605 if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC, 606 DObj->getAppleObjCSection().Data)) 607 getAppleObjC().dump(OS); 608 if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames, 609 DObj->getDebugNamesSection().Data)) 610 getDebugNames().dump(OS); 611 } 612 613 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { 614 parseDWOUnits(LazyParse); 615 616 if (const auto &CUI = getCUIndex()) { 617 if (const auto *R = CUI.getFromHash(Hash)) 618 return dyn_cast_or_null<DWARFCompileUnit>( 619 DWOUnits.getUnitForIndexEntry(*R)); 620 return nullptr; 621 } 622 623 // If there's no index, just search through the CUs in the DWO - there's 624 // probably only one unless this is something like LTO - though an in-process 625 // built/cached lookup table could be used in that case to improve repeated 626 // lookups of different CUs in the DWO. 627 for (const auto &DWOCU : dwo_compile_units()) { 628 // Might not have parsed DWO ID yet. 629 if (!DWOCU->getDWOId()) { 630 if (Optional<uint64_t> DWOId = 631 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id))) 632 DWOCU->setDWOId(*DWOId); 633 else 634 // No DWO ID? 635 continue; 636 } 637 if (DWOCU->getDWOId() == Hash) 638 return dyn_cast<DWARFCompileUnit>(DWOCU.get()); 639 } 640 return nullptr; 641 } 642 643 DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) { 644 parseNormalUnits(); 645 if (auto *CU = NormalUnits.getUnitForOffset(Offset)) 646 return CU->getDIEForOffset(Offset); 647 return DWARFDie(); 648 } 649 650 bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) { 651 bool Success = true; 652 DWARFVerifier verifier(OS, *this, DumpOpts); 653 654 Success &= verifier.handleDebugAbbrev(); 655 if (DumpOpts.DumpType & DIDT_DebugInfo) 656 Success &= verifier.handleDebugInfo(); 657 if (DumpOpts.DumpType & DIDT_DebugLine) 658 Success &= verifier.handleDebugLine(); 659 Success &= verifier.handleAccelTables(); 660 return Success; 661 } 662 663 const DWARFUnitIndex &DWARFContext::getCUIndex() { 664 if (CUIndex) 665 return *CUIndex; 666 667 DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0); 668 669 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO); 670 CUIndex->parse(CUIndexData); 671 return *CUIndex; 672 } 673 674 const DWARFUnitIndex &DWARFContext::getTUIndex() { 675 if (TUIndex) 676 return *TUIndex; 677 678 DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); 679 680 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); 681 TUIndex->parse(TUIndexData); 682 return *TUIndex; 683 } 684 685 DWARFGdbIndex &DWARFContext::getGdbIndex() { 686 if (GdbIndex) 687 return *GdbIndex; 688 689 DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0); 690 GdbIndex = llvm::make_unique<DWARFGdbIndex>(); 691 GdbIndex->parse(GdbIndexData); 692 return *GdbIndex; 693 } 694 695 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { 696 if (Abbrev) 697 return Abbrev.get(); 698 699 DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0); 700 701 Abbrev.reset(new DWARFDebugAbbrev()); 702 Abbrev->extract(abbrData); 703 return Abbrev.get(); 704 } 705 706 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { 707 if (AbbrevDWO) 708 return AbbrevDWO.get(); 709 710 DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0); 711 AbbrevDWO.reset(new DWARFDebugAbbrev()); 712 AbbrevDWO->extract(abbrData); 713 return AbbrevDWO.get(); 714 } 715 716 const DWARFDebugLoc *DWARFContext::getDebugLoc() { 717 if (Loc) 718 return Loc.get(); 719 720 Loc.reset(new DWARFDebugLoc); 721 // Assume all units have the same address byte size. 722 if (getNumCompileUnits()) { 723 DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(), 724 getUnitAtIndex(0)->getAddressByteSize()); 725 Loc->parse(LocData); 726 } 727 return Loc.get(); 728 } 729 730 const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() { 731 if (LocDWO) 732 return LocDWO.get(); 733 734 LocDWO.reset(new DWARFDebugLoclists()); 735 // Assume all compile units have the same address byte size. 736 // FIXME: We don't need AddressSize for split DWARF since relocatable 737 // addresses cannot appear there. At the moment DWARFExpression requires it. 738 DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4); 739 // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and 740 // that means we are parsing the new style .debug_loc (pre-standatized version 741 // of the .debug_loclists). 742 LocDWO->parse(LocData, 4 /* Version */); 743 return LocDWO.get(); 744 } 745 746 const DWARFDebugAranges *DWARFContext::getDebugAranges() { 747 if (Aranges) 748 return Aranges.get(); 749 750 Aranges.reset(new DWARFDebugAranges()); 751 Aranges->generate(this); 752 return Aranges.get(); 753 } 754 755 const DWARFDebugFrame *DWARFContext::getDebugFrame() { 756 if (DebugFrame) 757 return DebugFrame.get(); 758 759 // There's a "bug" in the DWARFv3 standard with respect to the target address 760 // size within debug frame sections. While DWARF is supposed to be independent 761 // of its container, FDEs have fields with size being "target address size", 762 // which isn't specified in DWARF in general. It's only specified for CUs, but 763 // .eh_frame can appear without a .debug_info section. Follow the example of 764 // other tools (libdwarf) and extract this from the container (ObjectFile 765 // provides this information). This problem is fixed in DWARFv4 766 // See this dwarf-discuss discussion for more details: 767 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html 768 DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(), 769 isLittleEndian(), DObj->getAddressSize()); 770 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */)); 771 DebugFrame->parse(debugFrameData); 772 return DebugFrame.get(); 773 } 774 775 const DWARFDebugFrame *DWARFContext::getEHFrame() { 776 if (EHFrame) 777 return EHFrame.get(); 778 779 DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(), 780 DObj->getAddressSize()); 781 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */)); 782 DebugFrame->parse(debugFrameData); 783 return DebugFrame.get(); 784 } 785 786 const DWARFDebugMacro *DWARFContext::getDebugMacro() { 787 if (Macro) 788 return Macro.get(); 789 790 DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0); 791 Macro.reset(new DWARFDebugMacro()); 792 Macro->parse(MacinfoData); 793 return Macro.get(); 794 } 795 796 template <typename T> 797 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj, 798 const DWARFSection &Section, StringRef StringSection, 799 bool IsLittleEndian) { 800 if (Cache) 801 return *Cache; 802 DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0); 803 DataExtractor StrData(StringSection, IsLittleEndian, 0); 804 Cache.reset(new T(AccelSection, StrData)); 805 if (Error E = Cache->extract()) 806 llvm::consumeError(std::move(E)); 807 return *Cache; 808 } 809 810 const DWARFDebugNames &DWARFContext::getDebugNames() { 811 return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(), 812 DObj->getStringSection(), isLittleEndian()); 813 } 814 815 const AppleAcceleratorTable &DWARFContext::getAppleNames() { 816 return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(), 817 DObj->getStringSection(), isLittleEndian()); 818 } 819 820 const AppleAcceleratorTable &DWARFContext::getAppleTypes() { 821 return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(), 822 DObj->getStringSection(), isLittleEndian()); 823 } 824 825 const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() { 826 return getAccelTable(AppleNamespaces, *DObj, 827 DObj->getAppleNamespacesSection(), 828 DObj->getStringSection(), isLittleEndian()); 829 } 830 831 const AppleAcceleratorTable &DWARFContext::getAppleObjC() { 832 return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(), 833 DObj->getStringSection(), isLittleEndian()); 834 } 835 836 const DWARFDebugLine::LineTable * 837 DWARFContext::getLineTableForUnit(DWARFUnit *U) { 838 Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable = 839 getLineTableForUnit(U, dumpWarning); 840 if (!ExpectedLineTable) { 841 dumpWarning(ExpectedLineTable.takeError()); 842 return nullptr; 843 } 844 return *ExpectedLineTable; 845 } 846 847 Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit( 848 DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) { 849 if (!Line) 850 Line.reset(new DWARFDebugLine); 851 852 auto UnitDIE = U->getUnitDIE(); 853 if (!UnitDIE) 854 return nullptr; 855 856 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list)); 857 if (!Offset) 858 return nullptr; // No line table for this compile unit. 859 860 uint32_t stmtOffset = *Offset + U->getLineTableOffset(); 861 // See if the line table is cached. 862 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) 863 return lt; 864 865 // Make sure the offset is good before we try to parse. 866 if (stmtOffset >= U->getLineSection().Data.size()) 867 return nullptr; 868 869 // We have to parse it first. 870 DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(), 871 U->getAddressByteSize()); 872 return Line->getOrParseLineTable(lineData, stmtOffset, *this, U, 873 RecoverableErrorCallback); 874 } 875 876 void DWARFContext::parseNormalUnits() { 877 if (!NormalUnits.empty()) 878 return; 879 DObj->forEachInfoSections([&](const DWARFSection &S) { 880 NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO); 881 }); 882 NormalUnits.finishedInfoUnits(); 883 DObj->forEachTypesSections([&](const DWARFSection &S) { 884 NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES); 885 }); 886 } 887 888 void DWARFContext::parseDWOUnits(bool Lazy) { 889 if (!DWOUnits.empty()) 890 return; 891 DObj->forEachInfoDWOSections([&](const DWARFSection &S) { 892 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy); 893 }); 894 DWOUnits.finishedInfoUnits(); 895 DObj->forEachTypesDWOSections([&](const DWARFSection &S) { 896 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy); 897 }); 898 } 899 900 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { 901 parseNormalUnits(); 902 return dyn_cast_or_null<DWARFCompileUnit>( 903 NormalUnits.getUnitForOffset(Offset)); 904 } 905 906 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { 907 // First, get the offset of the compile unit. 908 uint32_t CUOffset = getDebugAranges()->findAddress(Address); 909 // Retrieve the compile unit. 910 return getCompileUnitForOffset(CUOffset); 911 } 912 913 DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) { 914 DIEsForAddress Result; 915 916 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 917 if (!CU) 918 return Result; 919 920 Result.CompileUnit = CU; 921 Result.FunctionDIE = CU->getSubroutineForAddress(Address); 922 923 std::vector<DWARFDie> Worklist; 924 Worklist.push_back(Result.FunctionDIE); 925 while (!Worklist.empty()) { 926 DWARFDie DIE = Worklist.back(); 927 Worklist.pop_back(); 928 929 if (DIE.getTag() == DW_TAG_lexical_block && 930 DIE.addressRangeContainsAddress(Address)) { 931 Result.BlockDIE = DIE; 932 break; 933 } 934 935 for (auto Child : DIE) 936 Worklist.push_back(Child); 937 } 938 939 return Result; 940 } 941 942 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, 943 uint64_t Address, 944 FunctionNameKind Kind, 945 std::string &FunctionName, 946 uint32_t &StartLine) { 947 // The address may correspond to instruction in some inlined function, 948 // so we have to build the chain of inlined functions and take the 949 // name of the topmost function in it. 950 SmallVector<DWARFDie, 4> InlinedChain; 951 CU->getInlinedChainForAddress(Address, InlinedChain); 952 if (InlinedChain.empty()) 953 return false; 954 955 const DWARFDie &DIE = InlinedChain[0]; 956 bool FoundResult = false; 957 const char *Name = nullptr; 958 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) { 959 FunctionName = Name; 960 FoundResult = true; 961 } 962 if (auto DeclLineResult = DIE.getDeclLine()) { 963 StartLine = DeclLineResult; 964 FoundResult = true; 965 } 966 967 return FoundResult; 968 } 969 970 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, 971 DILineInfoSpecifier Spec) { 972 DILineInfo Result; 973 974 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 975 if (!CU) 976 return Result; 977 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, 978 Result.FunctionName, 979 Result.StartLine); 980 if (Spec.FLIKind != FileLineInfoKind::None) { 981 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) 982 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 983 Spec.FLIKind, Result); 984 } 985 return Result; 986 } 987 988 DILineInfoTable 989 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 990 DILineInfoSpecifier Spec) { 991 DILineInfoTable Lines; 992 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 993 if (!CU) 994 return Lines; 995 996 std::string FunctionName = "<invalid>"; 997 uint32_t StartLine = 0; 998 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName, 999 StartLine); 1000 1001 // If the Specifier says we don't need FileLineInfo, just 1002 // return the top-most function at the starting address. 1003 if (Spec.FLIKind == FileLineInfoKind::None) { 1004 DILineInfo Result; 1005 Result.FunctionName = FunctionName; 1006 Result.StartLine = StartLine; 1007 Lines.push_back(std::make_pair(Address, Result)); 1008 return Lines; 1009 } 1010 1011 const DWARFLineTable *LineTable = getLineTableForUnit(CU); 1012 1013 // Get the index of row we're looking for in the line table. 1014 std::vector<uint32_t> RowVector; 1015 if (!LineTable->lookupAddressRange(Address, Size, RowVector)) 1016 return Lines; 1017 1018 for (uint32_t RowIndex : RowVector) { 1019 // Take file number and line/column from the row. 1020 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; 1021 DILineInfo Result; 1022 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(), 1023 Spec.FLIKind, Result.FileName); 1024 Result.FunctionName = FunctionName; 1025 Result.Line = Row.Line; 1026 Result.Column = Row.Column; 1027 Result.StartLine = StartLine; 1028 Lines.push_back(std::make_pair(Row.Address, Result)); 1029 } 1030 1031 return Lines; 1032 } 1033 1034 DIInliningInfo 1035 DWARFContext::getInliningInfoForAddress(uint64_t Address, 1036 DILineInfoSpecifier Spec) { 1037 DIInliningInfo InliningInfo; 1038 1039 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 1040 if (!CU) 1041 return InliningInfo; 1042 1043 const DWARFLineTable *LineTable = nullptr; 1044 SmallVector<DWARFDie, 4> InlinedChain; 1045 CU->getInlinedChainForAddress(Address, InlinedChain); 1046 if (InlinedChain.size() == 0) { 1047 // If there is no DIE for address (e.g. it is in unavailable .dwo file), 1048 // try to at least get file/line info from symbol table. 1049 if (Spec.FLIKind != FileLineInfoKind::None) { 1050 DILineInfo Frame; 1051 LineTable = getLineTableForUnit(CU); 1052 if (LineTable && 1053 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 1054 Spec.FLIKind, Frame)) 1055 InliningInfo.addFrame(Frame); 1056 } 1057 return InliningInfo; 1058 } 1059 1060 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0; 1061 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) { 1062 DWARFDie &FunctionDIE = InlinedChain[i]; 1063 DILineInfo Frame; 1064 // Get function name if necessary. 1065 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind)) 1066 Frame.FunctionName = Name; 1067 if (auto DeclLineResult = FunctionDIE.getDeclLine()) 1068 Frame.StartLine = DeclLineResult; 1069 if (Spec.FLIKind != FileLineInfoKind::None) { 1070 if (i == 0) { 1071 // For the topmost frame, initialize the line table of this 1072 // compile unit and fetch file/line info from it. 1073 LineTable = getLineTableForUnit(CU); 1074 // For the topmost routine, get file/line info from line table. 1075 if (LineTable) 1076 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 1077 Spec.FLIKind, Frame); 1078 } else { 1079 // Otherwise, use call file, call line and call column from 1080 // previous DIE in inlined chain. 1081 if (LineTable) 1082 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(), 1083 Spec.FLIKind, Frame.FileName); 1084 Frame.Line = CallLine; 1085 Frame.Column = CallColumn; 1086 Frame.Discriminator = CallDiscriminator; 1087 } 1088 // Get call file/line/column of a current DIE. 1089 if (i + 1 < n) { 1090 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn, 1091 CallDiscriminator); 1092 } 1093 } 1094 InliningInfo.addFrame(Frame); 1095 } 1096 return InliningInfo; 1097 } 1098 1099 std::shared_ptr<DWARFContext> 1100 DWARFContext::getDWOContext(StringRef AbsolutePath) { 1101 if (auto S = DWP.lock()) { 1102 DWARFContext *Ctxt = S->Context.get(); 1103 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1104 } 1105 1106 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath]; 1107 1108 if (auto S = Entry->lock()) { 1109 DWARFContext *Ctxt = S->Context.get(); 1110 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1111 } 1112 1113 Expected<OwningBinary<ObjectFile>> Obj = [&] { 1114 if (!CheckedForDWP) { 1115 SmallString<128> DWPName; 1116 auto Obj = object::ObjectFile::createObjectFile( 1117 this->DWPName.empty() 1118 ? (DObj->getFileName() + ".dwp").toStringRef(DWPName) 1119 : StringRef(this->DWPName)); 1120 if (Obj) { 1121 Entry = &DWP; 1122 return Obj; 1123 } else { 1124 CheckedForDWP = true; 1125 // TODO: Should this error be handled (maybe in a high verbosity mode) 1126 // before falling back to .dwo files? 1127 consumeError(Obj.takeError()); 1128 } 1129 } 1130 1131 return object::ObjectFile::createObjectFile(AbsolutePath); 1132 }(); 1133 1134 if (!Obj) { 1135 // TODO: Actually report errors helpfully. 1136 consumeError(Obj.takeError()); 1137 return nullptr; 1138 } 1139 1140 auto S = std::make_shared<DWOFile>(); 1141 S->File = std::move(Obj.get()); 1142 S->Context = DWARFContext::create(*S->File.getBinary()); 1143 *Entry = S; 1144 auto *Ctxt = S->Context.get(); 1145 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1146 } 1147 1148 static Error createError(const Twine &Reason, llvm::Error E) { 1149 return make_error<StringError>(Reason + toString(std::move(E)), 1150 inconvertibleErrorCode()); 1151 } 1152 1153 /// SymInfo contains information about symbol: it's address 1154 /// and section index which is -1LL for absolute symbols. 1155 struct SymInfo { 1156 uint64_t Address; 1157 uint64_t SectionIndex; 1158 }; 1159 1160 /// Returns the address of symbol relocation used against and a section index. 1161 /// Used for futher relocations computation. Symbol's section load address is 1162 static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj, 1163 const RelocationRef &Reloc, 1164 const LoadedObjectInfo *L, 1165 std::map<SymbolRef, SymInfo> &Cache) { 1166 SymInfo Ret = {0, (uint64_t)-1LL}; 1167 object::section_iterator RSec = Obj.section_end(); 1168 object::symbol_iterator Sym = Reloc.getSymbol(); 1169 1170 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end(); 1171 // First calculate the address of the symbol or section as it appears 1172 // in the object file 1173 if (Sym != Obj.symbol_end()) { 1174 bool New; 1175 std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}}); 1176 if (!New) 1177 return CacheIt->second; 1178 1179 Expected<uint64_t> SymAddrOrErr = Sym->getAddress(); 1180 if (!SymAddrOrErr) 1181 return createError("failed to compute symbol address: ", 1182 SymAddrOrErr.takeError()); 1183 1184 // Also remember what section this symbol is in for later 1185 auto SectOrErr = Sym->getSection(); 1186 if (!SectOrErr) 1187 return createError("failed to get symbol section: ", 1188 SectOrErr.takeError()); 1189 1190 RSec = *SectOrErr; 1191 Ret.Address = *SymAddrOrErr; 1192 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) { 1193 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); 1194 Ret.Address = RSec->getAddress(); 1195 } 1196 1197 if (RSec != Obj.section_end()) 1198 Ret.SectionIndex = RSec->getIndex(); 1199 1200 // If we are given load addresses for the sections, we need to adjust: 1201 // SymAddr = (Address of Symbol Or Section in File) - 1202 // (Address of Section in File) + 1203 // (Load Address of Section) 1204 // RSec is now either the section being targeted or the section 1205 // containing the symbol being targeted. In either case, 1206 // we need to perform the same computation. 1207 if (L && RSec != Obj.section_end()) 1208 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) 1209 Ret.Address += SectionLoadAddress - RSec->getAddress(); 1210 1211 if (CacheIt != Cache.end()) 1212 CacheIt->second = Ret; 1213 1214 return Ret; 1215 } 1216 1217 static bool isRelocScattered(const object::ObjectFile &Obj, 1218 const RelocationRef &Reloc) { 1219 const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj); 1220 if (!MachObj) 1221 return false; 1222 // MachO also has relocations that point to sections and 1223 // scattered relocations. 1224 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl()); 1225 return MachObj->isRelocationScattered(RelocInfo); 1226 } 1227 1228 ErrorPolicy DWARFContext::defaultErrorHandler(Error E) { 1229 WithColor::error() << toString(std::move(E)) << '\n'; 1230 return ErrorPolicy::Continue; 1231 } 1232 1233 namespace { 1234 struct DWARFSectionMap final : public DWARFSection { 1235 RelocAddrMap Relocs; 1236 }; 1237 1238 class DWARFObjInMemory final : public DWARFObject { 1239 bool IsLittleEndian; 1240 uint8_t AddressSize; 1241 StringRef FileName; 1242 const object::ObjectFile *Obj = nullptr; 1243 std::vector<SectionName> SectionNames; 1244 1245 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap, 1246 std::map<object::SectionRef, unsigned>>; 1247 1248 InfoSectionMap InfoSections; 1249 InfoSectionMap TypesSections; 1250 InfoSectionMap InfoDWOSections; 1251 InfoSectionMap TypesDWOSections; 1252 1253 DWARFSectionMap LocSection; 1254 DWARFSectionMap LocListsSection; 1255 DWARFSectionMap LineSection; 1256 DWARFSectionMap RangeSection; 1257 DWARFSectionMap RnglistsSection; 1258 DWARFSectionMap StringOffsetSection; 1259 DWARFSectionMap LineDWOSection; 1260 DWARFSectionMap LocDWOSection; 1261 DWARFSectionMap StringOffsetDWOSection; 1262 DWARFSectionMap RangeDWOSection; 1263 DWARFSectionMap RnglistsDWOSection; 1264 DWARFSectionMap AddrSection; 1265 DWARFSectionMap AppleNamesSection; 1266 DWARFSectionMap AppleTypesSection; 1267 DWARFSectionMap AppleNamespacesSection; 1268 DWARFSectionMap AppleObjCSection; 1269 DWARFSectionMap DebugNamesSection; 1270 DWARFSectionMap PubNamesSection; 1271 DWARFSectionMap PubTypesSection; 1272 DWARFSectionMap GnuPubNamesSection; 1273 DWARFSectionMap GnuPubTypesSection; 1274 1275 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) { 1276 return StringSwitch<DWARFSectionMap *>(Name) 1277 .Case("debug_loc", &LocSection) 1278 .Case("debug_loclists", &LocListsSection) 1279 .Case("debug_line", &LineSection) 1280 .Case("debug_str_offsets", &StringOffsetSection) 1281 .Case("debug_ranges", &RangeSection) 1282 .Case("debug_rnglists", &RnglistsSection) 1283 .Case("debug_loc.dwo", &LocDWOSection) 1284 .Case("debug_line.dwo", &LineDWOSection) 1285 .Case("debug_names", &DebugNamesSection) 1286 .Case("debug_rnglists.dwo", &RnglistsDWOSection) 1287 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) 1288 .Case("debug_addr", &AddrSection) 1289 .Case("apple_names", &AppleNamesSection) 1290 .Case("debug_pubnames", &PubNamesSection) 1291 .Case("debug_pubtypes", &PubTypesSection) 1292 .Case("debug_gnu_pubnames", &GnuPubNamesSection) 1293 .Case("debug_gnu_pubtypes", &GnuPubTypesSection) 1294 .Case("apple_types", &AppleTypesSection) 1295 .Case("apple_namespaces", &AppleNamespacesSection) 1296 .Case("apple_namespac", &AppleNamespacesSection) 1297 .Case("apple_objc", &AppleObjCSection) 1298 .Default(nullptr); 1299 } 1300 1301 StringRef AbbrevSection; 1302 StringRef ARangeSection; 1303 StringRef DebugFrameSection; 1304 StringRef EHFrameSection; 1305 StringRef StringSection; 1306 StringRef MacinfoSection; 1307 StringRef AbbrevDWOSection; 1308 StringRef StringDWOSection; 1309 StringRef CUIndexSection; 1310 StringRef GdbIndexSection; 1311 StringRef TUIndexSection; 1312 StringRef LineStringSection; 1313 1314 // A deque holding section data whose iterators are not invalidated when 1315 // new decompressed sections are inserted at the end. 1316 std::deque<SmallString<0>> UncompressedSections; 1317 1318 StringRef *mapSectionToMember(StringRef Name) { 1319 if (DWARFSection *Sec = mapNameToDWARFSection(Name)) 1320 return &Sec->Data; 1321 return StringSwitch<StringRef *>(Name) 1322 .Case("debug_abbrev", &AbbrevSection) 1323 .Case("debug_aranges", &ARangeSection) 1324 .Case("debug_frame", &DebugFrameSection) 1325 .Case("eh_frame", &EHFrameSection) 1326 .Case("debug_str", &StringSection) 1327 .Case("debug_macinfo", &MacinfoSection) 1328 .Case("debug_abbrev.dwo", &AbbrevDWOSection) 1329 .Case("debug_str.dwo", &StringDWOSection) 1330 .Case("debug_cu_index", &CUIndexSection) 1331 .Case("debug_tu_index", &TUIndexSection) 1332 .Case("gdb_index", &GdbIndexSection) 1333 .Case("debug_line_str", &LineStringSection) 1334 // Any more debug info sections go here. 1335 .Default(nullptr); 1336 } 1337 1338 /// If Sec is compressed section, decompresses and updates its contents 1339 /// provided by Data. Otherwise leaves it unchanged. 1340 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, 1341 StringRef &Data) { 1342 if (!Decompressor::isCompressed(Sec)) 1343 return Error::success(); 1344 1345 Expected<Decompressor> Decompressor = 1346 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); 1347 if (!Decompressor) 1348 return Decompressor.takeError(); 1349 1350 SmallString<0> Out; 1351 if (auto Err = Decompressor->resizeAndDecompress(Out)) 1352 return Err; 1353 1354 UncompressedSections.push_back(std::move(Out)); 1355 Data = UncompressedSections.back(); 1356 1357 return Error::success(); 1358 } 1359 1360 public: 1361 DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 1362 uint8_t AddrSize, bool IsLittleEndian) 1363 : IsLittleEndian(IsLittleEndian) { 1364 for (const auto &SecIt : Sections) { 1365 if (StringRef *SectionData = mapSectionToMember(SecIt.first())) 1366 *SectionData = SecIt.second->getBuffer(); 1367 else if (SecIt.first() == "debug_info") 1368 // Find debug_info and debug_types data by section rather than name as 1369 // there are multiple, comdat grouped, of these sections. 1370 InfoSections[SectionRef()].Data = SecIt.second->getBuffer(); 1371 else if (SecIt.first() == "debug_info.dwo") 1372 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer(); 1373 else if (SecIt.first() == "debug_types") 1374 TypesSections[SectionRef()].Data = SecIt.second->getBuffer(); 1375 else if (SecIt.first() == "debug_types.dwo") 1376 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer(); 1377 } 1378 } 1379 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L, 1380 function_ref<ErrorPolicy(Error)> HandleError) 1381 : IsLittleEndian(Obj.isLittleEndian()), 1382 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()), 1383 Obj(&Obj) { 1384 1385 StringMap<unsigned> SectionAmountMap; 1386 for (const SectionRef &Section : Obj.sections()) { 1387 StringRef Name; 1388 Section.getName(Name); 1389 ++SectionAmountMap[Name]; 1390 SectionNames.push_back({ Name, true }); 1391 1392 // Skip BSS and Virtual sections, they aren't interesting. 1393 if (Section.isBSS() || Section.isVirtual()) 1394 continue; 1395 1396 // Skip sections stripped by dsymutil. 1397 if (Section.isStripped()) 1398 continue; 1399 1400 StringRef Data; 1401 section_iterator RelocatedSection = Section.getRelocatedSection(); 1402 // Try to obtain an already relocated version of this section. 1403 // Else use the unrelocated section from the object file. We'll have to 1404 // apply relocations ourselves later. 1405 if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) 1406 Section.getContents(Data); 1407 1408 if (auto Err = maybeDecompress(Section, Name, Data)) { 1409 ErrorPolicy EP = HandleError(createError( 1410 "failed to decompress '" + Name + "', ", std::move(Err))); 1411 if (EP == ErrorPolicy::Halt) 1412 return; 1413 continue; 1414 } 1415 1416 // Compressed sections names in GNU style starts from ".z", 1417 // at this point section is decompressed and we drop compression prefix. 1418 Name = Name.substr( 1419 Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. 1420 1421 // Map platform specific debug section names to DWARF standard section 1422 // names. 1423 Name = Obj.mapDebugSectionName(Name); 1424 1425 if (StringRef *SectionData = mapSectionToMember(Name)) { 1426 *SectionData = Data; 1427 if (Name == "debug_ranges") { 1428 // FIXME: Use the other dwo range section when we emit it. 1429 RangeDWOSection.Data = Data; 1430 } 1431 } else if (Name == "debug_info") { 1432 // Find debug_info and debug_types data by section rather than name as 1433 // there are multiple, comdat grouped, of these sections. 1434 InfoSections[Section].Data = Data; 1435 } else if (Name == "debug_info.dwo") { 1436 InfoDWOSections[Section].Data = Data; 1437 } else if (Name == "debug_types") { 1438 TypesSections[Section].Data = Data; 1439 } else if (Name == "debug_types.dwo") { 1440 TypesDWOSections[Section].Data = Data; 1441 } 1442 1443 if (RelocatedSection == Obj.section_end()) 1444 continue; 1445 1446 StringRef RelSecName; 1447 StringRef RelSecData; 1448 RelocatedSection->getName(RelSecName); 1449 1450 // If the section we're relocating was relocated already by the JIT, 1451 // then we used the relocated version above, so we do not need to process 1452 // relocations for it now. 1453 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) 1454 continue; 1455 1456 // In Mach-o files, the relocations do not need to be applied if 1457 // there is no load offset to apply. The value read at the 1458 // relocation point already factors in the section address 1459 // (actually applying the relocations will produce wrong results 1460 // as the section address will be added twice). 1461 if (!L && isa<MachOObjectFile>(&Obj)) 1462 continue; 1463 1464 RelSecName = RelSecName.substr( 1465 RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes. 1466 1467 // TODO: Add support for relocations in other sections as needed. 1468 // Record relocations for the debug_info and debug_line sections. 1469 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName); 1470 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr; 1471 if (!Map) { 1472 // Find debug_info and debug_types relocs by section rather than name 1473 // as there are multiple, comdat grouped, of these sections. 1474 if (RelSecName == "debug_info") 1475 Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection]) 1476 .Relocs; 1477 else if (RelSecName == "debug_info.dwo") 1478 Map = &static_cast<DWARFSectionMap &>( 1479 InfoDWOSections[*RelocatedSection]) 1480 .Relocs; 1481 else if (RelSecName == "debug_types") 1482 Map = 1483 &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection]) 1484 .Relocs; 1485 else if (RelSecName == "debug_types.dwo") 1486 Map = &static_cast<DWARFSectionMap &>( 1487 TypesDWOSections[*RelocatedSection]) 1488 .Relocs; 1489 else 1490 continue; 1491 } 1492 1493 if (Section.relocation_begin() == Section.relocation_end()) 1494 continue; 1495 1496 // Symbol to [address, section index] cache mapping. 1497 std::map<SymbolRef, SymInfo> AddrCache; 1498 for (const RelocationRef &Reloc : Section.relocations()) { 1499 // FIXME: it's not clear how to correctly handle scattered 1500 // relocations. 1501 if (isRelocScattered(Obj, Reloc)) 1502 continue; 1503 1504 Expected<SymInfo> SymInfoOrErr = 1505 getSymbolInfo(Obj, Reloc, L, AddrCache); 1506 if (!SymInfoOrErr) { 1507 if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) 1508 return; 1509 continue; 1510 } 1511 1512 object::RelocVisitor V(Obj); 1513 uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address); 1514 if (V.error()) { 1515 SmallString<32> Type; 1516 Reloc.getTypeName(Type); 1517 ErrorPolicy EP = HandleError( 1518 createError("failed to compute relocation: " + Type + ", ", 1519 errorCodeToError(object_error::parse_failed))); 1520 if (EP == ErrorPolicy::Halt) 1521 return; 1522 continue; 1523 } 1524 RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; 1525 Map->insert({Reloc.getOffset(), Rel}); 1526 } 1527 } 1528 1529 for (SectionName &S : SectionNames) 1530 if (SectionAmountMap[S.Name] > 1) 1531 S.IsNameUnique = false; 1532 } 1533 1534 Optional<RelocAddrEntry> find(const DWARFSection &S, 1535 uint64_t Pos) const override { 1536 auto &Sec = static_cast<const DWARFSectionMap &>(S); 1537 RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos); 1538 if (AI == Sec.Relocs.end()) 1539 return None; 1540 return AI->second; 1541 } 1542 1543 const object::ObjectFile *getFile() const override { return Obj; } 1544 1545 ArrayRef<SectionName> getSectionNames() const override { 1546 return SectionNames; 1547 } 1548 1549 bool isLittleEndian() const override { return IsLittleEndian; } 1550 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; } 1551 const DWARFSection &getLineDWOSection() const override { 1552 return LineDWOSection; 1553 } 1554 const DWARFSection &getLocDWOSection() const override { 1555 return LocDWOSection; 1556 } 1557 StringRef getStringDWOSection() const override { return StringDWOSection; } 1558 const DWARFSection &getStringOffsetDWOSection() const override { 1559 return StringOffsetDWOSection; 1560 } 1561 const DWARFSection &getRangeDWOSection() const override { 1562 return RangeDWOSection; 1563 } 1564 const DWARFSection &getRnglistsDWOSection() const override { 1565 return RnglistsDWOSection; 1566 } 1567 const DWARFSection &getAddrSection() const override { return AddrSection; } 1568 StringRef getCUIndexSection() const override { return CUIndexSection; } 1569 StringRef getGdbIndexSection() const override { return GdbIndexSection; } 1570 StringRef getTUIndexSection() const override { return TUIndexSection; } 1571 1572 // DWARF v5 1573 const DWARFSection &getStringOffsetSection() const override { 1574 return StringOffsetSection; 1575 } 1576 StringRef getLineStringSection() const override { return LineStringSection; } 1577 1578 // Sections for DWARF5 split dwarf proposal. 1579 void forEachInfoDWOSections( 1580 function_ref<void(const DWARFSection &)> F) const override { 1581 for (auto &P : InfoDWOSections) 1582 F(P.second); 1583 } 1584 void forEachTypesDWOSections( 1585 function_ref<void(const DWARFSection &)> F) const override { 1586 for (auto &P : TypesDWOSections) 1587 F(P.second); 1588 } 1589 1590 StringRef getAbbrevSection() const override { return AbbrevSection; } 1591 const DWARFSection &getLocSection() const override { return LocSection; } 1592 const DWARFSection &getLoclistsSection() const override { return LocListsSection; } 1593 StringRef getARangeSection() const override { return ARangeSection; } 1594 StringRef getDebugFrameSection() const override { return DebugFrameSection; } 1595 StringRef getEHFrameSection() const override { return EHFrameSection; } 1596 const DWARFSection &getLineSection() const override { return LineSection; } 1597 StringRef getStringSection() const override { return StringSection; } 1598 const DWARFSection &getRangeSection() const override { return RangeSection; } 1599 const DWARFSection &getRnglistsSection() const override { 1600 return RnglistsSection; 1601 } 1602 StringRef getMacinfoSection() const override { return MacinfoSection; } 1603 const DWARFSection &getPubNamesSection() const override { return PubNamesSection; } 1604 const DWARFSection &getPubTypesSection() const override { return PubTypesSection; } 1605 const DWARFSection &getGnuPubNamesSection() const override { 1606 return GnuPubNamesSection; 1607 } 1608 const DWARFSection &getGnuPubTypesSection() const override { 1609 return GnuPubTypesSection; 1610 } 1611 const DWARFSection &getAppleNamesSection() const override { 1612 return AppleNamesSection; 1613 } 1614 const DWARFSection &getAppleTypesSection() const override { 1615 return AppleTypesSection; 1616 } 1617 const DWARFSection &getAppleNamespacesSection() const override { 1618 return AppleNamespacesSection; 1619 } 1620 const DWARFSection &getAppleObjCSection() const override { 1621 return AppleObjCSection; 1622 } 1623 const DWARFSection &getDebugNamesSection() const override { 1624 return DebugNamesSection; 1625 } 1626 1627 StringRef getFileName() const override { return FileName; } 1628 uint8_t getAddressSize() const override { return AddressSize; } 1629 void forEachInfoSections( 1630 function_ref<void(const DWARFSection &)> F) const override { 1631 for (auto &P : InfoSections) 1632 F(P.second); 1633 } 1634 void forEachTypesSections( 1635 function_ref<void(const DWARFSection &)> F) const override { 1636 for (auto &P : TypesSections) 1637 F(P.second); 1638 } 1639 }; 1640 } // namespace 1641 1642 std::unique_ptr<DWARFContext> 1643 DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, 1644 function_ref<ErrorPolicy(Error)> HandleError, 1645 std::string DWPName) { 1646 auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError); 1647 return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName)); 1648 } 1649 1650 std::unique_ptr<DWARFContext> 1651 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 1652 uint8_t AddrSize, bool isLittleEndian) { 1653 auto DObj = 1654 llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); 1655 return llvm::make_unique<DWARFContext>(std::move(DObj), ""); 1656 } 1657 1658 Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { 1659 // Detect the architecture from the object file. We usually don't need OS 1660 // info to lookup a target and create register info. 1661 Triple TT; 1662 TT.setArch(Triple::ArchType(Obj.getArch())); 1663 TT.setVendor(Triple::UnknownVendor); 1664 TT.setOS(Triple::UnknownOS); 1665 std::string TargetLookupError; 1666 const Target *TheTarget = 1667 TargetRegistry::lookupTarget(TT.str(), TargetLookupError); 1668 if (!TargetLookupError.empty()) 1669 return createStringError(errc::invalid_argument, 1670 TargetLookupError.c_str()); 1671 RegInfo.reset(TheTarget->createMCRegInfo(TT.str())); 1672 return Error::success(); 1673 } 1674 1675 uint8_t DWARFContext::getCUAddrSize() { 1676 // In theory, different compile units may have different address byte 1677 // sizes, but for simplicity we just use the address byte size of the 1678 // last compile unit. In practice the address size field is repeated across 1679 // various DWARF headers (at least in version 5) to make it easier to dump 1680 // them independently, not to enable varying the address size. 1681 uint8_t Addr = 0; 1682 for (const auto &CU : compile_units()) { 1683 Addr = CU->getAddressByteSize(); 1684 break; 1685 } 1686 return Addr; 1687 } 1688 1689 void DWARFContext::dumpWarning(Error Warning) { 1690 handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) { 1691 WithColor::warning() << Info.message() << '\n'; 1692 }); 1693 } 1694