Bug Summary

File:build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Warning:line 806, column 20
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name DWARFUnit.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/DebugInfo/DWARF -I include -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-16/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-10-03-140002-15933-1 -x c++ /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
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/BinaryFormat/Dwarf.h"
13#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
14#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
15#include "llvm/DebugInfo/DWARF/DWARFContext.h"
16#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
18#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
19#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
20#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
21#include "llvm/DebugInfo/DWARF/DWARFDie.h"
22#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
23#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
24#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
25#include "llvm/DebugInfo/DWARF/DWARFObject.h"
26#include "llvm/DebugInfo/DWARF/DWARFSection.h"
27#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
28#include "llvm/Object/ObjectFile.h"
29#include "llvm/Support/DataExtractor.h"
30#include "llvm/Support/Errc.h"
31#include "llvm/Support/Path.h"
32#include <algorithm>
33#include <cassert>
34#include <cstddef>
35#include <cstdint>
36#include <utility>
37#include <vector>
38
39using namespace llvm;
40using namespace dwarf;
41
42void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
43 const DWARFSection &Section,
44 DWARFSectionKind SectionKind) {
45 const DWARFObject &D = C.getDWARFObj();
46 addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
47 &D.getLocSection(), D.getStrSection(),
48 D.getStrOffsetsSection(), &D.getAddrSection(),
49 D.getLineSection(), D.isLittleEndian(), false, false,
50 SectionKind);
51}
52
53void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
54 const DWARFSection &DWOSection,
55 DWARFSectionKind SectionKind,
56 bool Lazy) {
57 const DWARFObject &D = C.getDWARFObj();
58 addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
59 &D.getLocDWOSection(), D.getStrDWOSection(),
60 D.getStrOffsetsDWOSection(), &D.getAddrSection(),
61 D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
62 SectionKind);
63}
64
65void DWARFUnitVector::addUnitsImpl(
66 DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
67 const DWARFDebugAbbrev *DA, const DWARFSection *RS,
68 const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
69 const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
70 bool Lazy, DWARFSectionKind SectionKind) {
71 DWARFDataExtractor Data(Obj, Section, LE, 0);
72 // Lazy initialization of Parser, now that we have all section info.
73 if (!Parser) {
74 Parser = [=, &Context, &Obj, &Section, &SOS,
75 &LS](uint64_t Offset, DWARFSectionKind SectionKind,
76 const DWARFSection *CurSection,
77 const DWARFUnitIndex::Entry *IndexEntry)
78 -> std::unique_ptr<DWARFUnit> {
79 const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
80 DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
81 if (!Data.isValidOffset(Offset))
82 return nullptr;
83 DWARFUnitHeader Header;
84 if (!Header.extract(Context, Data, &Offset, SectionKind))
85 return nullptr;
86 if (!IndexEntry && IsDWO) {
87 const DWARFUnitIndex &Index = getDWARFUnitIndex(
88 Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
89 if (Index) {
90 if (Header.isTypeUnit())
91 IndexEntry = Index.getFromHash(Header.getTypeHash());
92 else if (auto DWOId = Header.getDWOId())
93 IndexEntry = Index.getFromHash(*DWOId);
94 }
95 if (!IndexEntry)
96 IndexEntry = Index.getFromOffset(Header.getOffset());
97 }
98 if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
99 return nullptr;
100 std::unique_ptr<DWARFUnit> U;
101 if (Header.isTypeUnit())
102 U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
103 RS, LocSection, SS, SOS, AOS, LS,
104 LE, IsDWO, *this);
105 else
106 U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
107 DA, RS, LocSection, SS, SOS,
108 AOS, LS, LE, IsDWO, *this);
109 return U;
110 };
111 }
112 if (Lazy)
113 return;
114 // Find a reasonable insertion point within the vector. We skip over
115 // (a) units from a different section, (b) units from the same section
116 // but with lower offset-within-section. This keeps units in order
117 // within a section, although not necessarily within the object file,
118 // even if we do lazy parsing.
119 auto I = this->begin();
120 uint64_t Offset = 0;
121 while (Data.isValidOffset(Offset)) {
122 if (I != this->end() &&
123 (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
124 ++I;
125 continue;
126 }
127 auto U = Parser(Offset, SectionKind, &Section, nullptr);
128 // If parsing failed, we're done with this section.
129 if (!U)
130 break;
131 Offset = U->getNextUnitOffset();
132 I = std::next(this->insert(I, std::move(U)));
133 }
134}
135
136DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
137 auto I = llvm::upper_bound(*this, Unit,
138 [](const std::unique_ptr<DWARFUnit> &LHS,
139 const std::unique_ptr<DWARFUnit> &RHS) {
140 return LHS->getOffset() < RHS->getOffset();
141 });
142 return this->insert(I, std::move(Unit))->get();
143}
144
145DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
146 auto end = begin() + getNumInfoUnits();
147 auto *CU =
148 std::upper_bound(begin(), end, Offset,
149 [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
150 return LHS < RHS->getNextUnitOffset();
151 });
152 if (CU != end && (*CU)->getOffset() <= Offset)
153 return CU->get();
154 return nullptr;
155}
156
157DWARFUnit *
158DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
159 const auto *CUOff = E.getContribution(DW_SECT_INFO);
160 if (!CUOff)
161 return nullptr;
162
163 auto Offset = CUOff->Offset;
164 auto end = begin() + getNumInfoUnits();
165
166 auto *CU =
167 std::upper_bound(begin(), end, CUOff->Offset,
168 [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
169 return LHS < RHS->getNextUnitOffset();
170 });
171 if (CU != end && (*CU)->getOffset() <= Offset)
172 return CU->get();
173
174 if (!Parser)
175 return nullptr;
176
177 auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
178 if (!U)
179 U = nullptr;
180
181 auto *NewCU = U.get();
182 this->insert(CU, std::move(U));
183 ++NumInfoUnits;
184 return NewCU;
185}
186
187DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
188 const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
189 const DWARFSection *RS, const DWARFSection *LocSection,
190 StringRef SS, const DWARFSection &SOS,
191 const DWARFSection *AOS, const DWARFSection &LS, bool LE,
192 bool IsDWO, const DWARFUnitVector &UnitVector)
193 : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
194 RangeSection(RS), LineSection(LS), StringSection(SS),
195 StringOffsetSection(SOS), AddrOffsetSection(AOS), IsLittleEndian(LE),
196 IsDWO(IsDWO), UnitVector(UnitVector) {
197 clear();
198}
199
200DWARFUnit::~DWARFUnit() = default;
201
202DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
203 return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, IsLittleEndian,
204 getAddressByteSize());
205}
206
207Optional<object::SectionedAddress>
208DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
209 if (!AddrOffsetSectionBase) {
210 auto R = Context.info_section_units();
211 // Surprising if a DWO file has more than one skeleton unit in it - this
212 // probably shouldn't be valid, but if a use case is found, here's where to
213 // support it (probably have to linearly search for the matching skeleton CU
214 // here)
215 if (IsDWO && hasSingleElement(R))
216 return (*R.begin())->getAddrOffsetSectionItem(Index);
217
218 return None;
219 }
220
221 uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize();
222 if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
223 return None;
224 DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
225 IsLittleEndian, getAddressByteSize());
226 uint64_t Section;
227 uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
228 return {{Address, Section}};
229}
230
231Expected<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
232 if (!StringOffsetsTableContribution)
233 return make_error<StringError>(
234 "DW_FORM_strx used without a valid string offsets table",
235 inconvertibleErrorCode());
236 unsigned ItemSize = getDwarfStringOffsetsByteSize();
237 uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
238 if (StringOffsetSection.Data.size() < Offset + ItemSize)
239 return make_error<StringError>("DW_FORM_strx uses index " + Twine(Index) +
240 ", which is too large",
241 inconvertibleErrorCode());
242 DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
243 IsLittleEndian, 0);
244 return DA.getRelocatedValue(ItemSize, &Offset);
245}
246
247bool DWARFUnitHeader::extract(DWARFContext &Context,
248 const DWARFDataExtractor &debug_info,
249 uint64_t *offset_ptr,
250 DWARFSectionKind SectionKind) {
251 Offset = *offset_ptr;
252 Error Err = Error::success();
253 IndexEntry = nullptr;
254 std::tie(Length, FormParams.Format) =
255 debug_info.getInitialLength(offset_ptr, &Err);
256 FormParams.Version = debug_info.getU16(offset_ptr, &Err);
257 if (FormParams.Version >= 5) {
258 UnitType = debug_info.getU8(offset_ptr, &Err);
259 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
260 AbbrOffset = debug_info.getRelocatedValue(
261 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
262 } else {
263 AbbrOffset = debug_info.getRelocatedValue(
264 FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
265 FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
266 // Fake a unit type based on the section type. This isn't perfect,
267 // but distinguishing compile and type units is generally enough.
268 if (SectionKind == DW_SECT_EXT_TYPES)
269 UnitType = DW_UT_type;
270 else
271 UnitType = DW_UT_compile;
272 }
273 if (isTypeUnit()) {
274 TypeHash = debug_info.getU64(offset_ptr, &Err);
275 TypeOffset = debug_info.getUnsigned(
276 offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
277 } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
278 DWOId = debug_info.getU64(offset_ptr, &Err);
279
280 if (Err) {
281 Context.getWarningHandler()(joinErrors(
282 createStringError(
283 errc::invalid_argument,
284 "DWARF unit at 0x%8.8" PRIx64"l" "x" " cannot be parsed:", Offset),
285 std::move(Err)));
286 return false;
287 }
288
289 // Header fields all parsed, capture the size of this unit header.
290 assert(*offset_ptr - Offset <= 255 && "unexpected header size")(static_cast <bool> (*offset_ptr - Offset <= 255 &&
"unexpected header size") ? void (0) : __assert_fail ("*offset_ptr - Offset <= 255 && \"unexpected header size\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 290, __extension__
__PRETTY_FUNCTION__))
;
291 Size = uint8_t(*offset_ptr - Offset);
292 uint64_t NextCUOffset = Offset + getUnitLengthFieldByteSize() + getLength();
293
294 if (!debug_info.isValidOffset(getNextUnitOffset() - 1)) {
295 Context.getWarningHandler()(
296 createStringError(errc::invalid_argument,
297 "DWARF unit from offset 0x%8.8" PRIx64"l" "x" " incl. "
298 "to offset 0x%8.8" PRIx64"l" "x" " excl. "
299 "extends past section size 0x%8.8zx",
300 Offset, NextCUOffset, debug_info.size()));
301 return false;
302 }
303
304 if (!DWARFContext::isSupportedVersion(getVersion())) {
305 Context.getWarningHandler()(createStringError(
306 errc::invalid_argument,
307 "DWARF unit at offset 0x%8.8" PRIx64"l" "x" " "
308 "has unsupported version %" PRIu16"u" ", supported are 2-%u",
309 Offset, getVersion(), DWARFContext::getMaxSupportedVersion()));
310 return false;
311 }
312
313 // Type offset is unit-relative; should be after the header and before
314 // the end of the current unit.
315 if (isTypeUnit() && TypeOffset < Size) {
316 Context.getWarningHandler()(
317 createStringError(errc::invalid_argument,
318 "DWARF type unit at offset "
319 "0x%8.8" PRIx64"l" "x" " "
320 "has its relocated type_offset 0x%8.8" PRIx64"l" "x" " "
321 "pointing inside the header",
322 Offset, Offset + TypeOffset));
323 return false;
324 }
325 if (isTypeUnit() &&
326 TypeOffset >= getUnitLengthFieldByteSize() + getLength()) {
327 Context.getWarningHandler()(createStringError(
328 errc::invalid_argument,
329 "DWARF type unit from offset 0x%8.8" PRIx64"l" "x" " incl. "
330 "to offset 0x%8.8" PRIx64"l" "x" " excl. has its "
331 "relocated type_offset 0x%8.8" PRIx64"l" "x" " pointing past the unit end",
332 Offset, NextCUOffset, Offset + TypeOffset));
333 return false;
334 }
335
336 if (Error SizeErr = DWARFContext::checkAddressSizeSupported(
337 getAddressByteSize(), errc::invalid_argument,
338 "DWARF unit at offset 0x%8.8" PRIx64"l" "x", Offset)) {
339 Context.getWarningHandler()(std::move(SizeErr));
340 return false;
341 }
342
343 // Keep track of the highest DWARF version we encounter across all units.
344 Context.setMaxVersionIfGreater(getVersion());
345 return true;
346}
347
348bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
349 assert(Entry)(static_cast <bool> (Entry) ? void (0) : __assert_fail (
"Entry", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 349, __extension__
__PRETTY_FUNCTION__))
;
350 assert(!IndexEntry)(static_cast <bool> (!IndexEntry) ? void (0) : __assert_fail
("!IndexEntry", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 350
, __extension__ __PRETTY_FUNCTION__))
;
351 IndexEntry = Entry;
352 if (AbbrOffset)
353 return false;
354 auto *UnitContrib = IndexEntry->getContribution();
355 if (!UnitContrib ||
356 UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
357 return false;
358 auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
359 if (!AbbrEntry)
360 return false;
361 AbbrOffset = AbbrEntry->Offset;
362 return true;
363}
364
365Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
366 DWARFDebugRangeList &RangeList) const {
367 // Require that compile unit is extracted.
368 assert(!DieArray.empty())(static_cast <bool> (!DieArray.empty()) ? void (0) : __assert_fail
("!DieArray.empty()", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 368, __extension__ __PRETTY_FUNCTION__))
;
369 DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
370 IsLittleEndian, getAddressByteSize());
371 uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
372 return RangeList.extract(RangesData, &ActualRangeListOffset);
373}
374
375void DWARFUnit::clear() {
376 Abbrevs = nullptr;
377 BaseAddr.reset();
378 RangeSectionBase = 0;
379 LocSectionBase = 0;
380 AddrOffsetSectionBase = None;
381 SU = nullptr;
382 clearDIEs(false);
383 AddrDieMap.clear();
384 if (DWO)
385 DWO->clear();
386 DWO.reset();
387}
388
389const char *DWARFUnit::getCompilationDir() {
390 return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
391}
392
393void DWARFUnit::extractDIEsToVector(
394 bool AppendCUDie, bool AppendNonCUDies,
395 std::vector<DWARFDebugInfoEntry> &Dies) const {
396 if (!AppendCUDie && !AppendNonCUDies)
397 return;
398
399 // Set the offset to that of the first DIE and calculate the start of the
400 // next compilation unit header.
401 uint64_t DIEOffset = getOffset() + getHeaderSize();
402 uint64_t NextCUOffset = getNextUnitOffset();
403 DWARFDebugInfoEntry DIE;
404 DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
405 // The end offset has been already checked by DWARFUnitHeader::extract.
406 assert(DebugInfoData.isValidOffset(NextCUOffset - 1))(static_cast <bool> (DebugInfoData.isValidOffset(NextCUOffset
- 1)) ? void (0) : __assert_fail ("DebugInfoData.isValidOffset(NextCUOffset - 1)"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 406, __extension__
__PRETTY_FUNCTION__))
;
407 std::vector<uint32_t> Parents;
408 std::vector<uint32_t> PrevSiblings;
409 bool IsCUDie = true;
410
411 assert((static_cast <bool> (((AppendCUDie && Dies.empty
()) || (!AppendCUDie && Dies.size() == 1)) &&
"Dies array is not empty") ? void (0) : __assert_fail ("((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) && \"Dies array is not empty\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 413, __extension__
__PRETTY_FUNCTION__))
412 ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&(static_cast <bool> (((AppendCUDie && Dies.empty
()) || (!AppendCUDie && Dies.size() == 1)) &&
"Dies array is not empty") ? void (0) : __assert_fail ("((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) && \"Dies array is not empty\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 413, __extension__
__PRETTY_FUNCTION__))
413 "Dies array is not empty")(static_cast <bool> (((AppendCUDie && Dies.empty
()) || (!AppendCUDie && Dies.size() == 1)) &&
"Dies array is not empty") ? void (0) : __assert_fail ("((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) && \"Dies array is not empty\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 413, __extension__
__PRETTY_FUNCTION__))
;
414
415 // Fill Parents and Siblings stacks with initial value.
416 Parents.push_back(UINT32_MAX(4294967295U));
417 if (!AppendCUDie)
418 Parents.push_back(0);
419 PrevSiblings.push_back(0);
420
421 // Start to extract dies.
422 do {
423 assert(Parents.size() > 0 && "Empty parents stack")(static_cast <bool> (Parents.size() > 0 && "Empty parents stack"
) ? void (0) : __assert_fail ("Parents.size() > 0 && \"Empty parents stack\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 423, __extension__
__PRETTY_FUNCTION__))
;
424 assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&(static_cast <bool> ((Parents.back() == (4294967295U) ||
Parents.back() <= Dies.size()) && "Wrong parent index"
) ? void (0) : __assert_fail ("(Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) && \"Wrong parent index\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 425, __extension__
__PRETTY_FUNCTION__))
425 "Wrong parent index")(static_cast <bool> ((Parents.back() == (4294967295U) ||
Parents.back() <= Dies.size()) && "Wrong parent index"
) ? void (0) : __assert_fail ("(Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) && \"Wrong parent index\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 425, __extension__
__PRETTY_FUNCTION__))
;
426
427 // Extract die. Stop if any error occurred.
428 if (!DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
429 Parents.back()))
430 break;
431
432 // If previous sibling is remembered then update it`s SiblingIdx field.
433 if (PrevSiblings.back() > 0) {
434 assert(PrevSiblings.back() < Dies.size() &&(static_cast <bool> (PrevSiblings.back() < Dies.size
() && "Previous sibling index is out of Dies boundaries"
) ? void (0) : __assert_fail ("PrevSiblings.back() < Dies.size() && \"Previous sibling index is out of Dies boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 435, __extension__
__PRETTY_FUNCTION__))
435 "Previous sibling index is out of Dies boundaries")(static_cast <bool> (PrevSiblings.back() < Dies.size
() && "Previous sibling index is out of Dies boundaries"
) ? void (0) : __assert_fail ("PrevSiblings.back() < Dies.size() && \"Previous sibling index is out of Dies boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 435, __extension__
__PRETTY_FUNCTION__))
;
436 Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());
437 }
438
439 // Store die into the Dies vector.
440 if (IsCUDie) {
441 if (AppendCUDie)
442 Dies.push_back(DIE);
443 if (!AppendNonCUDies)
444 break;
445 // The average bytes per DIE entry has been seen to be
446 // around 14-20 so let's pre-reserve the needed memory for
447 // our DIE entries accordingly.
448 Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
449 } else {
450 // Remember last previous sibling.
451 PrevSiblings.back() = Dies.size();
452
453 Dies.push_back(DIE);
454 }
455
456 // Check for new children scope.
457 if (const DWARFAbbreviationDeclaration *AbbrDecl =
458 DIE.getAbbreviationDeclarationPtr()) {
459 if (AbbrDecl->hasChildren()) {
460 if (AppendCUDie || !IsCUDie) {
461 assert(Dies.size() > 0 && "Dies does not contain any die")(static_cast <bool> (Dies.size() > 0 && "Dies does not contain any die"
) ? void (0) : __assert_fail ("Dies.size() > 0 && \"Dies does not contain any die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 461, __extension__
__PRETTY_FUNCTION__))
;
462 Parents.push_back(Dies.size() - 1);
463 PrevSiblings.push_back(0);
464 }
465 } else if (IsCUDie)
466 // Stop if we have single compile unit die w/o children.
467 break;
468 } else {
469 // NULL DIE: finishes current children scope.
470 Parents.pop_back();
471 PrevSiblings.pop_back();
472 }
473
474 if (IsCUDie)
475 IsCUDie = false;
476
477 // Stop when compile unit die is removed from the parents stack.
478 } while (Parents.size() > 1);
479}
480
481void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
482 if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
483 Context.getRecoverableErrorHandler()(std::move(e));
484}
485
486Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
487 if ((CUDieOnly && !DieArray.empty()) ||
488 DieArray.size() > 1)
489 return Error::success(); // Already parsed.
490
491 bool HasCUDie = !DieArray.empty();
492 extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
493
494 if (DieArray.empty())
495 return Error::success();
496
497 // If CU DIE was just parsed, copy several attribute values from it.
498 if (HasCUDie)
499 return Error::success();
500
501 DWARFDie UnitDie(this, &DieArray[0]);
502 if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
503 Header.setDWOId(*DWOId);
504 if (!IsDWO) {
505 assert(AddrOffsetSectionBase == None)(static_cast <bool> (AddrOffsetSectionBase == None) ? void
(0) : __assert_fail ("AddrOffsetSectionBase == None", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 505, __extension__ __PRETTY_FUNCTION__))
;
506 assert(RangeSectionBase == 0)(static_cast <bool> (RangeSectionBase == 0) ? void (0) :
__assert_fail ("RangeSectionBase == 0", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 506, __extension__ __PRETTY_FUNCTION__))
;
507 assert(LocSectionBase == 0)(static_cast <bool> (LocSectionBase == 0) ? void (0) : __assert_fail
("LocSectionBase == 0", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 507, __extension__ __PRETTY_FUNCTION__))
;
508 AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
509 if (!AddrOffsetSectionBase)
510 AddrOffsetSectionBase =
511 toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
512 RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
513 LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
514 }
515
516 // In general, in DWARF v5 and beyond we derive the start of the unit's
517 // contribution to the string offsets table from the unit DIE's
518 // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
519 // attribute, so we assume that there is a contribution to the string
520 // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
521 // In both cases we need to determine the format of the contribution,
522 // which may differ from the unit's format.
523 DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
524 IsLittleEndian, 0);
525 if (IsDWO || getVersion() >= 5) {
526 auto StringOffsetOrError =
527 IsDWO ? determineStringOffsetsTableContributionDWO(DA)
528 : determineStringOffsetsTableContribution(DA);
529 if (!StringOffsetOrError)
530 return createStringError(errc::invalid_argument,
531 "invalid reference to or invalid content in "
532 ".debug_str_offsets[.dwo]: " +
533 toString(StringOffsetOrError.takeError()));
534
535 StringOffsetsTableContribution = *StringOffsetOrError;
536 }
537
538 // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
539 // describe address ranges.
540 if (getVersion() >= 5) {
541 // In case of DWP, the base offset from the index has to be added.
542 if (IsDWO) {
543 uint64_t ContributionBaseOffset = 0;
544 if (auto *IndexEntry = Header.getIndexEntry())
545 if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
546 ContributionBaseOffset = Contrib->Offset;
547 setRangesSection(
548 &Context.getDWARFObj().getRnglistsDWOSection(),
549 ContributionBaseOffset +
550 DWARFListTableHeader::getHeaderSize(Header.getFormat()));
551 } else
552 setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
553 toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
554 DWARFListTableHeader::getHeaderSize(
555 Header.getFormat())));
556 }
557
558 if (IsDWO) {
559 // If we are reading a package file, we need to adjust the location list
560 // data based on the index entries.
561 StringRef Data = Header.getVersion() >= 5
562 ? Context.getDWARFObj().getLoclistsDWOSection().Data
563 : Context.getDWARFObj().getLocDWOSection().Data;
564 if (auto *IndexEntry = Header.getIndexEntry())
565 if (const auto *C = IndexEntry->getContribution(
566 Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
567 Data = Data.substr(C->Offset, C->Length);
568
569 DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize());
570 LocTable =
571 std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
572 LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
573 } else if (getVersion() >= 5) {
574 LocTable = std::make_unique<DWARFDebugLoclists>(
575 DWARFDataExtractor(Context.getDWARFObj(),
576 Context.getDWARFObj().getLoclistsSection(),
577 IsLittleEndian, getAddressByteSize()),
578 getVersion());
579 } else {
580 LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
581 Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
582 IsLittleEndian, getAddressByteSize()));
583 }
584
585 // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
586 // skeleton CU DIE, so that DWARF users not aware of it are not broken.
587 return Error::success();
588}
589
590bool DWARFUnit::parseDWO() {
591 if (IsDWO)
592 return false;
593 if (DWO.get())
594 return false;
595 DWARFDie UnitDie = getUnitDIE();
596 if (!UnitDie)
597 return false;
598 auto DWOFileName = getVersion() >= 5
599 ? dwarf::toString(UnitDie.find(DW_AT_dwo_name))
600 : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
601 if (!DWOFileName)
602 return false;
603 auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
604 SmallString<16> AbsolutePath;
605 if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
606 *CompilationDir) {
607 sys::path::append(AbsolutePath, *CompilationDir);
608 }
609 sys::path::append(AbsolutePath, *DWOFileName);
610 auto DWOId = getDWOId();
611 if (!DWOId)
612 return false;
613 auto DWOContext = Context.getDWOContext(AbsolutePath);
614 if (!DWOContext)
615 return false;
616
617 DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
618 if (!DWOCU)
619 return false;
620 DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
621 DWO->setSkeletonUnit(this);
622 // Share .debug_addr and .debug_ranges section with compile unit in .dwo
623 if (AddrOffsetSectionBase)
624 DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
625 if (getVersion() == 4) {
626 auto DWORangesBase = UnitDie.getRangesBaseAttribute();
627 DWO->setRangesSection(RangeSection, DWORangesBase.value_or(0));
628 }
629
630 return true;
631}
632
633void DWARFUnit::clearDIEs(bool KeepCUDie) {
634 // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
635 // shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
636 // It depends on the implementation whether the request is fulfilled.
637 // Create a new vector with a small capacity and assign it to the DieArray to
638 // have previous contents freed.
639 DieArray = (KeepCUDie && !DieArray.empty())
640 ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
641 : std::vector<DWARFDebugInfoEntry>();
642}
643
644Expected<DWARFAddressRangesVector>
645DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
646 if (getVersion() <= 4) {
647 DWARFDebugRangeList RangeList;
648 if (Error E = extractRangeList(Offset, RangeList))
649 return std::move(E);
650 return RangeList.getAbsoluteRanges(getBaseAddress());
651 }
652 DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
653 IsLittleEndian, Header.getAddressByteSize());
654 DWARFDebugRnglistTable RnglistTable;
655 auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
656 if (RangeListOrError)
657 return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
658 return RangeListOrError.takeError();
659}
660
661Expected<DWARFAddressRangesVector>
662DWARFUnit::findRnglistFromIndex(uint32_t Index) {
663 if (auto Offset = getRnglistOffset(Index))
664 return findRnglistFromOffset(*Offset);
665
666 return createStringError(errc::invalid_argument,
667 "invalid range list table index %d (possibly "
668 "missing the entire range list table)",
669 Index);
670}
671
672Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
673 DWARFDie UnitDie = getUnitDIE();
674 if (!UnitDie)
675 return createStringError(errc::invalid_argument, "No unit DIE");
676
677 // First, check if unit DIE describes address ranges for the whole unit.
678 auto CUDIERangesOrError = UnitDie.getAddressRanges();
679 if (!CUDIERangesOrError)
680 return createStringError(errc::invalid_argument,
681 "decoding address ranges: %s",
682 toString(CUDIERangesOrError.takeError()).c_str());
683 return *CUDIERangesOrError;
684}
685
686Expected<DWARFLocationExpressionsVector>
687DWARFUnit::findLoclistFromOffset(uint64_t Offset) {
688 DWARFLocationExpressionsVector Result;
689
690 Error InterpretationError = Error::success();
691
692 Error ParseError = getLocationTable().visitAbsoluteLocationList(
693 Offset, getBaseAddress(),
694 [this](uint32_t Index) { return getAddrOffsetSectionItem(Index); },
695 [&](Expected<DWARFLocationExpression> L) {
696 if (L)
697 Result.push_back(std::move(*L));
698 else
699 InterpretationError =
700 joinErrors(L.takeError(), std::move(InterpretationError));
701 return !InterpretationError;
702 });
703
704 if (ParseError || InterpretationError)
705 return joinErrors(std::move(ParseError), std::move(InterpretationError));
706
707 return Result;
708}
709
710void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
711 if (Die.isSubroutineDIE()) {
712 auto DIERangesOrError = Die.getAddressRanges();
713 if (DIERangesOrError) {
714 for (const auto &R : DIERangesOrError.get()) {
715 // Ignore 0-sized ranges.
716 if (R.LowPC == R.HighPC)
717 continue;
718 auto B = AddrDieMap.upper_bound(R.LowPC);
719 if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
720 // The range is a sub-range of existing ranges, we need to split the
721 // existing range.
722 if (R.HighPC < B->second.first)
723 AddrDieMap[R.HighPC] = B->second;
724 if (R.LowPC > B->first)
725 AddrDieMap[B->first].first = R.LowPC;
726 }
727 AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
728 }
729 } else
730 llvm::consumeError(DIERangesOrError.takeError());
731 }
732 // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
733 // simplify the logic to update AddrDieMap. The child's range will always
734 // be equal or smaller than the parent's range. With this assumption, when
735 // adding one range into the map, it will at most split a range into 3
736 // sub-ranges.
737 for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
738 updateAddressDieMap(Child);
739}
740
741DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
742 extractDIEsIfNeeded(false);
743 if (AddrDieMap.empty())
744 updateAddressDieMap(getUnitDIE());
745 auto R = AddrDieMap.upper_bound(Address);
746 if (R == AddrDieMap.begin())
747 return DWARFDie();
748 // upper_bound's previous item contains Address.
749 --R;
750 if (Address >= R->second.first)
751 return DWARFDie();
752 return R->second.second;
753}
754
755void DWARFUnit::updateVariableDieMap(DWARFDie Die) {
756 for (DWARFDie Child : Die) {
757 if (isType(Child.getTag()))
4
Assuming the condition is false
5
Taking false branch
7
Assuming the condition is false
8
Taking false branch
10
Assuming the condition is false
11
Taking false branch
758 continue;
759 updateVariableDieMap(Child);
6
Calling 'DWARFUnit::updateVariableDieMap'
9
Calling 'DWARFUnit::updateVariableDieMap'
12
Calling 'DWARFUnit::updateVariableDieMap'
760 }
761
762 if (Die.getTag() != DW_TAG_variable)
13
Assuming the condition is false
14
Taking false branch
763 return;
764
765 Expected<DWARFLocationExpressionsVector> Locations =
766 Die.getLocations(DW_AT_location);
767 if (!Locations) {
15
Taking false branch
768 // Missing DW_AT_location is fine here.
769 consumeError(Locations.takeError());
770 return;
771 }
772
773 uint64_t Address = UINT64_MAX(18446744073709551615UL);
774
775 for (const DWARFLocationExpression &Location : *Locations) {
776 uint8_t AddressSize = getAddressByteSize();
777 DataExtractor Data(Location.Expr, /*IsLittleEndian=*/true, AddressSize);
778 DWARFExpression Expr(Data, AddressSize);
779 auto It = Expr.begin();
780 if (It == Expr.end())
16
Assuming the condition is false
17
Taking false branch
781 continue;
782
783 // Match exactly the main sequence used to describe global variables:
784 // `DW_OP_addr[x] [+ DW_OP_plus_uconst]`. Currently, this is the sequence
785 // that LLVM produces for DILocalVariables and DIGlobalVariables. If, in
786 // future, the DWARF producer (`DwarfCompileUnit::addLocationAttribute()` is
787 // a good starting point) is extended to use further expressions, this code
788 // needs to be updated.
789 uint64_t LocationAddr;
18
'LocationAddr' declared without an initial value
790 if (It->getCode() == dwarf::DW_OP_addr) {
19
Assuming the condition is false
20
Taking false branch
791 LocationAddr = It->getRawOperand(0);
792 } else if (It->getCode() == dwarf::DW_OP_addrx) {
21
Assuming the condition is true
22
Taking true branch
793 uint64_t DebugAddrOffset = It->getRawOperand(0);
794 if (auto Pointer = getAddrOffsetSectionItem(DebugAddrOffset)) {
23
Assuming the condition is false
24
Taking false branch
795 LocationAddr = Pointer->Address;
796 }
797 } else {
798 continue;
799 }
800
801 // Read the optional 2nd operand, a DW_OP_plus_uconst.
802 if (++It != Expr.end()) {
25
Assuming the condition is true
26
Taking true branch
803 if (It->getCode() != dwarf::DW_OP_plus_uconst)
27
Assuming the condition is false
28
Taking false branch
804 continue;
805
806 LocationAddr += It->getRawOperand(0);
29
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
807
808 // Probe for a 3rd operand, if it exists, bail.
809 if (++It != Expr.end())
810 continue;
811 }
812
813 Address = LocationAddr;
814 break;
815 }
816
817 // Get the size of the global variable. If all else fails (i.e. the global has
818 // no type), then we use a size of one to still allow symbolization of the
819 // exact address.
820 uint64_t GVSize = 1;
821 if (DWARFDie BaseType = Die.getAttributeValueAsReferencedDie(DW_AT_type))
822 if (Optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize()))
823 GVSize = *Size;
824
825 if (Address != UINT64_MAX(18446744073709551615UL))
826 VariableDieMap[Address] = {Address + GVSize, Die};
827}
828
829DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
830 extractDIEsIfNeeded(false);
831
832 auto RootDie = getUnitDIE();
833
834 auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
835 if (RootLookup.second)
1
Assuming field 'second' is true
2
Taking true branch
836 updateVariableDieMap(RootDie);
3
Calling 'DWARFUnit::updateVariableDieMap'
837
838 auto R = VariableDieMap.upper_bound(Address);
839 if (R == VariableDieMap.begin())
840 return DWARFDie();
841
842 // upper_bound's previous item contains Address.
843 --R;
844 if (Address >= R->second.first)
845 return DWARFDie();
846 return R->second.second;
847}
848
849void
850DWARFUnit::getInlinedChainForAddress(uint64_t Address,
851 SmallVectorImpl<DWARFDie> &InlinedChain) {
852 assert(InlinedChain.empty())(static_cast <bool> (InlinedChain.empty()) ? void (0) :
__assert_fail ("InlinedChain.empty()", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 852, __extension__ __PRETTY_FUNCTION__))
;
853 // Try to look for subprogram DIEs in the DWO file.
854 parseDWO();
855 // First, find the subroutine that contains the given address (the leaf
856 // of inlined chain).
857 DWARFDie SubroutineDIE =
858 (DWO ? *DWO : *this).getSubroutineForAddress(Address);
859
860 while (SubroutineDIE) {
861 if (SubroutineDIE.isSubprogramDIE()) {
862 InlinedChain.push_back(SubroutineDIE);
863 return;
864 }
865 if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
866 InlinedChain.push_back(SubroutineDIE);
867 SubroutineDIE = SubroutineDIE.getParent();
868 }
869}
870
871const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
872 DWARFSectionKind Kind) {
873 if (Kind == DW_SECT_INFO)
874 return Context.getCUIndex();
875 assert(Kind == DW_SECT_EXT_TYPES)(static_cast <bool> (Kind == DW_SECT_EXT_TYPES) ? void (
0) : __assert_fail ("Kind == DW_SECT_EXT_TYPES", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp"
, 875, __extension__ __PRETTY_FUNCTION__))
;
876 return Context.getTUIndex();
877}
878
879DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
880 if (const DWARFDebugInfoEntry *Entry = getParentEntry(Die))
881 return DWARFDie(this, Entry);
882
883 return DWARFDie();
884}
885
886const DWARFDebugInfoEntry *
887DWARFUnit::getParentEntry(const DWARFDebugInfoEntry *Die) const {
888 if (!Die)
889 return nullptr;
890 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size())(static_cast <bool> (Die >= DieArray.data() &&
Die < DieArray.data() + DieArray.size()) ? void (0) : __assert_fail
("Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 890, __extension__
__PRETTY_FUNCTION__))
;
891
892 if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) {
893 assert(*ParentIdx < DieArray.size() &&(static_cast <bool> (*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*ParentIdx < DieArray.size() && \"ParentIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 894, __extension__
__PRETTY_FUNCTION__))
894 "ParentIdx is out of DieArray boundaries")(static_cast <bool> (*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*ParentIdx < DieArray.size() && \"ParentIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 894, __extension__
__PRETTY_FUNCTION__))
;
895 return getDebugInfoEntry(*ParentIdx);
896 }
897
898 return nullptr;
899}
900
901DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
902 if (const DWARFDebugInfoEntry *Sibling = getSiblingEntry(Die))
903 return DWARFDie(this, Sibling);
904
905 return DWARFDie();
906}
907
908const DWARFDebugInfoEntry *
909DWARFUnit::getSiblingEntry(const DWARFDebugInfoEntry *Die) const {
910 if (!Die)
911 return nullptr;
912 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size())(static_cast <bool> (Die >= DieArray.data() &&
Die < DieArray.data() + DieArray.size()) ? void (0) : __assert_fail
("Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 912, __extension__
__PRETTY_FUNCTION__))
;
913
914 if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
915 assert(*SiblingIdx < DieArray.size() &&(static_cast <bool> (*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*SiblingIdx < DieArray.size() && \"SiblingIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 916, __extension__
__PRETTY_FUNCTION__))
916 "SiblingIdx is out of DieArray boundaries")(static_cast <bool> (*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*SiblingIdx < DieArray.size() && \"SiblingIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 916, __extension__
__PRETTY_FUNCTION__))
;
917 return &DieArray[*SiblingIdx];
918 }
919
920 return nullptr;
921}
922
923DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
924 if (const DWARFDebugInfoEntry *Sibling = getPreviousSiblingEntry(Die))
925 return DWARFDie(this, Sibling);
926
927 return DWARFDie();
928}
929
930const DWARFDebugInfoEntry *
931DWARFUnit::getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const {
932 if (!Die)
933 return nullptr;
934 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size())(static_cast <bool> (Die >= DieArray.data() &&
Die < DieArray.data() + DieArray.size()) ? void (0) : __assert_fail
("Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 934, __extension__
__PRETTY_FUNCTION__))
;
935
936 Optional<uint32_t> ParentIdx = Die->getParentIdx();
937 if (!ParentIdx)
938 // Die is a root die, there is no previous sibling.
939 return nullptr;
940
941 assert(*ParentIdx < DieArray.size() &&(static_cast <bool> (*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*ParentIdx < DieArray.size() && \"ParentIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 942, __extension__
__PRETTY_FUNCTION__))
942 "ParentIdx is out of DieArray boundaries")(static_cast <bool> (*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*ParentIdx < DieArray.size() && \"ParentIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 942, __extension__
__PRETTY_FUNCTION__))
;
943 assert(getDIEIndex(Die) > 0 && "Die is a root die")(static_cast <bool> (getDIEIndex(Die) > 0 &&
"Die is a root die") ? void (0) : __assert_fail ("getDIEIndex(Die) > 0 && \"Die is a root die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 943, __extension__
__PRETTY_FUNCTION__))
;
944
945 uint32_t PrevDieIdx = getDIEIndex(Die) - 1;
946 if (PrevDieIdx == *ParentIdx)
947 // Immediately previous node is parent, there is no previous sibling.
948 return nullptr;
949
950 while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
951 PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
952
953 assert(PrevDieIdx < DieArray.size() &&(static_cast <bool> (PrevDieIdx < DieArray.size() &&
"PrevDieIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("PrevDieIdx < DieArray.size() && \"PrevDieIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 954, __extension__
__PRETTY_FUNCTION__))
954 "PrevDieIdx is out of DieArray boundaries")(static_cast <bool> (PrevDieIdx < DieArray.size() &&
"PrevDieIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("PrevDieIdx < DieArray.size() && \"PrevDieIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 954, __extension__
__PRETTY_FUNCTION__))
;
955 assert(PrevDieIdx >= *ParentIdx &&(static_cast <bool> (PrevDieIdx >= *ParentIdx &&
"PrevDieIdx is not a child of parent of Die") ? void (0) : __assert_fail
("PrevDieIdx >= *ParentIdx && \"PrevDieIdx is not a child of parent of Die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 956, __extension__
__PRETTY_FUNCTION__))
956 "PrevDieIdx is not a child of parent of Die")(static_cast <bool> (PrevDieIdx >= *ParentIdx &&
"PrevDieIdx is not a child of parent of Die") ? void (0) : __assert_fail
("PrevDieIdx >= *ParentIdx && \"PrevDieIdx is not a child of parent of Die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 956, __extension__
__PRETTY_FUNCTION__))
;
957 }
958
959 return &DieArray[PrevDieIdx];
960}
961
962DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
963 if (const DWARFDebugInfoEntry *Child = getFirstChildEntry(Die))
964 return DWARFDie(this, Child);
965
966 return DWARFDie();
967}
968
969const DWARFDebugInfoEntry *
970DWARFUnit::getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {
971 if (!Die)
972 return nullptr;
973 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size())(static_cast <bool> (Die >= DieArray.data() &&
Die < DieArray.data() + DieArray.size()) ? void (0) : __assert_fail
("Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 973, __extension__
__PRETTY_FUNCTION__))
;
974
975 if (!Die->hasChildren())
976 return nullptr;
977
978 // TODO: Instead of checking here for invalid die we might reject
979 // invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
980 // We do not want access out of bounds when parsing corrupted debug data.
981 size_t I = getDIEIndex(Die) + 1;
982 if (I >= DieArray.size())
983 return nullptr;
984 return &DieArray[I];
985}
986
987DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
988 if (const DWARFDebugInfoEntry *Child = getLastChildEntry(Die))
989 return DWARFDie(this, Child);
990
991 return DWARFDie();
992}
993
994const DWARFDebugInfoEntry *
995DWARFUnit::getLastChildEntry(const DWARFDebugInfoEntry *Die) const {
996 if (!Die)
997 return nullptr;
998 assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size())(static_cast <bool> (Die >= DieArray.data() &&
Die < DieArray.data() + DieArray.size()) ? void (0) : __assert_fail
("Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()"
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 998, __extension__
__PRETTY_FUNCTION__))
;
999
1000 if (!Die->hasChildren())
1001 return nullptr;
1002
1003 if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
1004 assert(*SiblingIdx < DieArray.size() &&(static_cast <bool> (*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*SiblingIdx < DieArray.size() && \"SiblingIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1005, __extension__
__PRETTY_FUNCTION__))
1005 "SiblingIdx is out of DieArray boundaries")(static_cast <bool> (*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries") ? void (0) : __assert_fail
("*SiblingIdx < DieArray.size() && \"SiblingIdx is out of DieArray boundaries\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1005, __extension__
__PRETTY_FUNCTION__))
;
1006 assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&(static_cast <bool> (DieArray[*SiblingIdx - 1].getTag()
== dwarf::DW_TAG_null && "Bad end of children marker"
) ? void (0) : __assert_fail ("DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null && \"Bad end of children marker\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1007, __extension__
__PRETTY_FUNCTION__))
1007 "Bad end of children marker")(static_cast <bool> (DieArray[*SiblingIdx - 1].getTag()
== dwarf::DW_TAG_null && "Bad end of children marker"
) ? void (0) : __assert_fail ("DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null && \"Bad end of children marker\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1007, __extension__
__PRETTY_FUNCTION__))
;
1008 return &DieArray[*SiblingIdx - 1];
1009 }
1010
1011 // If SiblingIdx is set for non-root dies we could be sure that DWARF is
1012 // correct and "end of children marker" must be found. For root die we do not
1013 // have such a guarantee(parsing root die might be stopped if "end of children
1014 // marker" is missing, SiblingIdx is always zero for root die). That is why we
1015 // do not use assertion for checking for "end of children marker" for root
1016 // die.
1017
1018 // TODO: Instead of checking here for invalid die we might reject
1019 // invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
1020 if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
1021 DieArray.back().getTag() == dwarf::DW_TAG_null) {
1022 // For the unit die we might take last item from DieArray.
1023 assert(getDIEIndex(Die) ==(static_cast <bool> (getDIEIndex(Die) == getDIEIndex(const_cast
<DWARFUnit *>(this)->getUnitDIE()) && "Bad unit die"
) ? void (0) : __assert_fail ("getDIEIndex(Die) == getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) && \"Bad unit die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1025, __extension__
__PRETTY_FUNCTION__))
1024 getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) &&(static_cast <bool> (getDIEIndex(Die) == getDIEIndex(const_cast
<DWARFUnit *>(this)->getUnitDIE()) && "Bad unit die"
) ? void (0) : __assert_fail ("getDIEIndex(Die) == getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) && \"Bad unit die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1025, __extension__
__PRETTY_FUNCTION__))
1025 "Bad unit die")(static_cast <bool> (getDIEIndex(Die) == getDIEIndex(const_cast
<DWARFUnit *>(this)->getUnitDIE()) && "Bad unit die"
) ? void (0) : __assert_fail ("getDIEIndex(Die) == getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) && \"Bad unit die\""
, "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1025, __extension__
__PRETTY_FUNCTION__))
;
1026 return &DieArray.back();
1027 }
1028
1029 return nullptr;
1030}
1031
1032const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
1033 if (!Abbrevs)
1034 Abbrevs = Abbrev->getAbbreviationDeclarationSet(getAbbreviationsOffset());
1035 return Abbrevs;
1036}
1037
1038llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
1039 if (BaseAddr)
1040 return BaseAddr;
1041
1042 DWARFDie UnitDie = getUnitDIE();
1043 Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
1044 BaseAddr = toSectionedAddress(PC);
1045 return BaseAddr;
1046}
1047
1048Expected<StrOffsetsContributionDescriptor>
1049StrOffsetsContributionDescriptor::validateContributionSize(
1050 DWARFDataExtractor &DA) {
1051 uint8_t EntrySize = getDwarfOffsetByteSize();
1052 // In order to ensure that we don't read a partial record at the end of
1053 // the section we validate for a multiple of the entry size.
1054 uint64_t ValidationSize = alignTo(Size, EntrySize);
1055 // Guard against overflow.
1056 if (ValidationSize >= Size)
1057 if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
1058 return *this;
1059 return createStringError(errc::invalid_argument, "length exceeds section size");
1060}
1061
1062// Look for a DWARF64-formatted contribution to the string offsets table
1063// starting at a given offset and record it in a descriptor.
1064static Expected<StrOffsetsContributionDescriptor>
1065parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
1066 if (!DA.isValidOffsetForDataOfSize(Offset, 16))
1067 return createStringError(errc::invalid_argument, "section offset exceeds section size");
1068
1069 if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
1070 return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
1071
1072 uint64_t Size = DA.getU64(&Offset);
1073 uint8_t Version = DA.getU16(&Offset);
1074 (void)DA.getU16(&Offset); // padding
1075 // The encoded length includes the 2-byte version field and the 2-byte
1076 // padding, so we need to subtract them out when we populate the descriptor.
1077 return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
1078}
1079
1080// Look for a DWARF32-formatted contribution to the string offsets table
1081// starting at a given offset and record it in a descriptor.
1082static Expected<StrOffsetsContributionDescriptor>
1083parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
1084 if (!DA.isValidOffsetForDataOfSize(Offset, 8))
1085 return createStringError(errc::invalid_argument, "section offset exceeds section size");
1086
1087 uint32_t ContributionSize = DA.getU32(&Offset);
1088 if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
1089 return createStringError(errc::invalid_argument, "invalid length");
1090
1091 uint8_t Version = DA.getU16(&Offset);
1092 (void)DA.getU16(&Offset); // padding
1093 // The encoded length includes the 2-byte version field and the 2-byte
1094 // padding, so we need to subtract them out when we populate the descriptor.
1095 return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
1096 DWARF32);
1097}
1098
1099static Expected<StrOffsetsContributionDescriptor>
1100parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
1101 llvm::dwarf::DwarfFormat Format,
1102 uint64_t Offset) {
1103 StrOffsetsContributionDescriptor Desc;
1104 switch (Format) {
1105 case dwarf::DwarfFormat::DWARF64: {
1106 if (Offset < 16)
1107 return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
1108 auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16);
1109 if (!DescOrError)
1110 return DescOrError.takeError();
1111 Desc = *DescOrError;
1112 break;
1113 }
1114 case dwarf::DwarfFormat::DWARF32: {
1115 if (Offset < 8)
1116 return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
1117 auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8);
1118 if (!DescOrError)
1119 return DescOrError.takeError();
1120 Desc = *DescOrError;
1121 break;
1122 }
1123 }
1124 return Desc.validateContributionSize(DA);
1125}
1126
1127Expected<Optional<StrOffsetsContributionDescriptor>>
1128DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
1129 assert(!IsDWO)(static_cast <bool> (!IsDWO) ? void (0) : __assert_fail
("!IsDWO", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1129, __extension__
__PRETTY_FUNCTION__))
;
1130 auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
1131 if (!OptOffset)
1132 return None;
1133 auto DescOrError =
1134 parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset);
1135 if (!DescOrError)
1136 return DescOrError.takeError();
1137 return *DescOrError;
1138}
1139
1140Expected<Optional<StrOffsetsContributionDescriptor>>
1141DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
1142 assert(IsDWO)(static_cast <bool> (IsDWO) ? void (0) : __assert_fail (
"IsDWO", "llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp", 1142, __extension__
__PRETTY_FUNCTION__))
;
1143 uint64_t Offset = 0;
1144 auto IndexEntry = Header.getIndexEntry();
1145 const auto *C =
1146 IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
1147 if (C)
1148 Offset = C->Offset;
1149 if (getVersion() >= 5) {
1150 if (DA.getData().data() == nullptr)
1151 return None;
1152 Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
1153 // Look for a valid contribution at the given offset.
1154 auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
1155 if (!DescOrError)
1156 return DescOrError.takeError();
1157 return *DescOrError;
1158 }
1159 // Prior to DWARF v5, we derive the contribution size from the
1160 // index table (in a package file). In a .dwo file it is simply
1161 // the length of the string offsets section.
1162 StrOffsetsContributionDescriptor Desc;
1163 if (C)
1164 Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
1165 Header.getFormat());
1166 else if (!IndexEntry && !StringOffsetSection.Data.empty())
1167 Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
1168 4, Header.getFormat());
1169 else
1170 return None;
1171 auto DescOrError = Desc.validateContributionSize(DA);
1172 if (!DescOrError)
1173 return DescOrError.takeError();
1174 return *DescOrError;
1175}
1176
1177Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
1178 DataExtractor RangesData(RangeSection->Data, IsLittleEndian,
1179 getAddressByteSize());
1180 DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
1181 IsLittleEndian, 0);
1182 if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
1183 RangesData, RangeSectionBase, getFormat(), Index))
1184 return *Off + RangeSectionBase;
1185 return None;
1186}
1187
1188Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
1189 if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
1190 LocTable->getData(), LocSectionBase, getFormat(), Index))
1191 return *Off + LocSectionBase;
1192 return None;
1193}