Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- DWARFUnit.cpp ------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
10
#include "llvm/ADT/SmallString.h"
11
#include "llvm/ADT/StringRef.h"
12
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
13
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
14
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
15
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
16
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
17
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
18
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
19
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
20
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
21
#include "llvm/Support/DataExtractor.h"
22
#include "llvm/Support/Errc.h"
23
#include "llvm/Support/Path.h"
24
#include "llvm/Support/WithColor.h"
25
#include <algorithm>
26
#include <cassert>
27
#include <cstddef>
28
#include <cstdint>
29
#include <cstdio>
30
#include <utility>
31
#include <vector>
32
33
using namespace llvm;
34
using namespace dwarf;
35
36
void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
37
                                         const DWARFSection &Section,
38
1.44k
                                         DWARFSectionKind SectionKind) {
39
1.44k
  const DWARFObject &D = C.getDWARFObj();
40
1.44k
  addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
41
1.44k
               &D.getLocSection(), D.getStringSection(),
42
1.44k
               D.getStringOffsetSection(), &D.getAddrSection(),
43
1.44k
               D.getLineSection(), D.isLittleEndian(), false, false,
44
1.44k
               SectionKind);
45
1.44k
}
46
47
void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
48
                                            const DWARFSection &DWOSection,
49
                                            DWARFSectionKind SectionKind,
50
73
                                            bool Lazy) {
51
73
  const DWARFObject &D = C.getDWARFObj();
52
73
  addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
53
73
               &D.getLocDWOSection(), D.getStringDWOSection(),
54
73
               D.getStringOffsetDWOSection(), &D.getAddrSection(),
55
73
               D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
56
73
               SectionKind);
57
73
}
58
59
void DWARFUnitVector::addUnitsImpl(
60
    DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
61
    const DWARFDebugAbbrev *DA, const DWARFSection *RS,
62
    const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
63
    const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
64
1.51k
    bool Lazy, DWARFSectionKind SectionKind) {
65
1.51k
  DWARFDataExtractor Data(Obj, Section, LE, 0);
66
1.51k
  // Lazy initialization of Parser, now that we have all section info.
67
1.51k
  if (!Parser) {
68
1.45k
    Parser = [=, &Context, &Obj, &Section, &SOS,
69
1.45k
              &LS](uint32_t Offset, DWARFSectionKind SectionKind,
70
1.45k
                   const DWARFSection *CurSection,
71
1.45k
                   const DWARFUnitIndex::Entry *IndexEntry)
72
2.08k
        -> std::unique_ptr<DWARFUnit> {
73
2.08k
      const DWARFSection &InfoSection = CurSection ? 
*CurSection2.08k
:
Section1
;
74
2.08k
      DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
75
2.08k
      if (!Data.isValidOffset(Offset))
76
0
        return nullptr;
77
2.08k
      const DWARFUnitIndex *Index = nullptr;
78
2.08k
      if (IsDWO)
79
106
        Index = &getDWARFUnitIndex(Context, SectionKind);
80
2.08k
      DWARFUnitHeader Header;
81
2.08k
      if (!Header.extract(Context, Data, &Offset, SectionKind, Index,
82
2.08k
                          IndexEntry))
83
35
        return nullptr;
84
2.05k
      std::unique_ptr<DWARFUnit> U;
85
2.05k
      if (Header.isTypeUnit())
86
69
        U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
87
69
                                             RS, LocSection, SS, SOS, AOS, LS,
88
69
                                             LE, IsDWO, *this);
89
1.98k
      else
90
1.98k
        U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
91
1.98k
                                                DA, RS, LocSection, SS, SOS,
92
1.98k
                                                AOS, LS, LE, IsDWO, *this);
93
2.05k
      return U;
94
2.05k
    };
95
1.45k
  }
96
1.51k
  if (Lazy)
97
7
    return;
98
1.51k
  // Find a reasonable insertion point within the vector.  We skip over
99
1.51k
  // (a) units from a different section, (b) units from the same section
100
1.51k
  // but with lower offset-within-section.  This keeps units in order
101
1.51k
  // within a section, although not necessarily within the object file,
102
1.51k
  // even if we do lazy parsing.
103
1.51k
  auto I = this->begin();
104
1.51k
  uint32_t Offset = 0;
105
3.67k
  while (Data.isValidOffset(Offset)) {
106
2.19k
    if (I != this->end() &&
107
2.19k
        
(111
&(*I)->getInfoSection() != &Section111
||
(*I)->getOffset() == Offset0
)) {
108
111
      ++I;
109
111
      continue;
110
111
    }
111
2.08k
    auto U = Parser(Offset, SectionKind, &Section, nullptr);
112
2.08k
    // If parsing failed, we're done with this section.
113
2.08k
    if (!U)
114
35
      break;
115
2.04k
    Offset = U->getNextUnitOffset();
116
2.04k
    I = std::next(this->insert(I, std::move(U)));
117
2.04k
  }
