DWARFContext.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- DWARFContext.h -------------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===/
  13. #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  14. #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  15. #include "llvm/ADT/SmallVector.h"
  16. #include "llvm/ADT/StringMap.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/DebugInfo/DIContext.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
  20. #include "llvm/DebugInfo/DWARF/DWARFDie.h"
  21. #include "llvm/DebugInfo/DWARF/DWARFObject.h"
  22. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  23. #include "llvm/Object/Binary.h"
  24. #include "llvm/Object/ObjectFile.h"
  25. #include "llvm/Support/DataExtractor.h"
  26. #include "llvm/Support/Error.h"
  27. #include "llvm/Support/Host.h"
  28. #include <cstdint>
  29. #include <memory>
  30. namespace llvm {
  31. class MemoryBuffer;
  32. class AppleAcceleratorTable;
  33. class DWARFCompileUnit;
  34. class DWARFDebugAbbrev;
  35. class DWARFDebugAranges;
  36. class DWARFDebugFrame;
  37. class DWARFDebugLoc;
  38. class DWARFDebugMacro;
  39. class DWARFDebugNames;
  40. class DWARFGdbIndex;
  41. class DWARFTypeUnit;
  42. class DWARFUnitIndex;
  43. /// DWARFContext
  44. /// This data structure is the top level entity that deals with dwarf debug
  45. /// information parsing. The actual data is supplied through DWARFObj.
  46. class DWARFContext : public DIContext {
  47. DWARFUnitVector NormalUnits;
  48. std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
  49. std::unique_ptr<DWARFUnitIndex> CUIndex;
  50. std::unique_ptr<DWARFGdbIndex> GdbIndex;
  51. std::unique_ptr<DWARFUnitIndex> TUIndex;
  52. std::unique_ptr<DWARFDebugAbbrev> Abbrev;
  53. std::unique_ptr<DWARFDebugLoc> Loc;
  54. std::unique_ptr<DWARFDebugAranges> Aranges;
  55. std::unique_ptr<DWARFDebugLine> Line;
  56. std::unique_ptr<DWARFDebugFrame> DebugFrame;
  57. std::unique_ptr<DWARFDebugFrame> EHFrame;
  58. std::unique_ptr<DWARFDebugMacro> Macro;
  59. std::unique_ptr<DWARFDebugMacro> Macinfo;
  60. std::unique_ptr<DWARFDebugNames> Names;
  61. std::unique_ptr<AppleAcceleratorTable> AppleNames;
  62. std::unique_ptr<AppleAcceleratorTable> AppleTypes;
  63. std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
  64. std::unique_ptr<AppleAcceleratorTable> AppleObjC;
  65. DWARFUnitVector DWOUnits;
  66. std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
  67. std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
  68. std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
  69. std::unique_ptr<DWARFDebugMacro> MacroDWO;
  70. /// The maximum DWARF version of all units.
  71. unsigned MaxVersion = 0;
  72. struct DWOFile {
  73. object::OwningBinary<object::ObjectFile> File;
  74. std::unique_ptr<DWARFContext> Context;
  75. };
  76. StringMap<std::weak_ptr<DWOFile>> DWOFiles;
  77. std::weak_ptr<DWOFile> DWP;
  78. bool CheckedForDWP = false;
  79. std::string DWPName;
  80. std::function<void(Error)> RecoverableErrorHandler =
  81. WithColor::defaultErrorHandler;
  82. std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
  83. /// Read compile units from the debug_info section (if necessary)
  84. /// and type units from the debug_types sections (if necessary)
  85. /// and store them in NormalUnits.
  86. void parseNormalUnits();
  87. /// Read compile units from the debug_info.dwo section (if necessary)
  88. /// and type units from the debug_types.dwo section (if necessary)
  89. /// and store them in DWOUnits.
  90. /// If \p Lazy is true, set up to parse but don't actually parse them.
  91. enum { EagerParse = false, LazyParse = true };
  92. void parseDWOUnits(bool Lazy = false);
  93. std::unique_ptr<const DWARFObject> DObj;
  94. /// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
  95. /// section.
  96. enum MacroSecType {
  97. MacinfoSection,
  98. MacinfoDwoSection,
  99. MacroSection,
  100. MacroDwoSection
  101. };
  102. // When set parses debug_info.dwo/debug_abbrev.dwo manually and populates CU
  103. // Index, and TU Index for DWARF5.
  104. bool ParseCUTUIndexManually = false;
  105. public:
  106. DWARFContext(std::unique_ptr<const DWARFObject> DObj,
  107. std::string DWPName = "",
  108. std::function<void(Error)> RecoverableErrorHandler =
  109. WithColor::defaultErrorHandler,
  110. std::function<void(Error)> WarningHandler =
  111. WithColor::defaultWarningHandler);
  112. ~DWARFContext() override;
  113. DWARFContext(DWARFContext &) = delete;
  114. DWARFContext &operator=(DWARFContext &) = delete;
  115. const DWARFObject &getDWARFObj() const { return *DObj; }
  116. static bool classof(const DIContext *DICtx) {
  117. return DICtx->getKind() == CK_DWARF;
  118. }
  119. /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
  120. /// dump only the record at the specified offset.
  121. void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  122. std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
  123. void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
  124. std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
  125. dump(OS, DumpOpts, DumpOffsets);
  126. }
  127. bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
  128. using unit_iterator_range = DWARFUnitVector::iterator_range;
  129. using compile_unit_range = DWARFUnitVector::compile_unit_range;
  130. /// Get units from .debug_info in this context.
  131. unit_iterator_range info_section_units() {
  132. parseNormalUnits();
  133. return unit_iterator_range(NormalUnits.begin(),
  134. NormalUnits.begin() +
  135. NormalUnits.getNumInfoUnits());
  136. }
  137. const DWARFUnitVector &getNormalUnitsVector() {
  138. parseNormalUnits();
  139. return NormalUnits;
  140. }
  141. /// Get units from .debug_types in this context.
  142. unit_iterator_range types_section_units() {
  143. parseNormalUnits();
  144. return unit_iterator_range(
  145. NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
  146. }
  147. /// Get compile units in this context.
  148. compile_unit_range compile_units() {
  149. return make_filter_range(info_section_units(), isCompileUnit);
  150. }
  151. // If you want type_units(), it'll need to be a concat iterator of a filter of
  152. // TUs in info_section + all the (all type) units in types_section
  153. /// Get all normal compile/type units in this context.
  154. unit_iterator_range normal_units() {
  155. parseNormalUnits();
  156. return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
  157. }
  158. /// Get units from .debug_info..dwo in the DWO context.
  159. unit_iterator_range dwo_info_section_units() {
  160. parseDWOUnits();
  161. return unit_iterator_range(DWOUnits.begin(),
  162. DWOUnits.begin() + DWOUnits.getNumInfoUnits());
  163. }
  164. const DWARFUnitVector &getDWOUnitsVector() {
  165. parseDWOUnits();
  166. return DWOUnits;
  167. }
  168. /// Get units from .debug_types.dwo in the DWO context.
  169. unit_iterator_range dwo_types_section_units() {
  170. parseDWOUnits();
  171. return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
  172. DWOUnits.end());
  173. }
  174. /// Get compile units in the DWO context.
  175. compile_unit_range dwo_compile_units() {
  176. return make_filter_range(dwo_info_section_units(), isCompileUnit);
  177. }
  178. // If you want dwo_type_units(), it'll need to be a concat iterator of a
  179. // filter of TUs in dwo_info_section + all the (all type) units in
  180. // dwo_types_section.
  181. /// Get all units in the DWO context.
  182. unit_iterator_range dwo_units() {
  183. parseDWOUnits();
  184. return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
  185. }
  186. /// Get the number of compile units in this context.
  187. unsigned getNumCompileUnits() {
  188. parseNormalUnits();
  189. return NormalUnits.getNumInfoUnits();
  190. }
  191. /// Get the number of type units in this context.
  192. unsigned getNumTypeUnits() {
  193. parseNormalUnits();
  194. return NormalUnits.getNumTypesUnits();
  195. }
  196. /// Get the number of compile units in the DWO context.
  197. unsigned getNumDWOCompileUnits() {
  198. parseDWOUnits();
  199. return DWOUnits.getNumInfoUnits();
  200. }
  201. /// Get the number of type units in the DWO context.
  202. unsigned getNumDWOTypeUnits() {
  203. parseDWOUnits();
  204. return DWOUnits.getNumTypesUnits();
  205. }
  206. /// Get the unit at the specified index.
  207. DWARFUnit *getUnitAtIndex(unsigned index) {
  208. parseNormalUnits();
  209. return NormalUnits[index].get();
  210. }
  211. /// Get the unit at the specified index for the DWO units.
  212. DWARFUnit *getDWOUnitAtIndex(unsigned index) {
  213. parseDWOUnits();
  214. return DWOUnits[index].get();
  215. }
  216. DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
  217. DWARFTypeUnit *getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO);
  218. /// Return the compile unit that includes an offset (relative to .debug_info).
  219. DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
  220. /// Get a DIE given an exact offset.
  221. DWARFDie getDIEForOffset(uint64_t Offset);
  222. unsigned getMaxVersion() {
  223. // Ensure info units have been parsed to discover MaxVersion
  224. info_section_units();
  225. return MaxVersion;
  226. }
  227. unsigned getMaxDWOVersion() {
  228. // Ensure DWO info units have been parsed to discover MaxVersion
  229. dwo_info_section_units();
  230. return MaxVersion;
  231. }
  232. void setMaxVersionIfGreater(unsigned Version) {
  233. if (Version > MaxVersion)
  234. MaxVersion = Version;
  235. }
  236. const DWARFUnitIndex &getCUIndex();
  237. DWARFGdbIndex &getGdbIndex();
  238. const DWARFUnitIndex &getTUIndex();
  239. /// Get a pointer to the parsed DebugAbbrev object.
  240. const DWARFDebugAbbrev *getDebugAbbrev();
  241. /// Get a pointer to the parsed DebugLoc object.
  242. const DWARFDebugLoc *getDebugLoc();
  243. /// Get a pointer to the parsed dwo abbreviations object.
  244. const DWARFDebugAbbrev *getDebugAbbrevDWO();
  245. /// Get a pointer to the parsed DebugAranges object.
  246. const DWARFDebugAranges *getDebugAranges();
  247. /// Get a pointer to the parsed frame information object.
  248. Expected<const DWARFDebugFrame *> getDebugFrame();
  249. /// Get a pointer to the parsed eh frame information object.
  250. Expected<const DWARFDebugFrame *> getEHFrame();
  251. /// Get a pointer to the parsed DebugMacinfo information object.
  252. const DWARFDebugMacro *getDebugMacinfo();
  253. /// Get a pointer to the parsed DebugMacinfoDWO information object.
  254. const DWARFDebugMacro *getDebugMacinfoDWO();
  255. /// Get a pointer to the parsed DebugMacro information object.
  256. const DWARFDebugMacro *getDebugMacro();
  257. /// Get a pointer to the parsed DebugMacroDWO information object.
  258. const DWARFDebugMacro *getDebugMacroDWO();
  259. /// Get a reference to the parsed accelerator table object.
  260. const DWARFDebugNames &getDebugNames();
  261. /// Get a reference to the parsed accelerator table object.
  262. const AppleAcceleratorTable &getAppleNames();
  263. /// Get a reference to the parsed accelerator table object.
  264. const AppleAcceleratorTable &getAppleTypes();
  265. /// Get a reference to the parsed accelerator table object.
  266. const AppleAcceleratorTable &getAppleNamespaces();
  267. /// Get a reference to the parsed accelerator table object.
  268. const AppleAcceleratorTable &getAppleObjC();
  269. /// Get a pointer to a parsed line table corresponding to a compile unit.
  270. /// Report any parsing issues as warnings on stderr.
  271. const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
  272. /// Get a pointer to a parsed line table corresponding to a compile unit.
  273. /// Report any recoverable parsing problems using the handler.
  274. Expected<const DWARFDebugLine::LineTable *>
  275. getLineTableForUnit(DWARFUnit *U,
  276. function_ref<void(Error)> RecoverableErrorHandler);
  277. // Clear the line table object corresponding to a compile unit for memory
  278. // management purpose. When it's referred to again, it'll be re-populated.
  279. void clearLineTableForUnit(DWARFUnit *U);
  280. DataExtractor getStringExtractor() const {
  281. return DataExtractor(DObj->getStrSection(), false, 0);
  282. }
  283. DataExtractor getStringDWOExtractor() const {
  284. return DataExtractor(DObj->getStrDWOSection(), false, 0);
  285. }
  286. DataExtractor getLineStringExtractor() const {
  287. return DataExtractor(DObj->getLineStrSection(), false, 0);
  288. }
  289. /// Wraps the returned DIEs for a given address.
  290. struct DIEsForAddress {
  291. DWARFCompileUnit *CompileUnit = nullptr;
  292. DWARFDie FunctionDIE;
  293. DWARFDie BlockDIE;
  294. explicit operator bool() const { return CompileUnit != nullptr; }
  295. };
  296. /// Get the compilation unit, the function DIE and lexical block DIE for the
  297. /// given address where applicable.
  298. /// TODO: change input parameter from "uint64_t Address"
  299. /// into "SectionedAddress Address"
  300. DIEsForAddress getDIEsForAddress(uint64_t Address);
  301. DILineInfo getLineInfoForAddress(
  302. object::SectionedAddress Address,
  303. DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  304. DILineInfo
  305. getLineInfoForDataAddress(object::SectionedAddress Address) override;
  306. DILineInfoTable getLineInfoForAddressRange(
  307. object::SectionedAddress Address, uint64_t Size,
  308. DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  309. DIInliningInfo getInliningInfoForAddress(
  310. object::SectionedAddress Address,
  311. DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  312. std::vector<DILocal>
  313. getLocalsForAddress(object::SectionedAddress Address) override;
  314. bool isLittleEndian() const { return DObj->isLittleEndian(); }
  315. static unsigned getMaxSupportedVersion() { return 5; }
  316. static bool isSupportedVersion(unsigned version) {
  317. return version >= 2 && version <= getMaxSupportedVersion();
  318. }
  319. static SmallVector<uint8_t, 3> getSupportedAddressSizes() {
  320. return {2, 4, 8};
  321. }
  322. static bool isAddressSizeSupported(unsigned AddressSize) {
  323. return llvm::is_contained(getSupportedAddressSizes(), AddressSize);
  324. }
  325. template <typename... Ts>
  326. static Error checkAddressSizeSupported(unsigned AddressSize,
  327. std::error_code EC, char const *Fmt,
  328. const Ts &...Vals) {
  329. if (isAddressSizeSupported(AddressSize))
  330. return Error::success();
  331. std::string Buffer;
  332. raw_string_ostream Stream(Buffer);
  333. Stream << format(Fmt, Vals...)
  334. << " has unsupported address size: " << AddressSize
  335. << " (supported are ";
  336. ListSeparator LS;
  337. for (unsigned Size : DWARFContext::getSupportedAddressSizes())
  338. Stream << LS << Size;
  339. Stream << ')';
  340. return make_error<StringError>(Stream.str(), EC);
  341. }
  342. std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
  343. function_ref<void(Error)> getRecoverableErrorHandler() {
  344. return RecoverableErrorHandler;
  345. }
  346. function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
  347. enum class ProcessDebugRelocations { Process, Ignore };
  348. static std::unique_ptr<DWARFContext>
  349. create(const object::ObjectFile &Obj,
  350. ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
  351. const LoadedObjectInfo *L = nullptr, std::string DWPName = "",
  352. std::function<void(Error)> RecoverableErrorHandler =
  353. WithColor::defaultErrorHandler,
  354. std::function<void(Error)> WarningHandler =
  355. WithColor::defaultWarningHandler);
  356. static std::unique_ptr<DWARFContext>
  357. create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
  358. uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost,
  359. std::function<void(Error)> RecoverableErrorHandler =
  360. WithColor::defaultErrorHandler,
  361. std::function<void(Error)> WarningHandler =
  362. WithColor::defaultWarningHandler);
  363. /// Get address size from CUs.
  364. /// TODO: refactor compile_units() to make this const.
  365. uint8_t getCUAddrSize();
  366. Triple::ArchType getArch() const {
  367. return getDWARFObj().getFile()->getArch();
  368. }
  369. /// Return the compile unit which contains instruction with provided
  370. /// address.
  371. /// TODO: change input parameter from "uint64_t Address"
  372. /// into "SectionedAddress Address"
  373. DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
  374. /// Returns whether CU/TU should be populated manually. TU Index populated
  375. /// manually only for DWARF5.
  376. bool getParseCUTUIndexManually() const { return ParseCUTUIndexManually; }
  377. /// Sets whether CU/TU should be populated manually. TU Index populated
  378. /// manually only for DWARF5.
  379. void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
  380. private:
  381. /// Parse a macro[.dwo] or macinfo[.dwo] section.
  382. std::unique_ptr<DWARFDebugMacro>
  383. parseMacroOrMacinfo(MacroSecType SectionType);
  384. void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
  385. std::vector<DILocal> &Result);
  386. };
  387. } // end namespace llvm
  388. #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  389. #ifdef __GNUC__
  390. #pragma GCC diagnostic pop
  391. #endif