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/DWARFDebugLine.h" 18 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 19 #include "llvm/DebugInfo/DWARF/DWARFExpression.h" 20 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 21 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" 22 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 23 #include "llvm/Object/ObjectFile.h" 24 #include "llvm/Support/DataExtractor.h" 25 #include "llvm/Support/Format.h" 26 #include "llvm/Support/FormatVariadic.h" 27 #include "llvm/Support/MathExtras.h" 28 #include "llvm/Support/ScopedPrinter.h" 29 #include "llvm/Support/WithColor.h" 30 #include "llvm/Support/raw_ostream.h" 31 #include <cassert> 32 #include <cinttypes> 33 #include <cstdint> 34 #include <string> 35 #include <utility> 36 37 using namespace llvm; 38 using namespace dwarf; 39 using namespace object; 40 41 static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) { 42 OS << " ("; 43 do { 44 uint64_t Shift = countTrailingZeros(Val); 45 assert(Shift < 64 && "undefined behavior"); 46 uint64_t Bit = 1ULL << Shift; 47 auto PropName = ApplePropertyString(Bit); 48 if (!PropName.empty()) 49 OS << PropName; 50 else 51 OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit); 52 if (!(Val ^= Bit)) 53 break; 54 OS << ", "; 55 } while (true); 56 OS << ")"; 57 } 58 59 static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS, 60 const DWARFAddressRangesVector &Ranges, 61 unsigned AddressSize, unsigned Indent, 62 const DIDumpOptions &DumpOpts) { 63 if (!DumpOpts.ShowAddresses) 64 return; 65 66 for (const DWARFAddressRange &R : Ranges) { 67 OS << '\n'; 68 OS.indent(Indent); 69 R.dump(OS, AddressSize, DumpOpts, &Obj); 70 } 71 } 72 73 static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue, 74 DWARFUnit *U, unsigned Indent, 75 DIDumpOptions DumpOpts) { 76 assert(FormValue.isFormClass(DWARFFormValue::FC_SectionOffset) && 77 "bad FORM for location list"); 78 DWARFContext &Ctx = U->getContext(); 79 const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); 80 uint64_t Offset = *FormValue.getAsSectionOffset(); 81 82 if (FormValue.getForm() == DW_FORM_loclistx) { 83 FormValue.dump(OS, DumpOpts); 84 85 if (auto LoclistOffset = U->getLoclistOffset(Offset)) 86 Offset = *LoclistOffset; 87 else 88 return; 89 } 90 U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI, 91 Ctx.getDWARFObj(), U, DumpOpts, 92 Indent); 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 } 109 110 static DWARFDie resolveReferencedType(DWARFDie D, 111 dwarf::Attribute Attr = DW_AT_type) { 112 return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference(); 113 } 114 static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) { 115 return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference(); 116 } 117 118 namespace { 119 120 // FIXME: We should have pretty printers per language. Currently we print 121 // everything as if it was C++ and fall back to the TAG type name. 122 struct DWARFTypePrinter { 123 raw_ostream &OS; 124 bool Word = true; 125 bool EndedWithTemplate = false; 126 127 DWARFTypePrinter(raw_ostream &OS) : OS(OS) {} 128 129 /// Dump the name encoded in the type tag. 130 void appendTypeTagName(dwarf::Tag T) { 131 StringRef TagStr = TagString(T); 132 static constexpr StringRef Prefix = "DW_TAG_"; 133 static constexpr StringRef Suffix = "_type"; 134 if (!TagStr.startswith(Prefix) || !TagStr.endswith(Suffix)) 135 return; 136 OS << TagStr.substr(Prefix.size(), 137 TagStr.size() - (Prefix.size() + Suffix.size())) 138 << " "; 139 } 140 141 void appendArrayType(const DWARFDie &D) { 142 for (const DWARFDie &C : D.children()) { 143 if (C.getTag() != DW_TAG_subrange_type) 144 continue; 145 Optional<uint64_t> LB; 146 Optional<uint64_t> Count; 147 Optional<uint64_t> UB; 148 Optional<unsigned> DefaultLB; 149 if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound)) 150 LB = L->getAsUnsignedConstant(); 151 if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count)) 152 Count = CountV->getAsUnsignedConstant(); 153 if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound)) 154 UB = UpperV->getAsUnsignedConstant(); 155 if (Optional<DWARFFormValue> LV = 156 D.getDwarfUnit()->getUnitDIE().find(DW_AT_language)) 157 if (Optional<uint64_t> LC = LV->getAsUnsignedConstant()) 158 if ((DefaultLB = 159 LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC)))) 160 if (LB && *LB == *DefaultLB) 161 LB = None; 162 if (!LB && !Count && !UB) 163 OS << "[]"; 164 else if (!LB && (Count || UB) && DefaultLB) 165 OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']'; 166 else { 167 OS << "[["; 168 if (LB) 169 OS << *LB; 170 else 171 OS << '?'; 172 OS << ", "; 173 if (Count) 174 if (LB) 175 OS << *LB + *Count; 176 else 177 OS << "? + " << *Count; 178 else if (UB) 179 OS << *UB + 1; 180 else 181 OS << '?'; 182 OS << ")]"; 183 } 184 } 185 EndedWithTemplate = false; 186 } 187 188 DWARFDie skipQualifiers(DWARFDie D) { 189 while (D && (D.getTag() == DW_TAG_const_type || 190 D.getTag() == DW_TAG_volatile_type)) 191 D = resolveReferencedType(D); 192 return D; 193 } 194 195 bool needsParens(DWARFDie D) { 196 D = skipQualifiers(D); 197 return D && (D.getTag() == DW_TAG_subroutine_type || D.getTag() == DW_TAG_array_type); 198 } 199 200 void appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner, StringRef Ptr) { 201 appendQualifiedNameBefore(Inner); 202 if (Word) 203 OS << ' '; 204 if (needsParens(Inner)) 205 OS << '('; 206 OS << Ptr; 207 Word = false; 208 EndedWithTemplate = false; 209 } 210 211 DWARFDie 212 appendUnqualifiedNameBefore(DWARFDie D, 213 std::string *OriginalFullName = nullptr) { 214 Word = true; 215 if (!D) { 216 OS << "void"; 217 return DWARFDie(); 218 } 219 DWARFDie InnerDIE; 220 auto Inner = [&] { return InnerDIE = resolveReferencedType(D); }; 221 const dwarf::Tag T = D.getTag(); 222 switch (T) { 223 case DW_TAG_pointer_type: { 224 appendPointerLikeTypeBefore(D, Inner(), "*"); 225 break; 226 } 227 case DW_TAG_subroutine_type: { 228 appendQualifiedNameBefore(Inner()); 229 if (Word) { 230 OS << ' '; 231 } 232 Word = false; 233 break; 234 } 235 case DW_TAG_array_type: { 236 appendQualifiedNameBefore(Inner()); 237 break; 238 } 239 case DW_TAG_reference_type: 240 appendPointerLikeTypeBefore(D, Inner(), "&"); 241 break; 242 case DW_TAG_rvalue_reference_type: 243 appendPointerLikeTypeBefore(D, Inner(), "&&"); 244 break; 245 case DW_TAG_ptr_to_member_type: { 246 appendQualifiedNameBefore(Inner()); 247 if (needsParens(InnerDIE)) 248 OS << '('; 249 else if (Word) 250 OS << ' '; 251 if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) { 252 appendQualifiedName(Cont); 253 EndedWithTemplate = false; 254 OS << "::"; 255 } 256 OS << "*"; 257 Word = false; 258 break; 259 } 260 case DW_TAG_const_type: 261 case DW_TAG_volatile_type: 262 appendConstVolatileQualifierBefore(D); 263 break; 264 case DW_TAG_namespace: { 265 if (const char *Name = dwarf::toString(D.find(DW_AT_name), nullptr)) 266 OS << Name; 267 else 268 OS << "(anonymous namespace)"; 269 break; 270 } 271 case DW_TAG_unspecified_type: { 272 StringRef TypeName = D.getShortName(); 273 if (TypeName == "decltype(nullptr)") 274 TypeName = "std::nullptr_t"; 275 Word = true; 276 OS << TypeName; 277 EndedWithTemplate = false; 278 break; 279 } 280 /* 281 case DW_TAG_structure_type: 282 case DW_TAG_class_type: 283 case DW_TAG_enumeration_type: 284 case DW_TAG_base_type: 285 */ 286 default: { 287 const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr); 288 if (!NamePtr) { 289 appendTypeTagName(D.getTag()); 290 return DWARFDie(); 291 } 292 Word = true; 293 StringRef Name = NamePtr; 294 static constexpr StringRef MangledPrefix = "_STN|"; 295 if (Name.startswith(MangledPrefix)) { 296 Name = Name.drop_front(MangledPrefix.size()); 297 auto Separator = Name.find('|'); 298 assert(Separator != StringRef::npos); 299 StringRef BaseName = Name.substr(0, Separator); 300 StringRef TemplateArgs = Name.substr(Separator + 1); 301 if (OriginalFullName) 302 *OriginalFullName = (BaseName + TemplateArgs).str(); 303 Name = BaseName; 304 } else 305 EndedWithTemplate = Name.endswith(">"); 306 OS << Name; 307 // This check would be insufficient for operator overloads like 308 // "operator>>" - but for now Clang doesn't try to simplify them, so this 309 // is OK. Add more nuanced operator overload handling here if/when needed. 310 if (Name.endswith(">")) 311 break; 312 if (!appendTemplateParameters(D)) 313 break; 314 315 if (EndedWithTemplate) 316 OS << ' '; 317 OS << '>'; 318 EndedWithTemplate = true; 319 Word = true; 320 break; 321 } 322 } 323 return InnerDIE; 324 } 325 326 void appendUnqualifiedNameAfter(DWARFDie D, DWARFDie Inner, 327 bool SkipFirstParamIfArtificial = false) { 328 if (!D) 329 return; 330 switch (D.getTag()) { 331 case DW_TAG_subroutine_type: { 332 appendSubroutineNameAfter(D, Inner, SkipFirstParamIfArtificial, false, 333 false); 334 break; 335 } 336 case DW_TAG_array_type: { 337 appendArrayType(D); 338 break; 339 } 340 case DW_TAG_const_type: 341 case DW_TAG_volatile_type: 342 appendConstVolatileQualifierAfter(D); 343 break; 344 case DW_TAG_ptr_to_member_type: 345 case DW_TAG_reference_type: 346 case DW_TAG_rvalue_reference_type: 347 case DW_TAG_pointer_type: { 348 if (needsParens(Inner)) 349 OS << ')'; 350 appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner), 351 /*SkipFirstParamIfArtificial=*/D.getTag() == 352 DW_TAG_ptr_to_member_type); 353 break; 354 } 355 /* 356 case DW_TAG_structure_type: 357 case DW_TAG_class_type: 358 case DW_TAG_enumeration_type: 359 case DW_TAG_base_type: 360 case DW_TAG_namespace: 361 */ 362 default: 363 break; 364 } 365 } 366 367 void appendQualifiedName(DWARFDie D) { 368 if (D) 369 appendScopes(D.getParent()); 370 appendUnqualifiedName(D); 371 } 372 DWARFDie appendQualifiedNameBefore(DWARFDie D) { 373 if (D) 374 appendScopes(D.getParent()); 375 return appendUnqualifiedNameBefore(D); 376 } 377 bool appendTemplateParameters(DWARFDie D, bool *FirstParameter = nullptr) { 378 bool FirstParameterValue = true; 379 bool IsTemplate = false; 380 if (!FirstParameter) 381 FirstParameter = &FirstParameterValue; 382 for (const DWARFDie &C : D) { 383 auto Sep = [&] { 384 if (*FirstParameter) 385 OS << '<'; 386 else 387 OS << ", "; 388 IsTemplate = true; 389 EndedWithTemplate = false; 390 *FirstParameter = false; 391 }; 392 if (C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) { 393 IsTemplate = true; 394 appendTemplateParameters(C, FirstParameter); 395 } 396 if (C.getTag() == dwarf::DW_TAG_template_value_parameter) { 397 DWARFDie T = resolveReferencedType(C); 398 Sep(); 399 if (T.getTag() == DW_TAG_enumeration_type) { 400 OS << '('; 401 appendQualifiedName(T); 402 OS << ')'; 403 auto V = C.find(DW_AT_const_value); 404 OS << to_string(*V->getAsSignedConstant()); 405 continue; 406 } 407 // /Maybe/ we could do pointer type parameters, looking for the 408 // symbol in the ELF symbol table to get back to the variable... 409 // but probably not worth it. 410 if (T.getTag() == DW_TAG_pointer_type) 411 continue; 412 const char *RawName = dwarf::toString(T.find(DW_AT_name), nullptr); 413 assert(RawName); 414 StringRef Name = RawName; 415 auto V = C.find(DW_AT_const_value); 416 bool IsQualifiedChar = false; 417 if (Name == "bool") { 418 OS << (*V->getAsUnsignedConstant() ? "true" : "false"); 419 } else if (Name == "short") { 420 OS << "(short)"; 421 OS << to_string(*V->getAsSignedConstant()); 422 } else if (Name == "unsigned short") { 423 OS << "(unsigned short)"; 424 OS << to_string(*V->getAsSignedConstant()); 425 } else if (Name == "int") 426 OS << to_string(*V->getAsSignedConstant()); 427 else if (Name == "long") { 428 OS << to_string(*V->getAsSignedConstant()); 429 OS << "L"; 430 } else if (Name == "long long") { 431 OS << to_string(*V->getAsSignedConstant()); 432 OS << "LL"; 433 } else if (Name == "unsigned int") { 434 OS << to_string(*V->getAsUnsignedConstant()); 435 OS << "U"; 436 } else if (Name == "unsigned long") { 437 OS << to_string(*V->getAsUnsignedConstant()); 438 OS << "UL"; 439 } else if (Name == "unsigned long long") { 440 OS << to_string(*V->getAsUnsignedConstant()); 441 OS << "ULL"; 442 } else if (Name == "char" || 443 (IsQualifiedChar = 444 (Name == "unsigned char" || Name == "signed char"))) { 445 // FIXME: check T's DW_AT_type to see if it's signed or not (since 446 // char signedness is implementation defined). 447 auto Val = *V->getAsSignedConstant(); 448 // Copied/hacked up from Clang's CharacterLiteral::print - incomplete 449 // (doesn't actually support different character types/widths, sign 450 // handling's not done, and doesn't correctly test if a character is 451 // printable or needs to use a numeric escape sequence instead) 452 if (IsQualifiedChar) { 453 OS << '('; 454 OS << Name; 455 OS << ')'; 456 } 457 switch (Val) { 458 case '\\': 459 OS << "'\\\\'"; 460 break; 461 case '\'': 462 OS << "'\\''"; 463 break; 464 case '\a': 465 // TODO: K&R: the meaning of '\\a' is different in traditional C 466 OS << "'\\a'"; 467 break; 468 case '\b': 469 OS << "'\\b'"; 470 break; 471 case '\f': 472 OS << "'\\f'"; 473 break; 474 case '\n': 475 OS << "'\\n'"; 476 break; 477 case '\r': 478 OS << "'\\r'"; 479 break; 480 case '\t': 481 OS << "'\\t'"; 482 break; 483 case '\v': 484 OS << "'\\v'"; 485 break; 486 default: 487 if ((Val & ~0xFFu) == ~0xFFu) 488 Val &= 0xFFu; 489 if (Val < 127 && Val >= 32) { 490 OS << "'"; 491 OS << (char)Val; 492 OS << "'"; 493 } else if (Val < 256) 494 OS << to_string(llvm::format("'\\x%02x'", Val)); 495 else if (Val <= 0xFFFF) 496 OS << to_string(llvm::format("'\\u%04x'", Val)); 497 else 498 OS << to_string(llvm::format("'\\U%08x'", Val)); 499 } 500 } 501 continue; 502 } 503 if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) { 504 const char *RawName = 505 dwarf::toString(C.find(DW_AT_GNU_template_name), nullptr); 506 assert(RawName); 507 StringRef Name = RawName; 508 Sep(); 509 OS << Name; 510 continue; 511 } 512 if (C.getTag() != dwarf::DW_TAG_template_type_parameter) 513 continue; 514 auto TypeAttr = C.find(DW_AT_type); 515 Sep(); 516 appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr) 517 : DWARFDie()); 518 } 519 if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) { 520 OS << '<'; 521 EndedWithTemplate = false; 522 } 523 return IsTemplate; 524 } 525 void decomposeConstVolatile(DWARFDie &N, DWARFDie &T, DWARFDie &C, 526 DWARFDie &V) { 527 (N.getTag() == DW_TAG_const_type ? C : V) = N; 528 T = resolveReferencedType(N); 529 if (T) { 530 auto Tag = T.getTag(); 531 if (Tag == DW_TAG_const_type) { 532 C = T; 533 T = resolveReferencedType(T); 534 } else if (Tag == DW_TAG_volatile_type) { 535 V = T; 536 T = resolveReferencedType(T); 537 } 538 } 539 } 540 void appendConstVolatileQualifierAfter(DWARFDie N) { 541 DWARFDie C; 542 DWARFDie V; 543 DWARFDie T; 544 decomposeConstVolatile(N, T, C, V); 545 if (T && T.getTag() == DW_TAG_subroutine_type) 546 appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(), 547 V.isValid()); 548 else 549 appendUnqualifiedNameAfter(T, resolveReferencedType(T)); 550 } 551 void appendConstVolatileQualifierBefore(DWARFDie N) { 552 DWARFDie C; 553 DWARFDie V; 554 DWARFDie T; 555 decomposeConstVolatile(N, T, C, V); 556 bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type; 557 DWARFDie A = T; 558 while (A && A.getTag() == DW_TAG_array_type) 559 A = resolveReferencedType(A); 560 bool Leading = 561 (!A || (A.getTag() != DW_TAG_pointer_type && 562 A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) && 563 !Subroutine; 564 if (Leading) { 565 if (C) 566 OS << "const "; 567 if (V) 568 OS << "volatile "; 569 } 570 appendQualifiedNameBefore(T); 571 if (!Leading && !Subroutine) { 572 Word = true; 573 if (C) 574 OS << "const"; 575 if (V) { 576 if (C) 577 OS << ' '; 578 OS << "volatile"; 579 } 580 } 581 } 582 583 /// Recursively append the DIE type name when applicable. 584 void appendUnqualifiedName(DWARFDie D, 585 std::string *OriginalFullName = nullptr) { 586 // FIXME: We should have pretty printers per language. Currently we print 587 // everything as if it was C++ and fall back to the TAG type name. 588 DWARFDie Inner = appendUnqualifiedNameBefore(D, OriginalFullName); 589 appendUnqualifiedNameAfter(D, Inner); 590 } 591 592 void appendSubroutineNameAfter(DWARFDie D, DWARFDie Inner, 593 bool SkipFirstParamIfArtificial, bool Const, 594 bool Volatile) { 595 DWARFDie FirstParamIfArtificial; 596 OS << '('; 597 EndedWithTemplate = false; 598 bool First = true; 599 bool RealFirst = true; 600 for (DWARFDie P : D) { 601 if (P.getTag() != DW_TAG_formal_parameter && 602 P.getTag() != DW_TAG_unspecified_parameters) 603 return; 604 DWARFDie T = resolveReferencedType(P); 605 if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) { 606 FirstParamIfArtificial = T; 607 RealFirst = false; 608 continue; 609 } 610 if (!First) { 611 OS << ", "; 612 } 613 First = false; 614 if (P.getTag() == DW_TAG_unspecified_parameters) 615 OS << "..."; 616 else 617 appendQualifiedName(T); 618 } 619 EndedWithTemplate = false; 620 OS << ')'; 621 if (FirstParamIfArtificial) { 622 if (DWARFDie P = FirstParamIfArtificial) { 623 if (P.getTag() == DW_TAG_pointer_type) { 624 auto CVStep = [&](DWARFDie CV) { 625 if (DWARFDie U = resolveReferencedType(CV)) { 626 Const |= U.getTag() == DW_TAG_const_type; 627 Volatile |= U.getTag() == DW_TAG_volatile_type; 628 return U; 629 } 630 return DWARFDie(); 631 }; 632 if (DWARFDie CV = CVStep(P)) { 633 CVStep(CV); 634 } 635 } 636 } 637 } 638 639 if (auto CC = D.find(DW_AT_calling_convention)) { 640 switch (*CC->getAsUnsignedConstant()) { 641 case CallingConvention::DW_CC_BORLAND_stdcall: 642 OS << " __attribute__((stdcall))"; 643 break; 644 case CallingConvention::DW_CC_BORLAND_msfastcall: 645 OS << " __attribute__((fastcall))"; 646 break; 647 case CallingConvention::DW_CC_BORLAND_thiscall: 648 OS << " __attribute__((thiscall))"; 649 break; 650 case CallingConvention::DW_CC_LLVM_vectorcall: 651 OS << " __attribute__((vectorcall))"; 652 break; 653 case CallingConvention::DW_CC_BORLAND_pascal: 654 OS << " __attribute__((pascal))"; 655 break; 656 case CallingConvention::DW_CC_LLVM_Win64: 657 OS << " __attribute__((ms_abi))"; 658 break; 659 case CallingConvention::DW_CC_LLVM_X86_64SysV: 660 OS << " __attribute__((sysv_abi))"; 661 break; 662 case CallingConvention::DW_CC_LLVM_AAPCS: 663 // AArch64VectorCall missing? 664 OS << " __attribute__((pcs(\"aapcs\")))"; 665 break; 666 case CallingConvention::DW_CC_LLVM_AAPCS_VFP: 667 OS << " __attribute__((pcs(\"aapcs-vfp\")))"; 668 break; 669 case CallingConvention::DW_CC_LLVM_IntelOclBicc: 670 OS << " __attribute__((intel_ocl_bicc))"; 671 break; 672 case CallingConvention::DW_CC_LLVM_SpirFunction: 673 case CallingConvention::DW_CC_LLVM_OpenCLKernel: 674 // These aren't available as attributes, but maybe we should still 675 // render them somehow? (Clang doesn't render them, but that's an issue 676 // for template names too - since then the DWARF names of templates 677 // instantiated with function types with these calling conventions won't 678 // have distinct names - so we'd need to fix that too) 679 break; 680 case CallingConvention::DW_CC_LLVM_Swift: 681 // SwiftAsync missing 682 OS << " __attribute__((swiftcall))"; 683 break; 684 case CallingConvention::DW_CC_LLVM_PreserveMost: 685 OS << " __attribute__((preserve_most))"; 686 break; 687 case CallingConvention::DW_CC_LLVM_PreserveAll: 688 OS << " __attribute__((preserve_all))"; 689 break; 690 case CallingConvention::DW_CC_LLVM_X86RegCall: 691 OS << " __attribute__((regcall))"; 692 break; 693 } 694 } 695 696 if (Const) 697 OS << " const"; 698 if (Volatile) 699 OS << " volatile"; 700 if (D.find(DW_AT_reference)) 701 OS << " &"; 702 if (D.find(DW_AT_rvalue_reference)) 703 OS << " &&"; 704 705 appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner)); 706 } 707 void appendScopes(DWARFDie D) { 708 if (D.getTag() == DW_TAG_compile_unit) 709 return; 710 if (D.getTag() == DW_TAG_type_unit) 711 return; 712 if (D.getTag() == DW_TAG_skeleton_unit) 713 return; 714 if (D.getTag() == DW_TAG_subprogram) 715 return; 716 if (D.getTag() == DW_TAG_lexical_block) 717 return; 718 D = D.resolveTypeUnitReference(); 719 if (DWARFDie P = D.getParent()) 720 appendScopes(P); 721 appendUnqualifiedName(D); 722 OS << "::"; 723 } 724 }; 725 } // anonymous namespace 726 727 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, 728 const DWARFAttribute &AttrValue, unsigned Indent, 729 DIDumpOptions DumpOpts) { 730 if (!Die.isValid()) 731 return; 732 const char BaseIndent[] = " "; 733 OS << BaseIndent; 734 OS.indent(Indent + 2); 735 dwarf::Attribute Attr = AttrValue.Attr; 736 WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr); 737 738 dwarf::Form Form = AttrValue.Value.getForm(); 739 if (DumpOpts.Verbose || DumpOpts.ShowForm) 740 OS << formatv(" [{0}]", Form); 741 742 DWARFUnit *U = Die.getDwarfUnit(); 743 const DWARFFormValue &FormValue = AttrValue.Value; 744 745 OS << "\t("; 746 747 StringRef Name; 748 std::string File; 749 auto Color = HighlightColor::Enumerator; 750 if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) { 751 Color = HighlightColor::String; 752 if (const auto *LT = U->getContext().getLineTableForUnit(U)) 753 if (LT->getFileNameByIndex( 754 FormValue.getAsUnsignedConstant().getValue(), 755 U->getCompilationDir(), 756 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { 757 File = '"' + File + '"'; 758 Name = File; 759 } 760 } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) 761 Name = AttributeValueString(Attr, *Val); 762 763 if (!Name.empty()) 764 WithColor(OS, Color) << Name; 765 else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) 766 OS << *FormValue.getAsUnsignedConstant(); 767 else if (Attr == DW_AT_low_pc && 768 (FormValue.getAsAddress() == 769 dwarf::computeTombstoneAddress(U->getAddressByteSize()))) { 770 if (DumpOpts.Verbose) { 771 FormValue.dump(OS, DumpOpts); 772 OS << " ("; 773 } 774 OS << "dead code"; 775 if (DumpOpts.Verbose) 776 OS << ')'; 777 } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && 778 FormValue.getAsUnsignedConstant()) { 779 if (DumpOpts.ShowAddresses) { 780 // Print the actual address rather than the offset. 781 uint64_t LowPC, HighPC, Index; 782 if (Die.getLowAndHighPC(LowPC, HighPC, Index)) 783 DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC); 784 else 785 FormValue.dump(OS, DumpOpts); 786 } 787 } else if (DWARFAttribute::mayHaveLocationList(Attr) && 788 FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) 789 dumpLocationList(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, 790 DumpOpts); 791 else if (FormValue.isFormClass(DWARFFormValue::FC_Exprloc) || 792 (DWARFAttribute::mayHaveLocationExpr(Attr) && 793 FormValue.isFormClass(DWARFFormValue::FC_Block))) 794 dumpLocationExpr(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, 795 DumpOpts); 796 else 797 FormValue.dump(OS, DumpOpts); 798 799 std::string Space = DumpOpts.ShowAddresses ? " " : ""; 800 801 // We have dumped the attribute raw value. For some attributes 802 // having both the raw value and the pretty-printed value is 803 // interesting. These attributes are handled below. 804 if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) { 805 if (const char *Name = 806 Die.getAttributeValueAsReferencedDie(FormValue).getName( 807 DINameKind::LinkageName)) 808 OS << Space << "\"" << Name << '\"'; 809 } else if (Attr == DW_AT_type) { 810 DWARFDie D = resolveReferencedType(Die, FormValue); 811 if (D && !D.isNULL()) { 812 OS << Space << "\""; 813 dumpTypeQualifiedName(D, OS); 814 OS << '"'; 815 } 816 } else if (Attr == DW_AT_APPLE_property_attribute) { 817 if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant()) 818 dumpApplePropertyAttribute(OS, *OptVal); 819 } else if (Attr == DW_AT_ranges) { 820 const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj(); 821 // For DW_FORM_rnglistx we need to dump the offset separately, since 822 // we have only dumped the index so far. 823 if (FormValue.getForm() == DW_FORM_rnglistx) 824 if (auto RangeListOffset = 825 U->getRnglistOffset(*FormValue.getAsSectionOffset())) { 826 DWARFFormValue FV = DWARFFormValue::createFromUValue( 827 dwarf::DW_FORM_sec_offset, *RangeListOffset); 828 FV.dump(OS, DumpOpts); 829 } 830 if (auto RangesOrError = Die.getAddressRanges()) 831 dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(), 832 sizeof(BaseIndent) + Indent + 4, DumpOpts); 833 else 834 DumpOpts.RecoverableErrorHandler(createStringError( 835 errc::invalid_argument, "decoding address ranges: %s", 836 toString(RangesOrError.takeError()).c_str())); 837 } 838 839 OS << ")\n"; 840 } 841 842 void DWARFDie::getFullName(raw_string_ostream &OS, 843 std::string *OriginalFullName) const { 844 const char *NamePtr = getShortName(); 845 if (!NamePtr) 846 return; 847 if (getTag() == DW_TAG_GNU_template_parameter_pack) 848 return; 849 dumpTypeUnqualifiedName(*this, OS, OriginalFullName); 850 } 851 852 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; } 853 854 bool DWARFDie::isSubroutineDIE() const { 855 auto Tag = getTag(); 856 return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine; 857 } 858 859 Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const { 860 if (!isValid()) 861 return None; 862 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 863 if (AbbrevDecl) 864 return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U); 865 return None; 866 } 867 868 Optional<DWARFFormValue> 869 DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const { 870 if (!isValid()) 871 return None; 872 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 873 if (AbbrevDecl) { 874 for (auto Attr : Attrs) { 875 if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U)) 876 return Value; 877 } 878 } 879 return None; 880 } 881 882 Optional<DWARFFormValue> 883 DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { 884 SmallVector<DWARFDie, 3> Worklist; 885 Worklist.push_back(*this); 886 887 // Keep track if DIEs already seen to prevent infinite recursion. 888 // Empirically we rarely see a depth of more than 3 when dealing with valid 889 // DWARF. This corresponds to following the DW_AT_abstract_origin and 890 // DW_AT_specification just once. 891 SmallSet<DWARFDie, 3> Seen; 892 Seen.insert(*this); 893 894 while (!Worklist.empty()) { 895 DWARFDie Die = Worklist.pop_back_val(); 896 897 if (!Die.isValid()) 898 continue; 899 900 if (auto Value = Die.find(Attrs)) 901 return Value; 902 903 if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 904 if (Seen.insert(D).second) 905 Worklist.push_back(D); 906 907 if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification)) 908 if (Seen.insert(D).second) 909 Worklist.push_back(D); 910 } 911 912 return None; 913 } 914 915 DWARFDie 916 DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { 917 if (Optional<DWARFFormValue> F = find(Attr)) 918 return getAttributeValueAsReferencedDie(*F); 919 return DWARFDie(); 920 } 921 922 DWARFDie 923 DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const { 924 DWARFDie Result; 925 if (auto SpecRef = V.getAsRelativeReference()) { 926 if (SpecRef->Unit) 927 Result = SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + 928 SpecRef->Offset); 929 else if (auto SpecUnit = 930 U->getUnitVector().getUnitForOffset(SpecRef->Offset)) 931 Result = SpecUnit->getDIEForOffset(SpecRef->Offset); 932 } 933 return Result; 934 } 935 936 DWARFDie DWARFDie::resolveTypeUnitReference() const { 937 if (auto Attr = find(DW_AT_signature)) { 938 if (Optional<uint64_t> Sig = Attr->getAsReferenceUVal()) { 939 if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash( 940 U->getVersion(), *Sig, U->isDWOUnit())) 941 return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset()); 942 } 943 } 944 return *this; 945 } 946 947 Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const { 948 return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base})); 949 } 950 951 Optional<uint64_t> DWARFDie::getLocBaseAttribute() const { 952 return toSectionOffset(find(DW_AT_loclists_base)); 953 } 954 955 Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { 956 uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize()); 957 if (LowPC == Tombstone) 958 return None; 959 if (auto FormValue = find(DW_AT_high_pc)) { 960 if (auto Address = FormValue->getAsAddress()) { 961 // High PC is an address. 962 return Address; 963 } 964 if (auto Offset = FormValue->getAsUnsignedConstant()) { 965 // High PC is an offset from LowPC. 966 return LowPC + *Offset; 967 } 968 } 969 return None; 970 } 971 972 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, 973 uint64_t &SectionIndex) const { 974 auto F = find(DW_AT_low_pc); 975 auto LowPcAddr = toSectionedAddress(F); 976 if (!LowPcAddr) 977 return false; 978 if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) { 979 LowPC = LowPcAddr->Address; 980 HighPC = *HighPcAddr; 981 SectionIndex = LowPcAddr->SectionIndex; 982 return true; 983 } 984 return false; 985 } 986 987 Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const { 988 if (isNULL()) 989 return DWARFAddressRangesVector(); 990 // Single range specified by low/high PC. 991 uint64_t LowPC, HighPC, Index; 992 if (getLowAndHighPC(LowPC, HighPC, Index)) 993 return DWARFAddressRangesVector{{LowPC, HighPC, Index}}; 994 995 Optional<DWARFFormValue> Value = find(DW_AT_ranges); 996 if (Value) { 997 if (Value->getForm() == DW_FORM_rnglistx) 998 return U->findRnglistFromIndex(*Value->getAsSectionOffset()); 999 return U->findRnglistFromOffset(*Value->getAsSectionOffset()); 1000 } 1001 return DWARFAddressRangesVector(); 1002 } 1003 1004 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { 1005 auto RangesOrError = getAddressRanges(); 1006 if (!RangesOrError) { 1007 llvm::consumeError(RangesOrError.takeError()); 1008 return false; 1009 } 1010 1011 for (const auto &R : RangesOrError.get()) 1012 if (R.LowPC <= Address && Address < R.HighPC) 1013 return true; 1014 return false; 1015 } 1016 1017 Expected<DWARFLocationExpressionsVector> 1018 DWARFDie::getLocations(dwarf::Attribute Attr) const { 1019 Optional<DWARFFormValue> Location = find(Attr); 1020 if (!Location) 1021 return createStringError(inconvertibleErrorCode(), "No %s", 1022 dwarf::AttributeString(Attr).data()); 1023 1024 if (Optional<uint64_t> Off = Location->getAsSectionOffset()) { 1025 uint64_t Offset = *Off; 1026 1027 if (Location->getForm() == DW_FORM_loclistx) { 1028 if (auto LoclistOffset = U->getLoclistOffset(Offset)) 1029 Offset = *LoclistOffset; 1030 else 1031 return createStringError(inconvertibleErrorCode(), 1032 "Loclist table not found"); 1033 } 1034 return U->findLoclistFromOffset(Offset); 1035 } 1036 1037 if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { 1038 return DWARFLocationExpressionsVector{ 1039 DWARFLocationExpression{None, to_vector<4>(*Expr)}}; 1040 } 1041 1042 return createStringError( 1043 inconvertibleErrorCode(), "Unsupported %s encoding: %s", 1044 dwarf::AttributeString(Attr).data(), 1045 dwarf::FormEncodingString(Location->getForm()).data()); 1046 } 1047 1048 const char *DWARFDie::getSubroutineName(DINameKind Kind) const { 1049 if (!isSubroutineDIE()) 1050 return nullptr; 1051 return getName(Kind); 1052 } 1053 1054 const char *DWARFDie::getName(DINameKind Kind) const { 1055 if (!isValid() || Kind == DINameKind::None) 1056 return nullptr; 1057 // Try to get mangled name only if it was asked for. 1058 if (Kind == DINameKind::LinkageName) { 1059 if (auto Name = getLinkageName()) 1060 return Name; 1061 } 1062 return getShortName(); 1063 } 1064 1065 const char *DWARFDie::getShortName() const { 1066 if (!isValid()) 1067 return nullptr; 1068 1069 return dwarf::toString(findRecursively(dwarf::DW_AT_name), nullptr); 1070 } 1071 1072 const char *DWARFDie::getLinkageName() const { 1073 if (!isValid()) 1074 return nullptr; 1075 1076 return dwarf::toString(findRecursively({dwarf::DW_AT_MIPS_linkage_name, 1077 dwarf::DW_AT_linkage_name}), 1078 nullptr); 1079 } 1080 1081 uint64_t DWARFDie::getDeclLine() const { 1082 return toUnsigned(findRecursively(DW_AT_decl_line), 0); 1083 } 1084 1085 std::string 1086 DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const { 1087 if (auto FormValue = findRecursively(DW_AT_decl_file)) 1088 if (auto OptString = FormValue->getAsFile(Kind)) 1089 return *OptString; 1090 return {}; 1091 } 1092 1093 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, 1094 uint32_t &CallColumn, 1095 uint32_t &CallDiscriminator) const { 1096 CallFile = toUnsigned(find(DW_AT_call_file), 0); 1097 CallLine = toUnsigned(find(DW_AT_call_line), 0); 1098 CallColumn = toUnsigned(find(DW_AT_call_column), 0); 1099 CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0); 1100 } 1101 1102 Optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) { 1103 if (auto SizeAttr = find(DW_AT_byte_size)) 1104 if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant()) 1105 return Size; 1106 1107 switch (getTag()) { 1108 case DW_TAG_pointer_type: 1109 case DW_TAG_reference_type: 1110 case DW_TAG_rvalue_reference_type: 1111 return PointerSize; 1112 case DW_TAG_ptr_to_member_type: { 1113 if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type)) 1114 if (BaseType.getTag() == DW_TAG_subroutine_type) 1115 return 2 * PointerSize; 1116 return PointerSize; 1117 } 1118 case DW_TAG_const_type: 1119 case DW_TAG_immutable_type: 1120 case DW_TAG_volatile_type: 1121 case DW_TAG_restrict_type: 1122 case DW_TAG_typedef: { 1123 if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type)) 1124 return BaseType.getTypeSize(PointerSize); 1125 break; 1126 } 1127 case DW_TAG_array_type: { 1128 DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type); 1129 if (!BaseType) 1130 return None; 1131 Optional<uint64_t> BaseSize = BaseType.getTypeSize(PointerSize); 1132 if (!BaseSize) 1133 return None; 1134 uint64_t Size = *BaseSize; 1135 for (DWARFDie Child : *this) { 1136 if (Child.getTag() != DW_TAG_subrange_type) 1137 continue; 1138 1139 if (auto ElemCountAttr = Child.find(DW_AT_count)) 1140 if (Optional<uint64_t> ElemCount = 1141 ElemCountAttr->getAsUnsignedConstant()) 1142 Size *= *ElemCount; 1143 if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound)) 1144 if (Optional<int64_t> UpperBound = 1145 UpperBoundAttr->getAsSignedConstant()) { 1146 int64_t LowerBound = 0; 1147 if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound)) 1148 LowerBound = LowerBoundAttr->getAsSignedConstant().getValueOr(0); 1149 Size *= *UpperBound - LowerBound + 1; 1150 } 1151 } 1152 return Size; 1153 } 1154 default: 1155 if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type)) 1156 return BaseType.getTypeSize(PointerSize); 1157 break; 1158 } 1159 return None; 1160 } 1161 1162 /// Helper to dump a DIE with all of its parents, but no siblings. 1163 static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, 1164 DIDumpOptions DumpOpts, unsigned Depth = 0) { 1165 if (!Die) 1166 return Indent; 1167 if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth) 1168 return Indent; 1169 Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1); 1170 Die.dump(OS, Indent, DumpOpts); 1171 return Indent + 2; 1172 } 1173 1174 void DWARFDie::dump(raw_ostream &OS, unsigned Indent, 1175 DIDumpOptions DumpOpts) const { 1176 if (!isValid()) 1177 return; 1178 DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor(); 1179 const uint64_t Offset = getOffset(); 1180 uint64_t offset = Offset; 1181 if (DumpOpts.ShowParents) { 1182 DIDumpOptions ParentDumpOpts = DumpOpts; 1183 ParentDumpOpts.ShowParents = false; 1184 ParentDumpOpts.ShowChildren = false; 1185 Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts); 1186 } 1187 1188 if (debug_info_data.isValidOffset(offset)) { 1189 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 1190 if (DumpOpts.ShowAddresses) 1191 WithColor(OS, HighlightColor::Address).get() 1192 << format("\n0x%8.8" PRIx64 ": ", Offset); 1193 1194 if (abbrCode) { 1195 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 1196 if (AbbrevDecl) { 1197 WithColor(OS, HighlightColor::Tag).get().indent(Indent) 1198 << formatv("{0}", getTag()); 1199 if (DumpOpts.Verbose) { 1200 OS << format(" [%u] %c", abbrCode, 1201 AbbrevDecl->hasChildren() ? '*' : ' '); 1202 if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) 1203 OS << format(" (0x%8.8" PRIx64 ")", 1204 U->getDIEAtIndex(*ParentIdx).getOffset()); 1205 } 1206 OS << '\n'; 1207 1208 // Dump all data in the DIE for the attributes. 1209 for (const DWARFAttribute &AttrValue : attributes()) 1210 dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts); 1211 1212 if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0) { 1213 DWARFDie Child = getFirstChild(); 1214 DumpOpts.ChildRecurseDepth--; 1215 DIDumpOptions ChildDumpOpts = DumpOpts; 1216 ChildDumpOpts.ShowParents = false; 1217 while (Child) { 1218 Child.dump(OS, Indent + 2, ChildDumpOpts); 1219 Child = Child.getSibling(); 1220 } 1221 } 1222 } else { 1223 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 1224 << abbrCode << '\n'; 1225 } 1226 } else { 1227 OS.indent(Indent) << "NULL\n"; 1228 } 1229 } 1230 } 1231 1232 LLVM_DUMP_METHOD void DWARFDie::dump() const { dump(llvm::errs(), 0); } 1233 1234 DWARFDie DWARFDie::getParent() const { 1235 if (isValid()) 1236 return U->getParent(Die); 1237 return DWARFDie(); 1238 } 1239 1240 DWARFDie DWARFDie::getSibling() const { 1241 if (isValid()) 1242 return U->getSibling(Die); 1243 return DWARFDie(); 1244 } 1245 1246 DWARFDie DWARFDie::getPreviousSibling() const { 1247 if (isValid()) 1248 return U->getPreviousSibling(Die); 1249 return DWARFDie(); 1250 } 1251 1252 DWARFDie DWARFDie::getFirstChild() const { 1253 if (isValid()) 1254 return U->getFirstChild(Die); 1255 return DWARFDie(); 1256 } 1257 1258 DWARFDie DWARFDie::getLastChild() const { 1259 if (isValid()) 1260 return U->getLastChild(Die); 1261 return DWARFDie(); 1262 } 1263 1264 iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const { 1265 return make_range(attribute_iterator(*this, false), 1266 attribute_iterator(*this, true)); 1267 } 1268 1269 DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End) 1270 : Die(D), Index(0) { 1271 auto AbbrDecl = Die.getAbbreviationDeclarationPtr(); 1272 assert(AbbrDecl && "Must have abbreviation declaration"); 1273 if (End) { 1274 // This is the end iterator so we set the index to the attribute count. 1275 Index = AbbrDecl->getNumAttributes(); 1276 } else { 1277 // This is the begin iterator so we extract the value for this->Index. 1278 AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize(); 1279 updateForIndex(*AbbrDecl, 0); 1280 } 1281 } 1282 1283 void DWARFDie::attribute_iterator::updateForIndex( 1284 const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) { 1285 Index = I; 1286 // AbbrDecl must be valid before calling this function. 1287 auto NumAttrs = AbbrDecl.getNumAttributes(); 1288 if (Index < NumAttrs) { 1289 AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); 1290 // Add the previous byte size of any previous attribute value. 1291 AttrValue.Offset += AttrValue.ByteSize; 1292 uint64_t ParseOffset = AttrValue.Offset; 1293 if (AbbrDecl.getAttrIsImplicitConstByIndex(Index)) 1294 AttrValue.Value = DWARFFormValue::createFromSValue( 1295 AbbrDecl.getFormByIndex(Index), 1296 AbbrDecl.getAttrImplicitConstValueByIndex(Index)); 1297 else { 1298 auto U = Die.getDwarfUnit(); 1299 assert(U && "Die must have valid DWARF unit"); 1300 AttrValue.Value = DWARFFormValue::createFromUnit( 1301 AbbrDecl.getFormByIndex(Index), U, &ParseOffset); 1302 } 1303 AttrValue.ByteSize = ParseOffset - AttrValue.Offset; 1304 } else { 1305 assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); 1306 AttrValue = {}; 1307 } 1308 } 1309 1310 DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() { 1311 if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr()) 1312 updateForIndex(*AbbrDecl, Index + 1); 1313 return *this; 1314 } 1315 1316 bool DWARFAttribute::mayHaveLocationList(dwarf::Attribute Attr) { 1317 switch(Attr) { 1318 case DW_AT_location: 1319 case DW_AT_string_length: 1320 case DW_AT_return_addr: 1321 case DW_AT_data_member_location: 1322 case DW_AT_frame_base: 1323 case DW_AT_static_link: 1324 case DW_AT_segment: 1325 case DW_AT_use_location: 1326 case DW_AT_vtable_elem_location: 1327 return true; 1328 default: 1329 return false; 1330 } 1331 } 1332 1333 bool DWARFAttribute::mayHaveLocationExpr(dwarf::Attribute Attr) { 1334 switch (Attr) { 1335 // From the DWARF v5 specification. 1336 case DW_AT_location: 1337 case DW_AT_byte_size: 1338 case DW_AT_bit_offset: 1339 case DW_AT_bit_size: 1340 case DW_AT_string_length: 1341 case DW_AT_lower_bound: 1342 case DW_AT_return_addr: 1343 case DW_AT_bit_stride: 1344 case DW_AT_upper_bound: 1345 case DW_AT_count: 1346 case DW_AT_data_member_location: 1347 case DW_AT_frame_base: 1348 case DW_AT_segment: 1349 case DW_AT_static_link: 1350 case DW_AT_use_location: 1351 case DW_AT_vtable_elem_location: 1352 case DW_AT_allocated: 1353 case DW_AT_associated: 1354 case DW_AT_data_location: 1355 case DW_AT_byte_stride: 1356 case DW_AT_rank: 1357 case DW_AT_call_value: 1358 case DW_AT_call_origin: 1359 case DW_AT_call_target: 1360 case DW_AT_call_target_clobbered: 1361 case DW_AT_call_data_location: 1362 case DW_AT_call_data_value: 1363 // Extensions. 1364 case DW_AT_GNU_call_site_value: 1365 case DW_AT_GNU_call_site_target: 1366 return true; 1367 default: 1368 return false; 1369 } 1370 } 1371 1372 namespace llvm { 1373 1374 void dumpTypeQualifiedName(const DWARFDie &DIE, raw_ostream &OS) { 1375 DWARFTypePrinter(OS).appendQualifiedName(DIE); 1376 } 1377 1378 void dumpTypeUnqualifiedName(const DWARFDie &DIE, raw_ostream &OS, 1379 std::string *OriginalFullName) { 1380 DWARFTypePrinter(OS).appendUnqualifiedName(DIE, OriginalFullName); 1381 } 1382 1383 } // namespace llvm 1384