118
1.51k
}
119
120
108
DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
121
108
  auto I = std::upper_bound(begin(), end(), Unit,
122
108
                            [](const std::unique_ptr<DWARFUnit> &LHS,
123
108
                               const std::unique_ptr<DWARFUnit> &RHS) {
124
39
                              return LHS->getOffset() < RHS->getOffset();
125
39
                            });
126
108
  return this->insert(I, std::move(Unit))->get();
127
108
}
128
129
2.21k
DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const {
130
2.21k
  auto end = begin() + getNumInfoUnits();
131
2.21k
  auto *CU =
132
2.21k
      std::upper_bound(begin(), end, Offset,
133
4.57k
                       [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
134
4.57k
                         return LHS < RHS->getNextUnitOffset();
135
4.57k
                       });
136
2.21k
  if (CU != end && 
(*CU)->getOffset() <= Offset1.93k
)
137
1.93k
    return CU->get();
138
280
  return nullptr;
139
280
}
140
141
DWARFUnit *
142
1
DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
143
1
  const auto *CUOff = E.getOffset(DW_SECT_INFO);
144
1
  if (!CUOff)
145
0
    return nullptr;
146
1
147
1
  auto Offset = CUOff->Offset;
148
1
  auto end = begin() + getNumInfoUnits();
149
1
150
1
  auto *CU =
151
1
      std::upper_bound(begin(), end, CUOff->Offset,
152
1
                       [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
153
0
                         return LHS < RHS->getNextUnitOffset();
154
0
                       });
155
1
  if (CU != end && 
(*CU)->getOffset() <= Offset0
)
156
0
    return CU->get();
157
1
158
1
  if (!Parser)
159
0
    return nullptr;
160
1
161
1
  auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
162
1
  if (!U)
163
0
    U = nullptr;
164
1
165
1
  auto *NewCU = U.get();
166
1
  this->insert(CU, std::move(U));
167
1
  ++NumInfoUnits;
168
1
  return NewCU;
169
1
}
170
171
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
172
                     const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
173
                     const DWARFSection *RS, const DWARFSection *LocSection,
174
                     StringRef SS, const DWARFSection &SOS,
175
                     const DWARFSection *AOS, const DWARFSection &LS, bool LE,
176
                     bool IsDWO, const DWARFUnitVector &UnitVector)
177
    : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
178
      RangeSection(RS), LocSection(LocSection), LineSection(LS),
179
      StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
180
2.15k
      isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) {
181
2.15k
  clear();
182
2.15k
  // For split DWARF we only need to keep track of the location list section's
183
2.15k
  // data (no relocations), and if we are reading a package file, we need to
184
2.15k
  // adjust the location list data based on the index entries.
185
2.15k
  if (IsDWO) {
186
106
    LocSectionData = LocSection->Data;
187
106
    if (auto *IndexEntry = Header.getIndexEntry())
188
40
      if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
189
2
        LocSectionData = LocSectionData.substr(C->Offset, C->Length);
190
106
  }
191
2.15k
}
192
193
2.15k
DWARFUnit::~DWARFUnit() = default;
194
195
72.0k
DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
196
72.0k
  return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
197
72.0k
                            getAddressByteSize());
198
72.0k
}
199
200
Optional<object::SectionedAddress>
201
289
DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
202
289
  if (IsDWO) {
203
121
    auto R = Context.info_section_units();
204
121
    auto I = R.begin();
205
121
    // Surprising if a DWO file has more than one skeleton unit in it - this
206
121
    // probably shouldn't be valid, but if a use case is found, here's where to
207
121
    // support it (probably have to linearly search for the matching skeleton CU
208
121
    // here)
209
121
    if (I != R.end() && 
std::next(I) == R.end()69
)
210
45
      return (*I)->getAddrOffsetSectionItem(Index);
211
244
  }
212
244
  uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
213
244
  if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
214
45
    return None;
215
199
  DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
216
199
                        isLittleEndian, getAddressByteSize());
217
199
  uint64_t Section;
218
199
  uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
219
199
  return {{Address, Section}};
220
199
}
221
222
1.60k
Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
223
1.60k
  if (!StringOffsetsTableContribution)
224
1
    return None;
225
1.60k
  unsigned ItemSize = getDwarfStringOffsetsByteSize();
226
1.60k
  uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
227
1.60k
  if (StringOffsetSection.Data.size() < Offset + ItemSize)
228
1
    return None;
229
1.60k
  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
230
1.60k
                        isLittleEndian, 0);
231
1.60k
  return DA.getRelocatedValue(ItemSize, &Offset);
