1 //===- DWARFDie.cpp -------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 10 #include "llvm/ADT/None.h" 11 #include "llvm/ADT/Optional.h" 12 #include "llvm/ADT/SmallSet.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/BinaryFormat/Dwarf.h" 15 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 16 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 17 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 18 #include "llvm/DebugInfo/DWARF/DWARFExpression.h" 19 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 20 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 21 #include "llvm/Object/ObjectFile.h" 22 #include "llvm/Support/DataExtractor.h" 23 #include "llvm/Support/Format.h" 24 #include "llvm/Support/FormatAdapters.h" 25 #include "llvm/Support/FormatVariadic.h" 26 #include "llvm/Support/MathExtras.h" 27 #include "llvm/Support/WithColor.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <algorithm> 30 #include <cassert> 31 #include <cinttypes> 32 #include <cstdint> 33 #include <string> 34 #include <utility> 35 36 using namespace llvm; 37 using namespace dwarf; 38 using namespace object; 39 40 static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) { 41 OS << " ("; 42 do { 43 uint64_t Shift = countTrailingZeros(Val); 44 assert(Shift < 64 && "undefined behavior"); 45 uint64_t Bit = 1ULL << Shift; 46 auto PropName = ApplePropertyString(Bit); 47 if (!PropName.empty()) 48 OS << PropName; 49 else 50 OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit); 51 if (!(Val ^= Bit)) 52 break; 53 OS << ", "; 54 } while (true); 55 OS << ")"; 56 } 57 58 static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS, 59 const DWARFAddressRangesVector &Ranges, 60 unsigned AddressSize, unsigned Indent, 61 const DIDumpOptions &DumpOpts) { 62 if (!DumpOpts.ShowAddresses) 63 return; 64 65 for (const DWARFAddressRange &R : Ranges) { 66 OS << '\n'; 67 OS.indent(Indent); 68 R.dump(OS, AddressSize, DumpOpts, &Obj); 69 } 70 } 71 72 static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue, 73 DWARFUnit *U, unsigned Indent, 74 DIDumpOptions DumpOpts) { 75 assert(FormValue.isFormClass(DWARFFormValue::FC_SectionOffset) && 76 "bad FORM for location list"); 77 DWARFContext &Ctx = U->getContext(); 78 const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); 79 uint64_t Offset = *FormValue.getAsSectionOffset(); 80 81 if (FormValue.getForm() == DW_FORM_loclistx) { 82 FormValue.dump(OS, DumpOpts); 83 84 if (auto LoclistOffset = U->getLoclistOffset(Offset)) 85 Offset = *LoclistOffset; 86 else 87 return; 88 } 89 U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI, 90 Ctx.getDWARFObj(), U, DumpOpts, 91 Indent); 92 return; 93 } 94 95 static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, 96 DWARFUnit *U, unsigned Indent, 97 DIDumpOptions DumpOpts) { 98 assert((FormValue.isFormClass(DWARFFormValue::FC_Block) || 99 FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) && 100 "bad FORM for location expression"); 101 DWARFContext &Ctx = U->getContext(); 102 const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); 103 ArrayRef<uint8_t> Expr = *FormValue.getAsBlock(); 104 DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), 105 Ctx.isLittleEndian(), 0); 106 DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format) 107 .print(OS, DumpOpts, MRI, U); 108 return; 109 } 110 111 /// Dump the name encoded in the type tag. 112 static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) { 113 StringRef TagStr = TagString(T); 114 if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type")) 115 return; 116 OS << TagStr.substr(7, TagStr.size() - 12) << " "; 117 } 118 119 static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) { 120 for (const DWARFDie &C : D.children()) 121 if (C.getTag() == DW_TAG_subrange_type) { 122 Optional<uint64_t> LB; 123 Optional<uint64_t> Count; 124 Optional<uint64_t> UB; 125 Optional<unsigned> DefaultLB; 126 if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound)) 127 LB = L->getAsUnsignedConstant(); 128 if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count)) 129 Count = CountV->getAsUnsignedConstant(); 130 if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound)) 131 UB = UpperV->getAsUnsignedConstant(); 132 if (Optional<DWARFFormValue> LV = 133 D.getDwarfUnit()->getUnitDIE().find(DW_AT_language)) 134 if (Optional<uint64_t> LC = LV->getAsUnsignedConstant()) 135 if ((DefaultLB = 136 LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC)))) 137 if (LB && *LB == *DefaultLB) 138 LB = None; 139 if (!LB && !Count && !UB) 140 OS << "[]"; 141 else if (!LB && (Count || UB) && DefaultLB) 142 OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']'; 143 else { 144 OS << "[["; 145 if (LB) 146 OS << *LB; 147 else 148 OS << '?'; 149 OS << ", "; 150 if (Count) 151 if (LB) 152 OS << *LB + *Count; 153 else 154 OS << "? + " << *Count; 155 else if (UB) 156 OS << *UB + 1; 157 else 158 OS << '?'; 159 OS << ")]"; 160 } 161 } 162 } 163 164 /// Recursively dump the DIE type name when applicable. 165 static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) { 166 if (!D.isValid()) 167 return; 168 169 if (const char *Name = D.getName(DINameKind::LinkageName)) { 170 OS << Name; 171 return; 172 } 173 174 // FIXME: We should have pretty printers per language. Currently we print 175 // everything as if it was C++ and fall back to the TAG type name. 176 const dwarf::Tag T = D.getTag(); 177 switch (T) { 178 case DW_TAG_array_type: 179 case DW_TAG_pointer_type: 180 case DW_TAG_ptr_to_member_type: 181 case DW_TAG_reference_type: 182 case DW_TAG_rvalue_reference_type: 183 case DW_TAG_subroutine_type: 184 break; 185 default: 186 dumpTypeTagName(OS, T); 187 } 188 189 // Follow the DW_AT_type if possible. 190 DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type); 191 dumpTypeName(OS, TypeDie); 192 193 switch (T) { 194 case DW_TAG_subroutine_type: { 195 if (!TypeDie) 196 OS << "void"; 197 OS << '('; 198 bool First = true; 199 for (const DWARFDie &C : D.children()) { 200 if (C.getTag() == DW_TAG_formal_parameter) { 201 if (!First) 202 OS << ", "; 203 First = false; 204 dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type)); 205 } 206 } 207 OS << ')'; 208 break; 209 } 210 case DW_TAG_array_type: { 211 dumpArrayType(OS, D); 212 break; 213 } 214 case DW_TAG_pointer_type: 215 OS << '*'; 216 break; 217 case DW_TAG_ptr_to_member_type: 218 if (DWARFDie Cont = 219 D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) { 220 dumpTypeName(OS << ' ', Cont); 221 OS << "::"; 222 } 223 OS << '*'; 224 break; 225 case DW_TAG_reference_type: 226 OS << '&'; 227 break; 228 case DW_TAG_rvalue_reference_type: 229 OS << "&&"; 230 break; 231 default: 232 break; 233 } 234 } 235 236 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, 237 const DWARFAttribute &AttrValue, unsigned Indent, 238 DIDumpOptions DumpOpts) { 239 if (!Die.isValid()) 240 return; 241 const char BaseIndent[] = " "; 242 OS << BaseIndent; 243 OS.indent(Indent + 2); 244 dwarf::Attribute Attr = AttrValue.Attr; 245 WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr); 246 247 dwarf::Form Form = AttrValue.Value.getForm(); 248 if (DumpOpts.Verbose || DumpOpts.ShowForm) 249 OS << formatv(" [{0}]", Form); 250 251 DWARFUnit *U = Die.getDwarfUnit(); 252 const DWARFFormValue &FormValue = AttrValue.Value; 253 254 OS << "\t("; 255 256 StringRef Name; 257 std::string File; 258 auto Color = HighlightColor::Enumerator; 259 if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) { 260 Color = HighlightColor::String; 261 if (const auto *LT = U->getContext().getLineTableForUnit(U)) 262 if (LT->getFileNameByIndex( 263 FormValue.getAsUnsignedConstant().getValue(), 264 U->getCompilationDir(), 265 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { 266 File = '"' + File + '"'; 267 Name = File; 268 } 269 } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) 270 Name = AttributeValueString(Attr, *Val); 271 272 if (!Name.empty()) 273 WithColor(OS, Color) << Name; 274 else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) 275 OS << *FormValue.getAsUnsignedConstant(); 276 else if (Attr == DW_AT_low_pc && 277 (FormValue.getAsAddress() == 278 dwarf::computeTombstoneAddress(U->getAddressByteSize()))) { 279 if (DumpOpts.Verbose) { 280 FormValue.dump(OS, DumpOpts); 281 OS << " ("; 282 } 283 OS << "dead code"; 284 if (DumpOpts.Verbose) 285 OS << ')'; 286 } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && 287 FormValue.getAsUnsignedConstant()) { 288 if (DumpOpts.ShowAddresses) { 289 // Print the actual address rather than the offset. 290 uint64_t LowPC, HighPC, Index; 291 if (Die.getLowAndHighPC(LowPC, HighPC, Index)) 292 DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC); 293 else 294 FormValue.dump(OS, DumpOpts); 295 } 296 } else if (DWARFAttribute::mayHaveLocationList(Attr) && 297 FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) 298 dumpLocationList(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, 299 DumpOpts); 300 else if (FormValue.isFormClass(DWARFFormValue::FC_Exprloc) || 301 (DWARFAttribute::mayHaveLocationExpr(Attr) && 302 FormValue.isFormClass(DWARFFormValue::FC_Block))) 303 dumpLocationExpr(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, 304 DumpOpts); 305 else 306 FormValue.dump(OS, DumpOpts); 307 308 std::string Space = DumpOpts.ShowAddresses ? " " : ""; 309 310 // We have dumped the attribute raw value. For some attributes 311 // having both the raw value and the pretty-printed value is 312 // interesting. These attributes are handled below. 313 if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) { 314 if (const char *Name = 315 Die.getAttributeValueAsReferencedDie(FormValue).getName( 316 DINameKind::LinkageName)) 317 OS << Space << "\"" << Name << '\"'; 318 } else if (Attr == DW_AT_type) { 319 OS << Space << "\""; 320 dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue)); 321 OS << '"'; 322 } else if (Attr == DW_AT_APPLE_property_attribute) { 323 if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant()) 324 dumpApplePropertyAttribute(OS, *OptVal); 325 } else if (Attr == DW_AT_ranges) { 326 const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj(); 327 // For DW_FORM_rnglistx we need to dump the offset separately, since 328 // we have only dumped the index so far. 329 if (FormValue.getForm() == DW_FORM_rnglistx) 330 if (auto RangeListOffset = 331 U->getRnglistOffset(*FormValue.getAsSectionOffset())) { 332 DWARFFormValue FV = DWARFFormValue::createFromUValue( 333 dwarf::DW_FORM_sec_offset, *RangeListOffset); 334 FV.dump(OS, DumpOpts); 335 } 336 if (auto RangesOrError = Die.getAddressRanges()) 337 dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(), 338 sizeof(BaseIndent) + Indent + 4, DumpOpts); 339 else 340 DumpOpts.RecoverableErrorHandler(createStringError( 341 errc::invalid_argument, "decoding address ranges: %s", 342 toString(RangesOrError.takeError()).c_str())); 343 } 344 345 OS << ")\n"; 346 } 347 348 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; } 349 350 bool DWARFDie::isSubroutineDIE() const { 351 auto Tag = getTag(); 352 return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine; 353 } 354 355 Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const { 356 if (!isValid()) 357 return None; 358 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 359 if (AbbrevDecl) 360 return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U); 361 return None; 362 } 363 364 Optional<DWARFFormValue> 365 DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const { 366 if (!isValid()) 367 return None; 368 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 369 if (AbbrevDecl) { 370 for (auto Attr : Attrs) { 371 if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U)) 372 return Value; 373 } 374 } 375 return None; 376 } 377 378 Optional<DWARFFormValue> 379 DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { 380 SmallVector<DWARFDie, 3> Worklist; 381 Worklist.push_back(*this); 382 383 // Keep track if DIEs already seen to prevent infinite recursion. 384 // Empirically we rarely see a depth of more than 3 when dealing with valid 385 // DWARF. This corresponds to following the DW_AT_abstract_origin and 386 // DW_AT_specification just once. 387 SmallSet<DWARFDie, 3> Seen; 388 Seen.insert(*this); 389 390 while (!Worklist.empty()) { 391 DWARFDie Die = Worklist.pop_back_val(); 392 393 if (!Die.isValid()) 394 continue; 395 396 if (auto Value = Die.find(Attrs)) 397 return Value; 398 399 if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 400 if (Seen.insert(D).second) 401 Worklist.push_back(D); 402 403 if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification)) 404 if (Seen.insert(D).second) 405 Worklist.push_back(D); 406 } 407 408 return None; 409 } 410 411 DWARFDie 412 DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { 413 if (Optional<DWARFFormValue> F = find(Attr)) 414 return getAttributeValueAsReferencedDie(*F); 415 return DWARFDie(); 416 } 417 418 DWARFDie 419 DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const { 420 if (auto SpecRef = V.getAsRelativeReference()) { 421 if (SpecRef->Unit) 422 return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + SpecRef->Offset); 423 if (auto SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset)) 424 return SpecUnit->getDIEForOffset(SpecRef->Offset); 425 } 426 return DWARFDie(); 427 } 428 429 Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const { 430 return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base})); 431 } 432 433 Optional<uint64_t> DWARFDie::getLocBaseAttribute() const { 434 return toSectionOffset(find(DW_AT_loclists_base)); 435 } 436 437 Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { 438 uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize()); 439 if (LowPC == Tombstone) 440 return None; 441 if (auto FormValue = find(DW_AT_high_pc)) { 442 if (auto Address = FormValue->getAsAddress()) { 443 // High PC is an address. 444 return Address; 445 } 446 if (auto Offset = FormValue->getAsUnsignedConstant()) { 447 // High PC is an offset from LowPC. 448 return LowPC + *Offset; 449 } 450 } 451 return None; 452 } 453 454 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, 455 uint64_t &SectionIndex) const { 456 auto F = find(DW_AT_low_pc); 457 auto LowPcAddr = toSectionedAddress(F); 458 if (!LowPcAddr) 459 return false; 460 if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) { 461 LowPC = LowPcAddr->Address; 462 HighPC = *HighPcAddr; 463 SectionIndex = LowPcAddr->SectionIndex; 464 return true; 465 } 466 return false; 467 } 468 469 Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const { 470 if (isNULL()) 471 return DWARFAddressRangesVector(); 472 // Single range specified by low/high PC. 473 uint64_t LowPC, HighPC, Index; 474 if (getLowAndHighPC(LowPC, HighPC, Index)) 475 return DWARFAddressRangesVector{{LowPC, HighPC, Index}}; 476 477 Optional<DWARFFormValue> Value = find(DW_AT_ranges); 478 if (Value) { 479 if (Value->getForm() == DW_FORM_rnglistx) 480 return U->findRnglistFromIndex(*Value->getAsSectionOffset()); 481 return U->findRnglistFromOffset(*Value->getAsSectionOffset()); 482 } 483 return DWARFAddressRangesVector(); 484 } 485 486 void DWARFDie::collectChildrenAddressRanges( 487 DWARFAddressRangesVector &Ranges) const { 488 if (isNULL()) 489 return; 490 if (isSubprogramDIE()) { 491 if (auto DIERangesOrError = getAddressRanges()) 492 llvm::append_range(Ranges, DIERangesOrError.get()); 493 else 494 llvm::consumeError(DIERangesOrError.takeError()); 495 } 496 497 for (auto Child : children()) 498 Child.collectChildrenAddressRanges(Ranges); 499 } 500 501 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { 502 auto RangesOrError = getAddressRanges(); 503 if (!RangesOrError) { 504 llvm::consumeError(RangesOrError.takeError()); 505 return false; 506 } 507 508 for (const auto &R : RangesOrError.get()) 509 if (R.LowPC <= Address && Address < R.HighPC) 510 return true; 511 return false; 512 } 513 514 Expected<DWARFLocationExpressionsVector> 515 DWARFDie::getLocations(dwarf::Attribute Attr) const { 516 Optional<DWARFFormValue> Location = find(Attr); 517 if (!Location) 518 return createStringError(inconvertibleErrorCode(), "No %s", 519 dwarf::AttributeString(Attr).data()); 520 521 if (Optional<uint64_t> Off = Location->getAsSectionOffset()) { 522 uint64_t Offset = *Off; 523 524 if (Location->getForm() == DW_FORM_loclistx) { 525 if (auto LoclistOffset = U->getLoclistOffset(Offset)) 526 Offset = *LoclistOffset; 527 else 528 return createStringError(inconvertibleErrorCode(), 529 "Loclist table not found"); 530 } 531 return U->findLoclistFromOffset(Offset); 532 } 533 534 if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { 535 return DWARFLocationExpressionsVector{ 536 DWARFLocationExpression{None, to_vector<4>(*Expr)}}; 537 } 538 539 return createStringError( 540 inconvertibleErrorCode(), "Unsupported %s encoding: %s", 541 dwarf::AttributeString(Attr).data(), 542 dwarf::FormEncodingString(Location->getForm()).data()); 543 } 544 545 const char *DWARFDie::getSubroutineName(DINameKind Kind) const { 546 if (!isSubroutineDIE()) 547 return nullptr; 548 return getName(Kind); 549 } 550 551 const char *DWARFDie::getName(DINameKind Kind) const { 552 if (!isValid() || Kind == DINameKind::None) 553 return nullptr; 554 // Try to get mangled name only if it was asked for. 555 if (Kind == DINameKind::LinkageName) { 556 if (auto Name = getLinkageName()) 557 return Name; 558 } 559 return getShortName(); 560 } 561 562 const char *DWARFDie::getShortName() const { 563 if (!isValid()) 564 return nullptr; 565 566 return dwarf::toString(findRecursively(dwarf::DW_AT_name), nullptr); 567 } 568 569 const char *DWARFDie::getLinkageName() const { 570 if (!isValid()) 571 return nullptr; 572 573 return dwarf::toString(findRecursively({dwarf::DW_AT_MIPS_linkage_name, 574 dwarf::DW_AT_linkage_name}), 575 nullptr); 576 } 577 578 uint64_t DWARFDie::getDeclLine() const { 579 return toUnsigned(findRecursively(DW_AT_decl_line), 0); 580 } 581 582 std::string 583 DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const { 584 auto D = getAttributeValueAsReferencedDie(DW_AT_abstract_origin); 585 if (!D) 586 D = *this; 587 std::string FileName; 588 if (auto DeclFile = toUnsigned(D.find(DW_AT_decl_file))) { 589 if (const auto *LineTable = 590 getDwarfUnit()->getContext().getLineTableForUnit( 591 D.getDwarfUnit()->getLinkedUnit())) 592 LineTable->getFileNameByIndex( 593 *DeclFile, D.getDwarfUnit()->getCompilationDir(), Kind, FileName); 594 } 595 return FileName; 596 } 597 598 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, 599 uint32_t &CallColumn, 600 uint32_t &CallDiscriminator) const { 601 CallFile = toUnsigned(find(DW_AT_call_file), 0); 602 CallLine = toUnsigned(find(DW_AT_call_line), 0); 603 CallColumn = toUnsigned(find(DW_AT_call_column), 0); 604 CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0); 605 } 606 607 /// Helper to dump a DIE with all of its parents, but no siblings. 608 static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, 609 DIDumpOptions DumpOpts, unsigned Depth = 0) { 610 if (!Die) 611 return Indent; 612 if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth) 613 return Indent; 614 Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1); 615 Die.dump(OS, Indent, DumpOpts); 616 return Indent + 2; 617 } 618 619 void DWARFDie::dump(raw_ostream &OS, unsigned Indent, 620 DIDumpOptions DumpOpts) const { 621 if (!isValid()) 622 return; 623 DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor(); 624 const uint64_t Offset = getOffset(); 625 uint64_t offset = Offset; 626 if (DumpOpts.ShowParents) { 627 DIDumpOptions ParentDumpOpts = DumpOpts; 628 ParentDumpOpts.ShowParents = false; 629 ParentDumpOpts.ShowChildren = false; 630 Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts); 631 } 632 633 if (debug_info_data.isValidOffset(offset)) { 634 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 635 if (DumpOpts.ShowAddresses) 636 WithColor(OS, HighlightColor::Address).get() 637 << format("\n0x%8.8" PRIx64 ": ", Offset); 638 639 if (abbrCode) { 640 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 641 if (AbbrevDecl) { 642 WithColor(OS, HighlightColor::Tag).get().indent(Indent) 643 << formatv("{0}", getTag()); 644 if (DumpOpts.Verbose) 645 OS << format(" [%u] %c", abbrCode, 646 AbbrevDecl->hasChildren() ? '*' : ' '); 647 OS << '\n'; 648 649 // Dump all data in the DIE for the attributes. 650 for (const DWARFAttribute &AttrValue : attributes()) 651 dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts); 652 653 if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0) { 654 DWARFDie Child = getFirstChild(); 655 DumpOpts.ChildRecurseDepth--; 656 DIDumpOptions ChildDumpOpts = DumpOpts; 657 ChildDumpOpts.ShowParents = false; 658 while (Child) { 659 Child.dump(OS, Indent + 2, ChildDumpOpts); 660 Child = Child.getSibling(); 661 } 662 } 663 } else { 664 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 665 << abbrCode << '\n'; 666 } 667 } else { 668 OS.indent(Indent) << "NULL\n"; 669 } 670 } 671 } 672 673 LLVM_DUMP_METHOD void DWARFDie::dump() const { dump(llvm::errs(), 0); } 674 675 DWARFDie DWARFDie::getParent() const { 676 if (isValid()) 677 return U->getParent(Die); 678 return DWARFDie(); 679 } 680 681 DWARFDie DWARFDie::getSibling() const { 682 if (isValid()) 683 return U->getSibling(Die); 684 return DWARFDie(); 685 } 686 687 DWARFDie DWARFDie::getPreviousSibling() const { 688 if (isValid()) 689 return U->getPreviousSibling(Die); 690 return DWARFDie(); 691 } 692 693 DWARFDie DWARFDie::getFirstChild() const { 694 if (isValid()) 695 return U->getFirstChild(Die); 696 return DWARFDie(); 697 } 698 699 DWARFDie DWARFDie::getLastChild() const { 700 if (isValid()) 701 return U->getLastChild(Die); 702 return DWARFDie(); 703 } 704 705 iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const { 706 return make_range(attribute_iterator(*this, false), 707 attribute_iterator(*this, true)); 708 } 709 710 DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End) 711 : Die(D), Index(0) { 712 auto AbbrDecl = Die.getAbbreviationDeclarationPtr(); 713 assert(AbbrDecl && "Must have abbreviation declaration"); 714 if (End) { 715 // This is the end iterator so we set the index to the attribute count. 716 Index = AbbrDecl->getNumAttributes(); 717 } else { 718 // This is the begin iterator so we extract the value for this->Index. 719 AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize(); 720 updateForIndex(*AbbrDecl, 0); 721 } 722 } 723 724 void DWARFDie::attribute_iterator::updateForIndex( 725 const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) { 726 Index = I; 727 // AbbrDecl must be valid before calling this function. 728 auto NumAttrs = AbbrDecl.getNumAttributes(); 729 if (Index < NumAttrs) { 730 AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); 731 // Add the previous byte size of any previous attribute value. 732 AttrValue.Offset += AttrValue.ByteSize; 733 uint64_t ParseOffset = AttrValue.Offset; 734 if (AbbrDecl.getAttrIsImplicitConstByIndex(Index)) 735 AttrValue.Value = DWARFFormValue::createFromSValue( 736 AbbrDecl.getFormByIndex(Index), 737 AbbrDecl.getAttrImplicitConstValueByIndex(Index)); 738 else { 739 auto U = Die.getDwarfUnit(); 740 assert(U && "Die must have valid DWARF unit"); 741 AttrValue.Value = DWARFFormValue::createFromUnit( 742 AbbrDecl.getFormByIndex(Index), U, &ParseOffset); 743 } 744 AttrValue.ByteSize = ParseOffset - AttrValue.Offset; 745 } else { 746 assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); 747 AttrValue = {}; 748 } 749 } 750 751 DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() { 752 if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr()) 753 updateForIndex(*AbbrDecl, Index + 1); 754 return *this; 755 } 756 757 bool DWARFAttribute::mayHaveLocationList(dwarf::Attribute Attr) { 758 switch(Attr) { 759 case DW_AT_location: 760 case DW_AT_string_length: 761 case DW_AT_return_addr: 762 case DW_AT_data_member_location: 763 case DW_AT_frame_base: 764 case DW_AT_static_link: 765 case DW_AT_segment: 766 case DW_AT_use_location: 767 case DW_AT_vtable_elem_location: 768 return true; 769 default: 770 return false; 771 } 772 } 773 774 bool DWARFAttribute::mayHaveLocationExpr(dwarf::Attribute Attr) { 775 switch (Attr) { 776 // From the DWARF v5 specification. 777 case DW_AT_location: 778 case DW_AT_byte_size: 779 case DW_AT_bit_offset: 780 case DW_AT_bit_size: 781 case DW_AT_string_length: 782 case DW_AT_lower_bound: 783 case DW_AT_return_addr: 784 case DW_AT_bit_stride: 785 case DW_AT_upper_bound: 786 case DW_AT_count: 787 case DW_AT_data_member_location: 788 case DW_AT_frame_base: 789 case DW_AT_segment: 790 case DW_AT_static_link: 791 case DW_AT_use_location: 792 case DW_AT_vtable_elem_location: 793 case DW_AT_allocated: 794 case DW_AT_associated: 795 case DW_AT_data_location: 796 case DW_AT_byte_stride: 797 case DW_AT_rank: 798 case DW_AT_call_value: 799 case DW_AT_call_origin: 800 case DW_AT_call_target: 801 case DW_AT_call_target_clobbered: 802 case DW_AT_call_data_location: 803 case DW_AT_call_data_value: 804 // Extensions. 805 case DW_AT_GNU_call_site_value: 806 case DW_AT_GNU_call_site_target: 807 return true; 808 default: 809 return false; 810 } 811 } 812