1 //===- DWARFContext.cpp ---------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 10 #include "llvm/ADT/MapVector.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/DWARFDataExtractor.h" 20 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 21 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h" 22 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 23 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" 24 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 25 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 26 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 27 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 28 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" 29 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 30 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" 31 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 32 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 33 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" 34 #include "llvm/DebugInfo/DWARF/DWARFListTable.h" 35 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" 36 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 37 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 38 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" 39 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 40 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" 41 #include "llvm/MC/TargetRegistry.h" 42 #include "llvm/Object/Decompressor.h" 43 #include "llvm/Object/MachO.h" 44 #include "llvm/Object/ObjectFile.h" 45 #include "llvm/Object/RelocationResolver.h" 46 #include "llvm/Support/Casting.h" 47 #include "llvm/Support/DataExtractor.h" 48 #include "llvm/Support/Error.h" 49 #include "llvm/Support/Format.h" 50 #include "llvm/Support/LEB128.h" 51 #include "llvm/Support/MemoryBuffer.h" 52 #include "llvm/Support/Path.h" 53 #include "llvm/Support/raw_ostream.h" 54 #include <algorithm> 55 #include <cstdint> 56 #include <deque> 57 #include <map> 58 #include <string> 59 #include <utility> 60 #include <vector> 61 62 using namespace llvm; 63 using namespace dwarf; 64 using namespace object; 65 66 #define DEBUG_TYPE "dwarf" 67 68 using DWARFLineTable = DWARFDebugLine::LineTable; 69 using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; 70 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; 71 72 DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj, 73 std::string DWPName, 74 std::function<void(Error)> RecoverableErrorHandler, 75 std::function<void(Error)> WarningHandler) 76 : DIContext(CK_DWARF), DWPName(std::move(DWPName)), 77 RecoverableErrorHandler(RecoverableErrorHandler), 78 WarningHandler(WarningHandler), DObj(std::move(DObj)) {} 79 80 DWARFContext::~DWARFContext() = default; 81 82 /// Dump the UUID load command. 83 static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) { 84 auto *MachO = dyn_cast<MachOObjectFile>(&Obj); 85 if (!MachO) 86 return; 87 for (auto LC : MachO->load_commands()) { 88 raw_ostream::uuid_t UUID; 89 if (LC.C.cmd == MachO::LC_UUID) { 90 if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) { 91 OS << "error: UUID load command is too short.\n"; 92 return; 93 } 94 OS << "UUID: "; 95 memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID)); 96 OS.write_uuid(UUID); 97 Triple T = MachO->getArchTriple(); 98 OS << " (" << T.getArchName() << ')'; 99 OS << ' ' << MachO->getFileName() << '\n'; 100 } 101 } 102 } 103 104 using ContributionCollection = 105 std::vector<std::optional<StrOffsetsContributionDescriptor>>; 106 107 // Collect all the contributions to the string offsets table from all units, 108 // sort them by their starting offsets and remove duplicates. 109 static ContributionCollection 110 collectContributionData(DWARFContext::unit_iterator_range Units) { 111 ContributionCollection Contributions; 112 for (const auto &U : Units) 113 if (const auto &C = U->getStringOffsetsTableContribution()) 114 Contributions.push_back(C); 115 // Sort the contributions so that any invalid ones are placed at 116 // the start of the contributions vector. This way they are reported 117 // first. 118 llvm::sort(Contributions, 119 [](const std::optional<StrOffsetsContributionDescriptor> &L, 120 const std::optional<StrOffsetsContributionDescriptor> &R) { 121 if (L && R) 122 return L->Base < R->Base; 123 return R.has_value(); 124 }); 125 126 // Uniquify contributions, as it is possible that units (specifically 127 // type units in dwo or dwp files) share contributions. We don't want 128 // to report them more than once. 129 Contributions.erase( 130 std::unique(Contributions.begin(), Contributions.end(), 131 [](const std::optional<StrOffsetsContributionDescriptor> &L, 132 const std::optional<StrOffsetsContributionDescriptor> &R) { 133 if (L && R) 134 return L->Base == R->Base && L->Size == R->Size; 135 return false; 136 }), 137 Contributions.end()); 138 return Contributions; 139 } 140 141 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted 142 // string offsets section, where each compile or type unit contributes a 143 // number of entries (string offsets), with each contribution preceded by 144 // a header containing size and version number. Alternatively, it may be a 145 // monolithic series of string offsets, as generated by the pre-DWARF v5 146 // implementation of split DWARF; however, in that case we still need to 147 // collect contributions of units because the size of the offsets (4 or 8 148 // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64). 149 static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts, 150 StringRef SectionName, 151 const DWARFObject &Obj, 152 const DWARFSection &StringOffsetsSection, 153 StringRef StringSection, 154 DWARFContext::unit_iterator_range Units, 155 bool LittleEndian) { 156 auto Contributions = collectContributionData(Units); 157 DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); 158 DataExtractor StrData(StringSection, LittleEndian, 0); 159 uint64_t SectionSize = StringOffsetsSection.Data.size(); 160 uint64_t Offset = 0; 161 for (auto &Contribution : Contributions) { 162 // Report an ill-formed contribution. 163 if (!Contribution) { 164 OS << "error: invalid contribution to string offsets table in section ." 165 << SectionName << ".\n"; 166 return; 167 } 168 169 dwarf::DwarfFormat Format = Contribution->getFormat(); 170 int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); 171 uint16_t Version = Contribution->getVersion(); 172 uint64_t ContributionHeader = Contribution->Base; 173 // In DWARF v5 there is a contribution header that immediately precedes 174 // the string offsets base (the location we have previously retrieved from 175 // the CU DIE's DW_AT_str_offsets attribute). The header is located either 176 // 8 or 16 bytes before the base, depending on the contribution's format. 177 if (Version >= 5) 178 ContributionHeader -= Format == DWARF32 ? 8 : 16; 179 180 // Detect overlapping contributions. 181 if (Offset > ContributionHeader) { 182 DumpOpts.RecoverableErrorHandler(createStringError( 183 errc::invalid_argument, 184 "overlapping contributions to string offsets table in section .%s.", 185 SectionName.data())); 186 } 187 // Report a gap in the table. 188 if (Offset < ContributionHeader) { 189 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset); 190 OS << (ContributionHeader - Offset) << "\n"; 191 } 192 OS << format("0x%8.8" PRIx64 ": ", ContributionHeader); 193 // In DWARF v5 the contribution size in the descriptor does not equal 194 // the originally encoded length (it does not contain the length of the 195 // version field and the padding, a total of 4 bytes). Add them back in 196 // for reporting. 197 OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4)) 198 << ", Format = " << dwarf::FormatString(Format) 199 << ", Version = " << Version << "\n"; 200 201 Offset = Contribution->Base; 202 unsigned EntrySize = Contribution->getDwarfOffsetByteSize(); 203 while (Offset - Contribution->Base < Contribution->Size) { 204 OS << format("0x%8.8" PRIx64 ": ", Offset); 205 uint64_t StringOffset = 206 StrOffsetExt.getRelocatedValue(EntrySize, &Offset); 207 OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset); 208 const char *S = StrData.getCStr(&StringOffset); 209 if (S) 210 OS << format("\"%s\"", S); 211 OS << "\n"; 212 } 213 } 214 // Report a gap at the end of the table. 215 if (Offset < SectionSize) { 216 OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset); 217 OS << (SectionSize - Offset) << "\n"; 218 } 219 } 220 221 // Dump the .debug_addr section. 222 static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, 223 DIDumpOptions DumpOpts, uint16_t Version, 224 uint8_t AddrSize) { 225 uint64_t Offset = 0; 226 while (AddrData.isValidOffset(Offset)) { 227 DWARFDebugAddrTable AddrTable; 228 uint64_t TableOffset = Offset; 229 if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize, 230 DumpOpts.WarningHandler)) { 231 DumpOpts.RecoverableErrorHandler(std::move(Err)); 232 // Keep going after an error, if we can, assuming that the length field 233 // could be read. If it couldn't, stop reading the section. 234 if (auto TableLength = AddrTable.getFullLength()) { 235 Offset = TableOffset + *TableLength; 236 continue; 237 } 238 break; 239 } 240 AddrTable.dump(OS, DumpOpts); 241 } 242 } 243 244 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). 245 static void dumpRnglistsSection( 246 raw_ostream &OS, DWARFDataExtractor &rnglistData, 247 llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)> 248 LookupPooledAddress, 249 DIDumpOptions DumpOpts) { 250 uint64_t Offset = 0; 251 while (rnglistData.isValidOffset(Offset)) { 252 llvm::DWARFDebugRnglistTable Rnglists; 253 uint64_t TableOffset = Offset; 254 if (Error Err = Rnglists.extract(rnglistData, &Offset)) { 255 DumpOpts.RecoverableErrorHandler(std::move(Err)); 256 uint64_t Length = Rnglists.length(); 257 // Keep going after an error, if we can, assuming that the length field 258 // could be read. If it couldn't, stop reading the section. 259 if (Length == 0) 260 break; 261 Offset = TableOffset + Length; 262 } else { 263 Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts); 264 } 265 } 266 } 267 268 std::unique_ptr<DWARFDebugMacro> 269 DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) { 270 auto Macro = std::make_unique<DWARFDebugMacro>(); 271 auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) { 272 if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection 273 ? compile_units() 274 : dwo_compile_units(), 275 SectionType == MacroSection 276 ? getStringExtractor() 277 : getStringDWOExtractor(), 278 Data) 279 : Macro->parseMacinfo(Data)) { 280 RecoverableErrorHandler(std::move(Err)); 281 Macro = nullptr; 282 } 283 }; 284 switch (SectionType) { 285 case MacinfoSection: { 286 DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0); 287 ParseAndDump(Data, /*IsMacro=*/false); 288 break; 289 } 290 case MacinfoDwoSection: { 291 DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0); 292 ParseAndDump(Data, /*IsMacro=*/false); 293 break; 294 } 295 case MacroSection: { 296 DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(), 297 0); 298 ParseAndDump(Data, /*IsMacro=*/true); 299 break; 300 } 301 case MacroDwoSection: { 302 DWARFDataExtractor Data(DObj->getMacroDWOSection(), isLittleEndian(), 0); 303 ParseAndDump(Data, /*IsMacro=*/true); 304 break; 305 } 306 } 307 return Macro; 308 } 309 310 static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, 311 DWARFDataExtractor Data, const DWARFObject &Obj, 312 std::optional<uint64_t> DumpOffset) { 313 uint64_t Offset = 0; 314 315 while (Data.isValidOffset(Offset)) { 316 DWARFListTableHeader Header(".debug_loclists", "locations"); 317 if (Error E = Header.extract(Data, &Offset)) { 318 DumpOpts.RecoverableErrorHandler(std::move(E)); 319 return; 320 } 321 322 Header.dump(Data, OS, DumpOpts); 323 324 uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); 325 Data.setAddressSize(Header.getAddrSize()); 326 DWARFDebugLoclists Loc(Data, Header.getVersion()); 327 if (DumpOffset) { 328 if (DumpOffset >= Offset && DumpOffset < EndOffset) { 329 Offset = *DumpOffset; 330 Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj, 331 nullptr, DumpOpts, /*Indent=*/0); 332 OS << "\n"; 333 return; 334 } 335 } else { 336 Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts); 337 } 338 Offset = EndOffset; 339 } 340 } 341 342 static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, 343 DWARFDataExtractor Data, bool GnuStyle) { 344 DWARFDebugPubTable Table; 345 Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler); 346 Table.dump(OS); 347 } 348 349 void DWARFContext::dump( 350 raw_ostream &OS, DIDumpOptions DumpOpts, 351 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { 352 uint64_t DumpType = DumpOpts.DumpType; 353 354 StringRef Extension = sys::path::extension(DObj->getFileName()); 355 bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp"); 356 357 // Print UUID header. 358 const auto *ObjFile = DObj->getFile(); 359 if (DumpType & DIDT_UUID) 360 dumpUUID(OS, *ObjFile); 361 362 // Print a header for each explicitly-requested section. 363 // Otherwise just print one for non-empty sections. 364 // Only print empty .dwo section headers when dumping a .dwo file. 365 bool Explicit = DumpType != DIDT_All && !IsDWO; 366 bool ExplicitDWO = Explicit && IsDWO; 367 auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID, 368 StringRef Section) -> std::optional<uint64_t> * { 369 unsigned Mask = 1U << ID; 370 bool Should = (DumpType & Mask) && (Explicit || !Section.empty()); 371 if (!Should) 372 return nullptr; 373 OS << "\n" << Name << " contents:\n"; 374 return &DumpOffsets[ID]; 375 }; 376 377 // Dump individual sections. 378 if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev, 379 DObj->getAbbrevSection())) 380 getDebugAbbrev()->dump(OS); 381 if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev, 382 DObj->getAbbrevDWOSection())) 383 getDebugAbbrevDWO()->dump(OS); 384 385 auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) { 386 OS << '\n' << Name << " contents:\n"; 387 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo]) 388 for (const auto &U : Units) 389 U->getDIEForOffset(*DumpOffset) 390 .dump(OS, 0, DumpOpts.noImplicitRecursion()); 391 else 392 for (const auto &U : Units) 393 U->dump(OS, DumpOpts); 394 }; 395 if ((DumpType & DIDT_DebugInfo)) { 396 if (Explicit || getNumCompileUnits()) 397 dumpDebugInfo(".debug_info", info_section_units()); 398 if (ExplicitDWO || getNumDWOCompileUnits()) 399 dumpDebugInfo(".debug_info.dwo", dwo_info_section_units()); 400 } 401 402 auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) { 403 OS << '\n' << Name << " contents:\n"; 404 for (const auto &U : Units) 405 if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes]) 406 U->getDIEForOffset(*DumpOffset) 407 .dump(OS, 0, DumpOpts.noImplicitRecursion()); 408 else 409 U->dump(OS, DumpOpts); 410 }; 411 if ((DumpType & DIDT_DebugTypes)) { 412 if (Explicit || getNumTypeUnits()) 413 dumpDebugType(".debug_types", types_section_units()); 414 if (ExplicitDWO || getNumDWOTypeUnits()) 415 dumpDebugType(".debug_types.dwo", dwo_types_section_units()); 416 } 417 418 DIDumpOptions LLDumpOpts = DumpOpts; 419 if (LLDumpOpts.Verbose) 420 LLDumpOpts.DisplayRawContents = true; 421 422 if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, 423 DObj->getLocSection().Data)) { 424 getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off); 425 } 426 if (const auto *Off = 427 shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, 428 DObj->getLoclistsSection().Data)) { 429 DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), 430 0); 431 dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off); 432 } 433 if (const auto *Off = 434 shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists, 435 DObj->getLoclistsDWOSection().Data)) { 436 DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(), 437 isLittleEndian(), 0); 438 dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off); 439 } 440 441 if (const auto *Off = 442 shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, 443 DObj->getLocDWOSection().Data)) { 444 DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(), 445 4); 446 DWARFDebugLoclists Loc(Data, /*Version=*/4); 447 if (*Off) { 448 uint64_t Offset = **Off; 449 Loc.dumpLocationList(&Offset, OS, 450 /*BaseAddr=*/std::nullopt, *DObj, nullptr, 451 LLDumpOpts, 452 /*Indent=*/0); 453 OS << "\n"; 454 } else { 455 Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts); 456 } 457 } 458 459 if (const std::optional<uint64_t> *Off = 460 shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, 461 DObj->getFrameSection().Data)) { 462 if (Expected<const DWARFDebugFrame *> DF = getDebugFrame()) 463 (*DF)->dump(OS, DumpOpts, *Off); 464 else 465 RecoverableErrorHandler(DF.takeError()); 466 } 467 468 if (const std::optional<uint64_t> *Off = 469 shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, 470 DObj->getEHFrameSection().Data)) { 471 if (Expected<const DWARFDebugFrame *> DF = getEHFrame()) 472 (*DF)->dump(OS, DumpOpts, *Off); 473 else 474 RecoverableErrorHandler(DF.takeError()); 475 } 476 477 if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro, 478 DObj->getMacroSection().Data)) { 479 if (auto Macro = getDebugMacro()) 480 Macro->dump(OS); 481 } 482 483 if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro, 484 DObj->getMacroDWOSection())) { 485 if (auto MacroDWO = getDebugMacroDWO()) 486 MacroDWO->dump(OS); 487 } 488 489 if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro, 490 DObj->getMacinfoSection())) { 491 if (auto Macinfo = getDebugMacinfo()) 492 Macinfo->dump(OS); 493 } 494 495 if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro, 496 DObj->getMacinfoDWOSection())) { 497 if (auto MacinfoDWO = getDebugMacinfoDWO()) 498 MacinfoDWO->dump(OS); 499 } 500 501 if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges, 502 DObj->getArangesSection())) { 503 uint64_t offset = 0; 504 DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 505 0); 506 DWARFDebugArangeSet set; 507 while (arangesData.isValidOffset(offset)) { 508 if (Error E = 509 set.extract(arangesData, &offset, DumpOpts.WarningHandler)) { 510 RecoverableErrorHandler(std::move(E)); 511 break; 512 } 513 set.dump(OS); 514 } 515 } 516 517 auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser, 518 DIDumpOptions DumpOpts, 519 std::optional<uint64_t> DumpOffset) { 520 while (!Parser.done()) { 521 if (DumpOffset && Parser.getOffset() != *DumpOffset) { 522 Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler); 523 continue; 524 } 525 OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset()) 526 << "]\n"; 527 Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS, 528 DumpOpts.Verbose); 529 } 530 }; 531 532 auto DumpStrSection = [&](StringRef Section) { 533 DataExtractor StrData(Section, isLittleEndian(), 0); 534 uint64_t Offset = 0; 535 uint64_t StrOffset = 0; 536 while (StrData.isValidOffset(Offset)) { 537 Error Err = Error::success(); 538 const char *CStr = StrData.getCStr(&Offset, &Err); 539 if (Err) { 540 DumpOpts.WarningHandler(std::move(Err)); 541 return; 542 } 543 OS << format("0x%8.8" PRIx64 ": \"", StrOffset); 544 OS.write_escaped(CStr); 545 OS << "\"\n"; 546 StrOffset = Offset; 547 } 548 }; 549 550 if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine, 551 DObj->getLineSection().Data)) { 552 DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(), 553 0); 554 DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units()); 555 DumpLineSection(Parser, DumpOpts, *Off); 556 } 557 558 if (const auto *Off = 559 shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine, 560 DObj->getLineDWOSection().Data)) { 561 DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(), 562 isLittleEndian(), 0); 563 DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units()); 564 DumpLineSection(Parser, DumpOpts, *Off); 565 } 566 567 if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex, 568 DObj->getCUIndexSection())) { 569 getCUIndex().dump(OS); 570 } 571 572 if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex, 573 DObj->getTUIndexSection())) { 574 getTUIndex().dump(OS); 575 } 576 577 if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr, 578 DObj->getStrSection())) 579 DumpStrSection(DObj->getStrSection()); 580 581 if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr, 582 DObj->getStrDWOSection())) 583 DumpStrSection(DObj->getStrDWOSection()); 584 585 if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr, 586 DObj->getLineStrSection())) 587 DumpStrSection(DObj->getLineStrSection()); 588 589 if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr, 590 DObj->getAddrSection().Data)) { 591 DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(), 592 isLittleEndian(), 0); 593 dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize()); 594 } 595 596 if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges, 597 DObj->getRangesSection().Data)) { 598 uint8_t savedAddressByteSize = getCUAddrSize(); 599 DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(), 600 isLittleEndian(), savedAddressByteSize); 601 uint64_t offset = 0; 602 DWARFDebugRangeList rangeList; 603 while (rangesData.isValidOffset(offset)) { 604 if (Error E = rangeList.extract(rangesData, &offset)) { 605 DumpOpts.RecoverableErrorHandler(std::move(E)); 606 break; 607 } 608 rangeList.dump(OS); 609 } 610 } 611 612 auto LookupPooledAddress = 613 [&](uint32_t Index) -> std::optional<SectionedAddress> { 614 const auto &CUs = compile_units(); 615 auto I = CUs.begin(); 616 if (I == CUs.end()) 617 return std::nullopt; 618 return (*I)->getAddrOffsetSectionItem(Index); 619 }; 620 621 if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists, 622 DObj->getRnglistsSection().Data)) { 623 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(), 624 isLittleEndian(), 0); 625 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts); 626 } 627 628 if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists, 629 DObj->getRnglistsDWOSection().Data)) { 630 DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(), 631 isLittleEndian(), 0); 632 dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts); 633 } 634 635 if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames, 636 DObj->getPubnamesSection().Data)) { 637 DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(), 638 isLittleEndian(), 0); 639 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false); 640 } 641 642 if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes, 643 DObj->getPubtypesSection().Data)) { 644 DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(), 645 isLittleEndian(), 0); 646 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false); 647 } 648 649 if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames, 650 DObj->getGnuPubnamesSection().Data)) { 651 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(), 652 isLittleEndian(), 0); 653 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true); 654 } 655 656 if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes, 657 DObj->getGnuPubtypesSection().Data)) { 658 DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(), 659 isLittleEndian(), 0); 660 dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true); 661 } 662 663 if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets, 664 DObj->getStrOffsetsSection().Data)) 665 dumpStringOffsetsSection( 666 OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(), 667 DObj->getStrSection(), normal_units(), isLittleEndian()); 668 if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets, 669 DObj->getStrOffsetsDWOSection().Data)) 670 dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj, 671 DObj->getStrOffsetsDWOSection(), 672 DObj->getStrDWOSection(), dwo_units(), 673 isLittleEndian()); 674 675 if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex, 676 DObj->getGdbIndexSection())) { 677 getGdbIndex().dump(OS); 678 } 679 680 if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames, 681 DObj->getAppleNamesSection().Data)) 682 getAppleNames().dump(OS); 683 684 if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes, 685 DObj->getAppleTypesSection().Data)) 686 getAppleTypes().dump(OS); 687 688 if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces, 689 DObj->getAppleNamespacesSection().Data)) 690 getAppleNamespaces().dump(OS); 691 692 if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC, 693 DObj->getAppleObjCSection().Data)) 694 getAppleObjC().dump(OS); 695 if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames, 696 DObj->getNamesSection().Data)) 697 getDebugNames().dump(OS); 698 } 699 700 DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint16_t Version, uint64_t Hash, 701 bool IsDWO) { 702 parseDWOUnits(LazyParse); 703 704 if (const auto &TUI = getTUIndex()) { 705 if (const auto *R = TUI.getFromHash(Hash)) 706 return dyn_cast_or_null<DWARFTypeUnit>( 707 DWOUnits.getUnitForIndexEntry(*R)); 708 return nullptr; 709 } 710 711 struct UnitContainers { 712 const DWARFUnitVector &Units; 713 std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> ⤅ 714 }; 715 UnitContainers Units = IsDWO ? UnitContainers{DWOUnits, DWOTypeUnits} 716 : UnitContainers{NormalUnits, NormalTypeUnits}; 717 if (!Units.Map) { 718 Units.Map.emplace(); 719 for (const auto &U : IsDWO ? dwo_units() : normal_units()) { 720 if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get())) 721 (*Units.Map)[TU->getTypeHash()] = TU; 722 } 723 } 724 725 return (*Units.Map)[Hash]; 726 } 727 728 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { 729 parseDWOUnits(LazyParse); 730 731 if (const auto &CUI = getCUIndex()) { 732 if (const auto *R = CUI.getFromHash(Hash)) 733 return dyn_cast_or_null<DWARFCompileUnit>( 734 DWOUnits.getUnitForIndexEntry(*R)); 735 return nullptr; 736 } 737 738 // If there's no index, just search through the CUs in the DWO - there's 739 // probably only one unless this is something like LTO - though an in-process 740 // built/cached lookup table could be used in that case to improve repeated 741 // lookups of different CUs in the DWO. 742 for (const auto &DWOCU : dwo_compile_units()) { 743 // Might not have parsed DWO ID yet. 744 if (!DWOCU->getDWOId()) { 745 if (std::optional<uint64_t> DWOId = 746 toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id))) 747 DWOCU->setDWOId(*DWOId); 748 else 749 // No DWO ID? 750 continue; 751 } 752 if (DWOCU->getDWOId() == Hash) 753 return dyn_cast<DWARFCompileUnit>(DWOCU.get()); 754 } 755 return nullptr; 756 } 757 758 DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) { 759 parseNormalUnits(); 760 if (auto *CU = NormalUnits.getUnitForOffset(Offset)) 761 return CU->getDIEForOffset(Offset); 762 return DWARFDie(); 763 } 764 765 bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) { 766 bool Success = true; 767 DWARFVerifier verifier(OS, *this, DumpOpts); 768 769 Success &= verifier.handleDebugAbbrev(); 770 if (DumpOpts.DumpType & DIDT_DebugCUIndex) 771 Success &= verifier.handleDebugCUIndex(); 772 if (DumpOpts.DumpType & DIDT_DebugTUIndex) 773 Success &= verifier.handleDebugTUIndex(); 774 if (DumpOpts.DumpType & DIDT_DebugInfo) 775 Success &= verifier.handleDebugInfo(); 776 if (DumpOpts.DumpType & DIDT_DebugLine) 777 Success &= verifier.handleDebugLine(); 778 Success &= verifier.handleAccelTables(); 779 return Success; 780 } 781 782 void fixupIndex(const DWARFObject &DObj, DWARFContext &C, 783 DWARFUnitIndex &Index) { 784 using EntryType = DWARFUnitIndex::Entry::SectionContribution; 785 using EntryMap = DenseMap<uint32_t, EntryType>; 786 EntryMap Map; 787 if (DObj.getCUIndexSection().empty()) 788 return; 789 790 uint64_t Offset = 0; 791 uint32_t TruncOffset = 0; 792 DObj.forEachInfoDWOSections([&](const DWARFSection &S) { 793 if (!(C.getParseCUTUIndexManually() || 794 S.Data.size() >= std::numeric_limits<uint32_t>::max())) 795 return; 796 797 DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0); 798 while (Data.isValidOffset(Offset)) { 799 DWARFUnitHeader Header; 800 if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) { 801 logAllUnhandledErrors( 802 createError("Failed to parse CU header in DWP file"), errs()); 803 Map.clear(); 804 break; 805 } 806 807 auto Iter = Map.insert({TruncOffset, 808 {Header.getOffset(), Header.getNextUnitOffset() - 809 Header.getOffset()}}); 810 if (!Iter.second) { 811 logAllUnhandledErrors( 812 createError("Collision occured between for truncated offset 0x" + 813 Twine::utohexstr(TruncOffset)), 814 errs()); 815 Map.clear(); 816 return; 817 } 818 819 Offset = Header.getNextUnitOffset(); 820 TruncOffset = Offset; 821 } 822 }); 823 824 if (Map.empty()) 825 return; 826 827 for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) { 828 if (!E.isValid()) 829 continue; 830 DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution(); 831 auto Iter = Map.find(CUOff.getOffset()); 832 if (Iter == Map.end()) { 833 logAllUnhandledErrors(createError("Could not find CU offset 0x" + 834 Twine::utohexstr(CUOff.getOffset()) + 835 " in the Map"), 836 errs()); 837 break; 838 } 839 CUOff.setOffset(Iter->second.getOffset()); 840 if (CUOff.getOffset() != Iter->second.getOffset()) 841 logAllUnhandledErrors(createError("Length of CU in CU index doesn't " 842 "match calculated length at offset 0x" + 843 Twine::utohexstr(CUOff.getOffset())), 844 errs()); 845 } 846 847 return; 848 } 849 850 const DWARFUnitIndex &DWARFContext::getCUIndex() { 851 if (CUIndex) 852 return *CUIndex; 853 854 DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0); 855 CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO); 856 CUIndex->parse(CUIndexData); 857 fixupIndex(*DObj, *this, *CUIndex.get()); 858 return *CUIndex; 859 } 860 861 const DWARFUnitIndex &DWARFContext::getTUIndex() { 862 if (TUIndex) 863 return *TUIndex; 864 865 DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); 866 TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES); 867 bool isParseSuccessful = TUIndex->parse(TUIndexData); 868 // If we are parsing TU-index and for .debug_types section we don't need 869 // to do anything. 870 if (isParseSuccessful && TUIndex->getVersion() != 2) 871 fixupIndex(*DObj, *this, *TUIndex.get()); 872 return *TUIndex; 873 } 874 875 DWARFGdbIndex &DWARFContext::getGdbIndex() { 876 if (GdbIndex) 877 return *GdbIndex; 878 879 DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0); 880 GdbIndex = std::make_unique<DWARFGdbIndex>(); 881 GdbIndex->parse(GdbIndexData); 882 return *GdbIndex; 883 } 884 885 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { 886 if (Abbrev) 887 return Abbrev.get(); 888 889 DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0); 890 891 Abbrev.reset(new DWARFDebugAbbrev()); 892 Abbrev->extract(abbrData); 893 return Abbrev.get(); 894 } 895 896 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { 897 if (AbbrevDWO) 898 return AbbrevDWO.get(); 899 900 DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0); 901 AbbrevDWO.reset(new DWARFDebugAbbrev()); 902 AbbrevDWO->extract(abbrData); 903 return AbbrevDWO.get(); 904 } 905 906 const DWARFDebugLoc *DWARFContext::getDebugLoc() { 907 if (Loc) 908 return Loc.get(); 909 910 // Assume all units have the same address byte size. 911 auto LocData = 912 getNumCompileUnits() 913 ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(), 914 getUnitAtIndex(0)->getAddressByteSize()) 915 : DWARFDataExtractor("", isLittleEndian(), 0); 916 Loc.reset(new DWARFDebugLoc(std::move(LocData))); 917 return Loc.get(); 918 } 919 920 const DWARFDebugAranges *DWARFContext::getDebugAranges() { 921 if (Aranges) 922 return Aranges.get(); 923 924 Aranges.reset(new DWARFDebugAranges()); 925 Aranges->generate(this); 926 return Aranges.get(); 927 } 928 929 Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() { 930 if (DebugFrame) 931 return DebugFrame.get(); 932 933 const DWARFSection &DS = DObj->getFrameSection(); 934 935 // There's a "bug" in the DWARFv3 standard with respect to the target address 936 // size within debug frame sections. While DWARF is supposed to be independent 937 // of its container, FDEs have fields with size being "target address size", 938 // which isn't specified in DWARF in general. It's only specified for CUs, but 939 // .eh_frame can appear without a .debug_info section. Follow the example of 940 // other tools (libdwarf) and extract this from the container (ObjectFile 941 // provides this information). This problem is fixed in DWARFv4 942 // See this dwarf-discuss discussion for more details: 943 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html 944 DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(), 945 DObj->getAddressSize()); 946 auto DF = 947 std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false, DS.Address); 948 if (Error E = DF->parse(DebugFrameData)) 949 return std::move(E); 950 951 DebugFrame.swap(DF); 952 return DebugFrame.get(); 953 } 954 955 Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() { 956 if (EHFrame) 957 return EHFrame.get(); 958 959 const DWARFSection &DS = DObj->getEHFrameSection(); 960 DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(), 961 DObj->getAddressSize()); 962 963 auto DF = 964 std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true, DS.Address); 965 if (Error E = DF->parse(DebugFrameData)) 966 return std::move(E); 967 DebugFrame.swap(DF); 968 return DebugFrame.get(); 969 } 970 971 const DWARFDebugMacro *DWARFContext::getDebugMacro() { 972 if (!Macro) 973 Macro = parseMacroOrMacinfo(MacroSection); 974 return Macro.get(); 975 } 976 977 const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() { 978 if (!MacroDWO) 979 MacroDWO = parseMacroOrMacinfo(MacroDwoSection); 980 return MacroDWO.get(); 981 } 982 983 const DWARFDebugMacro *DWARFContext::getDebugMacinfo() { 984 if (!Macinfo) 985 Macinfo = parseMacroOrMacinfo(MacinfoSection); 986 return Macinfo.get(); 987 } 988 989 const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() { 990 if (!MacinfoDWO) 991 MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection); 992 return MacinfoDWO.get(); 993 } 994 995 template <typename T> 996 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj, 997 const DWARFSection &Section, StringRef StringSection, 998 bool IsLittleEndian) { 999 if (Cache) 1000 return *Cache; 1001 DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0); 1002 DataExtractor StrData(StringSection, IsLittleEndian, 0); 1003 Cache.reset(new T(AccelSection, StrData)); 1004 if (Error E = Cache->extract()) 1005 llvm::consumeError(std::move(E)); 1006 return *Cache; 1007 } 1008 1009 const DWARFDebugNames &DWARFContext::getDebugNames() { 1010 return getAccelTable(Names, *DObj, DObj->getNamesSection(), 1011 DObj->getStrSection(), isLittleEndian()); 1012 } 1013 1014 const AppleAcceleratorTable &DWARFContext::getAppleNames() { 1015 return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(), 1016 DObj->getStrSection(), isLittleEndian()); 1017 } 1018 1019 const AppleAcceleratorTable &DWARFContext::getAppleTypes() { 1020 return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(), 1021 DObj->getStrSection(), isLittleEndian()); 1022 } 1023 1024 const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() { 1025 return getAccelTable(AppleNamespaces, *DObj, 1026 DObj->getAppleNamespacesSection(), 1027 DObj->getStrSection(), isLittleEndian()); 1028 } 1029 1030 const AppleAcceleratorTable &DWARFContext::getAppleObjC() { 1031 return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(), 1032 DObj->getStrSection(), isLittleEndian()); 1033 } 1034 1035 const DWARFDebugLine::LineTable * 1036 DWARFContext::getLineTableForUnit(DWARFUnit *U) { 1037 Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable = 1038 getLineTableForUnit(U, WarningHandler); 1039 if (!ExpectedLineTable) { 1040 WarningHandler(ExpectedLineTable.takeError()); 1041 return nullptr; 1042 } 1043 return *ExpectedLineTable; 1044 } 1045 1046 Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit( 1047 DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) { 1048 if (!Line) 1049 Line.reset(new DWARFDebugLine); 1050 1051 auto UnitDIE = U->getUnitDIE(); 1052 if (!UnitDIE) 1053 return nullptr; 1054 1055 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list)); 1056 if (!Offset) 1057 return nullptr; // No line table for this compile unit. 1058 1059 uint64_t stmtOffset = *Offset + U->getLineTableOffset(); 1060 // See if the line table is cached. 1061 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) 1062 return lt; 1063 1064 // Make sure the offset is good before we try to parse. 1065 if (stmtOffset >= U->getLineSection().Data.size()) 1066 return nullptr; 1067 1068 // We have to parse it first. 1069 DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(), 1070 U->getAddressByteSize()); 1071 return Line->getOrParseLineTable(lineData, stmtOffset, *this, U, 1072 RecoverableErrorHandler); 1073 } 1074 1075 void DWARFContext::clearLineTableForUnit(DWARFUnit *U) { 1076 if (!Line) 1077 return; 1078 1079 auto UnitDIE = U->getUnitDIE(); 1080 if (!UnitDIE) 1081 return; 1082 1083 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list)); 1084 if (!Offset) 1085 return; 1086 1087 uint64_t stmtOffset = *Offset + U->getLineTableOffset(); 1088 Line->clearLineTable(stmtOffset); 1089 } 1090 1091 void DWARFContext::parseNormalUnits() { 1092 if (!NormalUnits.empty()) 1093 return; 1094 DObj->forEachInfoSections([&](const DWARFSection &S) { 1095 NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO); 1096 }); 1097 NormalUnits.finishedInfoUnits(); 1098 DObj->forEachTypesSections([&](const DWARFSection &S) { 1099 NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES); 1100 }); 1101 } 1102 1103 void DWARFContext::parseDWOUnits(bool Lazy) { 1104 if (!DWOUnits.empty()) 1105 return; 1106 DObj->forEachInfoDWOSections([&](const DWARFSection &S) { 1107 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy); 1108 }); 1109 DWOUnits.finishedInfoUnits(); 1110 DObj->forEachTypesDWOSections([&](const DWARFSection &S) { 1111 DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy); 1112 }); 1113 } 1114 1115 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) { 1116 parseNormalUnits(); 1117 return dyn_cast_or_null<DWARFCompileUnit>( 1118 NormalUnits.getUnitForOffset(Offset)); 1119 } 1120 1121 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { 1122 // First, get the offset of the compile unit. 1123 uint64_t CUOffset = getDebugAranges()->findAddress(Address); 1124 // Retrieve the compile unit. 1125 if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset)) 1126 return OffsetCU; 1127 1128 // Global variables are often not found by the above search, for one of two 1129 // reasons: 1130 // 1. .debug_aranges may not include global variables. On clang, it seems we 1131 // put the globals in the aranges, but this isn't true for gcc. 1132 // 2. Even if the global variable is in a .debug_arange, global variables 1133 // may not be captured in the [start, end) addresses described by the 1134 // parent compile unit. 1135 // 1136 // So, we walk the CU's and their child DI's manually, looking for the 1137 // specific global variable. 1138 for (std::unique_ptr<DWARFUnit> &CU : compile_units()) { 1139 if (DWARFDie Die = CU->getVariableForAddress(Address)) { 1140 return static_cast<DWARFCompileUnit *>(CU.get()); 1141 } 1142 } 1143 return nullptr; 1144 } 1145 1146 DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) { 1147 DIEsForAddress Result; 1148 1149 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 1150 if (!CU) 1151 return Result; 1152 1153 Result.CompileUnit = CU; 1154 Result.FunctionDIE = CU->getSubroutineForAddress(Address); 1155 1156 std::vector<DWARFDie> Worklist; 1157 Worklist.push_back(Result.FunctionDIE); 1158 while (!Worklist.empty()) { 1159 DWARFDie DIE = Worklist.back(); 1160 Worklist.pop_back(); 1161 1162 if (!DIE.isValid()) 1163 continue; 1164 1165 if (DIE.getTag() == DW_TAG_lexical_block && 1166 DIE.addressRangeContainsAddress(Address)) { 1167 Result.BlockDIE = DIE; 1168 break; 1169 } 1170 1171 append_range(Worklist, DIE); 1172 } 1173 1174 return Result; 1175 } 1176 1177 /// TODO: change input parameter from "uint64_t Address" 1178 /// into "SectionedAddress Address" 1179 static bool getFunctionNameAndStartLineForAddress( 1180 DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, 1181 DILineInfoSpecifier::FileLineInfoKind FileNameKind, 1182 std::string &FunctionName, std::string &StartFile, uint32_t &StartLine, 1183 std::optional<uint64_t> &StartAddress) { 1184 // The address may correspond to instruction in some inlined function, 1185 // so we have to build the chain of inlined functions and take the 1186 // name of the topmost function in it. 1187 SmallVector<DWARFDie, 4> InlinedChain; 1188 CU->getInlinedChainForAddress(Address, InlinedChain); 1189 if (InlinedChain.empty()) 1190 return false; 1191 1192 const DWARFDie &DIE = InlinedChain[0]; 1193 bool FoundResult = false; 1194 const char *Name = nullptr; 1195 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) { 1196 FunctionName = Name; 1197 FoundResult = true; 1198 } 1199 std::string DeclFile = DIE.getDeclFile(FileNameKind); 1200 if (!DeclFile.empty()) { 1201 StartFile = DeclFile; 1202 FoundResult = true; 1203 } 1204 if (auto DeclLineResult = DIE.getDeclLine()) { 1205 StartLine = DeclLineResult; 1206 FoundResult = true; 1207 } 1208 if (auto LowPcAddr = toSectionedAddress(DIE.find(DW_AT_low_pc))) 1209 StartAddress = LowPcAddr->Address; 1210 return FoundResult; 1211 } 1212 1213 static std::optional<int64_t> 1214 getExpressionFrameOffset(ArrayRef<uint8_t> Expr, 1215 std::optional<unsigned> FrameBaseReg) { 1216 if (!Expr.empty() && 1217 (Expr[0] == DW_OP_fbreg || 1218 (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) { 1219 unsigned Count; 1220 int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end()); 1221 // A single DW_OP_fbreg or DW_OP_breg. 1222 if (Expr.size() == Count + 1) 1223 return Offset; 1224 // Same + DW_OP_deref (Fortran arrays look like this). 1225 if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref) 1226 return Offset; 1227 // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value) 1228 } 1229 return std::nullopt; 1230 } 1231 1232 void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, 1233 DWARFDie Die, std::vector<DILocal> &Result) { 1234 if (Die.getTag() == DW_TAG_variable || 1235 Die.getTag() == DW_TAG_formal_parameter) { 1236 DILocal Local; 1237 if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName)) 1238 Local.FunctionName = Name; 1239 1240 std::optional<unsigned> FrameBaseReg; 1241 if (auto FrameBase = Subprogram.find(DW_AT_frame_base)) 1242 if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock()) 1243 if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 && 1244 (*Expr)[0] <= DW_OP_reg31) { 1245 FrameBaseReg = (*Expr)[0] - DW_OP_reg0; 1246 } 1247 1248 if (Expected<std::vector<DWARFLocationExpression>> Loc = 1249 Die.getLocations(DW_AT_location)) { 1250 for (const auto &Entry : *Loc) { 1251 if (std::optional<int64_t> FrameOffset = 1252 getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) { 1253 Local.FrameOffset = *FrameOffset; 1254 break; 1255 } 1256 } 1257 } else { 1258 // FIXME: missing DW_AT_location is OK here, but other errors should be 1259 // reported to the user. 1260 consumeError(Loc.takeError()); 1261 } 1262 1263 if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset)) 1264 Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant(); 1265 1266 if (auto Origin = 1267 Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 1268 Die = Origin; 1269 if (auto NameAttr = Die.find(DW_AT_name)) 1270 if (std::optional<const char *> Name = dwarf::toString(*NameAttr)) 1271 Local.Name = *Name; 1272 if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type)) 1273 Local.Size = Type.getTypeSize(getCUAddrSize()); 1274 if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) { 1275 if (const auto *LT = CU->getContext().getLineTableForUnit(CU)) 1276 LT->getFileNameByIndex( 1277 *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(), 1278 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, 1279 Local.DeclFile); 1280 } 1281 if (auto DeclLineAttr = Die.find(DW_AT_decl_line)) 1282 Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant(); 1283 1284 Result.push_back(Local); 1285 return; 1286 } 1287 1288 if (Die.getTag() == DW_TAG_inlined_subroutine) 1289 if (auto Origin = 1290 Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 1291 Subprogram = Origin; 1292 1293 for (auto Child : Die) 1294 addLocalsForDie(CU, Subprogram, Child, Result); 1295 } 1296 1297 std::vector<DILocal> 1298 DWARFContext::getLocalsForAddress(object::SectionedAddress Address) { 1299 std::vector<DILocal> Result; 1300 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); 1301 if (!CU) 1302 return Result; 1303 1304 DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address); 1305 if (Subprogram.isValid()) 1306 addLocalsForDie(CU, Subprogram, Subprogram, Result); 1307 return Result; 1308 } 1309 1310 DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address, 1311 DILineInfoSpecifier Spec) { 1312 DILineInfo Result; 1313 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); 1314 if (!CU) 1315 return Result; 1316 1317 getFunctionNameAndStartLineForAddress( 1318 CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName, 1319 Result.StartFileName, Result.StartLine, Result.StartAddress); 1320 if (Spec.FLIKind != FileLineInfoKind::None) { 1321 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) { 1322 LineTable->getFileLineInfoForAddress( 1323 {Address.Address, Address.SectionIndex}, CU->getCompilationDir(), 1324 Spec.FLIKind, Result); 1325 } 1326 } 1327 1328 return Result; 1329 } 1330 1331 DILineInfo 1332 DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) { 1333 DILineInfo Result; 1334 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); 1335 if (!CU) 1336 return Result; 1337 1338 if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) { 1339 Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath); 1340 Result.Line = Die.getDeclLine(); 1341 } 1342 1343 return Result; 1344 } 1345 1346 DILineInfoTable DWARFContext::getLineInfoForAddressRange( 1347 object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) { 1348 DILineInfoTable Lines; 1349 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); 1350 if (!CU) 1351 return Lines; 1352 1353 uint32_t StartLine = 0; 1354 std::string StartFileName; 1355 std::string FunctionName(DILineInfo::BadString); 1356 std::optional<uint64_t> StartAddress; 1357 getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, 1358 Spec.FLIKind, FunctionName, 1359 StartFileName, StartLine, StartAddress); 1360 1361 // If the Specifier says we don't need FileLineInfo, just 1362 // return the top-most function at the starting address. 1363 if (Spec.FLIKind == FileLineInfoKind::None) { 1364 DILineInfo Result; 1365 Result.FunctionName = FunctionName; 1366 Result.StartFileName = StartFileName; 1367 Result.StartLine = StartLine; 1368 Result.StartAddress = StartAddress; 1369 Lines.push_back(std::make_pair(Address.Address, Result)); 1370 return Lines; 1371 } 1372 1373 const DWARFLineTable *LineTable = getLineTableForUnit(CU); 1374 1375 // Get the index of row we're looking for in the line table. 1376 std::vector<uint32_t> RowVector; 1377 if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex}, 1378 Size, RowVector)) { 1379 return Lines; 1380 } 1381 1382 for (uint32_t RowIndex : RowVector) { 1383 // Take file number and line/column from the row. 1384 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; 1385 DILineInfo Result; 1386 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(), 1387 Spec.FLIKind, Result.FileName); 1388 Result.FunctionName = FunctionName; 1389 Result.Line = Row.Line; 1390 Result.Column = Row.Column; 1391 Result.StartFileName = StartFileName; 1392 Result.StartLine = StartLine; 1393 Result.StartAddress = StartAddress; 1394 Lines.push_back(std::make_pair(Row.Address.Address, Result)); 1395 } 1396 1397 return Lines; 1398 } 1399 1400 DIInliningInfo 1401 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address, 1402 DILineInfoSpecifier Spec) { 1403 DIInliningInfo InliningInfo; 1404 1405 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); 1406 if (!CU) 1407 return InliningInfo; 1408 1409 const DWARFLineTable *LineTable = nullptr; 1410 SmallVector<DWARFDie, 4> InlinedChain; 1411 CU->getInlinedChainForAddress(Address.Address, InlinedChain); 1412 if (InlinedChain.size() == 0) { 1413 // If there is no DIE for address (e.g. it is in unavailable .dwo file), 1414 // try to at least get file/line info from symbol table. 1415 if (Spec.FLIKind != FileLineInfoKind::None) { 1416 DILineInfo Frame; 1417 LineTable = getLineTableForUnit(CU); 1418 if (LineTable && LineTable->getFileLineInfoForAddress( 1419 {Address.Address, Address.SectionIndex}, 1420 CU->getCompilationDir(), Spec.FLIKind, Frame)) 1421 InliningInfo.addFrame(Frame); 1422 } 1423 return InliningInfo; 1424 } 1425 1426 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0; 1427 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) { 1428 DWARFDie &FunctionDIE = InlinedChain[i]; 1429 DILineInfo Frame; 1430 // Get function name if necessary. 1431 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind)) 1432 Frame.FunctionName = Name; 1433 if (auto DeclLineResult = FunctionDIE.getDeclLine()) 1434 Frame.StartLine = DeclLineResult; 1435 Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind); 1436 if (auto LowPcAddr = toSectionedAddress(FunctionDIE.find(DW_AT_low_pc))) 1437 Frame.StartAddress = LowPcAddr->Address; 1438 if (Spec.FLIKind != FileLineInfoKind::None) { 1439 if (i == 0) { 1440 // For the topmost frame, initialize the line table of this 1441 // compile unit and fetch file/line info from it. 1442 LineTable = getLineTableForUnit(CU); 1443 // For the topmost routine, get file/line info from line table. 1444 if (LineTable) 1445 LineTable->getFileLineInfoForAddress( 1446 {Address.Address, Address.SectionIndex}, CU->getCompilationDir(), 1447 Spec.FLIKind, Frame); 1448 } else { 1449 // Otherwise, use call file, call line and call column from 1450 // previous DIE in inlined chain. 1451 if (LineTable) 1452 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(), 1453 Spec.FLIKind, Frame.FileName); 1454 Frame.Line = CallLine; 1455 Frame.Column = CallColumn; 1456 Frame.Discriminator = CallDiscriminator; 1457 } 1458 // Get call file/line/column of a current DIE. 1459 if (i + 1 < n) { 1460 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn, 1461 CallDiscriminator); 1462 } 1463 } 1464 InliningInfo.addFrame(Frame); 1465 } 1466 return InliningInfo; 1467 } 1468 1469 std::shared_ptr<DWARFContext> 1470 DWARFContext::getDWOContext(StringRef AbsolutePath) { 1471 if (auto S = DWP.lock()) { 1472 DWARFContext *Ctxt = S->Context.get(); 1473 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1474 } 1475 1476 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath]; 1477 1478 if (auto S = Entry->lock()) { 1479 DWARFContext *Ctxt = S->Context.get(); 1480 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1481 } 1482 1483 Expected<OwningBinary<ObjectFile>> Obj = [&] { 1484 if (!CheckedForDWP) { 1485 SmallString<128> DWPName; 1486 auto Obj = object::ObjectFile::createObjectFile( 1487 this->DWPName.empty() 1488 ? (DObj->getFileName() + ".dwp").toStringRef(DWPName) 1489 : StringRef(this->DWPName)); 1490 if (Obj) { 1491 Entry = &DWP; 1492 return Obj; 1493 } else { 1494 CheckedForDWP = true; 1495 // TODO: Should this error be handled (maybe in a high verbosity mode) 1496 // before falling back to .dwo files? 1497 consumeError(Obj.takeError()); 1498 } 1499 } 1500 1501 return object::ObjectFile::createObjectFile(AbsolutePath); 1502 }(); 1503 1504 if (!Obj) { 1505 // TODO: Actually report errors helpfully. 1506 consumeError(Obj.takeError()); 1507 return nullptr; 1508 } 1509 1510 auto S = std::make_shared<DWOFile>(); 1511 S->File = std::move(Obj.get()); 1512 S->Context = DWARFContext::create(*S->File.getBinary(), 1513 ProcessDebugRelocations::Ignore); 1514 *Entry = S; 1515 auto *Ctxt = S->Context.get(); 1516 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 1517 } 1518 1519 static Error createError(const Twine &Reason, llvm::Error E) { 1520 return make_error<StringError>(Reason + toString(std::move(E)), 1521 inconvertibleErrorCode()); 1522 } 1523 1524 /// SymInfo contains information about symbol: it's address 1525 /// and section index which is -1LL for absolute symbols. 1526 struct SymInfo { 1527 uint64_t Address; 1528 uint64_t SectionIndex; 1529 }; 1530 1531 /// Returns the address of symbol relocation used against and a section index. 1532 /// Used for futher relocations computation. Symbol's section load address is 1533 static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj, 1534 const RelocationRef &Reloc, 1535 const LoadedObjectInfo *L, 1536 std::map<SymbolRef, SymInfo> &Cache) { 1537 SymInfo Ret = {0, (uint64_t)-1LL}; 1538 object::section_iterator RSec = Obj.section_end(); 1539 object::symbol_iterator Sym = Reloc.getSymbol(); 1540 1541 std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end(); 1542 // First calculate the address of the symbol or section as it appears 1543 // in the object file 1544 if (Sym != Obj.symbol_end()) { 1545 bool New; 1546 std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}}); 1547 if (!New) 1548 return CacheIt->second; 1549 1550 Expected<uint64_t> SymAddrOrErr = Sym->getAddress(); 1551 if (!SymAddrOrErr) 1552 return createError("failed to compute symbol address: ", 1553 SymAddrOrErr.takeError()); 1554 1555 // Also remember what section this symbol is in for later 1556 auto SectOrErr = Sym->getSection(); 1557 if (!SectOrErr) 1558 return createError("failed to get symbol section: ", 1559 SectOrErr.takeError()); 1560 1561 RSec = *SectOrErr; 1562 Ret.Address = *SymAddrOrErr; 1563 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) { 1564 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); 1565 Ret.Address = RSec->getAddress(); 1566 } 1567 1568 if (RSec != Obj.section_end()) 1569 Ret.SectionIndex = RSec->getIndex(); 1570 1571 // If we are given load addresses for the sections, we need to adjust: 1572 // SymAddr = (Address of Symbol Or Section in File) - 1573 // (Address of Section in File) + 1574 // (Load Address of Section) 1575 // RSec is now either the section being targeted or the section 1576 // containing the symbol being targeted. In either case, 1577 // we need to perform the same computation. 1578 if (L && RSec != Obj.section_end()) 1579 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) 1580 Ret.Address += SectionLoadAddress - RSec->getAddress(); 1581 1582 if (CacheIt != Cache.end()) 1583 CacheIt->second = Ret; 1584 1585 return Ret; 1586 } 1587 1588 static bool isRelocScattered(const object::ObjectFile &Obj, 1589 const RelocationRef &Reloc) { 1590 const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj); 1591 if (!MachObj) 1592 return false; 1593 // MachO also has relocations that point to sections and 1594 // scattered relocations. 1595 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl()); 1596 return MachObj->isRelocationScattered(RelocInfo); 1597 } 1598 1599 namespace { 1600 struct DWARFSectionMap final : public DWARFSection { 1601 RelocAddrMap Relocs; 1602 }; 1603 1604 class DWARFObjInMemory final : public DWARFObject { 1605 bool IsLittleEndian; 1606 uint8_t AddressSize; 1607 StringRef FileName; 1608 const object::ObjectFile *Obj = nullptr; 1609 std::vector<SectionName> SectionNames; 1610 1611 using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap, 1612 std::map<object::SectionRef, unsigned>>; 1613 1614 InfoSectionMap InfoSections; 1615 InfoSectionMap TypesSections; 1616 InfoSectionMap InfoDWOSections; 1617 InfoSectionMap TypesDWOSections; 1618 1619 DWARFSectionMap LocSection; 1620 DWARFSectionMap LoclistsSection; 1621 DWARFSectionMap LoclistsDWOSection; 1622 DWARFSectionMap LineSection; 1623 DWARFSectionMap RangesSection; 1624 DWARFSectionMap RnglistsSection; 1625 DWARFSectionMap StrOffsetsSection; 1626 DWARFSectionMap LineDWOSection; 1627 DWARFSectionMap FrameSection; 1628 DWARFSectionMap EHFrameSection; 1629 DWARFSectionMap LocDWOSection; 1630 DWARFSectionMap StrOffsetsDWOSection; 1631 DWARFSectionMap RangesDWOSection; 1632 DWARFSectionMap RnglistsDWOSection; 1633 DWARFSectionMap AddrSection; 1634 DWARFSectionMap AppleNamesSection; 1635 DWARFSectionMap AppleTypesSection; 1636 DWARFSectionMap AppleNamespacesSection; 1637 DWARFSectionMap AppleObjCSection; 1638 DWARFSectionMap NamesSection; 1639 DWARFSectionMap PubnamesSection; 1640 DWARFSectionMap PubtypesSection; 1641 DWARFSectionMap GnuPubnamesSection; 1642 DWARFSectionMap GnuPubtypesSection; 1643 DWARFSectionMap MacroSection; 1644 1645 DWARFSectionMap *mapNameToDWARFSection(StringRef Name) { 1646 return StringSwitch<DWARFSectionMap *>(Name) 1647 .Case("debug_loc", &LocSection) 1648 .Case("debug_loclists", &LoclistsSection) 1649 .Case("debug_loclists.dwo", &LoclistsDWOSection) 1650 .Case("debug_line", &LineSection) 1651 .Case("debug_frame", &FrameSection) 1652 .Case("eh_frame", &EHFrameSection) 1653 .Case("debug_str_offsets", &StrOffsetsSection) 1654 .Case("debug_ranges", &RangesSection) 1655 .Case("debug_rnglists", &RnglistsSection) 1656 .Case("debug_loc.dwo", &LocDWOSection) 1657 .Case("debug_line.dwo", &LineDWOSection) 1658 .Case("debug_names", &NamesSection) 1659 .Case("debug_rnglists.dwo", &RnglistsDWOSection) 1660 .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection) 1661 .Case("debug_addr", &AddrSection) 1662 .Case("apple_names", &AppleNamesSection) 1663 .Case("debug_pubnames", &PubnamesSection) 1664 .Case("debug_pubtypes", &PubtypesSection) 1665 .Case("debug_gnu_pubnames", &GnuPubnamesSection) 1666 .Case("debug_gnu_pubtypes", &GnuPubtypesSection) 1667 .Case("apple_types", &AppleTypesSection) 1668 .Case("apple_namespaces", &AppleNamespacesSection) 1669 .Case("apple_namespac", &AppleNamespacesSection) 1670 .Case("apple_objc", &AppleObjCSection) 1671 .Case("debug_macro", &MacroSection) 1672 .Default(nullptr); 1673 } 1674 1675 StringRef AbbrevSection; 1676 StringRef ArangesSection; 1677 StringRef StrSection; 1678 StringRef MacinfoSection; 1679 StringRef MacinfoDWOSection; 1680 StringRef MacroDWOSection; 1681 StringRef AbbrevDWOSection; 1682 StringRef StrDWOSection; 1683 StringRef CUIndexSection; 1684 StringRef GdbIndexSection; 1685 StringRef TUIndexSection; 1686 StringRef LineStrSection; 1687 1688 // A deque holding section data whose iterators are not invalidated when 1689 // new decompressed sections are inserted at the end. 1690 std::deque<SmallString<0>> UncompressedSections; 1691 1692 StringRef *mapSectionToMember(StringRef Name) { 1693 if (DWARFSection *Sec = mapNameToDWARFSection(Name)) 1694 return &Sec->Data; 1695 return StringSwitch<StringRef *>(Name) 1696 .Case("debug_abbrev", &AbbrevSection) 1697 .Case("debug_aranges", &ArangesSection) 1698 .Case("debug_str", &StrSection) 1699 .Case("debug_macinfo", &MacinfoSection) 1700 .Case("debug_macinfo.dwo", &MacinfoDWOSection) 1701 .Case("debug_macro.dwo", &MacroDWOSection) 1702 .Case("debug_abbrev.dwo", &AbbrevDWOSection) 1703 .Case("debug_str.dwo", &StrDWOSection) 1704 .Case("debug_cu_index", &CUIndexSection) 1705 .Case("debug_tu_index", &TUIndexSection) 1706 .Case("gdb_index", &GdbIndexSection) 1707 .Case("debug_line_str", &LineStrSection) 1708 // Any more debug info sections go here. 1709 .Default(nullptr); 1710 } 1711 1712 /// If Sec is compressed section, decompresses and updates its contents 1713 /// provided by Data. Otherwise leaves it unchanged. 1714 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, 1715 StringRef &Data) { 1716 if (!Sec.isCompressed()) 1717 return Error::success(); 1718 1719 Expected<Decompressor> Decompressor = 1720 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); 1721 if (!Decompressor) 1722 return Decompressor.takeError(); 1723 1724 SmallString<0> Out; 1725 if (auto Err = Decompressor->resizeAndDecompress(Out)) 1726 return Err; 1727 1728 UncompressedSections.push_back(std::move(Out)); 1729 Data = UncompressedSections.back(); 1730 1731 return Error::success(); 1732 } 1733 1734 public: 1735 DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 1736 uint8_t AddrSize, bool IsLittleEndian) 1737 : IsLittleEndian(IsLittleEndian) { 1738 for (const auto &SecIt : Sections) { 1739 if (StringRef *SectionData = mapSectionToMember(SecIt.first())) 1740 *SectionData = SecIt.second->getBuffer(); 1741 else if (SecIt.first() == "debug_info") 1742 // Find debug_info and debug_types data by section rather than name as 1743 // there are multiple, comdat grouped, of these sections. 1744 InfoSections[SectionRef()].Data = SecIt.second->getBuffer(); 1745 else if (SecIt.first() == "debug_info.dwo") 1746 InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer(); 1747 else if (SecIt.first() == "debug_types") 1748 TypesSections[SectionRef()].Data = SecIt.second->getBuffer(); 1749 else if (SecIt.first() == "debug_types.dwo") 1750 TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer(); 1751 } 1752 } 1753 DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L, 1754 function_ref<void(Error)> HandleError, 1755 function_ref<void(Error)> HandleWarning, 1756 DWARFContext::ProcessDebugRelocations RelocAction) 1757 : IsLittleEndian(Obj.isLittleEndian()), 1758 AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()), 1759 Obj(&Obj) { 1760 1761 StringMap<unsigned> SectionAmountMap; 1762 for (const SectionRef &Section : Obj.sections()) { 1763 StringRef Name; 1764 if (auto NameOrErr = Section.getName()) 1765 Name = *NameOrErr; 1766 else 1767 consumeError(NameOrErr.takeError()); 1768 1769 ++SectionAmountMap[Name]; 1770 SectionNames.push_back({ Name, true }); 1771 1772 // Skip BSS and Virtual sections, they aren't interesting. 1773 if (Section.isBSS() || Section.isVirtual()) 1774 continue; 1775 1776 // Skip sections stripped by dsymutil. 1777 if (Section.isStripped()) 1778 continue; 1779 1780 StringRef Data; 1781 Expected<section_iterator> SecOrErr = Section.getRelocatedSection(); 1782 if (!SecOrErr) { 1783 HandleError(createError("failed to get relocated section: ", 1784 SecOrErr.takeError())); 1785 continue; 1786 } 1787 1788 // Try to obtain an already relocated version of this section. 1789 // Else use the unrelocated section from the object file. We'll have to 1790 // apply relocations ourselves later. 1791 section_iterator RelocatedSection = 1792 Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end(); 1793 if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) { 1794 Expected<StringRef> E = Section.getContents(); 1795 if (E) 1796 Data = *E; 1797 else 1798 // maybeDecompress below will error. 1799 consumeError(E.takeError()); 1800 } 1801 1802 if (auto Err = maybeDecompress(Section, Name, Data)) { 1803 HandleError(createError("failed to decompress '" + Name + "', ", 1804 std::move(Err))); 1805 continue; 1806 } 1807 1808 // Compressed sections names in GNU style starts from ".z", 1809 // at this point section is decompressed and we drop compression prefix. 1810 Name = Name.substr( 1811 Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. 1812 1813 // Map platform specific debug section names to DWARF standard section 1814 // names. 1815 Name = Obj.mapDebugSectionName(Name); 1816 1817 if (StringRef *SectionData = mapSectionToMember(Name)) { 1818 *SectionData = Data; 1819 if (Name == "debug_ranges") { 1820 // FIXME: Use the other dwo range section when we emit it. 1821 RangesDWOSection.Data = Data; 1822 } else if (Name == "debug_frame" || Name == "eh_frame") { 1823 if (DWARFSection *S = mapNameToDWARFSection(Name)) 1824 S->Address = Section.getAddress(); 1825 } 1826 } else if (InfoSectionMap *Sections = 1827 StringSwitch<InfoSectionMap *>(Name) 1828 .Case("debug_info", &InfoSections) 1829 .Case("debug_info.dwo", &InfoDWOSections) 1830 .Case("debug_types", &TypesSections) 1831 .Case("debug_types.dwo", &TypesDWOSections) 1832 .Default(nullptr)) { 1833 // Find debug_info and debug_types data by section rather than name as 1834 // there are multiple, comdat grouped, of these sections. 1835 DWARFSectionMap &S = (*Sections)[Section]; 1836 S.Data = Data; 1837 } 1838 1839 if (RelocatedSection != Obj.section_end() && Name.contains(".dwo")) 1840 HandleWarning( 1841 createError("Unexpected relocations for dwo section " + Name)); 1842 1843 if (RelocatedSection == Obj.section_end() || 1844 (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore)) 1845 continue; 1846 1847 StringRef RelSecName; 1848 if (auto NameOrErr = RelocatedSection->getName()) 1849 RelSecName = *NameOrErr; 1850 else 1851 consumeError(NameOrErr.takeError()); 1852 1853 // If the section we're relocating was relocated already by the JIT, 1854 // then we used the relocated version above, so we do not need to process 1855 // relocations for it now. 1856 StringRef RelSecData; 1857 if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) 1858 continue; 1859 1860 // In Mach-o files, the relocations do not need to be applied if 1861 // there is no load offset to apply. The value read at the 1862 // relocation point already factors in the section address 1863 // (actually applying the relocations will produce wrong results 1864 // as the section address will be added twice). 1865 if (!L && isa<MachOObjectFile>(&Obj)) 1866 continue; 1867 1868 RelSecName = RelSecName.substr( 1869 RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes. 1870 1871 // TODO: Add support for relocations in other sections as needed. 1872 // Record relocations for the debug_info and debug_line sections. 1873 DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName); 1874 RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr; 1875 if (!Map) { 1876 // Find debug_info and debug_types relocs by section rather than name 1877 // as there are multiple, comdat grouped, of these sections. 1878 if (RelSecName == "debug_info") 1879 Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection]) 1880 .Relocs; 1881 else if (RelSecName == "debug_types") 1882 Map = 1883 &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection]) 1884 .Relocs; 1885 else 1886 continue; 1887 } 1888 1889 if (Section.relocation_begin() == Section.relocation_end()) 1890 continue; 1891 1892 // Symbol to [address, section index] cache mapping. 1893 std::map<SymbolRef, SymInfo> AddrCache; 1894 SupportsRelocation Supports; 1895 RelocationResolver Resolver; 1896 std::tie(Supports, Resolver) = getRelocationResolver(Obj); 1897 for (const RelocationRef &Reloc : Section.relocations()) { 1898 // FIXME: it's not clear how to correctly handle scattered 1899 // relocations. 1900 if (isRelocScattered(Obj, Reloc)) 1901 continue; 1902 1903 Expected<SymInfo> SymInfoOrErr = 1904 getSymbolInfo(Obj, Reloc, L, AddrCache); 1905 if (!SymInfoOrErr) { 1906 HandleError(SymInfoOrErr.takeError()); 1907 continue; 1908 } 1909 1910 // Check if Resolver can handle this relocation type early so as not to 1911 // handle invalid cases in DWARFDataExtractor. 1912 // 1913 // TODO Don't store Resolver in every RelocAddrEntry. 1914 if (Supports && Supports(Reloc.getType())) { 1915 auto I = Map->try_emplace( 1916 Reloc.getOffset(), 1917 RelocAddrEntry{ 1918 SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address, 1919 std::optional<object::RelocationRef>(), 0, Resolver}); 1920 // If we didn't successfully insert that's because we already had a 1921 // relocation for that offset. Store it as a second relocation in the 1922 // same RelocAddrEntry instead. 1923 if (!I.second) { 1924 RelocAddrEntry &entry = I.first->getSecond(); 1925 if (entry.Reloc2) { 1926 HandleError(createError( 1927 "At most two relocations per offset are supported")); 1928 } 1929 entry.Reloc2 = Reloc; 1930 entry.SymbolValue2 = SymInfoOrErr->Address; 1931 } 1932 } else { 1933 SmallString<32> Type; 1934 Reloc.getTypeName(Type); 1935 // FIXME: Support more relocations & change this to an error 1936 HandleWarning( 1937 createError("failed to compute relocation: " + Type + ", ", 1938 errorCodeToError(object_error::parse_failed))); 1939 } 1940 } 1941 } 1942 1943 for (SectionName &S : SectionNames) 1944 if (SectionAmountMap[S.Name] > 1) 1945 S.IsNameUnique = false; 1946 } 1947 1948 std::optional<RelocAddrEntry> find(const DWARFSection &S, 1949 uint64_t Pos) const override { 1950 auto &Sec = static_cast<const DWARFSectionMap &>(S); 1951 RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos); 1952 if (AI == Sec.Relocs.end()) 1953 return std::nullopt; 1954 return AI->second; 1955 } 1956 1957 const object::ObjectFile *getFile() const override { return Obj; } 1958 1959 ArrayRef<SectionName> getSectionNames() const override { 1960 return SectionNames; 1961 } 1962 1963 bool isLittleEndian() const override { return IsLittleEndian; } 1964 StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; } 1965 const DWARFSection &getLineDWOSection() const override { 1966 return LineDWOSection; 1967 } 1968 const DWARFSection &getLocDWOSection() const override { 1969 return LocDWOSection; 1970 } 1971 StringRef getStrDWOSection() const override { return StrDWOSection; } 1972 const DWARFSection &getStrOffsetsDWOSection() const override { 1973 return StrOffsetsDWOSection; 1974 } 1975 const DWARFSection &getRangesDWOSection() const override { 1976 return RangesDWOSection; 1977 } 1978 const DWARFSection &getRnglistsDWOSection() const override { 1979 return RnglistsDWOSection; 1980 } 1981 const DWARFSection &getLoclistsDWOSection() const override { 1982 return LoclistsDWOSection; 1983 } 1984 const DWARFSection &getAddrSection() const override { return AddrSection; } 1985 StringRef getCUIndexSection() const override { return CUIndexSection; } 1986 StringRef getGdbIndexSection() const override { return GdbIndexSection; } 1987 StringRef getTUIndexSection() const override { return TUIndexSection; } 1988 1989 // DWARF v5 1990 const DWARFSection &getStrOffsetsSection() const override { 1991 return StrOffsetsSection; 1992 } 1993 StringRef getLineStrSection() const override { return LineStrSection; } 1994 1995 // Sections for DWARF5 split dwarf proposal. 1996 void forEachInfoDWOSections( 1997 function_ref<void(const DWARFSection &)> F) const override { 1998 for (auto &P : InfoDWOSections) 1999 F(P.second); 2000 } 2001 void forEachTypesDWOSections( 2002 function_ref<void(const DWARFSection &)> F) const override { 2003 for (auto &P : TypesDWOSections) 2004 F(P.second); 2005 } 2006 2007 StringRef getAbbrevSection() const override { return AbbrevSection; } 2008 const DWARFSection &getLocSection() const override { return LocSection; } 2009 const DWARFSection &getLoclistsSection() const override { return LoclistsSection; } 2010 StringRef getArangesSection() const override { return ArangesSection; } 2011 const DWARFSection &getFrameSection() const override { 2012 return FrameSection; 2013 } 2014 const DWARFSection &getEHFrameSection() const override { 2015 return EHFrameSection; 2016 } 2017 const DWARFSection &getLineSection() const override { return LineSection; } 2018 StringRef getStrSection() const override { return StrSection; } 2019 const DWARFSection &getRangesSection() const override { return RangesSection; } 2020 const DWARFSection &getRnglistsSection() const override { 2021 return RnglistsSection; 2022 } 2023 const DWARFSection &getMacroSection() const override { return MacroSection; } 2024 StringRef getMacroDWOSection() const override { return MacroDWOSection; } 2025 StringRef getMacinfoSection() const override { return MacinfoSection; } 2026 StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; } 2027 const DWARFSection &getPubnamesSection() const override { return PubnamesSection; } 2028 const DWARFSection &getPubtypesSection() const override { return PubtypesSection; } 2029 const DWARFSection &getGnuPubnamesSection() const override { 2030 return GnuPubnamesSection; 2031 } 2032 const DWARFSection &getGnuPubtypesSection() const override { 2033 return GnuPubtypesSection; 2034 } 2035 const DWARFSection &getAppleNamesSection() const override { 2036 return AppleNamesSection; 2037 } 2038 const DWARFSection &getAppleTypesSection() const override { 2039 return AppleTypesSection; 2040 } 2041 const DWARFSection &getAppleNamespacesSection() const override { 2042 return AppleNamespacesSection; 2043 } 2044 const DWARFSection &getAppleObjCSection() const override { 2045 return AppleObjCSection; 2046 } 2047 const DWARFSection &getNamesSection() const override { 2048 return NamesSection; 2049 } 2050 2051 StringRef getFileName() const override { return FileName; } 2052 uint8_t getAddressSize() const override { return AddressSize; } 2053 void forEachInfoSections( 2054 function_ref<void(const DWARFSection &)> F) const override { 2055 for (auto &P : InfoSections) 2056 F(P.second); 2057 } 2058 void forEachTypesSections( 2059 function_ref<void(const DWARFSection &)> F) const override { 2060 for (auto &P : TypesSections) 2061 F(P.second); 2062 } 2063 }; 2064 } // namespace 2065 2066 std::unique_ptr<DWARFContext> 2067 DWARFContext::create(const object::ObjectFile &Obj, 2068 ProcessDebugRelocations RelocAction, 2069 const LoadedObjectInfo *L, std::string DWPName, 2070 std::function<void(Error)> RecoverableErrorHandler, 2071 std::function<void(Error)> WarningHandler) { 2072 auto DObj = std::make_unique<DWARFObjInMemory>( 2073 Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction); 2074 return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName), 2075 RecoverableErrorHandler, 2076 WarningHandler); 2077 } 2078 2079 std::unique_ptr<DWARFContext> 2080 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 2081 uint8_t AddrSize, bool isLittleEndian, 2082 std::function<void(Error)> RecoverableErrorHandler, 2083 std::function<void(Error)> WarningHandler) { 2084 auto DObj = 2085 std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); 2086 return std::make_unique<DWARFContext>( 2087 std::move(DObj), "", RecoverableErrorHandler, WarningHandler); 2088 } 2089 2090 uint8_t DWARFContext::getCUAddrSize() { 2091 // In theory, different compile units may have different address byte 2092 // sizes, but for simplicity we just use the address byte size of the 2093 // first compile unit. In practice the address size field is repeated across 2094 // various DWARF headers (at least in version 5) to make it easier to dump 2095 // them independently, not to enable varying the address size. 2096 auto CUs = compile_units(); 2097 return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize(); 2098 } 2099