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/DebugInfo/DWARF/DWARFAcceleratorTable.h" 17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 19 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 20 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" 21 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 22 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 23 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 24 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 25 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h" 26 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 27 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 28 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 29 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" 30 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 31 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 32 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" 33 #include "llvm/Object/Decompressor.h" 34 #include "llvm/Object/MachO.h" 35 #include "llvm/Object/ObjectFile.h" 36 #include "llvm/Object/RelocVisitor.h" 37 #include "llvm/Support/Casting.h" 38 #include "llvm/Support/DataExtractor.h" 39 #include "llvm/Support/Debug.h" 40 #include "llvm/Support/Error.h" 41 #include "llvm/Support/Format.h" 42 #include "llvm/Support/MemoryBuffer.h" 43 #include "llvm/Support/raw_ostream.h" 44 #include <algorithm> 45 #include <cstdint> 46 #include <map> 47 #include <set> 48 #include <string> 49 #include <utility> 50 #include <vector> 51 52 using namespace llvm; 53 using namespace dwarf; 54 using namespace object; 55 56 #define DEBUG_TYPE "dwarf" 57 58 typedef DWARFDebugLine::LineTable DWARFLineTable; 59 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; 60 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; 61 62 uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size, 63 uint32_t *Off, const RelocAddrMap *Relocs) { 64 if (!Relocs) 65 return Data.getUnsigned(Off, Size); 66 RelocAddrMap::const_iterator AI = Relocs->find(*Off); 67 if (AI == Relocs->end()) 68 return Data.getUnsigned(Off, Size); 69 return Data.getUnsigned(Off, Size) + AI->second.Value; 70 } 71 72 static void dumpAccelSection(raw_ostream &OS, StringRef Name, 73 const DWARFSection& Section, StringRef StringSection, 74 bool LittleEndian) { 75 DataExtractor AccelSection(Section.Data, LittleEndian, 0); 76 DataExtractor StrData(StringSection, LittleEndian, 0); 77 OS << "\n." << Name << " contents:\n"; 78 DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs); 79 if (!Accel.extract()) 80 return; 81 Accel.dump(OS); 82 } 83 84 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH, 85 bool SummarizeTypes) { 86 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) { 87 OS << ".debug_abbrev contents:\n"; 88 getDebugAbbrev()->dump(OS); 89 } 90 91 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) 92 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) { 93 OS << "\n.debug_abbrev.dwo contents:\n"; 94 D->dump(OS); 95 } 96 97 if (DumpType == DIDT_All || DumpType == DIDT_Info) { 98 OS << "\n.debug_info contents:\n"; 99 for (const auto &CU : compile_units()) 100 CU->dump(OS); 101 } 102 103 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) && 104 getNumDWOCompileUnits()) { 105 OS << "\n.debug_info.dwo contents:\n"; 106 for (const auto &DWOCU : dwo_compile_units()) 107 DWOCU->dump(OS); 108 } 109 110 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) { 111 OS << "\n.debug_types contents:\n"; 112 for (const auto &TUS : type_unit_sections()) 113 for (const auto &TU : TUS) 114 TU->dump(OS, SummarizeTypes); 115 } 116 117 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) && 118 getNumDWOTypeUnits()) { 119 OS << "\n.debug_types.dwo contents:\n"; 120 for (const auto &DWOTUS : dwo_type_unit_sections()) 121 for (const auto &DWOTU : DWOTUS) 122 DWOTU->dump(OS, SummarizeTypes); 123 } 124 125 if (DumpType == DIDT_All || DumpType == DIDT_Loc) { 126 OS << "\n.debug_loc contents:\n"; 127 getDebugLoc()->dump(OS); 128 } 129 130 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) { 131 OS << "\n.debug_loc.dwo contents:\n"; 132 getDebugLocDWO()->dump(OS); 133 } 134 135 if (DumpType == DIDT_All || DumpType == DIDT_Frames) { 136 OS << "\n.debug_frame contents:\n"; 137 getDebugFrame()->dump(OS); 138 if (DumpEH) { 139 OS << "\n.eh_frame contents:\n"; 140 getEHFrame()->dump(OS); 141 } 142 } 143 144 if (DumpType == DIDT_All || DumpType == DIDT_Macro) { 145 OS << "\n.debug_macinfo contents:\n"; 146 getDebugMacro()->dump(OS); 147 } 148 149 uint32_t offset = 0; 150 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) { 151 OS << "\n.debug_aranges contents:\n"; 152 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); 153 DWARFDebugArangeSet set; 154 while (set.extract(arangesData, &offset)) 155 set.dump(OS); 156 } 157 158 uint8_t savedAddressByteSize = 0; 159 if (DumpType == DIDT_All || DumpType == DIDT_Line) { 160 OS << "\n.debug_line contents:\n"; 161 for (const auto &CU : compile_units()) { 162 savedAddressByteSize = CU->getAddressByteSize(); 163 auto CUDIE = CU->getUnitDIE(); 164 if (!CUDIE) 165 continue; 166 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) { 167 DataExtractor lineData(getLineSection().Data, isLittleEndian(), 168 savedAddressByteSize); 169 DWARFDebugLine::LineTable LineTable; 170 uint32_t Offset = *StmtOffset; 171 LineTable.parse(lineData, &getLineSection().Relocs, &Offset); 172 LineTable.dump(OS); 173 } 174 } 175 } 176 177 if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) { 178 OS << "\n.debug_cu_index contents:\n"; 179 getCUIndex().dump(OS); 180 } 181 182 if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) { 183 OS << "\n.debug_tu_index contents:\n"; 184 getTUIndex().dump(OS); 185 } 186 187 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) { 188 OS << "\n.debug_line.dwo contents:\n"; 189 unsigned stmtOffset = 0; 190 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(), 191 savedAddressByteSize); 192 DWARFDebugLine::LineTable LineTable; 193 while (LineTable.Prologue.parse(lineData, &stmtOffset)) { 194 LineTable.dump(OS); 195 LineTable.clear(); 196 } 197 } 198 199 if (DumpType == DIDT_All || DumpType == DIDT_Str) { 200 OS << "\n.debug_str contents:\n"; 201 DataExtractor strData(getStringSection(), isLittleEndian(), 0); 202 offset = 0; 203 uint32_t strOffset = 0; 204 while (const char *s = strData.getCStr(&offset)) { 205 OS << format("0x%8.8x: \"%s\"\n", strOffset, s); 206 strOffset = offset; 207 } 208 } 209 210 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) && 211 !getStringDWOSection().empty()) { 212 OS << "\n.debug_str.dwo contents:\n"; 213 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0); 214 offset = 0; 215 uint32_t strDWOOffset = 0; 216 while (const char *s = strDWOData.getCStr(&offset)) { 217 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); 218 strDWOOffset = offset; 219 } 220 } 221 222 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) { 223 OS << "\n.debug_ranges contents:\n"; 224 // In fact, different compile units may have different address byte 225 // sizes, but for simplicity we just use the address byte size of the last 226 // compile unit (there is no easy and fast way to associate address range 227 // list and the compile unit it describes). 228 DataExtractor rangesData(getRangeSection().Data, isLittleEndian(), 229 savedAddressByteSize); 230 offset = 0; 231 DWARFDebugRangeList rangeList; 232 while (rangeList.extract(rangesData, &offset, getRangeSection().Relocs)) 233 rangeList.dump(OS); 234 } 235 236 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) 237 DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false) 238 .dump("debug_pubnames", OS); 239 240 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes) 241 DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false) 242 .dump("debug_pubtypes", OS); 243 244 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames) 245 DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(), 246 true /* GnuStyle */) 247 .dump("debug_gnu_pubnames", OS); 248 249 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) 250 DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(), 251 true /* GnuStyle */) 252 .dump("debug_gnu_pubtypes", OS); 253 254 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) && 255 !getStringOffsetDWOSection().empty()) { 256 OS << "\n.debug_str_offsets.dwo contents:\n"; 257 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 258 0); 259 offset = 0; 260 uint64_t size = getStringOffsetDWOSection().size(); 261 while (offset < size) { 262 OS << format("0x%8.8x: ", offset); 263 OS << format("%8.8x\n", strOffsetExt.getU32(&offset)); 264 } 265 } 266 267 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) && 268 !getGdbIndexSection().empty()) { 269 OS << "\n.gnu_index contents:\n"; 270 getGdbIndex().dump(OS); 271 } 272 273 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames) 274 dumpAccelSection(OS, "apple_names", getAppleNamesSection(), 275 getStringSection(), isLittleEndian()); 276 277 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes) 278 dumpAccelSection(OS, "apple_types", getAppleTypesSection(), 279 getStringSection(), isLittleEndian()); 280 281 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces) 282 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(), 283 getStringSection(), isLittleEndian()); 284 285 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC) 286 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(), 287 getStringSection(), isLittleEndian()); 288 } 289 290 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { 291 // FIXME: Improve this for the case where this DWO file is really a DWP file 292 // with an index - use the index for lookup instead of a linear search. 293 for (const auto &DWOCU : dwo_compile_units()) 294 if (DWOCU->getDWOId() == Hash) 295 return DWOCU.get(); 296 return nullptr; 297 } 298 299 DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) { 300 parseCompileUnits(); 301 if (auto *CU = CUs.getUnitForOffset(Offset)) 302 return CU->getDIEForOffset(Offset); 303 return DWARFDie(); 304 } 305 306 namespace { 307 308 class Verifier { 309 raw_ostream &OS; 310 DWARFContext &DCtx; 311 public: 312 Verifier(raw_ostream &S, DWARFContext &D) : OS(S), DCtx(D) {} 313 314 bool HandleDebugInfo() { 315 bool Success = true; 316 // A map that tracks all references (converted absolute references) so we 317 // can verify each reference points to a valid DIE and not an offset that 318 // lies between to valid DIEs. 319 std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets; 320 321 OS << "Verifying .debug_info...\n"; 322 for (const auto &CU : DCtx.compile_units()) { 323 unsigned NumDies = CU->getNumDIEs(); 324 for (unsigned I = 0; I < NumDies; ++I) { 325 auto Die = CU->getDIEAtIndex(I); 326 const auto Tag = Die.getTag(); 327 if (Tag == DW_TAG_null) 328 continue; 329 for (auto AttrValue : Die.attributes()) { 330 const auto Attr = AttrValue.Attr; 331 const auto Form = AttrValue.Value.getForm(); 332 switch (Attr) { 333 case DW_AT_ranges: 334 // Make sure the offset in the DW_AT_ranges attribute is valid. 335 if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) { 336 if (*SectionOffset >= DCtx.getRangeSection().Data.size()) { 337 Success = false; 338 OS << "error: DW_AT_ranges offset is beyond .debug_ranges " 339 "bounds:\n"; 340 Die.dump(OS, 0); 341 OS << "\n"; 342 } 343 } else { 344 Success = false; 345 OS << "error: DIE has invalid DW_AT_ranges encoding:\n"; 346 Die.dump(OS, 0); 347 OS << "\n"; 348 } 349 break; 350 case DW_AT_stmt_list: 351 // Make sure the offset in the DW_AT_stmt_list attribute is valid. 352 if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) { 353 if (*SectionOffset >= DCtx.getLineSection().Data.size()) { 354 Success = false; 355 OS << "error: DW_AT_stmt_list offset is beyond .debug_line " 356 "bounds: " 357 << format("0x%08" PRIx32, *SectionOffset) << "\n"; 358 CU->getUnitDIE().dump(OS, 0); 359 OS << "\n"; 360 } 361 } else { 362 Success = false; 363 OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n"; 364 Die.dump(OS, 0); 365 OS << "\n"; 366 } 367 break; 368 369 default: 370 break; 371 } 372 switch (Form) { 373 case DW_FORM_ref1: 374 case DW_FORM_ref2: 375 case DW_FORM_ref4: 376 case DW_FORM_ref8: 377 case DW_FORM_ref_udata: { 378 // Verify all CU relative references are valid CU offsets. 379 Optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); 380 assert(RefVal); 381 if (RefVal) { 382 auto DieCU = Die.getDwarfUnit(); 383 auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset(); 384 auto CUOffset = AttrValue.Value.getRawUValue(); 385 if (CUOffset >= CUSize) { 386 Success = false; 387 OS << "error: " << FormEncodingString(Form) << " CU offset " 388 << format("0x%08" PRIx32, CUOffset) 389 << " is invalid (must be less than CU size of " 390 << format("0x%08" PRIx32, CUSize) << "):\n"; 391 Die.dump(OS, 0); 392 OS << "\n"; 393 } else { 394 // Valid reference, but we will verify it points to an actual 395 // DIE later. 396 ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset()); 397 } 398 } 399 break; 400 } 401 case DW_FORM_ref_addr: { 402 // Verify all absolute DIE references have valid offsets in the 403 // .debug_info section. 404 Optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); 405 assert(RefVal); 406 if (RefVal) { 407 if(*RefVal >= DCtx.getInfoSection().Data.size()) { 408 Success = false; 409 OS << "error: DW_FORM_ref_addr offset beyond .debug_info " 410 "bounds:\n"; 411 Die.dump(OS, 0); 412 OS << "\n"; 413 } else { 414 // Valid reference, but we will verify it points to an actual 415 // DIE later. 416 ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset()); 417 } 418 } 419 break; 420 } 421 case DW_FORM_strp: { 422 auto SecOffset = AttrValue.Value.getAsSectionOffset(); 423 assert(SecOffset); // DW_FORM_strp is a section offset. 424 if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) { 425 Success = false; 426 OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n"; 427 Die.dump(OS, 0); 428 OS << "\n"; 429 } 430 break; 431 } 432 default: 433 break; 434 } 435 } 436 } 437 } 438 439 // Take all references and make sure they point to an actual DIE by 440 // getting the DIE by offset and emitting an error 441 OS << "Verifying .debug_info references...\n"; 442 for (auto Pair: ReferenceToDIEOffsets) { 443 auto Die = DCtx.getDIEForOffset(Pair.first); 444 if (Die) 445 continue; 446 Success = false; 447 OS << "error: invalid DIE reference " << format("0x%08" PRIx64, Pair.first) 448 << ". Offset is in between DIEs:\n"; 449 for (auto Offset: Pair.second) { 450 auto ReferencingDie = DCtx.getDIEForOffset(Offset); 451 ReferencingDie.dump(OS, 0); 452 OS << "\n"; 453 } 454 OS << "\n"; 455 } 456 return Success; 457 } 458 459 bool HandleDebugLine() { 460 std::map<uint64_t, DWARFDie> StmtListToDie; 461 bool Success = true; 462 OS << "Verifying .debug_line...\n"; 463 for (const auto &CU : DCtx.compile_units()) { 464 uint32_t LineTableOffset = 0; 465 auto CUDie = CU->getUnitDIE(); 466 auto StmtFormValue = CUDie.find(DW_AT_stmt_list); 467 if (!StmtFormValue) { 468 // No line table for this compile unit. 469 continue; 470 } 471 // Get the attribute value as a section offset. No need to produce an 472 // error here if the encoding isn't correct because we validate this in 473 // the .debug_info verifier. 474 if (auto StmtSectionOffset = toSectionOffset(StmtFormValue)) { 475 LineTableOffset = *StmtSectionOffset; 476 if (LineTableOffset >= DCtx.getLineSection().Data.size()) { 477 // Make sure we don't get a valid line table back if the offset 478 // is wrong. 479 assert(DCtx.getLineTableForUnit(CU.get()) == nullptr); 480 // Skip this line table as it isn't valid. No need to create an error 481 // here because we validate this in the .debug_info verifier. 482 continue; 483 } else { 484 auto Iter = StmtListToDie.find(LineTableOffset); 485 if (Iter != StmtListToDie.end()) { 486 Success = false; 487 OS << "error: two compile unit DIEs, " 488 << format("0x%08" PRIx32, Iter->second.getOffset()) << " and " 489 << format("0x%08" PRIx32, CUDie.getOffset()) 490 << ", have the same DW_AT_stmt_list section offset:\n"; 491 Iter->second.dump(OS, 0); 492 CUDie.dump(OS, 0); 493 OS << '\n'; 494 // Already verified this line table before, no need to do it again. 495 continue; 496 } 497 StmtListToDie[LineTableOffset] = CUDie; 498 } 499 } 500 auto LineTable = DCtx.getLineTableForUnit(CU.get()); 501 if (!LineTable) { 502 Success = false; 503 OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset) 504 << "] was not able to be parsed for CU:\n"; 505 CUDie.dump(OS, 0); 506 OS << '\n'; 507 continue; 508 } 509 uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size(); 510 uint64_t PrevAddress = 0; 511 uint32_t RowIndex = 0; 512 for (const auto &Row : LineTable->Rows) { 513 if (Row.Address < PrevAddress) { 514 Success = false; 515 OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset) 516 << "] row[" << RowIndex 517 << "] decreases in address from previous row:\n"; 518 519 DWARFDebugLine::Row::dumpTableHeader(OS); 520 if (RowIndex > 0) 521 LineTable->Rows[RowIndex - 1].dump(OS); 522 Row.dump(OS); 523 OS << '\n'; 524 } 525 526 if (Row.File > MaxFileIndex) { 527 Success = false; 528 OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset) 529 << "][" << RowIndex << "] has invalid file index " << Row.File 530 << " (valid values are [1," << MaxFileIndex << "]):\n"; 531 DWARFDebugLine::Row::dumpTableHeader(OS); 532 Row.dump(OS); 533 OS << '\n'; 534 } 535 if (Row.EndSequence) 536 PrevAddress = 0; 537 else 538 PrevAddress = Row.Address; 539 ++RowIndex; 540 } 541 } 542 return Success; 543 } 544 }; 545 546 } // anonymous namespace 547 548 bool DWARFContext::verify(raw_ostream &OS, DIDumpType DumpType) { 549 bool Success = true; 550 DWARFVerifier verifier(OS, *this); 551 if (DumpType == DIDT_All || DumpType == DIDT_Info) { 552 if (!verifier.handleDebugInfo()) 553 Success = false; 554 } 555 if (DumpType == DIDT_All || DumpType == DIDT_Line) { 556 if (!verifier.handleDebugLine()) 557 Success = false; 558 } 559 return Success; 560 } 561 const DWARFUnitIndex &DWARFContext::getCUIndex() { 562 if (CUIndex) 563 return *CUIndex; 564 565 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0); 566 567 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO); 568 CUIndex->parse(CUIndexData); 569 return *CUIndex; 570 } 571 572 const DWARFUnitIndex &DWARFContext::getTUIndex() { 573 if (TUIndex) 574 return *TUIndex; 575 576 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0); 577 578 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); 579 TUIndex->parse(TUIndexData); 580 return *TUIndex; 581 } 582 583 DWARFGdbIndex &DWARFContext::getGdbIndex() { 584 if (GdbIndex) 585 return *GdbIndex; 586 587 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0); 588 GdbIndex = llvm::make_unique<DWARFGdbIndex>(); 589 GdbIndex->parse(GdbIndexData); 590 return *GdbIndex; 591 } 592 593 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { 594 if (Abbrev) 595 return Abbrev.get(); 596 597 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); 598 599 Abbrev.reset(new DWARFDebugAbbrev()); 600 Abbrev->extract(abbrData); 601 return Abbrev.get(); 602 } 603 604 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { 605 if (AbbrevDWO) 606 return AbbrevDWO.get(); 607 608 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0); 609 AbbrevDWO.reset(new DWARFDebugAbbrev()); 610 AbbrevDWO->extract(abbrData); 611 return AbbrevDWO.get(); 612 } 613 614 const DWARFDebugLoc *DWARFContext::getDebugLoc() { 615 if (Loc) 616 return Loc.get(); 617 618 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0); 619 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs)); 620 // assume all compile units have the same address byte size 621 if (getNumCompileUnits()) 622 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize()); 623 return Loc.get(); 624 } 625 626 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() { 627 if (LocDWO) 628 return LocDWO.get(); 629 630 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0); 631 LocDWO.reset(new DWARFDebugLocDWO()); 632 LocDWO->parse(LocData); 633 return LocDWO.get(); 634 } 635 636 const DWARFDebugAranges *DWARFContext::getDebugAranges() { 637 if (Aranges) 638 return Aranges.get(); 639 640 Aranges.reset(new DWARFDebugAranges()); 641 Aranges->generate(this); 642 return Aranges.get(); 643 } 644 645 const DWARFDebugFrame *DWARFContext::getDebugFrame() { 646 if (DebugFrame) 647 return DebugFrame.get(); 648 649 // There's a "bug" in the DWARFv3 standard with respect to the target address 650 // size within debug frame sections. While DWARF is supposed to be independent 651 // of its container, FDEs have fields with size being "target address size", 652 // which isn't specified in DWARF in general. It's only specified for CUs, but 653 // .eh_frame can appear without a .debug_info section. Follow the example of 654 // other tools (libdwarf) and extract this from the container (ObjectFile 655 // provides this information). This problem is fixed in DWARFv4 656 // See this dwarf-discuss discussion for more details: 657 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html 658 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(), 659 getAddressSize()); 660 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */)); 661 DebugFrame->parse(debugFrameData); 662 return DebugFrame.get(); 663 } 664 665 const DWARFDebugFrame *DWARFContext::getEHFrame() { 666 if (EHFrame) 667 return EHFrame.get(); 668 669 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(), 670 getAddressSize()); 671 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */)); 672 DebugFrame->parse(debugFrameData); 673 return DebugFrame.get(); 674 } 675 676 const DWARFDebugMacro *DWARFContext::getDebugMacro() { 677 if (Macro) 678 return Macro.get(); 679 680 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0); 681 Macro.reset(new DWARFDebugMacro()); 682 Macro->parse(MacinfoData); 683 return Macro.get(); 684 } 685 686 const DWARFLineTable * 687 DWARFContext::getLineTableForUnit(DWARFUnit *U) { 688 if (!Line) 689 Line.reset(new DWARFDebugLine(&getLineSection().Relocs)); 690 691 auto UnitDIE = U->getUnitDIE(); 692 if (!UnitDIE) 693 return nullptr; 694 695 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list)); 696 if (!Offset) 697 return nullptr; // No line table for this compile unit. 698 699 uint32_t stmtOffset = *Offset + U->getLineTableOffset(); 700 // See if the line table is cached. 701 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) 702 return lt; 703 704 // Make sure the offset is good before we try to parse. 705 if (stmtOffset >= U->getLineSection().size()) 706 return nullptr; 707 708 // We have to parse it first. 709 DataExtractor lineData(U->getLineSection(), isLittleEndian(), 710 U->getAddressByteSize()); 711 return Line->getOrParseLineTable(lineData, stmtOffset); 712 } 713 714 void DWARFContext::parseCompileUnits() { 715 CUs.parse(*this, getInfoSection()); 716 } 717 718 void DWARFContext::parseTypeUnits() { 719 if (!TUs.empty()) 720 return; 721 for (const auto &I : getTypesSections()) { 722 TUs.emplace_back(); 723 TUs.back().parse(*this, I.second); 724 } 725 } 726 727 void DWARFContext::parseDWOCompileUnits() { 728 DWOCUs.parseDWO(*this, getInfoDWOSection()); 729 } 730 731 void DWARFContext::parseDWOTypeUnits() { 732 if (!DWOTUs.empty()) 733 return; 734 for (const auto &I : getTypesDWOSections()) { 735 DWOTUs.emplace_back(); 736 DWOTUs.back().parseDWO(*this, I.second); 737 } 738 } 739 740 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { 741 parseCompileUnits(); 742 return CUs.getUnitForOffset(Offset); 743 } 744 745 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { 746 // First, get the offset of the compile unit. 747 uint32_t CUOffset = getDebugAranges()->findAddress(Address); 748 // Retrieve the compile unit. 749 return getCompileUnitForOffset(CUOffset); 750 } 751 752 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, 753 uint64_t Address, 754 FunctionNameKind Kind, 755 std::string &FunctionName, 756 uint32_t &StartLine) { 757 // The address may correspond to instruction in some inlined function, 758 // so we have to build the chain of inlined functions and take the 759 // name of the topmost function in it. 760 SmallVector<DWARFDie, 4> InlinedChain; 761 CU->getInlinedChainForAddress(Address, InlinedChain); 762 if (InlinedChain.empty()) 763 return false; 764 765 const DWARFDie &DIE = InlinedChain[0]; 766 bool FoundResult = false; 767 const char *Name = nullptr; 768 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) { 769 FunctionName = Name; 770 FoundResult = true; 771 } 772 if (auto DeclLineResult = DIE.getDeclLine()) { 773 StartLine = DeclLineResult; 774 FoundResult = true; 775 } 776 777 return FoundResult; 778 } 779 780 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, 781 DILineInfoSpecifier Spec) { 782 DILineInfo Result; 783 784 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 785 if (!CU) 786 return Result; 787 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, 788 Result.FunctionName, 789 Result.StartLine); 790 if (Spec.FLIKind != FileLineInfoKind::None) { 791 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) 792 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 793 Spec.FLIKind, Result); 794 } 795 return Result; 796 } 797 798 DILineInfoTable 799 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 800 DILineInfoSpecifier Spec) { 801 DILineInfoTable Lines; 802 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 803 if (!CU) 804 return Lines; 805 806 std::string FunctionName = "<invalid>"; 807 uint32_t StartLine = 0; 808 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName, 809 StartLine); 810 811 // If the Specifier says we don't need FileLineInfo, just 812 // return the top-most function at the starting address. 813 if (Spec.FLIKind == FileLineInfoKind::None) { 814 DILineInfo Result; 815 Result.FunctionName = FunctionName; 816 Result.StartLine = StartLine; 817 Lines.push_back(std::make_pair(Address, Result)); 818 return Lines; 819 } 820 821 const DWARFLineTable *LineTable = getLineTableForUnit(CU); 822 823 // Get the index of row we're looking for in the line table. 824 std::vector<uint32_t> RowVector; 825 if (!LineTable->lookupAddressRange(Address, Size, RowVector)) 826 return Lines; 827 828 for (uint32_t RowIndex : RowVector) { 829 // Take file number and line/column from the row. 830 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; 831 DILineInfo Result; 832 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(), 833 Spec.FLIKind, Result.FileName); 834 Result.FunctionName = FunctionName; 835 Result.Line = Row.Line; 836 Result.Column = Row.Column; 837 Result.StartLine = StartLine; 838 Lines.push_back(std::make_pair(Row.Address, Result)); 839 } 840 841 return Lines; 842 } 843 844 DIInliningInfo 845 DWARFContext::getInliningInfoForAddress(uint64_t Address, 846 DILineInfoSpecifier Spec) { 847 DIInliningInfo InliningInfo; 848 849 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 850 if (!CU) 851 return InliningInfo; 852 853 const DWARFLineTable *LineTable = nullptr; 854 SmallVector<DWARFDie, 4> InlinedChain; 855 CU->getInlinedChainForAddress(Address, InlinedChain); 856 if (InlinedChain.size() == 0) { 857 // If there is no DIE for address (e.g. it is in unavailable .dwo file), 858 // try to at least get file/line info from symbol table. 859 if (Spec.FLIKind != FileLineInfoKind::None) { 860 DILineInfo Frame; 861 LineTable = getLineTableForUnit(CU); 862 if (LineTable && 863 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 864 Spec.FLIKind, Frame)) 865 InliningInfo.addFrame(Frame); 866 } 867 return InliningInfo; 868 } 869 870 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0; 871 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) { 872 DWARFDie &FunctionDIE = InlinedChain[i]; 873 DILineInfo Frame; 874 // Get function name if necessary. 875 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind)) 876 Frame.FunctionName = Name; 877 if (auto DeclLineResult = FunctionDIE.getDeclLine()) 878 Frame.StartLine = DeclLineResult; 879 if (Spec.FLIKind != FileLineInfoKind::None) { 880 if (i == 0) { 881 // For the topmost frame, initialize the line table of this 882 // compile unit and fetch file/line info from it. 883 LineTable = getLineTableForUnit(CU); 884 // For the topmost routine, get file/line info from line table. 885 if (LineTable) 886 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), 887 Spec.FLIKind, Frame); 888 } else { 889 // Otherwise, use call file, call line and call column from 890 // previous DIE in inlined chain. 891 if (LineTable) 892 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(), 893 Spec.FLIKind, Frame.FileName); 894 Frame.Line = CallLine; 895 Frame.Column = CallColumn; 896 Frame.Discriminator = CallDiscriminator; 897 } 898 // Get call file/line/column of a current DIE. 899 if (i + 1 < n) { 900 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn, 901 CallDiscriminator); 902 } 903 } 904 InliningInfo.addFrame(Frame); 905 } 906 return InliningInfo; 907 } 908 909 std::shared_ptr<DWARFContext> 910 DWARFContext::getDWOContext(StringRef AbsolutePath) { 911 if (auto S = DWP.lock()) { 912 DWARFContext *Ctxt = S->Context.get(); 913 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 914 } 915 916 std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath]; 917 918 if (auto S = Entry->lock()) { 919 DWARFContext *Ctxt = S->Context.get(); 920 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 921 } 922 923 SmallString<128> DWPName; 924 Expected<OwningBinary<ObjectFile>> Obj = [&] { 925 if (!CheckedForDWP) { 926 (getFileName() + ".dwp").toVector(DWPName); 927 auto Obj = object::ObjectFile::createObjectFile(DWPName); 928 if (Obj) { 929 Entry = &DWP; 930 return Obj; 931 } else { 932 CheckedForDWP = true; 933 // TODO: Should this error be handled (maybe in a high verbosity mode) 934 // before falling back to .dwo files? 935 consumeError(Obj.takeError()); 936 } 937 } 938 939 return object::ObjectFile::createObjectFile(AbsolutePath); 940 }(); 941 942 if (!Obj) { 943 // TODO: Actually report errors helpfully. 944 consumeError(Obj.takeError()); 945 return nullptr; 946 } 947 948 auto S = std::make_shared<DWOFile>(); 949 S->File = std::move(Obj.get()); 950 S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary()); 951 *Entry = S; 952 auto *Ctxt = S->Context.get(); 953 return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); 954 } 955 956 static Error createError(const Twine &Reason, llvm::Error E) { 957 return make_error<StringError>(Reason + toString(std::move(E)), 958 inconvertibleErrorCode()); 959 } 960 961 /// Returns the address of symbol relocation used against. Used for futher 962 /// relocations computation. Symbol's section load address is taken in account if 963 /// LoadedObjectInfo interface is provided. 964 static Expected<uint64_t> 965 getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, 966 const LoadedObjectInfo *L, 967 std::map<SymbolRef, uint64_t> &Cache) { 968 uint64_t Ret = 0; 969 object::section_iterator RSec = Obj.section_end(); 970 object::symbol_iterator Sym = Reloc.getSymbol(); 971 972 std::map<SymbolRef, uint64_t>::iterator CacheIt = Cache.end(); 973 // First calculate the address of the symbol or section as it appears 974 // in the object file 975 if (Sym != Obj.symbol_end()) { 976 bool New; 977 std::tie(CacheIt, New) = Cache.insert({*Sym, 0}); 978 if (!New) 979 return CacheIt->second; 980 981 Expected<uint64_t> SymAddrOrErr = Sym->getAddress(); 982 if (!SymAddrOrErr) 983 return createError("error: failed to compute symbol address: ", 984 SymAddrOrErr.takeError()); 985 986 // Also remember what section this symbol is in for later 987 auto SectOrErr = Sym->getSection(); 988 if (!SectOrErr) 989 return createError("error: failed to get symbol section: ", 990 SectOrErr.takeError()); 991 992 RSec = *SectOrErr; 993 Ret = *SymAddrOrErr; 994 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) { 995 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); 996 Ret = RSec->getAddress(); 997 } 998 999 // If we are given load addresses for the sections, we need to adjust: 1000 // SymAddr = (Address of Symbol Or Section in File) - 1001 // (Address of Section in File) + 1002 // (Load Address of Section) 1003 // RSec is now either the section being targeted or the section 1004 // containing the symbol being targeted. In either case, 1005 // we need to perform the same computation. 1006 if (L && RSec != Obj.section_end()) 1007 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) 1008 Ret += SectionLoadAddress - RSec->getAddress(); 1009 1010 if (CacheIt != Cache.end()) 1011 CacheIt->second = Ret; 1012 1013 return Ret; 1014 } 1015 1016 static bool isRelocScattered(const object::ObjectFile &Obj, 1017 const RelocationRef &Reloc) { 1018 const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj); 1019 if (!MachObj) 1020 return false; 1021 // MachO also has relocations that point to sections and 1022 // scattered relocations. 1023 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl()); 1024 return MachObj->isRelocationScattered(RelocInfo); 1025 } 1026 1027 Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec, 1028 StringRef Name, StringRef &Data) { 1029 if (!Decompressor::isCompressed(Sec)) 1030 return Error::success(); 1031 1032 Expected<Decompressor> Decompressor = 1033 Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); 1034 if (!Decompressor) 1035 return Decompressor.takeError(); 1036 1037 SmallString<32> Out; 1038 if (auto Err = Decompressor->resizeAndDecompress(Out)) 1039 return Err; 1040 1041 UncompressedSections.emplace_back(std::move(Out)); 1042 Data = UncompressedSections.back(); 1043 1044 return Error::success(); 1045 } 1046 1047 DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, 1048 const LoadedObjectInfo *L) 1049 : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()), 1050 AddressSize(Obj.getBytesInAddress()) { 1051 for (const SectionRef &Section : Obj.sections()) { 1052 StringRef name; 1053 Section.getName(name); 1054 // Skip BSS and Virtual sections, they aren't interesting. 1055 bool IsBSS = Section.isBSS(); 1056 if (IsBSS) 1057 continue; 1058 bool IsVirtual = Section.isVirtual(); 1059 if (IsVirtual) 1060 continue; 1061 StringRef data; 1062 1063 section_iterator RelocatedSection = Section.getRelocatedSection(); 1064 // Try to obtain an already relocated version of this section. 1065 // Else use the unrelocated section from the object file. We'll have to 1066 // apply relocations ourselves later. 1067 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data)) 1068 Section.getContents(data); 1069 1070 if (auto Err = maybeDecompress(Section, name, data)) { 1071 errs() << "error: failed to decompress '" + name + "', " + 1072 toString(std::move(Err)) 1073 << '\n'; 1074 continue; 1075 } 1076 1077 // Compressed sections names in GNU style starts from ".z", 1078 // at this point section is decompressed and we drop compression prefix. 1079 name = name.substr( 1080 name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. 1081 1082 if (StringRef *SectionData = MapSectionToMember(name)) { 1083 *SectionData = data; 1084 if (name == "debug_ranges") { 1085 // FIXME: Use the other dwo range section when we emit it. 1086 RangeDWOSection.Data = data; 1087 } 1088 } else if (name == "debug_types") { 1089 // Find debug_types data by section rather than name as there are 1090 // multiple, comdat grouped, debug_types sections. 1091 TypesSections[Section].Data = data; 1092 } else if (name == "debug_types.dwo") { 1093 TypesDWOSections[Section].Data = data; 1094 } 1095 1096 if (RelocatedSection == Obj.section_end()) 1097 continue; 1098 1099 StringRef RelSecName; 1100 StringRef RelSecData; 1101 RelocatedSection->getName(RelSecName); 1102 1103 // If the section we're relocating was relocated already by the JIT, 1104 // then we used the relocated version above, so we do not need to process 1105 // relocations for it now. 1106 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData)) 1107 continue; 1108 1109 // In Mach-o files, the relocations do not need to be applied if 1110 // there is no load offset to apply. The value read at the 1111 // relocation point already factors in the section address 1112 // (actually applying the relocations will produce wrong results 1113 // as the section address will be added twice). 1114 if (!L && isa<MachOObjectFile>(&Obj)) 1115 continue; 1116 1117 RelSecName = RelSecName.substr( 1118 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes. 1119 1120 // TODO: Add support for relocations in other sections as needed. 1121 // Record relocations for the debug_info and debug_line sections. 1122 RelocAddrMap *Map = 1123 StringSwitch<RelocAddrMap *>(RelSecName) 1124 .Case("debug_info", &InfoSection.Relocs) 1125 .Case("debug_loc", &LocSection.Relocs) 1126 .Case("debug_info.dwo", &InfoDWOSection.Relocs) 1127 .Case("debug_line", &LineSection.Relocs) 1128 .Case("debug_ranges", &RangeSection.Relocs) 1129 .Case("debug_addr", &AddrSection.Relocs) 1130 .Case("apple_names", &AppleNamesSection.Relocs) 1131 .Case("apple_types", &AppleTypesSection.Relocs) 1132 .Case("apple_namespaces", &AppleNamespacesSection.Relocs) 1133 .Case("apple_namespac", &AppleNamespacesSection.Relocs) 1134 .Case("apple_objc", &AppleObjCSection.Relocs) 1135 .Default(nullptr); 1136 if (!Map) { 1137 // Find debug_types relocs by section rather than name as there are 1138 // multiple, comdat grouped, debug_types sections. 1139 if (RelSecName == "debug_types") 1140 Map = &TypesSections[*RelocatedSection].Relocs; 1141 else if (RelSecName == "debug_types.dwo") 1142 Map = &TypesDWOSections[*RelocatedSection].Relocs; 1143 else 1144 continue; 1145 } 1146 1147 if (Section.relocation_begin() == Section.relocation_end()) 1148 continue; 1149 1150 std::map<SymbolRef, uint64_t> AddrCache; 1151 for (const RelocationRef &Reloc : Section.relocations()) { 1152 // FIXME: it's not clear how to correctly handle scattered 1153 // relocations. 1154 if (isRelocScattered(Obj, Reloc)) 1155 continue; 1156 1157 Expected<uint64_t> SymAddrOrErr = 1158 getSymbolAddress(Obj, Reloc, L, AddrCache); 1159 if (!SymAddrOrErr) { 1160 errs() << toString(SymAddrOrErr.takeError()) << '\n'; 1161 continue; 1162 } 1163 1164 object::RelocVisitor V(Obj); 1165 uint64_t Val = V.visit(Reloc.getType(), Reloc, *SymAddrOrErr); 1166 if (V.error()) { 1167 SmallString<32> Name; 1168 Reloc.getTypeName(Name); 1169 errs() << "error: failed to compute relocation: " << Name << "\n"; 1170 continue; 1171 } 1172 Map->insert({Reloc.getOffset(), {Val}}); 1173 } 1174 } 1175 } 1176 1177 DWARFContextInMemory::DWARFContextInMemory( 1178 const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize, 1179 bool isLittleEndian) 1180 : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) { 1181 for (const auto &SecIt : Sections) { 1182 if (StringRef *SectionData = MapSectionToMember(SecIt.first())) 1183 *SectionData = SecIt.second->getBuffer(); 1184 } 1185 } 1186 1187 StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) { 1188 return StringSwitch<StringRef *>(Name) 1189 .Case("debug_info", &InfoSection.Data) 1190 .Case("debug_abbrev", &AbbrevSection) 1191 .Case("debug_loc", &LocSection.Data) 1192 .Case("debug_line", &LineSection.Data) 1193 .Case("debug_aranges", &ARangeSection) 1194 .Case("debug_frame", &DebugFrameSection) 1195 .Case("eh_frame", &EHFrameSection) 1196 .Case("debug_str", &StringSection) 1197 .Case("debug_ranges", &RangeSection.Data) 1198 .Case("debug_macinfo", &MacinfoSection) 1199 .Case("debug_pubnames", &PubNamesSection) 1200 .Case("debug_pubtypes", &PubTypesSection) 1201 .Case("debug_gnu_pubnames", &GnuPubNamesSection) 1202 .Case("debug_gnu_pubtypes", &GnuPubTypesSection) 1203 .Case("debug_info.dwo", &InfoDWOSection.Data) 1204 .Case("debug_abbrev.dwo", &AbbrevDWOSection) 1205 .Case("debug_loc.dwo", &LocDWOSection.Data) 1206 .Case("debug_line.dwo", &LineDWOSection.Data) 1207 .Case("debug_str.dwo", &StringDWOSection) 1208 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) 1209 .Case("debug_addr", &AddrSection.Data) 1210 .Case("apple_names", &AppleNamesSection.Data) 1211 .Case("apple_types", &AppleTypesSection.Data) 1212 .Case("apple_namespaces", &AppleNamespacesSection.Data) 1213 .Case("apple_namespac", &AppleNamespacesSection.Data) 1214 .Case("apple_objc", &AppleObjCSection.Data) 1215 .Case("debug_cu_index", &CUIndexSection) 1216 .Case("debug_tu_index", &TUIndexSection) 1217 .Case("gdb_index", &GdbIndexSection) 1218 // Any more debug info sections go here. 1219 .Default(nullptr); 1220 } 1221 1222 void DWARFContextInMemory::anchor() {} 1223