1cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===-- DWARFUnit.cpp -----------------------------------------------------===// 2cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// 3cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// The LLVM Compiler Infrastructure 4cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// 5cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// This file is distributed under the University of Illinois Open Source 6cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// License. See LICENSE.TXT for details. 7cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie// 8cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie//===----------------------------------------------------------------------===// 9cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 10cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFUnit.h" 11cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "DWARFContext.h" 12cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "llvm/DebugInfo/DWARFFormValue.h" 13cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "llvm/Support/Dwarf.h" 14cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie#include "llvm/Support/Path.h" 15262f548b09b9208a067814c612859410f82d2273David Blaikie#include <cstdio> 16cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 17cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieusing namespace llvm; 18cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieusing namespace dwarf; 19cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFUnit::DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS, 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef SS, StringRef SOS, StringRef AOS, 22cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const RelocAddrMap *M, bool LE) 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : Abbrev(DA), InfoSection(IS), RangeSection(RS), StringSection(SS), 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringOffsetSection(SOS), AddrOffsetSection(AOS), RelocMap(M), 25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines isLittleEndian(LE) { 26cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie clear(); 27cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 28cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 29cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFUnit::~DWARFUnit() { 30cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 31cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 32cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, 33cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint64_t &Result) const { 34cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize; 35cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (AddrOffsetSection.size() < Offset + AddrSize) 36cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 37cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize); 38cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Result = DA.getAddress(&Offset); 39cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return true; 40cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 41cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 42cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::getStringOffsetSectionItem(uint32_t Index, 43cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t &Result) const { 44cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // FIXME: string offset section entries are 8-byte for DWARF64. 45cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const uint32_t ItemSize = 4; 46cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t Offset = Index * ItemSize; 47cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (StringOffsetSection.size() < Offset + ItemSize) 48cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 49cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DataExtractor DA(StringOffsetSection, isLittleEndian, 0); 50cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Result = DA.getU32(&Offset); 51cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return true; 52cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 53cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 54cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { 55cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Length = debug_info.getU32(offset_ptr); 56cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Version = debug_info.getU16(offset_ptr); 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t AbbrOffset = debug_info.getU32(offset_ptr); 58cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie AddrSize = debug_info.getU8(offset_ptr); 59cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1); 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool VersionOK = DWARFContext::isSupportedVersion(Version); 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool AddrSizeOK = AddrSize == 4 || AddrSize == 8; 63cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!LengthOK || !VersionOK || !AddrSizeOK) 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Abbrevs == nullptr) 69cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 70cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 71cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return true; 72cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 73cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 74cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) { 75cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie clear(); 76cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 77cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Offset = *offset_ptr; 78cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 79cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (debug_info.isValidOffset(*offset_ptr)) { 80cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (extractImpl(debug_info, offset_ptr)) 81cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return true; 82cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 83cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // reset the offset to where we tried to parse from if anything went wrong 84cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie *offset_ptr = Offset; 85cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 86cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 87cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 88cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 89cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 90cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::extractRangeList(uint32_t RangeListOffset, 91cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWARFDebugRangeList &RangeList) const { 92cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Require that compile unit is extracted. 93cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie assert(DieArray.size() > 0); 94cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize); 95cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; 96cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return RangeList.extract(RangesData, &ActualRangeListOffset); 97cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 98cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 99cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFUnit::clear() { 100cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Offset = 0; 101cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Length = 0; 102cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Version = 0; 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Abbrevs = nullptr; 104cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie AddrSize = 0; 105cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie BaseAddr = 0; 106cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie RangeSectionBase = 0; 107cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie AddrOffsetSectionBase = 0; 108cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie clearDIEs(false); 109cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWO.reset(); 110cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 111cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 112cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieconst char *DWARFUnit::getCompilationDir() { 113cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie extractDIEsIfNeeded(true); 114cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DieArray.empty()) 115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr); 117cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 118cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 119cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieuint64_t DWARFUnit::getDWOId() { 120cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie extractDIEsIfNeeded(true); 121cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const uint64_t FailValue = -1ULL; 122cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DieArray.empty()) 123cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return FailValue; 124cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return DieArray[0] 125c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov .getAttributeValueAsUnsignedConstant(this, DW_AT_GNU_dwo_id, FailValue); 126cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 127cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 128cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFUnit::setDIERelations() { 129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DieArray.size() <= 1) 130cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return; 131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::vector<DWARFDebugInfoEntryMinimal *> ParentChain; 133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWARFDebugInfoEntryMinimal *SiblingChain = nullptr; 134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &DIE : DieArray) { 135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (SiblingChain) { 136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SiblingChain->setSibling(&DIE); 137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const DWARFAbbreviationDeclaration *AbbrDecl = 139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DIE.getAbbreviationDeclarationPtr()) { 140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Normal DIE. 141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (AbbrDecl->hasChildren()) { 142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ParentChain.push_back(&DIE); 143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SiblingChain = nullptr; 144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SiblingChain = &DIE; 146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 147cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } else { 148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // NULL entry terminates the sibling chain. 149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SiblingChain = ParentChain.back(); 150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ParentChain.pop_back(); 151cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 152cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SiblingChain == nullptr || SiblingChain == &DieArray[0]); 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(ParentChain.empty()); 155cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 156cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 157cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFUnit::extractDIEsToVector( 158cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie bool AppendCUDie, bool AppendNonCUDies, 159cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie std::vector<DWARFDebugInfoEntryMinimal> &Dies) const { 160cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!AppendCUDie && !AppendNonCUDies) 161cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return; 162cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 163cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Set the offset to that of the first DIE and calculate the start of the 164cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // next compilation unit header. 165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t DIEOffset = Offset + getHeaderSize(); 166cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t NextCUOffset = getNextUnitOffset(); 167cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWARFDebugInfoEntryMinimal DIE; 168cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint32_t Depth = 0; 169cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie bool IsCUDie = true; 170cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (DIEOffset < NextCUOffset && DIE.extractFast(this, &DIEOffset)) { 172cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (IsCUDie) { 173cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (AppendCUDie) 174cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Dies.push_back(DIE); 175cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!AppendNonCUDies) 176cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie break; 177cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // The average bytes per DIE entry has been seen to be 178cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // around 14-20 so let's pre-reserve the needed memory for 179cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // our DIE entries accordingly. 180cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Dies.reserve(Dies.size() + getDebugInfoSize() / 14); 181cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie IsCUDie = false; 182cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } else { 183cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie Dies.push_back(DIE); 184cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 185cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (const DWARFAbbreviationDeclaration *AbbrDecl = 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DIE.getAbbreviationDeclarationPtr()) { 188cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Normal DIE 189cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (AbbrDecl->hasChildren()) 190cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie ++Depth; 191cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } else { 192cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // NULL DIE. 193cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (Depth > 0) 194cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie --Depth; 195cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (Depth == 0) 196cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie break; // We are done with this compile unit! 197cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 198cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 199cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 200cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Give a little bit of info if we encounter corrupt DWARF (our offset 201cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // should always terminate at or before the start of the next compilation 202cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // unit header). 203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DIEOffset > NextCUOffset) 204cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie fprintf(stderr, "warning: DWARF compile unit extends beyond its " 205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), DIEOffset); 206cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 207cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 208cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiesize_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { 209cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if ((CUDieOnly && DieArray.size() > 0) || 210cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DieArray.size() > 1) 211cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return 0; // Already parsed. 212cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 213cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie bool HasCUDie = DieArray.size() > 0; 214cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray); 215cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 216cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DieArray.empty()) 217cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return 0; 218cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 219cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // If CU DIE was just parsed, copy several attribute values from it. 220cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!HasCUDie) { 221cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie uint64_t BaseAddr = 222c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov DieArray[0].getAttributeValueAsAddress(this, DW_AT_low_pc, -1ULL); 223c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov if (BaseAddr == -1ULL) 224c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov BaseAddr = DieArray[0].getAttributeValueAsAddress(this, DW_AT_entry_pc, 0); 225cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie setBaseAddress(BaseAddr); 226c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset( 227c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov this, DW_AT_GNU_addr_base, 0); 228c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset( 229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines this, DW_AT_ranges_base, 0); 230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for 231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // skeleton CU DIE, so that DWARF users not aware of it are not broken. 232cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 233cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 234cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie setDIERelations(); 235cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return DieArray.size(); 236cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 237cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 238cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFUnit::DWOHolder::DWOHolder(object::ObjectFile *DWOFile) 239cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie : DWOFile(DWOFile), 240cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWOContext(cast<DWARFContext>(DIContext::getDWARFContext(DWOFile))), 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWOU(nullptr) { 242cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DWOContext->getNumDWOCompileUnits() > 0) 243cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWOU = DWOContext->getDWOCompileUnitAtIndex(0); 244cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 245cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 246cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikiebool DWARFUnit::parseDWO() { 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DWO.get()) 248cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 249cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie extractDIEsIfNeeded(true); 250cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DieArray.empty()) 251cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 252cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const char *DWOFileName = 253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, nullptr); 254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!DWOFileName) 255cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 256cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const char *CompilationDir = 257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr); 258cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie SmallString<16> AbsolutePath; 259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (sys::path::is_relative(DWOFileName) && CompilationDir != nullptr) { 260cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie sys::path::append(AbsolutePath, CompilationDir); 261cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 262cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie sys::path::append(AbsolutePath, DWOFileName); 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<object::ObjectFile *> DWOFile = 264cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie object::ObjectFile::createObjectFile(AbsolutePath); 265cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!DWOFile) 266cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 267cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Reset DWOHolder. 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DWO.reset(new DWOHolder(DWOFile.get())); 269cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWARFUnit *DWOCU = DWO->getUnit(); 270cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Verify that compile unit in .dwo file is valid. 271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!DWOCU || DWOCU->getDWOId() != getDWOId()) { 272cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWO.reset(); 273cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return false; 274cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 275cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Share .debug_addr and .debug_ranges section with compile unit in .dwo 276cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); 277cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t DWORangesBase = DieArray[0].getRangesBaseAttribute(this, 0); 278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DWOCU->setRangesSection(RangeSection, DWORangesBase); 279cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return true; 280cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 281cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 282cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikievoid DWARFUnit::clearDIEs(bool KeepCUDie) { 283cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DieArray.size() > (unsigned)KeepCUDie) { 284cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // std::vectors never get any smaller when resized to a smaller size, 285cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // or when clear() or erase() are called, the size will report that it 286cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // is smaller, but the memory allocated remains intact (call capacity() 287cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // to see this). So we need to create a temporary vector and swap the 288cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // contents which will cause just the internal pointers to be swapped 289cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // so that when temporary vector goes out of scope, it will destroy the 290cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // contents. 291cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie std::vector<DWARFDebugInfoEntryMinimal> TmpArray; 292cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DieArray.swap(TmpArray); 293cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Save at least the compile unit DIE 294cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (KeepCUDie) 295cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DieArray.push_back(TmpArray.front()); 296cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 297cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 298cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) { 300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // First, check if CU DIE describes address ranges for the unit. 301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto &CUDIERanges = getCompileUnitDIE()->getAddressRanges(this); 302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!CUDIERanges.empty()) { 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end()); 304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 307cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // This function is usually called if there in no .debug_aranges section 308cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // in order to produce a compile unit level set of address ranges that 309cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // is accurate. If the DIEs weren't parsed, then we don't want all dies for 310cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // all compile units to stay loaded when they weren't needed. So we can end 311cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // up parsing the DWARF and then throwing them all away to keep memory usage 312cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // down. 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const bool ClearDIEs = extractDIEsIfNeeded(false) > 1; 314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DieArray[0].collectChildrenAddressRanges(this, CURanges); 315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Collect address ranges from DIEs in .dwo if necessary. 317cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie bool DWOCreated = parseDWO(); 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DWO.get()) 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWO->getUnit()->collectAddressRanges(CURanges); 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DWOCreated) 321cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie DWO.reset(); 322cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 323cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Keep memory down by clearing DIEs if this generate function 324cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // caused them to be parsed. 325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ClearDIEs) 326cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie clearDIEs(true); 327cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 328cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 329cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikieconst DWARFDebugInfoEntryMinimal * 330cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFUnit::getSubprogramForAddress(uint64_t Address) { 331cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie extractDIEsIfNeeded(false); 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const DWARFDebugInfoEntryMinimal &DIE : DieArray) { 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DIE.isSubprogramDIE() && 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DIE.addressRangeContainsAddress(this, Address)) { 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return &DIE; 336cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 339cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 340cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 341cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFDebugInfoEntryInlinedChain 342cd7c4980d4ee2d22d92a4907f2d029e67b52d732David BlaikieDWARFUnit::getInlinedChainForAddress(uint64_t Address) { 343cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // First, find a subprogram that contains the given address (the root 344cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // of inlined chain). 345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const DWARFUnit *ChainCU = nullptr; 346cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie const DWARFDebugInfoEntryMinimal *SubprogramDIE = 347cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie getSubprogramForAddress(Address); 348cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (SubprogramDIE) { 349cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie ChainCU = this; 350cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } else { 351cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Try to look for subprogram DIEs in the DWO file. 352cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie parseDWO(); 353cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (DWO.get()) { 354cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address); 355cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (SubprogramDIE) 356cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie ChainCU = DWO->getUnit(); 357cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 358cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie } 359cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie 360cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie // Get inlined chain rooted at this subprogram DIE. 361cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie if (!SubprogramDIE) 362cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return DWARFDebugInfoEntryInlinedChain(); 363cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address); 364cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie} 365