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