232
1.60k
}
233
234
bool DWARFUnitHeader::extract(DWARFContext &Context,
235
                              const DWARFDataExtractor &debug_info,
236
                              uint32_t *offset_ptr,
237
                              DWARFSectionKind SectionKind,
238
                              const DWARFUnitIndex *Index,
239
2.19k
                              const DWARFUnitIndex::Entry *Entry) {
240
2.19k
  Offset = *offset_ptr;
241
2.19k
  IndexEntry = Entry;
242
2.19k
  if (!IndexEntry && 
Index2.19k
)
243
105
    IndexEntry = Index->getFromOffset(*offset_ptr);
244
2.19k
  Length = debug_info.getRelocatedValue(4, offset_ptr);
245
2.19k
  FormParams.Format = DWARF32;
246
2.19k
  unsigned SizeOfLength = 4;
247
2.19k
  if (Length == 0xffffffff) {
248
9
    Length = debug_info.getU64(offset_ptr);
249
9
    FormParams.Format = DWARF64;
250
9
    SizeOfLength = 8;
251
9
  }
252
2.19k
  FormParams.Version = debug_info.getU16(offset_ptr);
253
2.19k
  if (FormParams.Version >= 5) {
254
155
    UnitType = debug_info.getU8(offset_ptr);
255
155
    FormParams.AddrSize = debug_info.getU8(offset_ptr);
256
155
    AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
257
2.03k
  } else {
258
2.03k
    AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
259
2.03k
    FormParams.AddrSize = debug_info.getU8(offset_ptr);
260
2.03k
    // Fake a unit type based on the section type.  This isn't perfect,
261
2.03k
    // but distinguishing compile and type units is generally enough.
262
2.03k
    if (SectionKind == DW_SECT_TYPES)
263
53
      UnitType = DW_UT_type;
264
1.98k
    else
265
1.98k
      UnitType = DW_UT_compile;
266
2.03k
  }
267
2.19k
  if (IndexEntry) {
268
40
    if (AbbrOffset)
269
0
      return false;
270
40
    auto *UnitContrib = IndexEntry->getOffset();
271
40
    if (!UnitContrib || UnitContrib->Length != (Length + 4))
272
0
      return false;
273
40
    auto *AbbrEntry = IndexEntry->getOffset(DW_SECT_ABBREV);
274
40
    if (!AbbrEntry)
275
0
      return false;
276
40
    AbbrOffset = AbbrEntry->Offset;
277
40
  }
278
2.19k
  if (isTypeUnit()) {
279
71
    TypeHash = debug_info.getU64(offset_ptr);
280
71
    TypeOffset = debug_info.getU32(offset_ptr);
281
2.12k
  } else if (UnitType == DW_UT_split_compile || 
UnitType == DW_UT_skeleton2.11k
)
282
19
    DWOId = debug_info.getU64(offset_ptr);
283
2.19k
284
2.19k
  // Header fields all parsed, capture the size of this unit header.
285
2.19k
  assert(*offset_ptr - Offset <= 255 && "unexpected header size");
286
2.19k
  Size = uint8_t(*offset_ptr - Offset);
287
2.19k
288
2.19k
  // Type offset is unit-relative; should be after the header and before
289
2.19k
  // the end of the current unit.
290
2.19k
  bool TypeOffsetOK =
291
2.19k
      !isTypeUnit()
292
2.19k
          ? 
true2.12k
293
2.19k
          : 
TypeOffset >= Size71
&&
TypeOffset < getLength() + SizeOfLength71
;
294
2.19k
  bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
295
2.19k
  bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
296
2.19k
  bool AddrSizeOK = getAddressByteSize() == 4 || 
getAddressByteSize() == 82.04k
;
297
2.19k
298
2.19k
  if (!LengthOK || 
!VersionOK2.18k
||
!AddrSizeOK2.16k
||
!TypeOffsetOK2.15k
)
299
35
    return false;
300
2.15k
301
2.15k
  // Keep track of the highest DWARF version we encounter across all units.
302
2.15k
  Context.setMaxVersionIfGreater(getVersion());
303
2.15k
  return true;
304
2.15k
}
305
306
// Parse the rangelist table header, including the optional array of offsets
307
// following it (DWARF v5 and later).
308
static Expected<DWARFDebugRnglistTable>
309
17
parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
310
17
  // TODO: Support DWARF64
311
17
  // We are expected to be called with Offset 0 or pointing just past the table
312
17
  // header, which is 12 bytes long for DWARF32.
313
17
  if (Offset > 0) {
314
14
    if (Offset < 12U)
315
2
      return createStringError(errc::invalid_argument, "Did not detect a valid"
316
2
                               " range list table with base = 0x%" PRIu32,
317
2
                               Offset);
318
12
    Offset -= 12U;
319
12
  }
320
17
  llvm::DWARFDebugRnglistTable Table;
321
15
  if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
322
0
    return std::move(E);
323
15
  return Table;
324
15
}
325
326
Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
327
151
                                  DWARFDebugRangeList &RangeList) const {
328
151
  // Require that compile unit is extracted.
329
151
  assert(!DieArray.empty());
330
151
  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
331
151
                                isLittleEndian, getAddressByteSize());
332
151
  uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
