DWARFContext.h 15 KB

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