1 //===- DWARFDie.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 "SyntaxHighlighting.h" 11 #include "llvm/ADT/None.h" 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 15 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 16 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 17 #include "llvm/DebugInfo/DWARF/DWARFDie.h" 18 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 19 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 20 #include "llvm/Support/DataExtractor.h" 21 #include "llvm/Support/Dwarf.h" 22 #include "llvm/Support/Format.h" 23 #include "llvm/Support/MathExtras.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include <algorithm> 26 #include <cassert> 27 #include <cinttypes> 28 #include <cstdint> 29 #include <string> 30 #include <utility> 31 32 using namespace llvm; 33 using namespace dwarf; 34 using namespace syntax; 35 36 static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) { 37 OS << " ("; 38 do { 39 uint64_t Shift = countTrailingZeros(Val); 40 assert(Shift < 64 && "undefined behavior"); 41 uint64_t Bit = 1ULL << Shift; 42 auto PropName = ApplePropertyString(Bit); 43 if (!PropName.empty()) 44 OS << PropName; 45 else 46 OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit); 47 if (!(Val ^= Bit)) 48 break; 49 OS << ", "; 50 } while (true); 51 OS << ")"; 52 } 53 54 static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges, 55 unsigned AddressSize, unsigned Indent) { 56 if (Ranges.empty()) 57 return; 58 59 for (const auto &Range: Ranges) { 60 OS << '\n'; 61 OS.indent(Indent); 62 OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")", 63 AddressSize*2, Range.first, 64 AddressSize*2, Range.second); 65 } 66 } 67 68 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, 69 uint32_t *OffsetPtr, dwarf::Attribute Attr, 70 dwarf::Form Form, unsigned Indent) { 71 if (!Die.isValid()) 72 return; 73 const char BaseIndent[] = " "; 74 OS << BaseIndent; 75 OS.indent(Indent+2); 76 auto attrString = AttributeString(Attr); 77 if (!attrString.empty()) 78 WithColor(OS, syntax::Attribute) << attrString; 79 else 80 WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr); 81 82 auto formString = FormEncodingString(Form); 83 if (!formString.empty()) 84 OS << " [" << formString << ']'; 85 else 86 OS << format(" [DW_FORM_Unknown_%x]", Form); 87 88 DWARFUnit *U = Die.getDwarfUnit(); 89 DWARFFormValue formValue(Form); 90 91 if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U)) 92 return; 93 94 OS << "\t("; 95 96 StringRef Name; 97 std::string File; 98 auto Color = syntax::Enumerator; 99 if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) { 100 Color = syntax::String; 101 if (const auto *LT = U->getContext().getLineTableForUnit(U)) 102 if (LT->getFileNameByIndex(formValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { 103 File = '"' + File + '"'; 104 Name = File; 105 } 106 } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant()) 107 Name = AttributeValueString(Attr, *Val); 108 109 if (!Name.empty()) 110 WithColor(OS, Color) << Name; 111 else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) 112 OS << *formValue.getAsUnsignedConstant(); 113 else 114 formValue.dump(OS); 115 116 // We have dumped the attribute raw value. For some attributes 117 // having both the raw value and the pretty-printed value is 118 // interesting. These attributes are handled below. 119 if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) { 120 if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(DINameKind::LinkageName)) 121 OS << " \"" << Name << '\"'; 122 } else if (Attr == DW_AT_APPLE_property_attribute) { 123 if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant()) 124 dumpApplePropertyAttribute(OS, *OptVal); 125 } else if (Attr == DW_AT_ranges) { 126 dumpRanges(OS, Die.getAddressRanges(), U->getAddressByteSize(), 127 sizeof(BaseIndent)+Indent+4); 128 } 129 130 OS << ")\n"; 131 } 132 133 bool DWARFDie::isSubprogramDIE() const { 134 return getTag() == DW_TAG_subprogram; 135 } 136 137 bool DWARFDie::isSubroutineDIE() const { 138 auto Tag = getTag(); 139 return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine; 140 } 141 142 Optional<DWARFFormValue> 143 DWARFDie::find(dwarf::Attribute Attr) const { 144 if (!isValid()) 145 return None; 146 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 147 if (AbbrevDecl) 148 return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U); 149 return None; 150 } 151 152 Optional<DWARFFormValue> 153 DWARFDie::findRecursively(dwarf::Attribute Attr) const { 154 if (!isValid()) 155 return None; 156 if (auto Value = find(Attr)) 157 return Value; 158 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 159 if (auto Value = Die.find(Attr)) 160 return Value; 161 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification)) 162 if (auto Value = Die.find(Attr)) 163 return Value; 164 return None; 165 } 166 167 Optional<DWARFFormValue> 168 DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const { 169 if (!isValid()) 170 return None; 171 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 172 if (AbbrevDecl) { 173 for (auto Attr : Attrs) { 174 if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U)) 175 return Value; 176 } 177 } 178 return None; 179 } 180 181 Optional<DWARFFormValue> 182 DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { 183 if (!isValid()) 184 return None; 185 if (auto Value = find(Attrs)) 186 return Value; 187 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) 188 if (auto Value = Die.find(Attrs)) 189 return Value; 190 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification)) 191 if (auto Value = Die.find(Attrs)) 192 return Value; 193 return None; 194 } 195 196 DWARFDie 197 DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { 198 auto SpecRef = toReference(find(Attr)); 199 if (SpecRef) { 200 auto SpecUnit = U->getUnitSection().getUnitForOffset(*SpecRef); 201 if (SpecUnit) 202 return SpecUnit->getDIEForOffset(*SpecRef); 203 } 204 return DWARFDie(); 205 } 206 207 Optional<uint64_t> 208 DWARFDie::getRangesBaseAttribute() const { 209 return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base})); 210 } 211 212 Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { 213 if (auto FormValue = find(DW_AT_high_pc)) { 214 if (auto Address = FormValue->getAsAddress()) { 215 // High PC is an address. 216 return Address; 217 } 218 if (auto Offset = FormValue->getAsUnsignedConstant()) { 219 // High PC is an offset from LowPC. 220 return LowPC + *Offset; 221 } 222 } 223 return None; 224 } 225 226 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const { 227 auto LowPcAddr = toAddress(find(DW_AT_low_pc)); 228 if (!LowPcAddr) 229 return false; 230 if (auto HighPcAddr = getHighPC(*LowPcAddr)) { 231 LowPC = *LowPcAddr; 232 HighPC = *HighPcAddr; 233 return true; 234 } 235 return false; 236 } 237 238 DWARFAddressRangesVector 239 DWARFDie::getAddressRanges() const { 240 if (isNULL()) 241 return DWARFAddressRangesVector(); 242 // Single range specified by low/high PC. 243 uint64_t LowPC, HighPC; 244 if (getLowAndHighPC(LowPC, HighPC)) { 245 return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); 246 } 247 // Multiple ranges from .debug_ranges section. 248 auto RangesOffset = toSectionOffset(find(DW_AT_ranges)); 249 if (RangesOffset) { 250 DWARFDebugRangeList RangeList; 251 if (U->extractRangeList(*RangesOffset, RangeList)) 252 return RangeList.getAbsoluteRanges(U->getBaseAddress()); 253 } 254 return DWARFAddressRangesVector(); 255 } 256 257 void 258 DWARFDie::collectChildrenAddressRanges(DWARFAddressRangesVector& Ranges) const { 259 if (isNULL()) 260 return; 261 if (isSubprogramDIE()) { 262 const auto &DIERanges = getAddressRanges(); 263 Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end()); 264 } 265 266 for (auto Child: children()) 267 Child.collectChildrenAddressRanges(Ranges); 268 } 269 270 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { 271 for (const auto& R : getAddressRanges()) { 272 if (R.first <= Address && Address < R.second) 273 return true; 274 } 275 return false; 276 } 277 278 const char * 279 DWARFDie::getSubroutineName(DINameKind Kind) const { 280 if (!isSubroutineDIE()) 281 return nullptr; 282 return getName(Kind); 283 } 284 285 const char * 286 DWARFDie::getName(DINameKind Kind) const { 287 if (!isValid() || Kind == DINameKind::None) 288 return nullptr; 289 // Try to get mangled name only if it was asked for. 290 if (Kind == DINameKind::LinkageName) { 291 if (auto Name = dwarf::toString(findRecursively({DW_AT_MIPS_linkage_name, 292 DW_AT_linkage_name}), nullptr)) 293 return Name; 294 } 295 if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr)) 296 return Name; 297 return nullptr; 298 } 299 300 uint64_t DWARFDie::getDeclLine() const { 301 return toUnsigned(findRecursively(DW_AT_decl_line), 0); 302 } 303 304 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, 305 uint32_t &CallColumn) const { 306 CallFile = toUnsigned(find(DW_AT_call_file), 0); 307 CallLine = toUnsigned(find(DW_AT_call_line), 0); 308 CallColumn = toUnsigned(find(DW_AT_call_column), 0); 309 } 310 311 void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth, 312 unsigned Indent) const { 313 if (!isValid()) 314 return; 315 DataExtractor debug_info_data = U->getDebugInfoExtractor(); 316 const uint32_t Offset = getOffset(); 317 uint32_t offset = Offset; 318 319 if (debug_info_data.isValidOffset(offset)) { 320 uint32_t abbrCode = debug_info_data.getULEB128(&offset); 321 WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset); 322 323 if (abbrCode) { 324 auto AbbrevDecl = getAbbreviationDeclarationPtr(); 325 if (AbbrevDecl) { 326 auto tagString = TagString(getTag()); 327 if (!tagString.empty()) 328 WithColor(OS, syntax::Tag).get().indent(Indent) << tagString; 329 else 330 WithColor(OS, syntax::Tag).get().indent(Indent) 331 << format("DW_TAG_Unknown_%x", getTag()); 332 333 OS << format(" [%u] %c\n", abbrCode, 334 AbbrevDecl->hasChildren() ? '*' : ' '); 335 336 // Dump all data in the DIE for the attributes. 337 for (const auto &AttrSpec : AbbrevDecl->attributes()) { 338 if (AttrSpec.Form == DW_FORM_implicit_const) { 339 // We are dumping .debug_info section , 340 // implicit_const attribute values are not really stored here, 341 // but in .debug_abbrev section. So we just skip such attrs. 342 continue; 343 } 344 dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form, 345 Indent); 346 } 347 348 DWARFDie child = getFirstChild(); 349 if (RecurseDepth > 0 && child) { 350 while (child) { 351 child.dump(OS, RecurseDepth-1, Indent+2); 352 child = child.getSibling(); 353 } 354 } 355 } else { 356 OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 357 << abbrCode << '\n'; 358 } 359 } else { 360 OS.indent(Indent) << "NULL\n"; 361 } 362 } 363 } 364 365 void DWARFDie::getInlinedChainForAddress( 366 const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const { 367 if (isNULL()) 368 return; 369 DWARFDie DIE(*this); 370 while (DIE) { 371 // Append current DIE to inlined chain only if it has correct tag 372 // (e.g. it is not a lexical block). 373 if (DIE.isSubroutineDIE()) 374 InlinedChain.push_back(DIE); 375 376 // Try to get child which also contains provided address. 377 DWARFDie Child = DIE.getFirstChild(); 378 while (Child) { 379 if (Child.addressRangeContainsAddress(Address)) { 380 // Assume there is only one such child. 381 break; 382 } 383 Child = Child.getSibling(); 384 } 385 DIE = Child; 386 } 387 // Reverse the obtained chain to make the root of inlined chain last. 388 std::reverse(InlinedChain.begin(), InlinedChain.end()); 389 } 390 391 DWARFDie DWARFDie::getParent() const { 392 if (isValid()) 393 return U->getParent(Die); 394 return DWARFDie(); 395 } 396 397 DWARFDie DWARFDie::getSibling() const { 398 if (isValid()) 399 return U->getSibling(Die); 400 return DWARFDie(); 401 } 402 403 iterator_range<DWARFDie::attribute_iterator> 404 DWARFDie::attributes() const { 405 return make_range(attribute_iterator(*this, false), 406 attribute_iterator(*this, true)); 407 } 408 409 DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End) : 410 Die(D), AttrValue(0), Index(0) { 411 auto AbbrDecl = Die.getAbbreviationDeclarationPtr(); 412 assert(AbbrDecl && "Must have abbreviation declaration"); 413 if (End) { 414 // This is the end iterator so we set the index to the attribute count. 415 Index = AbbrDecl->getNumAttributes(); 416 } else { 417 // This is the begin iterator so we extract the value for this->Index. 418 AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize(); 419 updateForIndex(*AbbrDecl, 0); 420 } 421 } 422 423 void DWARFDie::attribute_iterator::updateForIndex( 424 const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) { 425 Index = I; 426 // AbbrDecl must be valid befor calling this function. 427 auto NumAttrs = AbbrDecl.getNumAttributes(); 428 if (Index < NumAttrs) { 429 AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); 430 // Add the previous byte size of any previous attribute value. 431 AttrValue.Offset += AttrValue.ByteSize; 432 AttrValue.Value.setForm(AbbrDecl.getFormByIndex(Index)); 433 uint32_t ParseOffset = AttrValue.Offset; 434 auto U = Die.getDwarfUnit(); 435 assert(U && "Die must have valid DWARF unit"); 436 bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(), 437 &ParseOffset, U); 438 (void)b; 439 assert(b && "extractValue cannot fail on fully parsed DWARF"); 440 AttrValue.ByteSize = ParseOffset - AttrValue.Offset; 441 } else { 442 assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); 443 AttrValue.clear(); 444 } 445 } 446 447 DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() { 448 if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr()) 449 updateForIndex(*AbbrDecl, Index + 1); 450 return *this; 451 } 452