333
151
  return RangeList.extract(RangesData, &ActualRangeListOffset);
334
151
}
335
336
2.15k
void DWARFUnit::clear() {
337
2.15k
  Abbrevs = nullptr;
338
2.15k
  BaseAddr.reset();
339
2.15k
  RangeSectionBase = 0;
340
2.15k
  AddrOffsetSectionBase = 0;
341
2.15k
  clearDIEs(false);
342
2.15k
  DWO.reset();
343
2.15k
}
344
345
3.90k
const char *DWARFUnit::getCompilationDir() {
346
3.90k
  return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
347
3.90k
}
348
349
void DWARFUnit::extractDIEsToVector(
350
    bool AppendCUDie, bool AppendNonCUDies,
351
2.41k
    std::vector<DWARFDebugInfoEntry> &Dies) const {
352
2.41k
  if (!AppendCUDie && 
!AppendNonCUDies299
)
353
0
    return;
354
2.41k
355
2.41k
  // Set the offset to that of the first DIE and calculate the start of the
356
2.41k
  // next compilation unit header.
357
2.41k
  uint32_t DIEOffset = getOffset() + getHeaderSize();
358
2.41k
  uint32_t NextCUOffset = getNextUnitOffset();
359
2.41k
  DWARFDebugInfoEntry DIE;
360
2.41k
  DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
361
2.41k
  uint32_t Depth = 0;
362
2.41k
  bool IsCUDie = true;
363
2.41k
364
17.3k
  while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
365
17.3k
                         Depth)) {
366
17.1k
    if (IsCUDie) {
367
2.41k
      if (AppendCUDie)
368
2.11k
        Dies.push_back(DIE);
369
2.41k
      if (!AppendNonCUDies)
370
502
        break;
371
1.90k
      // The average bytes per DIE entry has been seen to be
372
1.90k
      // around 14-20 so let's pre-reserve the needed memory for
373
1.90k
      // our DIE entries accordingly.
374
1.90k
      Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
375
1.90k
      IsCUDie = false;
376
14.7k
    } else {
377
14.7k
      Dies.push_back(DIE);
378
14.7k
    }
379
17.1k
380
17.1k
    
if (const DWARFAbbreviationDeclaration *16.6k
AbbrDecl16.6k
=
381
12.6k
            DIE.getAbbreviationDeclarationPtr()) {
382
12.6k
      // Normal DIE
383
12.6k
      if (AbbrDecl->hasChildren())
384
4.06k
        ++Depth;
385
12.6k
    } else {
386
4.08k
      // NULL DIE.
387
4.08k
      if (Depth > 0)
388
4.05k
        --Depth;
389
4.08k
      if (Depth == 0)
390
1.71k
        break;  // We are done with this compile unit!
391
4.08k
    }
392
16.6k
  }
393
2.41k
394
2.41k
  // Give a little bit of info if we encounter corrupt DWARF (our offset
395
2.41k
  // should always terminate at or before the start of the next compilation
396
2.41k
  // unit header).
397
2.41k
  if (DIEOffset > NextCUOffset)
398
7
    WithColor::warning() << format("DWARF compile unit extends beyond its "
399
7
                                   "bounds cu 0x%8.8x at 0x%8.8x\n",
400
7
                                   getOffset(), DIEOffset);
401
2.41k
}
402
403
27.8k
size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
404
27.8k
  if ((CUDieOnly && 
!DieArray.empty()13.9k
) ||
405
27.8k
      
DieArray.size() > 114.3k
)
406
25.3k
    return 0; // Already parsed.
407
2.41k
408
2.41k
  bool HasCUDie = !DieArray.empty();
409
2.41k
  extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
410
2.41k
411
2.41k
  if (DieArray.empty())
412
8
    return 0;
413
2.41k
414
2.41k
  // If CU DIE was just parsed, copy several attribute values from it.
415
2.41k
  if (!HasCUDie) {
416
2.11k
    DWARFDie UnitDie = getUnitDIE();
417
2.11k
    if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
418
161
      Header.setDWOId(*DWOId);
419
2.11k
    if (!IsDWO) {
420
2.00k
      assert(AddrOffsetSectionBase == 0);
421
2.00k
      assert(RangeSectionBase == 0);
422
2.00k
      AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
423
2.00k
      if (!AddrOffsetSectionBase)
424
1.95k
        AddrOffsetSectionBase =
425
1.95k
            toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
426
2.00k
      RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
427
2.00k
    }
428
2.11k
429
2.11k
    // In general, in DWARF v5 and beyond we derive the start of the unit's
430
2.11k
    // contribution to the string offsets table from the unit DIE's
431
2.11k
    // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
432
2.11k
    // attribute, so we assume that there is a contribution to the string
433
2.11k
    // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
434
2.11k
    // In both cases we need to determine the format of the contribution,
435
2.11k
    // which may differ from the unit's format.
436
2.11k
    DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
437
2.11k
                          isLittleEndian, 0);
