DWARFUnit.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  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. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  9. #include "llvm/ADT/SmallString.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
  13. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
  15. #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
  17. #include "llvm/DebugInfo/DWARF/DWARFDie.h"
  18. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
  20. #include "llvm/Support/DataExtractor.h"
  21. #include "llvm/Support/Errc.h"
  22. #include "llvm/Support/Path.h"
  23. #include <algorithm>
  24. #include <cassert>
  25. #include <cstddef>
  26. #include <cstdint>
  27. #include <cstdio>
  28. #include <utility>
  29. #include <vector>
  30. using namespace llvm;
  31. using namespace dwarf;
  32. void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
  33. const DWARFSection &Section,
  34. DWARFSectionKind SectionKind) {
  35. const DWARFObject &D = C.getDWARFObj();
  36. addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
  37. &D.getLocSection(), D.getStrSection(),
  38. D.getStrOffsetsSection(), &D.getAddrSection(),
  39. D.getLineSection(), D.isLittleEndian(), false, false,
  40. SectionKind);
  41. }
  42. void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
  43. const DWARFSection &DWOSection,
  44. DWARFSectionKind SectionKind,
  45. bool Lazy) {
  46. const DWARFObject &D = C.getDWARFObj();
  47. addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
  48. &D.getLocDWOSection(), D.getStrDWOSection(),
  49. D.getStrOffsetsDWOSection(), &D.getAddrSection(),
  50. D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
  51. SectionKind);
  52. }
  53. void DWARFUnitVector::addUnitsImpl(
  54. DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
  55. const DWARFDebugAbbrev *DA, const DWARFSection *RS,
  56. const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
  57. const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
  58. bool Lazy, DWARFSectionKind SectionKind) {
  59. DWARFDataExtractor Data(Obj, Section, LE, 0);
  60. // Lazy initialization of Parser, now that we have all section info.
  61. if (!Parser) {
  62. Parser = [=, &Context, &Obj, &Section, &SOS,
  63. &LS](uint64_t Offset, DWARFSectionKind SectionKind,
  64. const DWARFSection *CurSection,
  65. const DWARFUnitIndex::Entry *IndexEntry)
  66. -> std::unique_ptr<DWARFUnit> {
  67. const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
  68. DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
  69. if (!Data.isValidOffset(Offset))
  70. return nullptr;
  71. DWARFUnitHeader Header;
  72. if (!Header.extract(Context, Data, &Offset, SectionKind))
  73. return nullptr;
  74. if (!IndexEntry && IsDWO) {
  75. const DWARFUnitIndex &Index = getDWARFUnitIndex(
  76. Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
  77. IndexEntry = Index.getFromOffset(Header.getOffset());
  78. }
  79. if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
  80. return nullptr;
  81. std::unique_ptr<DWARFUnit> U;
  82. if (Header.isTypeUnit())
  83. U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
  84. RS, LocSection, SS, SOS, AOS, LS,
  85. LE, IsDWO, *this);
  86. else
  87. U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
  88. DA, RS, LocSection, SS, SOS,
  89. AOS, LS, LE, IsDWO, *this);
  90. return U;
  91. };
  92. }
  93. if (Lazy)
  94. return;
  95. // Find a reasonable insertion point within the vector. We skip over
  96. // (a) units from a different section, (b) units from the same section
  97. // but with lower offset-within-section. This keeps units in order
  98. // within a section, although not necessarily within the object file,
  99. // even if we do lazy parsing.
  100. auto I = this->begin();
  101. uint64_t Offset = 0;
  102. while (Data.isValidOffset(Offset)) {
  103. if (I != this->end() &&
  104. (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
  105. ++I;
  106. continue;
  107. }
  108. auto U = Parser(Offset, SectionKind, &Section, nullptr);
  109. // If parsing failed, we're done with this section.
  110. if (!U)
  111. break;
  112. Offset = U->getNextUnitOffset();
  113. I = std::next(this->insert(I, std::move(U)));
  114. }
  115. }
  116. DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
  117. auto I = std::upper_bound(begin(), end(), Unit,
  118. [](const std::unique_ptr<DWARFUnit> &LHS,
  119. const std::unique_ptr<DWARFUnit> &RHS) {
  120. return LHS->getOffset() < RHS->getOffset();
  121. });
  122. return this->insert(I, std::move(Unit))->get();
  123. }
  124. DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
  125. auto end = begin() + getNumInfoUnits();
  126. auto *CU =
  127. std::upper_bound(begin(), end, Offset,
  128. [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
  129. return LHS < RHS->getNextUnitOffset();
  130. });
  131. if (CU != end && (*CU)->getOffset() <= Offset)
  132. return CU->get();
  133. return nullptr;
  134. }
  135. DWARFUnit *
  136. DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
  137. const auto *CUOff = E.getContribution(DW_SECT_INFO);
  138. if (!CUOff)
  139. return nullptr;
  140. auto Offset = CUOff->Offset;
  141. auto end = begin() + getNumInfoUnits();
  142. auto *CU =
  143. std::upper_bound(begin(), end, CUOff->Offset,
  144. [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
  145. return LHS < RHS->getNextUnitOffset();
  146. });
  147. if (CU != end && (*CU)->getOffset() <= Offset)
  148. return CU->get();
  149. if (!Parser)
  150. return nullptr;
  151. auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
  152. if (!U)
  153. U = nullptr;
  154. auto *NewCU = U.get();
  155. this->insert(CU, std::move(U));
  156. ++NumInfoUnits;
  157. return NewCU;
  158. }
  159. DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
  160. const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
  161. const DWARFSection *RS, const DWARFSection *LocSection,
  162. StringRef SS, const DWARFSection &SOS,
  163. const DWARFSection *AOS, const DWARFSection &LS, bool LE,
  164. bool IsDWO, const DWARFUnitVector &UnitVector)
  165. : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
  166. RangeSection(RS), LineSection(LS), StringSection(SS),
  167. StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
  168. IsDWO(IsDWO), UnitVector(UnitVector) {
  169. clear();
  170. }
  171. DWARFUnit::~DWARFUnit() = default;
  172. DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
  173. return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
  174. getAddressByteSize());
  175. }
  176. Optional<object::SectionedAddress>
  177. DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
  178. if (!AddrOffsetSectionBase) {
  179. auto R = Context.info_section_units();
  180. // Surprising if a DWO file has more than one skeleton unit in it - this
  181. // probably shouldn't be valid, but if a use case is found, here's where to
  182. // support it (probably have to linearly search for the matching skeleton CU
  183. // here)
  184. if (IsDWO && hasSingleElement(R))
  185. return (*R.begin())->getAddrOffsetSectionItem(Index);
  186. return None;
  187. }
  188. uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize();
  189. if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
  190. return None;
  191. DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
  192. isLittleEndian, getAddressByteSize());
  193. uint64_t Section;
  194. uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
  195. return {{Address, Section}};
  196. }
  197. Expected<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
  198. if (!StringOffsetsTableContribution)
  199. return make_error<StringError>(
  200. "DW_FORM_strx used without a valid string offsets table",
  201. inconvertibleErrorCode());
  202. unsigned ItemSize = getDwarfStringOffsetsByteSize();
  203. uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
  204. if (StringOffsetSection.Data.size() < Offset + ItemSize)
  205. return make_error<StringError>("DW_FORM_strx uses index " + Twine(Index) +
  206. ", which is too large",
  207. inconvertibleErrorCode());
  208. DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
  209. isLittleEndian, 0);
  210. return DA.getRelocatedValue(ItemSize, &Offset);
  211. }
  212. bool DWARFUnitHeader::extract(DWARFContext &Context,
  213. const DWARFDataExtractor &debug_info,
  214. uint64_t *offset_ptr,
  215. DWARFSectionKind SectionKind) {
  216. Offset = *offset_ptr;
  217. Error Err = Error::success();
  218. IndexEntry = nullptr;
  219. std::tie(Length, FormParams.Format) =
  220. debug_info.getInitialLength(offset_ptr, &Err);
  221. FormParams.Version = debug_info.getU16(offset_ptr, &Err);
  222. if (FormParams.Version >= 5) {
  223. UnitType = debug_info.getU8(offset_ptr, &Err);
  224. FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
  225. AbbrOffset = debug_info.getRelocatedValue(
  226. FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
  227. } else {
  228. AbbrOffset = debug_info.getRelocatedValue(
  229. FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
  230. FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
  231. // Fake a unit type based on the section type. This isn't perfect,
  232. // but distinguishing compile and type units is generally enough.
  233. if (SectionKind == DW_SECT_EXT_TYPES)
  234. UnitType = DW_UT_type;
  235. else
  236. UnitType = DW_UT_compile;
  237. }
  238. if (isTypeUnit()) {
  239. TypeHash = debug_info.getU64(offset_ptr, &Err);
  240. TypeOffset = debug_info.getUnsigned(
  241. offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
  242. } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
  243. DWOId = debug_info.getU64(offset_ptr, &Err);
  244. if (Err) {
  245. Context.getWarningHandler()(joinErrors(
  246. createStringError(
  247. errc::invalid_argument,
  248. "DWARF unit at 0x%8.8" PRIx64 " cannot be parsed:", Offset),
  249. std::move(Err)));
  250. return false;
  251. }
  252. // Header fields all parsed, capture the size of this unit header.
  253. assert(*offset_ptr - Offset <= 255 && "unexpected header size");
  254. Size = uint8_t(*offset_ptr - Offset);
  255. uint64_t NextCUOffset = Offset + getUnitLengthFieldByteSize() + getLength();
  256. if (!debug_info.isValidOffset(getNextUnitOffset() - 1)) {
  257. Context.getWarningHandler()(
  258. createStringError(errc::invalid_argument,
  259. "DWARF unit from offset 0x%8.8" PRIx64 " incl. "
  260. "to offset 0x%8.8" PRIx64 " excl. "
  261. "extends past section size 0x%8.8zx",
  262. Offset, NextCUOffset, debug_info.size()));
  263. return false;
  264. }
  265. if (!DWARFContext::isSupportedVersion(getVersion())) {
  266. Context.getWarningHandler()(createStringError(
  267. errc::invalid_argument,
  268. "DWARF unit at offset 0x%8.8" PRIx64 " "
  269. "has unsupported version %" PRIu16 ", supported are 2-%u",
  270. Offset, getVersion(), DWARFContext::getMaxSupportedVersion()));
  271. return false;
  272. }
  273. // Type offset is unit-relative; should be after the header and before
  274. // the end of the current unit.
  275. if (isTypeUnit() && TypeOffset < Size) {
  276. Context.getWarningHandler()(
  277. createStringError(errc::invalid_argument,
  278. "DWARF type unit at offset "
  279. "0x%8.8" PRIx64 " "
  280. "has its relocated type_offset 0x%8.8" PRIx64 " "
  281. "pointing inside the header",
  282. Offset, Offset + TypeOffset));
  283. return false;
  284. }
  285. if (isTypeUnit() &&
  286. TypeOffset >= getUnitLengthFieldByteSize() + getLength()) {
  287. Context.getWarningHandler()(createStringError(
  288. errc::invalid_argument,
  289. "DWARF type unit from offset 0x%8.8" PRIx64 " incl. "
  290. "to offset 0x%8.8" PRIx64 " excl. has its "
  291. "relocated type_offset 0x%8.8" PRIx64 " pointing past the unit end",
  292. Offset, NextCUOffset, Offset + TypeOffset));
  293. return false;
  294. }
  295. if (Error SizeErr = DWARFContext::checkAddressSizeSupported(
  296. getAddressByteSize(), errc::invalid_argument,
  297. "DWARF unit at offset 0x%8.8" PRIx64, Offset)) {
  298. Context.getWarningHandler()(std::move(SizeErr));
  299. return false;
  300. }
  301. // Keep track of the highest DWARF version we encounter across all units.
  302. Context.setMaxVersionIfGreater(getVersion());
  303. return true;
  304. }
  305. bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
  306. assert(Entry);
  307. assert(!IndexEntry);
  308. IndexEntry = Entry;
  309. if (AbbrOffset)
  310. return false;
  311. auto *UnitContrib = IndexEntry->getContribution();
  312. if (!UnitContrib ||
  313. UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
  314. return false;
  315. auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
  316. if (!AbbrEntry)
  317. return false;
  318. AbbrOffset = AbbrEntry->Offset;
  319. return true;
  320. }
  321. Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
  322. DWARFDebugRangeList &RangeList) const {
  323. // Require that compile unit is extracted.
  324. assert(!DieArray.empty());
  325. DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
  326. isLittleEndian, getAddressByteSize());
  327. uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
  328. return RangeList.extract(RangesData, &ActualRangeListOffset);
  329. }
  330. void DWARFUnit::clear() {
  331. Abbrevs = nullptr;
  332. BaseAddr.reset();
  333. RangeSectionBase = 0;
  334. LocSectionBase = 0;
  335. AddrOffsetSectionBase = None;
  336. SU = nullptr;
  337. clearDIEs(false);
  338. DWO.reset();
  339. }
  340. const char *DWARFUnit::getCompilationDir() {
  341. return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
  342. }
  343. void DWARFUnit::extractDIEsToVector(
  344. bool AppendCUDie, bool AppendNonCUDies,
  345. std::vector<DWARFDebugInfoEntry> &Dies) const {
  346. if (!AppendCUDie && !AppendNonCUDies)
  347. return;
  348. // Set the offset to that of the first DIE and calculate the start of the
  349. // next compilation unit header.
  350. uint64_t DIEOffset = getOffset() + getHeaderSize();
  351. uint64_t NextCUOffset = getNextUnitOffset();
  352. DWARFDebugInfoEntry DIE;
  353. DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
  354. // The end offset has been already checked by DWARFUnitHeader::extract.
  355. assert(DebugInfoData.isValidOffset(NextCUOffset - 1));
  356. std::vector<uint32_t> Parents;
  357. std::vector<uint32_t> PrevSiblings;
  358. bool IsCUDie = true;
  359. assert(
  360. ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&
  361. "Dies array is not empty");
  362. // Fill Parents and Siblings stacks with initial value.
  363. Parents.push_back(UINT32_MAX);
  364. if (!AppendCUDie)
  365. Parents.push_back(0);
  366. PrevSiblings.push_back(0);
  367. // Start to extract dies.
  368. do {
  369. assert(Parents.size() > 0 && "Empty parents stack");
  370. assert((Parents.back() == UINT32_MAX || Parents.back() <= Dies.size()) &&
  371. "Wrong parent index");
  372. // Extract die. Stop if any error occured.
  373. if (!DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
  374. Parents.back()))
  375. break;
  376. // If previous sibling is remembered then update it`s SiblingIdx field.
  377. if (PrevSiblings.back() > 0) {
  378. assert(PrevSiblings.back() < Dies.size() &&
  379. "Previous sibling index is out of Dies boundaries");
  380. Dies[PrevSiblings.back()].setSiblingIdx(Dies.size());
  381. }
  382. // Store die into the Dies vector.
  383. if (IsCUDie) {
  384. if (AppendCUDie)
  385. Dies.push_back(DIE);
  386. if (!AppendNonCUDies)
  387. break;
  388. // The average bytes per DIE entry has been seen to be
  389. // around 14-20 so let's pre-reserve the needed memory for
  390. // our DIE entries accordingly.
  391. Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
  392. } else {
  393. // Remember last previous sibling.
  394. PrevSiblings.back() = Dies.size();
  395. Dies.push_back(DIE);
  396. }
  397. // Check for new children scope.
  398. if (const DWARFAbbreviationDeclaration *AbbrDecl =
  399. DIE.getAbbreviationDeclarationPtr()) {
  400. if (AbbrDecl->hasChildren()) {
  401. if (AppendCUDie || !IsCUDie) {
  402. assert(Dies.size() > 0 && "Dies does not contain any die");
  403. Parents.push_back(Dies.size() - 1);
  404. PrevSiblings.push_back(0);
  405. }
  406. } else if (IsCUDie)
  407. // Stop if we have single compile unit die w/o children.
  408. break;
  409. } else {
  410. // NULL DIE: finishes current children scope.
  411. Parents.pop_back();
  412. PrevSiblings.pop_back();
  413. }
  414. if (IsCUDie)
  415. IsCUDie = false;
  416. // Stop when compile unit die is removed from the parents stack.
  417. } while (Parents.size() > 1);
  418. }
  419. void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
  420. if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
  421. Context.getRecoverableErrorHandler()(std::move(e));
  422. }
  423. Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
  424. if ((CUDieOnly && !DieArray.empty()) ||
  425. DieArray.size() > 1)
  426. return Error::success(); // Already parsed.
  427. bool HasCUDie = !DieArray.empty();
  428. extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
  429. if (DieArray.empty())
  430. return Error::success();
  431. // If CU DIE was just parsed, copy several attribute values from it.
  432. if (HasCUDie)
  433. return Error::success();
  434. DWARFDie UnitDie(this, &DieArray[0]);
  435. if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
  436. Header.setDWOId(*DWOId);
  437. if (!IsDWO) {
  438. assert(AddrOffsetSectionBase == None);
  439. assert(RangeSectionBase == 0);
  440. assert(LocSectionBase == 0);
  441. AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
  442. if (!AddrOffsetSectionBase)
  443. AddrOffsetSectionBase =
  444. toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
  445. RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
  446. LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
  447. }
  448. // In general, in DWARF v5 and beyond we derive the start of the unit's
  449. // contribution to the string offsets table from the unit DIE's
  450. // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
  451. // attribute, so we assume that there is a contribution to the string
  452. // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
  453. // In both cases we need to determine the format of the contribution,
  454. // which may differ from the unit's format.
  455. DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
  456. isLittleEndian, 0);
  457. if (IsDWO || getVersion() >= 5) {
  458. auto StringOffsetOrError =
  459. IsDWO ? determineStringOffsetsTableContributionDWO(DA)
  460. : determineStringOffsetsTableContribution(DA);
  461. if (!StringOffsetOrError)
  462. return createStringError(errc::invalid_argument,
  463. "invalid reference to or invalid content in "
  464. ".debug_str_offsets[.dwo]: " +
  465. toString(StringOffsetOrError.takeError()));
  466. StringOffsetsTableContribution = *StringOffsetOrError;
  467. }
  468. // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
  469. // describe address ranges.
  470. if (getVersion() >= 5) {
  471. // In case of DWP, the base offset from the index has to be added.
  472. if (IsDWO) {
  473. uint64_t ContributionBaseOffset = 0;
  474. if (auto *IndexEntry = Header.getIndexEntry())
  475. if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
  476. ContributionBaseOffset = Contrib->Offset;
  477. setRangesSection(
  478. &Context.getDWARFObj().getRnglistsDWOSection(),
  479. ContributionBaseOffset +
  480. DWARFListTableHeader::getHeaderSize(Header.getFormat()));
  481. } else
  482. setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
  483. toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
  484. DWARFListTableHeader::getHeaderSize(
  485. Header.getFormat())));
  486. }
  487. if (IsDWO) {
  488. // If we are reading a package file, we need to adjust the location list
  489. // data based on the index entries.
  490. StringRef Data = Header.getVersion() >= 5
  491. ? Context.getDWARFObj().getLoclistsDWOSection().Data
  492. : Context.getDWARFObj().getLocDWOSection().Data;
  493. if (auto *IndexEntry = Header.getIndexEntry())
  494. if (const auto *C = IndexEntry->getContribution(
  495. Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
  496. Data = Data.substr(C->Offset, C->Length);
  497. DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
  498. LocTable =
  499. std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
  500. LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
  501. } else if (getVersion() >= 5) {
  502. LocTable = std::make_unique<DWARFDebugLoclists>(
  503. DWARFDataExtractor(Context.getDWARFObj(),
  504. Context.getDWARFObj().getLoclistsSection(),
  505. isLittleEndian, getAddressByteSize()),
  506. getVersion());
  507. } else {
  508. LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
  509. Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
  510. isLittleEndian, getAddressByteSize()));
  511. }
  512. // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
  513. // skeleton CU DIE, so that DWARF users not aware of it are not broken.
  514. return Error::success();
  515. }
  516. bool DWARFUnit::parseDWO() {
  517. if (IsDWO)
  518. return false;
  519. if (DWO.get())
  520. return false;
  521. DWARFDie UnitDie = getUnitDIE();
  522. if (!UnitDie)
  523. return false;
  524. auto DWOFileName = getVersion() >= 5
  525. ? dwarf::toString(UnitDie.find(DW_AT_dwo_name))
  526. : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
  527. if (!DWOFileName)
  528. return false;
  529. auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
  530. SmallString<16> AbsolutePath;
  531. if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
  532. *CompilationDir) {
  533. sys::path::append(AbsolutePath, *CompilationDir);
  534. }
  535. sys::path::append(AbsolutePath, *DWOFileName);
  536. auto DWOId = getDWOId();
  537. if (!DWOId)
  538. return false;
  539. auto DWOContext = Context.getDWOContext(AbsolutePath);
  540. if (!DWOContext)
  541. return false;
  542. DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
  543. if (!DWOCU)
  544. return false;
  545. DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
  546. DWO->setSkeletonUnit(this);
  547. // Share .debug_addr and .debug_ranges section with compile unit in .dwo
  548. if (AddrOffsetSectionBase)
  549. DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
  550. if (getVersion() == 4) {
  551. auto DWORangesBase = UnitDie.getRangesBaseAttribute();
  552. DWO->setRangesSection(RangeSection, DWORangesBase.getValueOr(0));
  553. }
  554. return true;
  555. }
  556. void DWARFUnit::clearDIEs(bool KeepCUDie) {
  557. // Do not use resize() + shrink_to_fit() to free memory occupied by dies.
  558. // shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
  559. // It depends on the implementation whether the request is fulfilled.
  560. // Create a new vector with a small capacity and assign it to the DieArray to
  561. // have previous contents freed.
  562. DieArray = (KeepCUDie && !DieArray.empty())
  563. ? std::vector<DWARFDebugInfoEntry>({DieArray[0]})
  564. : std::vector<DWARFDebugInfoEntry>();
  565. }
  566. Expected<DWARFAddressRangesVector>
  567. DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
  568. if (getVersion() <= 4) {
  569. DWARFDebugRangeList RangeList;
  570. if (Error E = extractRangeList(Offset, RangeList))
  571. return std::move(E);
  572. return RangeList.getAbsoluteRanges(getBaseAddress());
  573. }
  574. DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
  575. isLittleEndian, Header.getAddressByteSize());
  576. DWARFDebugRnglistTable RnglistTable;
  577. auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
  578. if (RangeListOrError)
  579. return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
  580. return RangeListOrError.takeError();
  581. }
  582. Expected<DWARFAddressRangesVector>
  583. DWARFUnit::findRnglistFromIndex(uint32_t Index) {
  584. if (auto Offset = getRnglistOffset(Index))
  585. return findRnglistFromOffset(*Offset);
  586. return createStringError(errc::invalid_argument,
  587. "invalid range list table index %d (possibly "
  588. "missing the entire range list table)",
  589. Index);
  590. }
  591. Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
  592. DWARFDie UnitDie = getUnitDIE();
  593. if (!UnitDie)
  594. return createStringError(errc::invalid_argument, "No unit DIE");
  595. // First, check if unit DIE describes address ranges for the whole unit.
  596. auto CUDIERangesOrError = UnitDie.getAddressRanges();
  597. if (!CUDIERangesOrError)
  598. return createStringError(errc::invalid_argument,
  599. "decoding address ranges: %s",
  600. toString(CUDIERangesOrError.takeError()).c_str());
  601. return *CUDIERangesOrError;
  602. }
  603. Expected<DWARFLocationExpressionsVector>
  604. DWARFUnit::findLoclistFromOffset(uint64_t Offset) {
  605. DWARFLocationExpressionsVector Result;
  606. Error InterpretationError = Error::success();
  607. Error ParseError = getLocationTable().visitAbsoluteLocationList(
  608. Offset, getBaseAddress(),
  609. [this](uint32_t Index) { return getAddrOffsetSectionItem(Index); },
  610. [&](Expected<DWARFLocationExpression> L) {
  611. if (L)
  612. Result.push_back(std::move(*L));
  613. else
  614. InterpretationError =
  615. joinErrors(L.takeError(), std::move(InterpretationError));
  616. return !InterpretationError;
  617. });
  618. if (ParseError || InterpretationError)
  619. return joinErrors(std::move(ParseError), std::move(InterpretationError));
  620. return Result;
  621. }
  622. void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
  623. if (Die.isSubroutineDIE()) {
  624. auto DIERangesOrError = Die.getAddressRanges();
  625. if (DIERangesOrError) {
  626. for (const auto &R : DIERangesOrError.get()) {
  627. // Ignore 0-sized ranges.
  628. if (R.LowPC == R.HighPC)
  629. continue;
  630. auto B = AddrDieMap.upper_bound(R.LowPC);
  631. if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
  632. // The range is a sub-range of existing ranges, we need to split the
  633. // existing range.
  634. if (R.HighPC < B->second.first)
  635. AddrDieMap[R.HighPC] = B->second;
  636. if (R.LowPC > B->first)
  637. AddrDieMap[B->first].first = R.LowPC;
  638. }
  639. AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
  640. }
  641. } else
  642. llvm::consumeError(DIERangesOrError.takeError());
  643. }
  644. // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
  645. // simplify the logic to update AddrDieMap. The child's range will always
  646. // be equal or smaller than the parent's range. With this assumption, when
  647. // adding one range into the map, it will at most split a range into 3
  648. // sub-ranges.
  649. for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
  650. updateAddressDieMap(Child);
  651. }
  652. DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
  653. extractDIEsIfNeeded(false);
  654. if (AddrDieMap.empty())
  655. updateAddressDieMap(getUnitDIE());
  656. auto R = AddrDieMap.upper_bound(Address);
  657. if (R == AddrDieMap.begin())
  658. return DWARFDie();
  659. // upper_bound's previous item contains Address.
  660. --R;
  661. if (Address >= R->second.first)
  662. return DWARFDie();
  663. return R->second.second;
  664. }
  665. void
  666. DWARFUnit::getInlinedChainForAddress(uint64_t Address,
  667. SmallVectorImpl<DWARFDie> &InlinedChain) {
  668. assert(InlinedChain.empty());
  669. // Try to look for subprogram DIEs in the DWO file.
  670. parseDWO();
  671. // First, find the subroutine that contains the given address (the leaf
  672. // of inlined chain).
  673. DWARFDie SubroutineDIE =
  674. (DWO ? *DWO : *this).getSubroutineForAddress(Address);
  675. while (SubroutineDIE) {
  676. if (SubroutineDIE.isSubprogramDIE()) {
  677. InlinedChain.push_back(SubroutineDIE);
  678. return;
  679. }
  680. if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
  681. InlinedChain.push_back(SubroutineDIE);
  682. SubroutineDIE = SubroutineDIE.getParent();
  683. }
  684. }
  685. const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
  686. DWARFSectionKind Kind) {
  687. if (Kind == DW_SECT_INFO)
  688. return Context.getCUIndex();
  689. assert(Kind == DW_SECT_EXT_TYPES);
  690. return Context.getTUIndex();
  691. }
  692. DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
  693. if (!Die)
  694. return DWARFDie();
  695. if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) {
  696. assert(*ParentIdx < DieArray.size() &&
  697. "ParentIdx is out of DieArray boundaries");
  698. return DWARFDie(this, &DieArray[*ParentIdx]);
  699. }
  700. return DWARFDie();
  701. }
  702. DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
  703. if (!Die)
  704. return DWARFDie();
  705. if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
  706. assert(*SiblingIdx < DieArray.size() &&
  707. "SiblingIdx is out of DieArray boundaries");
  708. return DWARFDie(this, &DieArray[*SiblingIdx]);
  709. }
  710. return DWARFDie();
  711. }
  712. DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
  713. if (!Die)
  714. return DWARFDie();
  715. Optional<uint32_t> ParentIdx = Die->getParentIdx();
  716. if (!ParentIdx)
  717. // Die is a root die, there is no previous sibling.
  718. return DWARFDie();
  719. assert(*ParentIdx < DieArray.size() &&
  720. "ParentIdx is out of DieArray boundaries");
  721. assert(getDIEIndex(Die) > 0 && "Die is a root die");
  722. uint32_t PrevDieIdx = getDIEIndex(Die) - 1;
  723. if (PrevDieIdx == *ParentIdx)
  724. // Immediately previous node is parent, there is no previous sibling.
  725. return DWARFDie();
  726. while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
  727. PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
  728. assert(PrevDieIdx < DieArray.size() &&
  729. "PrevDieIdx is out of DieArray boundaries");
  730. assert(PrevDieIdx >= *ParentIdx &&
  731. "PrevDieIdx is not a child of parent of Die");
  732. }
  733. return DWARFDie(this, &DieArray[PrevDieIdx]);
  734. }
  735. DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
  736. if (!Die->hasChildren())
  737. return DWARFDie();
  738. // TODO: Instead of checking here for invalid die we might reject
  739. // invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
  740. // We do not want access out of bounds when parsing corrupted debug data.
  741. size_t I = getDIEIndex(Die) + 1;
  742. if (I >= DieArray.size())
  743. return DWARFDie();
  744. return DWARFDie(this, &DieArray[I]);
  745. }
  746. DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
  747. if (!Die->hasChildren())
  748. return DWARFDie();
  749. if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
  750. assert(*SiblingIdx < DieArray.size() &&
  751. "SiblingIdx is out of DieArray boundaries");
  752. assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&
  753. "Bad end of children marker");
  754. return DWARFDie(this, &DieArray[*SiblingIdx - 1]);
  755. }
  756. // If SiblingIdx is set for non-root dies we could be sure that DWARF is
  757. // correct and "end of children marker" must be found. For root die we do not
  758. // have such a guarantee(parsing root die might be stopped if "end of children
  759. // marker" is missing, SiblingIdx is always zero for root die). That is why we
  760. // do not use assertion for checking for "end of children marker" for root
  761. // die.
  762. // TODO: Instead of checking here for invalid die we might reject
  763. // invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
  764. if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
  765. DieArray.back().getTag() == dwarf::DW_TAG_null) {
  766. // For the unit die we might take last item from DieArray.
  767. assert(getDIEIndex(Die) == getDIEIndex(getUnitDIE()) && "Bad unit die");
  768. return DWARFDie(this, &DieArray.back());
  769. }
  770. return DWARFDie();
  771. }
  772. const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
  773. if (!Abbrevs)
  774. Abbrevs = Abbrev->getAbbreviationDeclarationSet(getAbbreviationsOffset());
  775. return Abbrevs;
  776. }
  777. llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
  778. if (BaseAddr)
  779. return BaseAddr;
  780. DWARFDie UnitDie = getUnitDIE();
  781. Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
  782. BaseAddr = toSectionedAddress(PC);
  783. return BaseAddr;
  784. }
  785. Expected<StrOffsetsContributionDescriptor>
  786. StrOffsetsContributionDescriptor::validateContributionSize(
  787. DWARFDataExtractor &DA) {
  788. uint8_t EntrySize = getDwarfOffsetByteSize();
  789. // In order to ensure that we don't read a partial record at the end of
  790. // the section we validate for a multiple of the entry size.
  791. uint64_t ValidationSize = alignTo(Size, EntrySize);
  792. // Guard against overflow.
  793. if (ValidationSize >= Size)
  794. if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
  795. return *this;
  796. return createStringError(errc::invalid_argument, "length exceeds section size");
  797. }
  798. // Look for a DWARF64-formatted contribution to the string offsets table
  799. // starting at a given offset and record it in a descriptor.
  800. static Expected<StrOffsetsContributionDescriptor>
  801. parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
  802. if (!DA.isValidOffsetForDataOfSize(Offset, 16))
  803. return createStringError(errc::invalid_argument, "section offset exceeds section size");
  804. if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
  805. return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
  806. uint64_t Size = DA.getU64(&Offset);
  807. uint8_t Version = DA.getU16(&Offset);
  808. (void)DA.getU16(&Offset); // padding
  809. // The encoded length includes the 2-byte version field and the 2-byte
  810. // padding, so we need to subtract them out when we populate the descriptor.
  811. return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
  812. }
  813. // Look for a DWARF32-formatted contribution to the string offsets table
  814. // starting at a given offset and record it in a descriptor.
  815. static Expected<StrOffsetsContributionDescriptor>
  816. parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
  817. if (!DA.isValidOffsetForDataOfSize(Offset, 8))
  818. return createStringError(errc::invalid_argument, "section offset exceeds section size");
  819. uint32_t ContributionSize = DA.getU32(&Offset);
  820. if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
  821. return createStringError(errc::invalid_argument, "invalid length");
  822. uint8_t Version = DA.getU16(&Offset);
  823. (void)DA.getU16(&Offset); // padding
  824. // The encoded length includes the 2-byte version field and the 2-byte
  825. // padding, so we need to subtract them out when we populate the descriptor.
  826. return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
  827. DWARF32);
  828. }
  829. static Expected<StrOffsetsContributionDescriptor>
  830. parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
  831. llvm::dwarf::DwarfFormat Format,
  832. uint64_t Offset) {
  833. StrOffsetsContributionDescriptor Desc;
  834. switch (Format) {
  835. case dwarf::DwarfFormat::DWARF64: {
  836. if (Offset < 16)
  837. return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
  838. auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16);
  839. if (!DescOrError)
  840. return DescOrError.takeError();
  841. Desc = *DescOrError;
  842. break;
  843. }
  844. case dwarf::DwarfFormat::DWARF32: {
  845. if (Offset < 8)
  846. return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
  847. auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8);
  848. if (!DescOrError)
  849. return DescOrError.takeError();
  850. Desc = *DescOrError;
  851. break;
  852. }
  853. }
  854. return Desc.validateContributionSize(DA);
  855. }
  856. Expected<Optional<StrOffsetsContributionDescriptor>>
  857. DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
  858. assert(!IsDWO);
  859. auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
  860. if (!OptOffset)
  861. return None;
  862. auto DescOrError =
  863. parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset);
  864. if (!DescOrError)
  865. return DescOrError.takeError();
  866. return *DescOrError;
  867. }
  868. Expected<Optional<StrOffsetsContributionDescriptor>>
  869. DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
  870. assert(IsDWO);
  871. uint64_t Offset = 0;
  872. auto IndexEntry = Header.getIndexEntry();
  873. const auto *C =
  874. IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
  875. if (C)
  876. Offset = C->Offset;
  877. if (getVersion() >= 5) {
  878. if (DA.getData().data() == nullptr)
  879. return None;
  880. Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16;
  881. // Look for a valid contribution at the given offset.
  882. auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset);
  883. if (!DescOrError)
  884. return DescOrError.takeError();
  885. return *DescOrError;
  886. }
  887. // Prior to DWARF v5, we derive the contribution size from the
  888. // index table (in a package file). In a .dwo file it is simply
  889. // the length of the string offsets section.
  890. StrOffsetsContributionDescriptor Desc;
  891. if (C)
  892. Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
  893. Header.getFormat());
  894. else if (!IndexEntry && !StringOffsetSection.Data.empty())
  895. Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
  896. 4, Header.getFormat());
  897. else
  898. return None;
  899. auto DescOrError = Desc.validateContributionSize(DA);
  900. if (!DescOrError)
  901. return DescOrError.takeError();
  902. return *DescOrError;
  903. }
  904. Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
  905. DataExtractor RangesData(RangeSection->Data, isLittleEndian,
  906. getAddressByteSize());
  907. DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
  908. isLittleEndian, 0);
  909. if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
  910. RangesData, RangeSectionBase, getFormat(), Index))
  911. return *Off + RangeSectionBase;
  912. return None;
  913. }
  914. Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
  915. if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
  916. LocTable->getData(), LocSectionBase, getFormat(), Index))
  917. return *Off + LocSectionBase;
  918. return None;
  919. }