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 "DWARFContext.h" 11 #include "DWARFDebugArangeSet.h" 12 13 #include "llvm/ADT/SmallString.h" 14 #include "llvm/ADT/StringSwitch.h" 15 #include "llvm/Support/Compression.h" 16 #include "llvm/Support/Dwarf.h" 17 #include "llvm/Support/Format.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/raw_ostream.h" 20 #include <algorithm> 21 using namespace llvm; 22 using namespace dwarf; 23 using namespace object; 24 25 #define DEBUG_TYPE "dwarf" 26 27 typedef DWARFDebugLine::LineTable DWARFLineTable; 28 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; 29 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; 30 31 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, 32 bool LittleEndian, bool GnuStyle) { 33 OS << "\n." << Name << " contents:\n"; 34 DataExtractor pubNames(Data, LittleEndian, 0); 35 uint32_t offset = 0; 36 while (pubNames.isValidOffset(offset)) { 37 OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); 38 OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); 39 OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); 40 OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; 41 if (GnuStyle) 42 OS << "Offset Linkage Kind Name\n"; 43 else 44 OS << "Offset Name\n"; 45 46 while (offset < Data.size()) { 47 uint32_t dieRef = pubNames.getU32(&offset); 48 if (dieRef == 0) 49 break; 50 OS << format("0x%8.8x ", dieRef); 51 if (GnuStyle) { 52 PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); 53 OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) 54 << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) 55 << ' '; 56 } 57 OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; 58 } 59 } 60 } 61 62 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { 63 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) { 64 OS << ".debug_abbrev contents:\n"; 65 getDebugAbbrev()->dump(OS); 66 } 67 68 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) 69 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) { 70 OS << "\n.debug_abbrev.dwo contents:\n"; 71 D->dump(OS); 72 } 73 74 if (DumpType == DIDT_All || DumpType == DIDT_Info) { 75 OS << "\n.debug_info contents:\n"; 76 for (const auto &CU : compile_units()) 77 CU->dump(OS); 78 } 79 80 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) && 81 getNumDWOCompileUnits()) { 82 OS << "\n.debug_info.dwo contents:\n"; 83 for (const auto &DWOCU : dwo_compile_units()) 84 DWOCU->dump(OS); 85 } 86 87 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) { 88 OS << "\n.debug_types contents:\n"; 89 for (const auto &TU : type_units()) 90 TU->dump(OS); 91 } 92 93 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) && 94 getNumDWOTypeUnits()) { 95 OS << "\n.debug_types.dwo contents:\n"; 96 for (const auto &DWOTU : dwo_type_units()) 97 DWOTU->dump(OS); 98 } 99 100 if (DumpType == DIDT_All || DumpType == DIDT_Loc) { 101 OS << "\n.debug_loc contents:\n"; 102 getDebugLoc()->dump(OS); 103 } 104 105 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) { 106 OS << "\n.debug_loc.dwo contents:\n"; 107 getDebugLocDWO()->dump(OS); 108 } 109 110 if (DumpType == DIDT_All || DumpType == DIDT_Frames) { 111 OS << "\n.debug_frame contents:\n"; 112 getDebugFrame()->dump(OS); 113 } 114 115 uint32_t offset = 0; 116 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) { 117 OS << "\n.debug_aranges contents:\n"; 118 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); 119 DWARFDebugArangeSet set; 120 while (set.extract(arangesData, &offset)) 121 set.dump(OS); 122 } 123 124 uint8_t savedAddressByteSize = 0; 125 if (DumpType == DIDT_All || DumpType == DIDT_Line) { 126 OS << "\n.debug_line contents:\n"; 127 for (const auto &CU : compile_units()) { 128 savedAddressByteSize = CU->getAddressByteSize(); 129 unsigned stmtOffset = 130 CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset( 131 CU.get(), DW_AT_stmt_list, -1U); 132 if (stmtOffset != -1U) { 133 DataExtractor lineData(getLineSection().Data, isLittleEndian(), 134 savedAddressByteSize); 135 DWARFDebugLine::LineTable LineTable; 136 LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset); 137 LineTable.dump(OS); 138 } 139 } 140 } 141 142 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) { 143 OS << "\n.debug_line.dwo contents:\n"; 144 unsigned stmtOffset = 0; 145 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(), 146 savedAddressByteSize); 147 DWARFDebugLine::LineTable LineTable; 148 while (LineTable.Prologue.parse(lineData, &stmtOffset)) { 149 LineTable.dump(OS); 150 LineTable.clear(); 151 } 152 } 153 154 if (DumpType == DIDT_All || DumpType == DIDT_Str) { 155 OS << "\n.debug_str contents:\n"; 156 DataExtractor strData(getStringSection(), isLittleEndian(), 0); 157 offset = 0; 158 uint32_t strOffset = 0; 159 while (const char *s = strData.getCStr(&offset)) { 160 OS << format("0x%8.8x: \"%s\"\n", strOffset, s); 161 strOffset = offset; 162 } 163 } 164 165 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) && 166 !getStringDWOSection().empty()) { 167 OS << "\n.debug_str.dwo contents:\n"; 168 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0); 169 offset = 0; 170 uint32_t strDWOOffset = 0; 171 while (const char *s = strDWOData.getCStr(&offset)) { 172 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); 173 strDWOOffset = offset; 174 } 175 } 176 177 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) { 178 OS << "\n.debug_ranges contents:\n"; 179 // In fact, different compile units may have different address byte 180 // sizes, but for simplicity we just use the address byte size of the last 181 // compile unit (there is no easy and fast way to associate address range 182 // list and the compile unit it describes). 183 DataExtractor rangesData(getRangeSection(), isLittleEndian(), 184 savedAddressByteSize); 185 offset = 0; 186 DWARFDebugRangeList rangeList; 187 while (rangeList.extract(rangesData, &offset)) 188 rangeList.dump(OS); 189 } 190 191 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) 192 dumpPubSection(OS, "debug_pubnames", getPubNamesSection(), 193 isLittleEndian(), false); 194 195 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes) 196 dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(), 197 isLittleEndian(), false); 198 199 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames) 200 dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(), 201 isLittleEndian(), true /* GnuStyle */); 202 203 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) 204 dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(), 205 isLittleEndian(), true /* GnuStyle */); 206 207 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) && 208 !getStringOffsetDWOSection().empty()) { 209 OS << "\n.debug_str_offsets.dwo contents:\n"; 210 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 211 0); 212 offset = 0; 213 uint64_t size = getStringOffsetDWOSection().size(); 214 while (offset < size) { 215 OS << format("0x%8.8x: ", offset); 216 OS << format("%8.8x\n", strOffsetExt.getU32(&offset)); 217 } 218 } 219 } 220 221 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { 222 if (Abbrev) 223 return Abbrev.get(); 224 225 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); 226 227 Abbrev.reset(new DWARFDebugAbbrev()); 228 Abbrev->extract(abbrData); 229 return Abbrev.get(); 230 } 231 232 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { 233 if (AbbrevDWO) 234 return AbbrevDWO.get(); 235 236 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0); 237 AbbrevDWO.reset(new DWARFDebugAbbrev()); 238 AbbrevDWO->extract(abbrData); 239 return AbbrevDWO.get(); 240 } 241 242 const DWARFDebugLoc *DWARFContext::getDebugLoc() { 243 if (Loc) 244 return Loc.get(); 245 246 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0); 247 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs)); 248 // assume all compile units have the same address byte size 249 if (getNumCompileUnits()) 250 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize()); 251 return Loc.get(); 252 } 253 254 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() { 255 if (LocDWO) 256 return LocDWO.get(); 257 258 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0); 259 LocDWO.reset(new DWARFDebugLocDWO()); 260 LocDWO->parse(LocData); 261 return LocDWO.get(); 262 } 263 264 const DWARFDebugAranges *DWARFContext::getDebugAranges() { 265 if (Aranges) 266 return Aranges.get(); 267 268 Aranges.reset(new DWARFDebugAranges()); 269 Aranges->generate(this); 270 return Aranges.get(); 271 } 272 273 const DWARFDebugFrame *DWARFContext::getDebugFrame() { 274 if (DebugFrame) 275 return DebugFrame.get(); 276 277 // There's a "bug" in the DWARFv3 standard with respect to the target address 278 // size within debug frame sections. While DWARF is supposed to be independent 279 // of its container, FDEs have fields with size being "target address size", 280 // which isn't specified in DWARF in general. It's only specified for CUs, but 281 // .eh_frame can appear without a .debug_info section. Follow the example of 282 // other tools (libdwarf) and extract this from the container (ObjectFile 283 // provides this information). This problem is fixed in DWARFv4 284 // See this dwarf-discuss discussion for more details: 285 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html 286 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(), 287 getAddressSize()); 288 DebugFrame.reset(new DWARFDebugFrame()); 289 DebugFrame->parse(debugFrameData); 290 return DebugFrame.get(); 291 } 292 293 const DWARFLineTable * 294 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { 295 if (!Line) 296 Line.reset(new DWARFDebugLine(&getLineSection().Relocs)); 297 298 unsigned stmtOffset = 299 cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset( 300 cu, DW_AT_stmt_list, -1U); 301 if (stmtOffset == -1U) 302 return nullptr; // No line table for this compile unit. 303 304 // See if the line table is cached. 305 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) 306 return lt; 307 308 // We have to parse it first. 309 DataExtractor lineData(getLineSection().Data, isLittleEndian(), 310 cu->getAddressByteSize()); 311 return Line->getOrParseLineTable(lineData, stmtOffset); 312 } 313 314 void DWARFContext::parseCompileUnits() { 315 if (!CUs.empty()) 316 return; 317 uint32_t offset = 0; 318 const DataExtractor &DIData = DataExtractor(getInfoSection().Data, 319 isLittleEndian(), 0); 320 while (DIData.isValidOffset(offset)) { 321 std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit( 322 getDebugAbbrev(), getInfoSection().Data, getRangeSection(), 323 getStringSection(), StringRef(), getAddrSection(), 324 &getInfoSection().Relocs, isLittleEndian())); 325 if (!CU->extract(DIData, &offset)) { 326 break; 327 } 328 CUs.push_back(std::move(CU)); 329 offset = CUs.back()->getNextUnitOffset(); 330 } 331 } 332 333 void DWARFContext::parseTypeUnits() { 334 if (!TUs.empty()) 335 return; 336 for (const auto &I : getTypesSections()) { 337 uint32_t offset = 0; 338 const DataExtractor &DIData = 339 DataExtractor(I.second.Data, isLittleEndian(), 0); 340 while (DIData.isValidOffset(offset)) { 341 std::unique_ptr<DWARFTypeUnit> TU( 342 new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(), 343 getStringSection(), StringRef(), getAddrSection(), 344 &I.second.Relocs, isLittleEndian())); 345 if (!TU->extract(DIData, &offset)) 346 break; 347 TUs.push_back(std::move(TU)); 348 offset = TUs.back()->getNextUnitOffset(); 349 } 350 } 351 } 352 353 void DWARFContext::parseDWOCompileUnits() { 354 if (!DWOCUs.empty()) 355 return; 356 uint32_t offset = 0; 357 const DataExtractor &DIData = 358 DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); 359 while (DIData.isValidOffset(offset)) { 360 std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit( 361 getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(), 362 getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), 363 &getInfoDWOSection().Relocs, isLittleEndian())); 364 if (!DWOCU->extract(DIData, &offset)) { 365 break; 366 } 367 DWOCUs.push_back(std::move(DWOCU)); 368 offset = DWOCUs.back()->getNextUnitOffset(); 369 } 370 } 371 372 void DWARFContext::parseDWOTypeUnits() { 373 if (!DWOTUs.empty()) 374 return; 375 for (const auto &I : getTypesDWOSections()) { 376 uint32_t offset = 0; 377 const DataExtractor &DIData = 378 DataExtractor(I.second.Data, isLittleEndian(), 0); 379 while (DIData.isValidOffset(offset)) { 380 std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit( 381 getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(), 382 getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), 383 &I.second.Relocs, isLittleEndian())); 384 if (!TU->extract(DIData, &offset)) 385 break; 386 DWOTUs.push_back(std::move(TU)); 387 offset = DWOTUs.back()->getNextUnitOffset(); 388 } 389 } 390 } 391 392 namespace { 393 struct OffsetComparator { 394 395 bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS, 396 const std::unique_ptr<DWARFCompileUnit> &RHS) const { 397 return LHS->getOffset() < RHS->getOffset(); 398 } 399 bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS, 400 uint32_t RHS) const { 401 return LHS->getOffset() < RHS; 402 } 403 bool operator()(uint32_t LHS, 404 const std::unique_ptr<DWARFCompileUnit> &RHS) const { 405 return LHS < RHS->getOffset(); 406 } 407 }; 408 } 409 410 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { 411 parseCompileUnits(); 412 413 std::unique_ptr<DWARFCompileUnit> *CU = 414 std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator()); 415 if (CU != CUs.end()) { 416 return CU->get(); 417 } 418 return nullptr; 419 } 420 421 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { 422 // First, get the offset of the compile unit. 423 uint32_t CUOffset = getDebugAranges()->findAddress(Address); 424 // Retrieve the compile unit. 425 return getCompileUnitForOffset(CUOffset); 426 } 427 428 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, 429 const DWARFLineTable *LineTable, 430 uint64_t FileIndex, FileLineInfoKind Kind, 431 std::string &FileName) { 432 if (!CU || !LineTable || Kind == FileLineInfoKind::None || 433 !LineTable->getFileNameByIndex(FileIndex, Kind, FileName)) 434 return false; 435 if (Kind == FileLineInfoKind::AbsoluteFilePath && 436 sys::path::is_relative(FileName)) { 437 // We may still need to append compilation directory of compile unit. 438 SmallString<16> AbsolutePath; 439 if (const char *CompilationDir = CU->getCompilationDir()) { 440 sys::path::append(AbsolutePath, CompilationDir); 441 } 442 sys::path::append(AbsolutePath, FileName); 443 FileName = AbsolutePath.str(); 444 } 445 return true; 446 } 447 448 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, 449 const DWARFLineTable *LineTable, 450 uint64_t Address, 451 FileLineInfoKind Kind, 452 DILineInfo &Result) { 453 if (!CU || !LineTable) 454 return false; 455 // Get the index of row we're looking for in the line table. 456 uint32_t RowIndex = LineTable->lookupAddress(Address); 457 if (RowIndex == -1U) 458 return false; 459 // Take file number and line/column from the row. 460 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; 461 if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind, 462 Result.FileName)) 463 return false; 464 Result.Line = Row.Line; 465 Result.Column = Row.Column; 466 return true; 467 } 468 469 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, 470 FunctionNameKind Kind, 471 std::string &FunctionName) { 472 if (Kind == FunctionNameKind::None) 473 return false; 474 // The address may correspond to instruction in some inlined function, 475 // so we have to build the chain of inlined functions and take the 476 // name of the topmost function in it. 477 const DWARFDebugInfoEntryInlinedChain &InlinedChain = 478 CU->getInlinedChainForAddress(Address); 479 if (InlinedChain.DIEs.size() == 0) 480 return false; 481 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; 482 if (const char *Name = 483 TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) { 484 FunctionName = Name; 485 return true; 486 } 487 return false; 488 } 489 490 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, 491 DILineInfoSpecifier Spec) { 492 DILineInfo Result; 493 494 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 495 if (!CU) 496 return Result; 497 getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName); 498 if (Spec.FLIKind != FileLineInfoKind::None) { 499 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); 500 getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result); 501 } 502 return Result; 503 } 504 505 DILineInfoTable 506 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 507 DILineInfoSpecifier Spec) { 508 DILineInfoTable Lines; 509 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 510 if (!CU) 511 return Lines; 512 513 std::string FunctionName = "<invalid>"; 514 getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName); 515 516 // If the Specifier says we don't need FileLineInfo, just 517 // return the top-most function at the starting address. 518 if (Spec.FLIKind == FileLineInfoKind::None) { 519 DILineInfo Result; 520 Result.FunctionName = FunctionName; 521 Lines.push_back(std::make_pair(Address, Result)); 522 return Lines; 523 } 524 525 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); 526 527 // Get the index of row we're looking for in the line table. 528 std::vector<uint32_t> RowVector; 529 if (!LineTable->lookupAddressRange(Address, Size, RowVector)) 530 return Lines; 531 532 for (uint32_t RowIndex : RowVector) { 533 // Take file number and line/column from the row. 534 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; 535 DILineInfo Result; 536 getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind, 537 Result.FileName); 538 Result.FunctionName = FunctionName; 539 Result.Line = Row.Line; 540 Result.Column = Row.Column; 541 Lines.push_back(std::make_pair(Row.Address, Result)); 542 } 543 544 return Lines; 545 } 546 547 DIInliningInfo 548 DWARFContext::getInliningInfoForAddress(uint64_t Address, 549 DILineInfoSpecifier Spec) { 550 DIInliningInfo InliningInfo; 551 552 DWARFCompileUnit *CU = getCompileUnitForAddress(Address); 553 if (!CU) 554 return InliningInfo; 555 556 const DWARFLineTable *LineTable = nullptr; 557 const DWARFDebugInfoEntryInlinedChain &InlinedChain = 558 CU->getInlinedChainForAddress(Address); 559 if (InlinedChain.DIEs.size() == 0) { 560 // If there is no DIE for address (e.g. it is in unavailable .dwo file), 561 // try to at least get file/line info from symbol table. 562 if (Spec.FLIKind != FileLineInfoKind::None) { 563 DILineInfo Frame; 564 LineTable = getLineTableForCompileUnit(CU); 565 if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, 566 Frame)) { 567 InliningInfo.addFrame(Frame); 568 } 569 } 570 return InliningInfo; 571 } 572 573 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0; 574 for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) { 575 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; 576 DILineInfo Frame; 577 // Get function name if necessary. 578 if (const char *Name = 579 FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind)) 580 Frame.FunctionName = Name; 581 if (Spec.FLIKind != FileLineInfoKind::None) { 582 if (i == 0) { 583 // For the topmost frame, initialize the line table of this 584 // compile unit and fetch file/line info from it. 585 LineTable = getLineTableForCompileUnit(CU); 586 // For the topmost routine, get file/line info from line table. 587 getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, 588 Frame); 589 } else { 590 // Otherwise, use call file, call line and call column from 591 // previous DIE in inlined chain. 592 getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind, 593 Frame.FileName); 594 Frame.Line = CallLine; 595 Frame.Column = CallColumn; 596 } 597 // Get call file/line/column of a current DIE. 598 if (i + 1 < n) { 599 FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine, 600 CallColumn); 601 } 602 } 603 InliningInfo.addFrame(Frame); 604 } 605 return InliningInfo; 606 } 607 608 static bool consumeCompressedDebugSectionHeader(StringRef &data, 609 uint64_t &OriginalSize) { 610 // Consume "ZLIB" prefix. 611 if (!data.startswith("ZLIB")) 612 return false; 613 data = data.substr(4); 614 // Consume uncompressed section size (big-endian 8 bytes). 615 DataExtractor extractor(data, false, 8); 616 uint32_t Offset = 0; 617 OriginalSize = extractor.getU64(&Offset); 618 if (Offset == 0) 619 return false; 620 data = data.substr(Offset); 621 return true; 622 } 623 624 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) 625 : IsLittleEndian(Obj->isLittleEndian()), 626 AddressSize(Obj->getBytesInAddress()) { 627 for (const SectionRef &Section : Obj->sections()) { 628 StringRef name; 629 Section.getName(name); 630 StringRef data; 631 Section.getContents(data); 632 633 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. 634 635 // Check if debug info section is compressed with zlib. 636 if (name.startswith("zdebug_")) { 637 uint64_t OriginalSize; 638 if (!zlib::isAvailable() || 639 !consumeCompressedDebugSectionHeader(data, OriginalSize)) 640 continue; 641 UncompressedSections.resize(UncompressedSections.size() + 1); 642 if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) != 643 zlib::StatusOK) { 644 UncompressedSections.pop_back(); 645 continue; 646 } 647 // Make data point to uncompressed section contents and save its contents. 648 name = name.substr(1); 649 data = UncompressedSections.back(); 650 } 651 652 StringRef *SectionData = 653 StringSwitch<StringRef *>(name) 654 .Case("debug_info", &InfoSection.Data) 655 .Case("debug_abbrev", &AbbrevSection) 656 .Case("debug_loc", &LocSection.Data) 657 .Case("debug_line", &LineSection.Data) 658 .Case("debug_aranges", &ARangeSection) 659 .Case("debug_frame", &DebugFrameSection) 660 .Case("debug_str", &StringSection) 661 .Case("debug_ranges", &RangeSection) 662 .Case("debug_pubnames", &PubNamesSection) 663 .Case("debug_pubtypes", &PubTypesSection) 664 .Case("debug_gnu_pubnames", &GnuPubNamesSection) 665 .Case("debug_gnu_pubtypes", &GnuPubTypesSection) 666 .Case("debug_info.dwo", &InfoDWOSection.Data) 667 .Case("debug_abbrev.dwo", &AbbrevDWOSection) 668 .Case("debug_loc.dwo", &LocDWOSection.Data) 669 .Case("debug_line.dwo", &LineDWOSection.Data) 670 .Case("debug_str.dwo", &StringDWOSection) 671 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) 672 .Case("debug_addr", &AddrSection) 673 // Any more debug info sections go here. 674 .Default(nullptr); 675 if (SectionData) { 676 *SectionData = data; 677 if (name == "debug_ranges") { 678 // FIXME: Use the other dwo range section when we emit it. 679 RangeDWOSection = data; 680 } 681 } else if (name == "debug_types") { 682 // Find debug_types data by section rather than name as there are 683 // multiple, comdat grouped, debug_types sections. 684 TypesSections[Section].Data = data; 685 } else if (name == "debug_types.dwo") { 686 TypesDWOSections[Section].Data = data; 687 } 688 689 section_iterator RelocatedSection = Section.getRelocatedSection(); 690 if (RelocatedSection == Obj->section_end()) 691 continue; 692 693 StringRef RelSecName; 694 RelocatedSection->getName(RelSecName); 695 RelSecName = RelSecName.substr( 696 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes. 697 698 // TODO: Add support for relocations in other sections as needed. 699 // Record relocations for the debug_info and debug_line sections. 700 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName) 701 .Case("debug_info", &InfoSection.Relocs) 702 .Case("debug_loc", &LocSection.Relocs) 703 .Case("debug_info.dwo", &InfoDWOSection.Relocs) 704 .Case("debug_line", &LineSection.Relocs) 705 .Default(nullptr); 706 if (!Map) { 707 // Find debug_types relocs by section rather than name as there are 708 // multiple, comdat grouped, debug_types sections. 709 if (RelSecName == "debug_types") 710 Map = &TypesSections[*RelocatedSection].Relocs; 711 else if (RelSecName == "debug_types.dwo") 712 Map = &TypesDWOSections[*RelocatedSection].Relocs; 713 else 714 continue; 715 } 716 717 if (Section.relocation_begin() != Section.relocation_end()) { 718 uint64_t SectionSize; 719 RelocatedSection->getSize(SectionSize); 720 for (const RelocationRef &Reloc : Section.relocations()) { 721 uint64_t Address; 722 Reloc.getOffset(Address); 723 uint64_t Type; 724 Reloc.getType(Type); 725 uint64_t SymAddr = 0; 726 // ELF relocations may need the symbol address 727 if (Obj->isELF()) { 728 object::symbol_iterator Sym = Reloc.getSymbol(); 729 Sym->getAddress(SymAddr); 730 } 731 732 object::RelocVisitor V(Obj->getFileFormatName()); 733 // The section address is always 0 for debug sections. 734 object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr)); 735 if (V.error()) { 736 SmallString<32> Name; 737 std::error_code ec(Reloc.getTypeName(Name)); 738 if (ec) { 739 errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; 740 } 741 errs() << "error: failed to compute relocation: " 742 << Name << "\n"; 743 continue; 744 } 745 746 if (Address + R.Width > SectionSize) { 747 errs() << "error: " << R.Width << "-byte relocation starting " 748 << Address << " bytes into section " << name << " which is " 749 << SectionSize << " bytes long.\n"; 750 continue; 751 } 752 if (R.Width > 8) { 753 errs() << "error: can't handle a relocation of more than 8 bytes at " 754 "a time.\n"; 755 continue; 756 } 757 DEBUG(dbgs() << "Writing " << format("%p", R.Value) 758 << " at " << format("%p", Address) 759 << " with width " << format("%d", R.Width) 760 << "\n"); 761 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value))); 762 } 763 } 764 } 765 } 766 767 void DWARFContextInMemory::anchor() { } 768