438
2.11k
    if (IsDWO || 
getVersion() >= 52.00k
) {
439
225
      auto StringOffsetOrError =
440
225
          IsDWO ? 
determineStringOffsetsTableContributionDWO(DA)106
441
225
                : 
determineStringOffsetsTableContribution(DA)119
;
442
225
      if (!StringOffsetOrError) {
443
11
        WithColor::error() << "invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: "
444
11
                           << toString(StringOffsetOrError.takeError()) << '\n';
445
214
      } else {
446
214
        StringOffsetsTableContribution = *StringOffsetOrError;
447
214
      }
448
225
    }
449
2.11k
450
2.11k
    // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
451
2.11k
    // describe address ranges.
452
2.11k
    if (getVersion() >= 5) {
453
143
      if (IsDWO)
454
24
        setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
455
119
      else
456
119
        setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
457
119
                         toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
458
143
      if (RangeSection->Data.size()) {
459
17
        // Parse the range list table header. Individual range lists are
460
17
        // extracted lazily.
461
17
        DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
462
17
                                    isLittleEndian, 0);
463
17
        if (auto TableOrError =
464
15
                parseRngListTableHeader(RangesDA, RangeSectionBase))
465
15
          RngListTable = TableOrError.get();
466
2
        else
467
2
          WithColor::error() << "parsing a range list table: "
468
2
                             << toString(TableOrError.takeError())
469
2
                             << '\n';
470
17
471
17
        // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
472
17
        // Adjust RangeSectionBase to point past the table header.
473
17
        if (IsDWO && 
RngListTable3
)
474
3
          RangeSectionBase = RngListTable->getHeaderSize();
475
17
      }
476
143
    }
477
2.11k
478
2.11k
    // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
479
2.11k
    // skeleton CU DIE, so that DWARF users not aware of it are not broken.
480
2.11k
    }
481
2.41k
482
2.41k
  return DieArray.size();
483
2.41k
}
484
485
885
bool DWARFUnit::parseDWO() {
486
885
  if (IsDWO)
487
0
    return false;
488
885
  if (DWO.get())
489
2
    return false;
490
883
  DWARFDie UnitDie = getUnitDIE();
491
883
  if (!UnitDie)
492
0
    return false;
493
883
  auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
494
883
  if (!DWOFileName)
495
873
    return false;
496
10
  auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
497
10
  SmallString<16> AbsolutePath;
498
10
  if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
499
10
      
*CompilationDir9
) {
500
9
    sys::path::append(AbsolutePath, *CompilationDir);
501
9
  }
502
10
  sys::path::append(AbsolutePath, *DWOFileName);
503
10
  auto DWOId = getDWOId();
504
10
  if (!DWOId)
505
0
    return false;
506
10
  auto DWOContext = Context.getDWOContext(AbsolutePath);
507
10
  if (!DWOContext)
508
4
    return false;
509
6
510
6
  DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
511
6
  if (!DWOCU)
512
0
    return false;
513
6
  DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
514
6
  // Share .debug_addr and .debug_ranges section with compile unit in .dwo
515
6
  DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
516
6
  if (getVersion() >= 5) {
517
0
    DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
518
0
    DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
519
0
                                isLittleEndian, 0);
520
0
    if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
521
0
      DWO->RngListTable = TableOrError.get();
522
0
    else
523
0
      WithColor::error() << "parsing a range list table: "
524
0
                         << toString(TableOrError.takeError())
525
0
                         << '\n';
526
0
    if (DWO->RngListTable)
527
0
      DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
528
6
  } else {
529
6
    auto DWORangesBase = UnitDie.getRangesBaseAttribute();
530
6
    DWO->setRangesSection(RangeSection, DWORangesBase ? 
*DWORangesBase1
:
05
);
531
6
  }
532
6
533
6
  return true;
534
6
}
535
536
2.15k
void DWARFUnit::clearDIEs(bool KeepCUDie) {
537
2.15k
  if (DieArray.size() > (unsigned)KeepCUDie) {
538
0
    DieArray.resize((unsigned)KeepCUDie);
539
0
    DieArray.shrink_to_fit();
540
0
  }
541
2.15k
}
542
543
Expected<DWARFAddressRangesVector>
544
168
DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
545
168
  if (getVersion() <= 4) {
546
151
    DWARFDebugRangeList RangeList;
547
151
    if (Error E = extractRangeList(Offset, RangeList))
548
6
      return std::move(E);
549
145
    return RangeList.getAbsoluteRanges(getBaseAddress());
550
145
  }
551
17
  if (RngListTable) {
552
16
    DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
553
16
                                  isLittleEndian, RngListTable->getAddrSize());
554
16
    auto RangeListOrError = RngListTable->findList(RangesData, Offset);
555
16
    if (RangeListOrError)
556
14
      return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
557
2
    return RangeListOrError.takeError();
558
2
  }
