1bd5bc2161cb4520134d3e7eb6ac5f160b3653e78Eric Christopher//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// 272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// The LLVM Compiler Infrastructure 472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source 672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details. 772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// 872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===// 972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugInfoEntry.h" 1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFCompileUnit.h" 1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFContext.h" 1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFDebugAbbrev.h" 14cd61455798777446f35723fdb77f54a17e602009Alexey Samsonov#include "llvm/DebugInfo/DWARFFormValue.h" 15dd8e9f395e881972b320d947de88102a0be04b70Eric Christopher#include "llvm/Support/Debug.h" 1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h" 1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h" 1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h" 1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm; 2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf; 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; 2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 23cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, 2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer unsigned recurseDepth, 2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer unsigned indent) const { 26cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DataExtractor debug_info_data = u->getDebugInfoExtractor(); 2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer uint32_t offset = Offset; 2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer if (debug_info_data.isValidOffset(offset)) { 3080cc2598f89d09a6df2b84a5f8cea813b280b17bBenjamin Kramer uint32_t abbrCode = debug_info_data.getULEB128(&offset); 3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 320942255f6daf49354dd1e19cc5f07aca65bea0d1Benjamin Kramer OS << format("\n0x%8.8x: ", Offset); 3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer if (abbrCode) { 3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer if (AbbrevDecl) { 3575c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer const char *tagString = TagString(getTag()); 3675c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer if (tagString) 3775c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS.indent(indent) << tagString; 3875c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer else 3975c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); 4075c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS << format(" [%u] %c\n", abbrCode, 4175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer AbbrevDecl->hasChildren() ? '*' : ' '); 4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 43e5ef305be2505741941b8e7c7a391add3632ebc3Eric Christopher // Dump all data in the DIE for the attributes. 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &AttrSpec : AbbrevDecl->attributes()) { 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent); 4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer const DWARFDebugInfoEntryMinimal *child = getFirstChild(); 4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer if (recurseDepth > 0 && child) { 5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer while (child) { 51cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie child->dump(OS, u, recurseDepth-1, indent+2); 5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer child = child->getSibling(); 5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } else { 5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer OS << "Abbreviation code not found in 'debug_abbrev' class for code: " 5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer << abbrCode << '\n'; 5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } else { 600942255f6daf49354dd1e19cc5f07aca65bea0d1Benjamin Kramer OS.indent(indent) << "NULL\n"; 6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, 66cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFUnit *u, 67cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t *offset_ptr, 68cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint16_t attr, uint16_t form, 6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer unsigned indent) const { 70a9b697975592b204e86496efc62a8b26fbfa1a03David Blaikie OS << " "; 7175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS.indent(indent+2); 7275c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer const char *attrString = AttributeString(attr); 7375c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer if (attrString) 7475c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS << attrString; 7575c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer else 7675c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS << format("DW_AT_Unknown_%x", attr); 7775c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer const char *formString = FormEncodingString(form); 7875c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer if (formString) 7975c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS << " [" << formString << ']'; 8075c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer else 8175c63087b4e1528cc608b1586014fc1ebad2d9fbBenjamin Kramer OS << format(" [DW_FORM_Unknown_%x]", form); 8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer DWARFFormValue formValue(form); 8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 85cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u)) 8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer return; 8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer OS << "\t("; 89cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie formValue.dump(OS, u); 9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer OS << ")\n"; 9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 93cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U, 94d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov uint32_t *OffsetPtr) { 95d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov Offset = *OffsetPtr; 96cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 9739f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov uint32_t UEndOffset = U->getNextUnitOffset(); 9839f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) 9939f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov return false; 100d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr); 101d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov if (0 == AbbrCode) { 102d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov // NULL debug tag entry. 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AbbrevDecl = nullptr; 104d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov return true; 105d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov } 106cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode); 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (nullptr == AbbrevDecl) { 10839f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov // Restore the original offset. 10939f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov *OffsetPtr = Offset; 11039f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov return false; 11139f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov } 1126faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes( 1136faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov U->getAddressByteSize(), U->getVersion()); 1146faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov assert(FixedFormSizes.size() > 0); 115d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov 116d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov // Skip all data in the .debug_info for the attributes 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &AttrSpec : AbbrevDecl->attributes()) { 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint16_t Form = AttrSpec.Form; 119d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov 120d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov uint8_t FixedFormSize = 1216faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0; 122d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov if (FixedFormSize) 123d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov *OffsetPtr += FixedFormSize; 1246faff4886a3059a8cda08f015d29a6c9a0a4de3cAlexey Samsonov else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) { 125d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov // Restore the original offset. 126d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov *OffsetPtr = Offset; 127d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov return false; 128d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov } 12972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 130d6b89ef0fa17cf77677358a797934fa061564f5bAlexey Samsonov return true; 13172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 13272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1335eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const { 1345eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov return getTag() == DW_TAG_subprogram; 1355eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov} 1365eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov 1375eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonovbool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const { 1385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov uint32_t Tag = getTag(); 1395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov return Tag == DW_TAG_subprogram || 1405eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov Tag == DW_TAG_inlined_subroutine; 1415eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov} 1425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov 1432e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonovbool DWARFDebugInfoEntryMinimal::getAttributeValue( 1442e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const { 1452e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov if (!AbbrevDecl) 1462e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov return false; 14772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1482e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr); 1492e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov if (AttrIdx == -1U) 1502e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov return false; 15172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1522e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov DataExtractor DebugInfoData = U->getDebugInfoExtractor(); 1532e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov uint32_t DebugInfoOffset = getOffset(); 15472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1552e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov // Skip the abbreviation code so we are at the data for the attributes 1562e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov DebugInfoData.getULEB128(&DebugInfoOffset); 15772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1582e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov // Skip preceding attribute values. 1592e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov for (uint32_t i = 0; i < AttrIdx; ++i) { 1602e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i), 1612e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov DebugInfoData, &DebugInfoOffset, U); 16272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer } 16372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 1642e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx)); 1652e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U); 16672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 16772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 16863fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonovconst char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString( 169cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const { 17063fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov DWARFFormValue FormValue; 171c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (!getAttributeValue(U, Attr, FormValue)) 172c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return FailValue; 173c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov Optional<const char *> Result = FormValue.getAsCString(U); 174c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return Result.hasValue() ? Result.getValue() : FailValue; 17572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 17672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 17763fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( 178cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 17963fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov DWARFFormValue FormValue; 180c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (!getAttributeValue(U, Attr, FormValue)) 181c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return FailValue; 182c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov Optional<uint64_t> Result = FormValue.getAsAddress(U); 183c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return Result.hasValue() ? Result.getValue() : FailValue; 18463fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov} 18563fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov 186c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant( 187cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 18863fd2af3892a81026f40374d08b5124e72ccff4eAlexey Samsonov DWARFFormValue FormValue; 189c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (!getAttributeValue(U, Attr, FormValue)) 190c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return FailValue; 191c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov Optional<uint64_t> Result = FormValue.getAsUnsignedConstant(); 192c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return Result.hasValue() ? Result.getValue() : FailValue; 19372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 19472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer 195cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( 1962e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 1972e56d575b7ea507684935d5cd6d5aee96d72ceb4Alexey Samsonov DWARFFormValue FormValue; 198c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (!getAttributeValue(U, Attr, FormValue)) 199c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return FailValue; 200c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov Optional<uint64_t> Result = FormValue.getAsReference(U); 201c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return Result.hasValue() ? Result.getValue() : FailValue; 202c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov} 203c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov 204c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonovuint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset( 205c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { 206c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov DWARFFormValue FormValue; 207c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (!getAttributeValue(U, Attr, FormValue)) 208c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return FailValue; 209c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov Optional<uint64_t> Result = FormValue.getAsSectionOffset(); 210c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov return Result.hasValue() ? Result.getValue() : FailValue; 21172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer} 21210df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer 213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesuint64_t 214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesDWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U, 215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t FailValue) const { 216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Result = 217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL); 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Result != -1ULL) 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Result; 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue); 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 223cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U, 224203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher uint64_t &LowPC, 225203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher uint64_t &HighPC) const { 226cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL); 227d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov if (LowPC == -1ULL) 228d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov return false; 229d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); 230d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov if (HighPC == -1ULL) { 231d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case 232d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov // it represents function size. 233d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL); 234d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov if (HighPC != -1ULL) 235d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov HighPC += LowPC; 236d2d54e2b7c8a427cf1f4684bee335c4bedc5a99bAlexey Samsonov } 2375eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov return (HighPC != -1ULL); 2385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov} 2395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov 240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFAddressRangesVector 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const { 2425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov if (isNULL()) 243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DWARFAddressRangesVector(); 244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Single range specified by low/high PC. 2455eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov uint64_t LowPC, HighPC; 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (getLowAndHighPC(U, LowPC, HighPC)) { 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Multiple ranges from .debug_ranges section. 250c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov uint32_t RangesOffset = 251c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U); 2525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov if (RangesOffset != -1U) { 2535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov DWARFDebugRangeList RangeList; 254cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (U->extractRangeList(RangesOffset, RangeList)) 255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return RangeList.getAbsoluteRanges(U->getBaseAddress()); 256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DWARFAddressRangesVector(); 258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges( 261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const { 262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isNULL()) 263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isSubprogramDIE()) { 265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto &DIERanges = getAddressRanges(U); 266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end()); 267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const DWARFDebugInfoEntryMinimal *Child = getFirstChild(); 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (Child) { 271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Child->collectChildrenAddressRanges(U, Ranges); 272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Child = Child->getSibling(); 273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( 277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const DWARFUnit *U, const uint64_t Address) const { 278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto& R : getAddressRanges(U)) { 279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (R.first <= Address && Address < R.second) 280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 2813e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov } 2823e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov return false; 2833e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov} 2843e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov 285cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieconst char * 286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, 287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FunctionNameKind Kind) const { 288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!isSubroutineDIE() || Kind == FunctionNameKind::None) 289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Try to get mangled name only if it was asked for. 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Kind == FunctionNameKind::LinkageName) { 292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const char *name = 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return name; 295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const char *name = 296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getAttributeValueAsString(U, DW_AT_linkage_name, nullptr)) 297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return name; 298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr)) 3009d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov return name; 3019d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov // Try to get name from specification DIE. 3029d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov uint32_t spec_ref = 303cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie getAttributeValueAsReference(U, DW_AT_specification, -1U); 3049d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov if (spec_ref != -1U) { 3059d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov DWARFDebugInfoEntryMinimal spec_die; 30639f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov if (spec_die.extractFast(U, &spec_ref)) { 307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const char *name = spec_die.getSubroutineName(U, Kind)) 3089d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov return name; 3093e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov } 3103e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov } 3119d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov // Try to get name from abstract origin DIE. 3129d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov uint32_t abs_origin_ref = 313cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); 3149d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov if (abs_origin_ref != -1U) { 3159d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov DWARFDebugInfoEntryMinimal abs_origin_die; 31639f62fa3dd1f683288e67ba58bef785b2dcaa98cAlexey Samsonov if (abs_origin_die.extractFast(U, &abs_origin_ref)) { 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) 3189d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov return name; 3199d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov } 3209d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov } 321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 3223e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov} 3235eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov 324cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U, 325203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher uint32_t &CallFile, 326203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher uint32_t &CallLine, 327203e6f60a84096d7fbc0ded932a6636177580198Eric Christopher uint32_t &CallColumn) const { 328c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0); 329c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0); 330c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0); 3315eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov} 3325eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov 333e664290ad6d988e0ae40f2461084f6adbababa47Alexey SamsonovDWARFDebugInfoEntryInlinedChain 3345eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDWARFDebugInfoEntryMinimal::getInlinedChainForAddress( 335cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFUnit *U, const uint64_t Address) const { 336e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov DWARFDebugInfoEntryInlinedChain InlinedChain; 337cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie InlinedChain.U = U; 3385eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov if (isNULL()) 3395eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov return InlinedChain; 3405eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) { 3415eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov // Append current DIE to inlined chain only if it has correct tag 3425eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov // (e.g. it is not a lexical block). 3435eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov if (DIE->isSubroutineDIE()) { 344e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov InlinedChain.DIEs.push_back(*DIE); 3455eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov } 3465eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov // Try to get child which also contains provided address. 3475eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild(); 3485eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov while (Child) { 349cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (Child->addressRangeContainsAddress(U, Address)) { 3505eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov // Assume there is only one such child. 3515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov break; 3525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov } 3535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov Child = Child->getSibling(); 3545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov } 3555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov DIE = Child; 3565eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov } 3575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov // Reverse the obtained chain to make the root of inlined chain last. 358e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end()); 3595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov return InlinedChain; 3605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov} 361