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