559
1
560
1
  return createStringError(errc::invalid_argument,
561
1
                           "missing or invalid range list table");
562
1
}
563
564
Expected<DWARFAddressRangesVector>
565
14
DWARFUnit::findRnglistFromIndex(uint32_t Index) {
566
14
  if (auto Offset = getRnglistOffset(Index))
567
12
    return findRnglistFromOffset(*Offset + RangeSectionBase);
568
2
569
2
  if (RngListTable)
570
0
    return createStringError(errc::invalid_argument,
571
0
                             "invalid range list table index %d", Index);
572
2
  else
573
2
    return createStringError(errc::invalid_argument,
574
2
                             "missing or invalid range list table");
575
2
}
576
577
314
Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
578
314
  DWARFDie UnitDie = getUnitDIE();
579
314
  if (!UnitDie)
580
0
    return createStringError(errc::invalid_argument, "No unit DIE");
581
314
582
314
  // First, check if unit DIE describes address ranges for the whole unit.
583
314
  auto CUDIERangesOrError = UnitDie.getAddressRanges();
584
314
  if (!CUDIERangesOrError)
585
4
    return createStringError(errc::invalid_argument,
586
4
                             "decoding address ranges: %s",
587
4
                             toString(CUDIERangesOrError.takeError()).c_str());
588
310
  return *CUDIERangesOrError;
589
310
}
590
591
2.42k
void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
592
2.42k
  if (Die.isSubroutineDIE()) {
593
515
    auto DIERangesOrError = Die.getAddressRanges();
594
515
    if (DIERangesOrError) {
595
515
      for (const auto &R : DIERangesOrError.get()) {
596
346
        // Ignore 0-sized ranges.
597
346
        if (R.LowPC == R.HighPC)
598
0
          continue;
599
346
        auto B = AddrDieMap.upper_bound(R.LowPC);
600
346
        if (B != AddrDieMap.begin() && 
R.LowPC < (--B)->second.first198
) {
601
119
          // The range is a sub-range of existing ranges, we need to split the
602
119
          // existing range.
603
119
          if (R.HighPC < B->second.first)
604
111
            AddrDieMap[R.HighPC] = B->second;
605
119
          if (R.LowPC > B->first)
606
15
            AddrDieMap[B->first].first = R.LowPC;
607
119
        }
608
346
        AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
609
346
      }
610
515
    } else
611
0
      llvm::consumeError(DIERangesOrError.takeError());
612
515
  }
613
2.42k
  // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
614
2.42k
  // simplify the logic to update AddrDieMap. The child's range will always
615
2.42k
  // be equal or smaller than the parent's range. With this assumption, when
616
2.42k
  // adding one range into the map, it will at most split a range into 3
617
2.42k
  // sub-ranges.
618
4.62k
  for (DWARFDie Child = Die.getFirstChild(); Child; 
Child = Child.getSibling()2.20k
)
619
2.20k
    updateAddressDieMap(Child);
620
2.42k
}
621
622
885
DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
623
885
  extractDIEsIfNeeded(false);
624
885
  if (AddrDieMap.empty())
625
218
    updateAddressDieMap(getUnitDIE());
626
885
  auto R = AddrDieMap.upper_bound(Address);
627
885
  if (R == AddrDieMap.begin())
628
76
    return DWARFDie();
629
809
  // upper_bound's previous item contains Address.
630
809
  --R;
631
809
  if (Address >= R->second.first)
632
89
    return DWARFDie();
633
720
  return R->second.second;
634
720
}
635
636
void
637
DWARFUnit::getInlinedChainForAddress(uint64_t Address,
638
878
                                     SmallVectorImpl<DWARFDie> &InlinedChain) {
639
878
  assert(InlinedChain.empty());
640
878
  // Try to look for subprogram DIEs in the DWO file.
641
878
  parseDWO();
642
878
  // First, find the subroutine that contains the given address (the leaf
643
878
  // of inlined chain).
644
878
  DWARFDie SubroutineDIE =
645
878
      (DWO ? 
*DWO7
:
*this871
).getSubroutineForAddress(Address);
646
878
647
878
  if (!SubroutineDIE)
648
164
    return;
649
714
650
824
  
while (714
!SubroutineDIE.isSubprogramDIE()) {
651
110
    if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
652
108
      InlinedChain.push_back(SubroutineDIE);
653
110
    SubroutineDIE  = SubroutineDIE.getParent();
654
110
  }
655
714
  InlinedChain.push_back(SubroutineDIE);
656
714
}
657
658
const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
659
106
                                              DWARFSectionKind Kind) {
660
106
  if (Kind == DW_SECT_INFO)
661
83
    return Context.getCUIndex();
662
23
  assert(Kind == DW_SECT_TYPES);
663
23
  return Context.getTUIndex();
664
23
}
665
666
139
DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
667
139
  if (!Die)
668
0
    return DWARFDie();
669
139
  const uint32_t Depth = Die->getDepth();
