DWARFUnit.cpp 12 KB

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