DWARFDebugInfoEntry.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. //===-- DWARFDebugInfoEntry.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 "SyntaxHighlighting.h"
  10. #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
  11. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
  13. #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  15. #include "llvm/Support/DataTypes.h"
  16. #include "llvm/Support/Debug.h"
  17. #include "llvm/Support/Dwarf.h"
  18. #include "llvm/Support/Format.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. using namespace llvm;
  21. using namespace dwarf;
  22. using namespace syntax;
  23. // Small helper to extract a DIE pointed by a reference
  24. // attribute. It looks up the Unit containing the DIE and calls
  25. // DIE.extractFast with the right unit. Returns new unit on success,
  26. // nullptr otherwise.
  27. static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE,
  28. const DWARFUnit *Unit,
  29. uint32_t *Offset) {
  30. Unit = Unit->getUnitSection().getUnitForOffset(*Offset);
  31. return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr;
  32. }
  33. void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u,
  34. unsigned recurseDepth,
  35. unsigned indent) const {
  36. DataExtractor debug_info_data = u->getDebugInfoExtractor();
  37. uint32_t offset = Offset;
  38. if (debug_info_data.isValidOffset(offset)) {
  39. uint32_t abbrCode = debug_info_data.getULEB128(&offset);
  40. WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);
  41. if (abbrCode) {
  42. if (AbbrevDecl) {
  43. const char *tagString = TagString(getTag());
  44. if (tagString)
  45. WithColor(OS, syntax::Tag).get().indent(indent) << tagString;
  46. else
  47. WithColor(OS, syntax::Tag).get().indent(indent) <<
  48. format("DW_TAG_Unknown_%x", getTag());
  49. OS << format(" [%u] %c\n", abbrCode,
  50. AbbrevDecl->hasChildren() ? '*' : ' ');
  51. // Dump all data in the DIE for the attributes.
  52. for (const auto &AttrSpec : AbbrevDecl->attributes()) {
  53. dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
  54. }
  55. const DWARFDebugInfoEntryMinimal *child = getFirstChild();
  56. if (recurseDepth > 0 && child) {
  57. while (child) {
  58. child->dump(OS, u, recurseDepth-1, indent+2);
  59. child = child->getSibling();
  60. }
  61. }
  62. } else {
  63. OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
  64. << abbrCode << '\n';
  65. }
  66. } else {
  67. OS.indent(indent) << "NULL\n";
  68. }
  69. }
  70. }
  71. static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
  72. OS << " (";
  73. do {
  74. uint64_t Shift = countTrailingZeros(Val);
  75. assert(Shift < 64 && "undefined behavior");
  76. uint64_t Bit = 1ULL << Shift;
  77. if (const char *PropName = ApplePropertyString(Bit))
  78. OS << PropName;
  79. else
  80. OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
  81. if (!(Val ^= Bit))
  82. break;
  83. OS << ", ";
  84. } while (true);
  85. OS << ")";
  86. }
  87. static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges,
  88. unsigned AddressSize, unsigned Indent) {
  89. if (Ranges.empty())
  90. return;
  91. for (const auto &Range: Ranges) {
  92. OS << '\n';
  93. OS.indent(Indent);
  94. OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")",
  95. AddressSize*2, Range.first,
  96. AddressSize*2, Range.second);
  97. }
  98. }
  99. void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
  100. DWARFUnit *u,
  101. uint32_t *offset_ptr,
  102. uint16_t attr, uint16_t form,
  103. unsigned indent) const {
  104. const char BaseIndent[] = " ";
  105. OS << BaseIndent;
  106. OS.indent(indent+2);
  107. const char *attrString = AttributeString(attr);
  108. if (attrString)
  109. WithColor(OS, syntax::Attribute) << attrString;
  110. else
  111. WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", attr);
  112. const char *formString = FormEncodingString(form);
  113. if (formString)
  114. OS << " [" << formString << ']';
  115. else
  116. OS << format(" [DW_FORM_Unknown_%x]", form);
  117. DWARFFormValue formValue(form);
  118. if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
  119. return;
  120. OS << "\t(";
  121. const char *Name = nullptr;
  122. std::string File;
  123. auto Color = syntax::Enumerator;
  124. if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
  125. Color = syntax::String;
  126. if (const auto *LT = u->getContext().getLineTableForUnit(u))
  127. if (LT->getFileNameByIndex(
  128. formValue.getAsUnsignedConstant().getValue(),
  129. u->getCompilationDir(),
  130. DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
  131. File = '"' + File + '"';
  132. Name = File.c_str();
  133. }
  134. } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
  135. Name = AttributeValueString(attr, *Val);
  136. if (Name)
  137. WithColor(OS, Color) << Name;
  138. else if (attr == DW_AT_decl_line || attr == DW_AT_call_line)
  139. OS << *formValue.getAsUnsignedConstant();
  140. else
  141. formValue.dump(OS, u);
  142. // We have dumped the attribute raw value. For some attributes
  143. // having both the raw value and the pretty-printed value is
  144. // interesting. These attributes are handled below.
  145. if (attr == DW_AT_specification || attr == DW_AT_abstract_origin) {
  146. Optional<uint64_t> Ref = formValue.getAsReference(u);
  147. if (Ref.hasValue()) {
  148. uint32_t RefOffset = Ref.getValue();
  149. DWARFDebugInfoEntryMinimal DIE;
  150. if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &RefOffset))
  151. if (const char *Name = DIE.getName(RefU, DINameKind::LinkageName))
  152. OS << " \"" << Name << '\"';
  153. }
  154. } else if (attr == DW_AT_APPLE_property_attribute) {
  155. if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
  156. dumpApplePropertyAttribute(OS, *OptVal);
  157. } else if (attr == DW_AT_ranges) {
  158. dumpRanges(OS, getAddressRanges(u), u->getAddressByteSize(),
  159. sizeof(BaseIndent)+indent+4);
  160. }
  161. OS << ")\n";
  162. }
  163. bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
  164. uint32_t *OffsetPtr) {
  165. Offset = *OffsetPtr;
  166. DataExtractor DebugInfoData = U->getDebugInfoExtractor();
  167. uint32_t UEndOffset = U->getNextUnitOffset();
  168. if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
  169. return false;
  170. uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
  171. if (0 == AbbrCode) {
  172. // NULL debug tag entry.
  173. AbbrevDecl = nullptr;
  174. return true;
  175. }
  176. AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
  177. if (nullptr == AbbrevDecl) {
  178. // Restore the original offset.
  179. *OffsetPtr = Offset;
  180. return false;
  181. }
  182. ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
  183. U->getAddressByteSize(), U->getVersion());
  184. assert(FixedFormSizes.size() > 0);
  185. // Skip all data in the .debug_info for the attributes
  186. for (const auto &AttrSpec : AbbrevDecl->attributes()) {
  187. uint16_t Form = AttrSpec.Form;
  188. uint8_t FixedFormSize =
  189. (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
  190. if (FixedFormSize)
  191. *OffsetPtr += FixedFormSize;
  192. else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
  193. // Restore the original offset.
  194. *OffsetPtr = Offset;
  195. return false;
  196. }
  197. }
  198. return true;
  199. }
  200. bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
  201. return getTag() == DW_TAG_subprogram;
  202. }
  203. bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
  204. uint32_t Tag = getTag();
  205. return Tag == DW_TAG_subprogram ||
  206. Tag == DW_TAG_inlined_subroutine;
  207. }
  208. bool DWARFDebugInfoEntryMinimal::getAttributeValue(
  209. const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const {
  210. if (!AbbrevDecl)
  211. return false;
  212. uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr);
  213. if (AttrIdx == -1U)
  214. return false;
  215. DataExtractor DebugInfoData = U->getDebugInfoExtractor();
  216. uint32_t DebugInfoOffset = getOffset();
  217. // Skip the abbreviation code so we are at the data for the attributes
  218. DebugInfoData.getULEB128(&DebugInfoOffset);
  219. // Skip preceding attribute values.
  220. for (uint32_t i = 0; i < AttrIdx; ++i) {
  221. DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i),
  222. DebugInfoData, &DebugInfoOffset, U);
  223. }
  224. FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx));
  225. return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U);
  226. }
  227. const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
  228. const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const {
  229. DWARFFormValue FormValue;
  230. if (!getAttributeValue(U, Attr, FormValue))
  231. return FailValue;
  232. Optional<const char *> Result = FormValue.getAsCString(U);
  233. return Result.hasValue() ? Result.getValue() : FailValue;
  234. }
  235. uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
  236. const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
  237. DWARFFormValue FormValue;
  238. if (!getAttributeValue(U, Attr, FormValue))
  239. return FailValue;
  240. Optional<uint64_t> Result = FormValue.getAsAddress(U);
  241. return Result.hasValue() ? Result.getValue() : FailValue;
  242. }
  243. uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant(
  244. const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
  245. DWARFFormValue FormValue;
  246. if (!getAttributeValue(U, Attr, FormValue))
  247. return FailValue;
  248. Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
  249. return Result.hasValue() ? Result.getValue() : FailValue;
  250. }
  251. uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
  252. const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
  253. DWARFFormValue FormValue;
  254. if (!getAttributeValue(U, Attr, FormValue))
  255. return FailValue;
  256. Optional<uint64_t> Result = FormValue.getAsReference(U);
  257. return Result.hasValue() ? Result.getValue() : FailValue;
  258. }
  259. uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
  260. const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
  261. DWARFFormValue FormValue;
  262. if (!getAttributeValue(U, Attr, FormValue))
  263. return FailValue;
  264. Optional<uint64_t> Result = FormValue.getAsSectionOffset();
  265. return Result.hasValue() ? Result.getValue() : FailValue;
  266. }
  267. uint64_t
  268. DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
  269. uint64_t FailValue) const {
  270. uint64_t Result =
  271. getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
  272. if (Result != -1ULL)
  273. return Result;
  274. return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
  275. }
  276. bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
  277. uint64_t &LowPC,
  278. uint64_t &HighPC) const {
  279. LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
  280. if (LowPC == -1ULL)
  281. return false;
  282. HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
  283. if (HighPC == -1ULL) {
  284. // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
  285. // it represents function size.
  286. HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL);
  287. if (HighPC != -1ULL)
  288. HighPC += LowPC;
  289. }
  290. return (HighPC != -1ULL);
  291. }
  292. DWARFAddressRangesVector
  293. DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
  294. if (isNULL())
  295. return DWARFAddressRangesVector();
  296. // Single range specified by low/high PC.
  297. uint64_t LowPC, HighPC;
  298. if (getLowAndHighPC(U, LowPC, HighPC)) {
  299. return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
  300. }
  301. // Multiple ranges from .debug_ranges section.
  302. uint32_t RangesOffset =
  303. getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
  304. if (RangesOffset != -1U) {
  305. DWARFDebugRangeList RangeList;
  306. if (U->extractRangeList(RangesOffset, RangeList))
  307. return RangeList.getAbsoluteRanges(U->getBaseAddress());
  308. }
  309. return DWARFAddressRangesVector();
  310. }
  311. void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
  312. const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
  313. if (isNULL())
  314. return;
  315. if (isSubprogramDIE()) {
  316. const auto &DIERanges = getAddressRanges(U);
  317. Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
  318. }
  319. const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
  320. while (Child) {
  321. Child->collectChildrenAddressRanges(U, Ranges);
  322. Child = Child->getSibling();
  323. }
  324. }
  325. bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
  326. const DWARFUnit *U, const uint64_t Address) const {
  327. for (const auto& R : getAddressRanges(U)) {
  328. if (R.first <= Address && Address < R.second)
  329. return true;
  330. }
  331. return false;
  332. }
  333. const char *
  334. DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
  335. DINameKind Kind) const {
  336. if (!isSubroutineDIE())
  337. return nullptr;
  338. return getName(U, Kind);
  339. }
  340. const char *
  341. DWARFDebugInfoEntryMinimal::getName(const DWARFUnit *U,
  342. DINameKind Kind) const {
  343. if (Kind == DINameKind::None)
  344. return nullptr;
  345. // Try to get mangled name only if it was asked for.
  346. if (Kind == DINameKind::LinkageName) {
  347. if (const char *name =
  348. getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
  349. return name;
  350. if (const char *name =
  351. getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
  352. return name;
  353. }
  354. if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
  355. return name;
  356. // Try to get name from specification DIE.
  357. uint32_t spec_ref =
  358. getAttributeValueAsReference(U, DW_AT_specification, -1U);
  359. if (spec_ref != -1U) {
  360. DWARFDebugInfoEntryMinimal spec_die;
  361. if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) {
  362. if (const char *name = spec_die.getName(RefU, Kind))
  363. return name;
  364. }
  365. }
  366. // Try to get name from abstract origin DIE.
  367. uint32_t abs_origin_ref =
  368. getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
  369. if (abs_origin_ref != -1U) {
  370. DWARFDebugInfoEntryMinimal abs_origin_die;
  371. if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U,
  372. &abs_origin_ref)) {
  373. if (const char *name = abs_origin_die.getName(RefU, Kind))
  374. return name;
  375. }
  376. }
  377. return nullptr;
  378. }
  379. void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
  380. uint32_t &CallFile,
  381. uint32_t &CallLine,
  382. uint32_t &CallColumn) const {
  383. CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0);
  384. CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0);
  385. CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0);
  386. }
  387. DWARFDebugInfoEntryInlinedChain
  388. DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
  389. const DWARFUnit *U, const uint64_t Address) const {
  390. DWARFDebugInfoEntryInlinedChain InlinedChain;
  391. InlinedChain.U = U;
  392. if (isNULL())
  393. return InlinedChain;
  394. for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
  395. // Append current DIE to inlined chain only if it has correct tag
  396. // (e.g. it is not a lexical block).
  397. if (DIE->isSubroutineDIE()) {
  398. InlinedChain.DIEs.push_back(*DIE);
  399. }
  400. // Try to get child which also contains provided address.
  401. const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
  402. while (Child) {
  403. if (Child->addressRangeContainsAddress(U, Address)) {
  404. // Assume there is only one such child.
  405. break;
  406. }
  407. Child = Child->getSibling();
  408. }
  409. DIE = Child;
  410. }
  411. // Reverse the obtained chain to make the root of inlined chain last.
  412. std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
  413. return InlinedChain;
  414. }