670
139
  // Unit DIEs always have a depth of zero and never have parents.
671
139
  if (Depth == 0)
672
6
    return DWARFDie();
673
133
  // Depth of 1 always means parent is the compile/type unit.
674
133
  if (Depth == 1)
675
7
    return getUnitDIE();
676
126
  // Look for previous DIE with a depth that is one less than the Die's depth.
677
126
  const uint32_t ParentDepth = Depth - 1;
678
230
  for (uint32_t I = getDIEIndex(Die) - 1; I > 0; 
--I104
) {
679
230
    if (DieArray[I].getDepth() == ParentDepth)
680
126
      return DWARFDie(this, &DieArray[I]);
681
230
  }
682
126
  
return DWARFDie()0
;
683
126
}
684
685
14.2k
DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
686
14.2k
  if (!Die)
687
0
    return DWARFDie();
688
14.2k
  uint32_t Depth = Die->getDepth();
689
14.2k
  // Unit DIEs always have a depth of zero and never have siblings.
690
14.2k
  if (Depth == 0)
691
1
    return DWARFDie();
692
14.2k
  // NULL DIEs don't have siblings.
693
14.2k
  if (Die->getAbbreviationDeclarationPtr() == nullptr)
694
2.75k
    return DWARFDie();
695
11.5k
696
11.5k
  // Find the next DIE whose depth is the same as the Die's depth.
697
20.5k
  
for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); 11.5k
I < EndIdx;
698
20.5k
       
++I8.99k
) {
699
20.5k
    if (DieArray[I].getDepth() == Depth)
700
11.5k
      return DWARFDie(this, &DieArray[I]);
701
20.5k
  }
702
11.5k
  
return DWARFDie()6
;
703
11.5k
}
704
705
3.24k
DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
706
3.24k
  if (!Die)
707
0
    return DWARFDie();
708
3.24k
  uint32_t Depth = Die->getDepth();
709
3.24k
  // Unit DIEs always have a depth of zero and never have siblings.
710
3.24k
  if (Depth == 0)
711
0
    return DWARFDie();
712
3.24k
713
3.24k
  // Find the previous DIE whose depth is the same as the Die's depth.
714
4.21k
  
for (size_t I = getDIEIndex(Die); 3.24k
I > 0;) {
715
4.21k
    --I;
716
4.21k
    if (DieArray[I].getDepth() == Depth - 1)
717
1.02k
      return DWARFDie();
718
3.19k
    if (DieArray[I].getDepth() == Depth)
719
2.22k
      return DWARFDie(this, &DieArray[I]);
720
3.19k
  }
721
3.24k
  
return DWARFDie()0
;
722
3.24k
}
723
724
13.2k
DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
725
13.2k
  if (!Die->hasChildren())
726
7.98k
    return DWARFDie();
727
5.27k
728
5.27k
  // We do not want access out of bounds when parsing corrupted debug data.
729
5.27k
  size_t I = getDIEIndex(Die) + 1;
730
5.27k
  if (I >= DieArray.size())
731
1
    return DWARFDie();
732
5.27k
  return DWARFDie(this, &DieArray[I]);
733
5.27k
}
734
735
4.05k
DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
736
4.05k
  if (!Die->hasChildren())
737
1.66k
    return DWARFDie();
738
2.39k
739
2.39k
  uint32_t Depth = Die->getDepth();
740
13.8k
  for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
741
13.8k
       
++I11.4k
) {
742
13.8k
    if (DieArray[I].getDepth() == Depth + 1 &&
743
13.8k
        
DieArray[I].getTag() == dwarf::DW_TAG_null9.92k
)
744
2.38k
      return DWARFDie(this, &DieArray[I]);
745
11.4k
    assert(DieArray[I].getDepth() > Depth && "Not processing children?");
746
11.4k
  }
747
2.39k
  
return DWARFDie()6
;
748
2.39k
}
749
750
13.9k
const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
751
13.9k
  if (!Abbrevs)
752
2.10k
    Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
753
13.9k
  return Abbrevs;
754
13.9k
}
755
756
362
llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
757
362
  if (BaseAddr)
758
114
    return BaseAddr;
759
248
760
248
  DWARFDie UnitDie = getUnitDIE();
761
248
  Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
762
248
  BaseAddr = toSectionedAddress(PC);
763
248
  return BaseAddr;
764
248
}
765
766
Expected<StrOffsetsContributionDescriptor>
767
StrOffsetsContributionDescriptor::validateContributionSize(
768
96
    DWARFDataExtractor &DA) {
769
96
  uint8_t EntrySize = getDwarfOffsetByteSize();
770
96
  // In order to ensure that we don't read a partial record at the end of
771
96
  // the section we validate for a multiple of the entry size.
772
96
  uint64_t ValidationSize = alignTo(Size, EntrySize);
773
96
  // Guard against overflow.
774
96
  if (ValidationSize >= Size)
775
96
    if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
776
95
      return *this;
777
1
  return createStringError(errc::invalid_argument, "length exceeds section size");
778
1
}
779
780
// Look for a DWARF64-formatted contribution to the string offsets table
781
// starting at a given offset and record it in a descriptor.
782
static Expected<StrOffsetsContributionDescriptor>
783
5
parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
784
5
  if (!DA.isValidOffsetForDataOfSize(Offset, 16))
785
1
    return createStringError(errc::invalid_argument, "section offset exceeds section size");
786
4
787
4
  if (DA.getU32(&Offset) != 0xffffffff)
788
1
    return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
789
3
790
3
  uint64_t Size = DA.getU64(&Offset);
791
3
  uint8_t Version = DA.getU16(&Offset);
792
3
  (void)DA.getU16(&Offset); // padding
793
3
  // The encoded length includes the 2-byte version field and the 2-byte
794
3
  // padding, so we need to subtract them out when we populate the descriptor.
795
3
  return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
796
3
}
797
798
// Look for a DWARF32-formatted contribution to the string offsets table
799
// starting at a given offset and record it in a descriptor.
800
static Expected<StrOffsetsContributionDescriptor>
801
99
parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
802
99
  if (!DA.isValidOffsetForDataOfSize(Offset, 8))
803
5
    return createStringError(errc::invalid_argument, "section offset exceeds section size");
804
94
805
94
  uint32_t ContributionSize = DA.getU32(&Offset);
806
94
  if (ContributionSize >= 0xfffffff0)
807
1
    return createStringError(errc::invalid_argument, "invalid length");
808
93
809
93
  uint8_t Version = DA.getU16(&Offset);
810
93
  (void)DA.getU16(&Offset); // padding
811
93
  // The encoded length includes the 2-byte version field and the 2-byte
812
93
  // padding, so we need to subtract them out when we populate the descriptor.
813
93
  return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
814
93
                                          DWARF32);
815
93
}
816
817
static Expected<StrOffsetsContributionDescriptor>
818
parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
819
                                   llvm::dwarf::DwarfFormat Format,
820
106
                                   uint64_t Offset) {
821
106
  StrOffsetsContributionDescriptor Desc;
822
106
  switch (Format) {
823
106
  case dwarf::DwarfFormat::DWARF64: {
824
6
    if (Offset < 16)
825
1
      return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
826
5
    auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16);
827
5
    if (!DescOrError)
828
2
      return DescOrError.takeError();
829
3
    Desc = *DescOrError;
830
3
    break;
831
3
  }
832
100
  case dwarf::DwarfFormat::DWARF32: {
833
100
    if (Offset < 8)
834
1
      return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
835
99
    auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
836
99
    if (!DescOrError)
837
6
      return DescOrError.takeError();
838
93
    Desc = *DescOrError;
839
93
    break;
840
93
  }
841
96
  }
842
96
  return Desc.validateContributionSize(DA);
843
96
}
844
845
Expected<Optional<StrOffsetsContributionDescriptor>>
846
119
DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
847
119
  uint64_t Offset;
848
119
  if (IsDWO) {
849
0
    Offset = 0;
850
0
    if (DA.getData().data() == nullptr)
851
0
      return None;
852
119
  } else {
853
119
    auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
854
119
    if (!OptOffset)
855
32
      return None;
856
87
    Offset = *OptOffset;
857
87
  }
858
119
  auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
859
87
  if (!DescOrError)
860
11
    return DescOrError.takeError();
861
76
  return *DescOrError;
862
76
}
863
864
Expected<Optional<StrOffsetsContributionDescriptor>>
865
106
DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
866
106
  uint64_t Offset = 0;
867
106
  auto IndexEntry = Header.getIndexEntry();
868
106
  const auto *C =
869
106
      IndexEntry ? 
IndexEntry->getOffset(DW_SECT_STR_OFFSETS)40
:
nullptr66
;
870
106
  if (C)
871
37
    Offset = C->Offset;
872
106
  if (getVersion() >= 5) {
873
24
    if (DA.getData().data() == nullptr)
874
5
      return None;
875
19
    Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 
160
;
876
19
    // Look for a valid contribution at the given offset.
877
19
    auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
878
19
    if (!DescOrError)
879
0
      return DescOrError.takeError();
880
19
    return *DescOrError;
881
19
  }
882
82
  // Prior to DWARF v5, we derive the contribution size from the
883
82
  // index table (in a package file). In a .dwo file it is simply
884
82
  // the length of the string offsets section.
885
82
  if (!IndexEntry)
886
46
    return {
887
46
        Optional<StrOffsetsContributionDescriptor>(
888
46
            {0, StringOffsetSection.Data.size(), 4, DWARF32})};
889
36
  if (C)
890
33
    return {Optional<StrOffsetsContributionDescriptor>(
891
33
        {C->Offset, C->Length, 4, DWARF32})};
892
3
  return None;
893
3
}