DWARFContext.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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. Optional<DenseMap<uint64_t, DWARFTypeUnit*>> NormalTypeUnits;
  56. std::unique_ptr<DWARFUnitIndex> CUIndex;
  57. std::unique_ptr<DWARFGdbIndex> GdbIndex;
  58. std::unique_ptr<DWARFUnitIndex> TUIndex;
  59. std::unique_ptr<DWARFDebugAbbrev> Abbrev;
  60. std::unique_ptr<DWARFDebugLoc> Loc;
  61. std::unique_ptr<DWARFDebugAranges> Aranges;
  62. std::unique_ptr<DWARFDebugLine> Line;
  63. std::unique_ptr<DWARFDebugFrame> DebugFrame;
  64. std::unique_ptr<DWARFDebugFrame> EHFrame;
  65. std::unique_ptr<DWARFDebugMacro> Macro;
  66. std::unique_ptr<DWARFDebugMacro> Macinfo;
  67. std::unique_ptr<DWARFDebugNames> Names;
  68. std::unique_ptr<AppleAcceleratorTable> AppleNames;
  69. std::unique_ptr<AppleAcceleratorTable> AppleTypes;
  70. std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
  71. std::unique_ptr<AppleAcceleratorTable> AppleObjC;
  72. DWARFUnitVector DWOUnits;
  73. Optional<DenseMap<uint64_t, DWARFTypeUnit*>> DWOTypeUnits;
  74. std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
  75. std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
  76. std::unique_ptr<DWARFDebugMacro> MacroDWO;
  77. /// The maximum DWARF version of all units.
  78. unsigned MaxVersion = 0;
  79. struct DWOFile {
  80. object::OwningBinary<object::ObjectFile> File;
  81. std::unique_ptr<DWARFContext> Context;
  82. };
  83. StringMap<std::weak_ptr<DWOFile>> DWOFiles;
  84. std::weak_ptr<DWOFile> DWP;
  85. bool CheckedForDWP = false;
  86. std::string DWPName;
  87. std::unique_ptr<MCRegisterInfo> RegInfo;
  88. std::function<void(Error)> RecoverableErrorHandler =
  89. WithColor::defaultErrorHandler;
  90. std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
  91. /// Read compile units from the debug_info section (if necessary)
  92. /// and type units from the debug_types sections (if necessary)
  93. /// and store them in NormalUnits.
  94. void parseNormalUnits();
  95. /// Read compile units from the debug_info.dwo section (if necessary)
  96. /// and type units from the debug_types.dwo section (if necessary)
  97. /// and store them in DWOUnits.
  98. /// If \p Lazy is true, set up to parse but don't actually parse them.
  99. enum { EagerParse = false, LazyParse = true };
  100. void parseDWOUnits(bool Lazy = false);
  101. std::unique_ptr<const DWARFObject> DObj;
  102. /// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
  103. /// section.
  104. enum MacroSecType {
  105. MacinfoSection,
  106. MacinfoDwoSection,
  107. MacroSection,
  108. MacroDwoSection
  109. };
  110. public:
  111. DWARFContext(std::unique_ptr<const DWARFObject> DObj,
  112. std::string DWPName = "",
  113. std::function<void(Error)> RecoverableErrorHandler =
  114. WithColor::defaultErrorHandler,
  115. std::function<void(Error)> WarningHandler =
  116. WithColor::defaultWarningHandler);
  117. ~DWARFContext();
  118. DWARFContext(DWARFContext &) = delete;
  119. DWARFContext &operator=(DWARFContext &) = delete;
  120. const DWARFObject &getDWARFObj() const { return *DObj; }
  121. static bool classof(const DIContext *DICtx) {
  122. return DICtx->getKind() == CK_DWARF;
  123. }
  124. /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
  125. /// dump only the record at the specified offset.
  126. void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  127. std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
  128. void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
  129. std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
  130. dump(OS, DumpOpts, DumpOffsets);
  131. }
  132. bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
  133. using unit_iterator_range = DWARFUnitVector::iterator_range;
  134. using compile_unit_range = DWARFUnitVector::compile_unit_range;
  135. /// Get units from .debug_info in this context.
  136. unit_iterator_range info_section_units() {
  137. parseNormalUnits();
  138. return unit_iterator_range(NormalUnits.begin(),
  139. NormalUnits.begin() +
  140. NormalUnits.getNumInfoUnits());
  141. }
  142. const DWARFUnitVector &getNormalUnitsVector() {
  143. parseNormalUnits();
  144. return NormalUnits;
  145. }
  146. /// Get units from .debug_types in this context.
  147. unit_iterator_range types_section_units() {
  148. parseNormalUnits();
  149. return unit_iterator_range(
  150. NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
  151. }
  152. /// Get compile units in this context.
  153. compile_unit_range compile_units() {
  154. return make_filter_range(info_section_units(), isCompileUnit);
  155. }
  156. // If you want type_units(), it'll need to be a concat iterator of a filter of
  157. // TUs in info_section + all the (all type) units in types_section
  158. /// Get all normal compile/type units in this context.
  159. unit_iterator_range normal_units() {
  160. parseNormalUnits();
  161. return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
  162. }
  163. /// Get units from .debug_info..dwo in the DWO context.
  164. unit_iterator_range dwo_info_section_units() {
  165. parseDWOUnits();
  166. return unit_iterator_range(DWOUnits.begin(),
  167. DWOUnits.begin() + DWOUnits.getNumInfoUnits());
  168. }
  169. const DWARFUnitVector &getDWOUnitsVector() {
  170. parseDWOUnits();
  171. return DWOUnits;
  172. }
  173. /// Get units from .debug_types.dwo in the DWO context.
  174. unit_iterator_range dwo_types_section_units() {
  175. parseDWOUnits();
  176. return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
  177. DWOUnits.end());
  178. }
  179. /// Get compile units in the DWO context.
  180. compile_unit_range dwo_compile_units() {
  181. return make_filter_range(dwo_info_section_units(), isCompileUnit);
  182. }
  183. // If you want dwo_type_units(), it'll need to be a concat iterator of a
  184. // filter of TUs in dwo_info_section + all the (all type) units in
  185. // dwo_types_section.
  186. /// Get all units in the DWO context.
  187. unit_iterator_range dwo_units() {
  188. parseDWOUnits();
  189. return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
  190. }
  191. /// Get the number of compile units in this context.
  192. unsigned getNumCompileUnits() {
  193. parseNormalUnits();
  194. return NormalUnits.getNumInfoUnits();
  195. }
  196. /// Get the number of type units in this context.
  197. unsigned getNumTypeUnits() {
  198. parseNormalUnits();
  199. return NormalUnits.getNumTypesUnits();
  200. }
  201. /// Get the number of compile units in the DWO context.
  202. unsigned getNumDWOCompileUnits() {
  203. parseDWOUnits();
  204. return DWOUnits.getNumInfoUnits();
  205. }
  206. /// Get the number of type units in the DWO context.
  207. unsigned getNumDWOTypeUnits() {
  208. parseDWOUnits();
  209. return DWOUnits.getNumTypesUnits();
  210. }
  211. /// Get the unit at the specified index.
  212. DWARFUnit *getUnitAtIndex(unsigned index) {
  213. parseNormalUnits();
  214. return NormalUnits[index].get();
  215. }
  216. /// Get the unit at the specified index for the DWO units.
  217. DWARFUnit *getDWOUnitAtIndex(unsigned index) {
  218. parseDWOUnits();
  219. return DWOUnits[index].get();
  220. }
  221. DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
  222. DWARFTypeUnit *getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO);
  223. /// Return the compile unit that includes an offset (relative to .debug_info).
  224. DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
  225. /// Get a DIE given an exact offset.
  226. DWARFDie getDIEForOffset(uint64_t Offset);
  227. unsigned getMaxVersion() {
  228. // Ensure info units have been parsed to discover MaxVersion
  229. info_section_units();
  230. return MaxVersion;
  231. }
  232. unsigned getMaxDWOVersion() {
  233. // Ensure DWO info units have been parsed to discover MaxVersion
  234. dwo_info_section_units();
  235. return MaxVersion;
  236. }
  237. void setMaxVersionIfGreater(unsigned Version) {
  238. if (Version > MaxVersion)
  239. MaxVersion = Version;
  240. }
  241. const DWARFUnitIndex &getCUIndex();
  242. DWARFGdbIndex &getGdbIndex();
  243. const DWARFUnitIndex &getTUIndex();
  244. /// Get a pointer to the parsed DebugAbbrev object.
  245. const DWARFDebugAbbrev *getDebugAbbrev();
  246. /// Get a pointer to the parsed DebugLoc object.
  247. const DWARFDebugLoc *getDebugLoc();
  248. /// Get a pointer to the parsed dwo abbreviations object.
  249. const DWARFDebugAbbrev *getDebugAbbrevDWO();
  250. /// Get a pointer to the parsed DebugAranges object.
  251. const DWARFDebugAranges *getDebugAranges();
  252. /// Get a pointer to the parsed frame information object.
  253. Expected<const DWARFDebugFrame *> getDebugFrame();
  254. /// Get a pointer to the parsed eh frame information object.
  255. Expected<const DWARFDebugFrame *> getEHFrame();
  256. /// Get a pointer to the parsed DebugMacinfo information object.
  257. const DWARFDebugMacro *getDebugMacinfo();
  258. /// Get a pointer to the parsed DebugMacinfoDWO information object.
  259. const DWARFDebugMacro *getDebugMacinfoDWO();
  260. /// Get a pointer to the parsed DebugMacro information object.
  261. const DWARFDebugMacro *getDebugMacro();
  262. /// Get a pointer to the parsed DebugMacroDWO information object.
  263. const DWARFDebugMacro *getDebugMacroDWO();
  264. /// Get a reference to the parsed accelerator table object.
  265. const DWARFDebugNames &getDebugNames();
  266. /// Get a reference to the parsed accelerator table object.
  267. const AppleAcceleratorTable &getAppleNames();
  268. /// Get a reference to the parsed accelerator table object.
  269. const AppleAcceleratorTable &getAppleTypes();
  270. /// Get a reference to the parsed accelerator table object.
  271. const AppleAcceleratorTable &getAppleNamespaces();
  272. /// Get a reference to the parsed accelerator table object.
  273. const AppleAcceleratorTable &getAppleObjC();
  274. /// Get a pointer to a parsed line table corresponding to a compile unit.
  275. /// Report any parsing issues as warnings on stderr.
  276. const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
  277. /// Get a pointer to a parsed line table corresponding to a compile unit.
  278. /// Report any recoverable parsing problems using the handler.
  279. Expected<const DWARFDebugLine::LineTable *>
  280. getLineTableForUnit(DWARFUnit *U,
  281. function_ref<void(Error)> RecoverableErrorHandler);
  282. DataExtractor getStringExtractor() const {
  283. return DataExtractor(DObj->getStrSection(), false, 0);
  284. }
  285. DataExtractor getStringDWOExtractor() const {
  286. return DataExtractor(DObj->getStrDWOSection(), false, 0);
  287. }
  288. DataExtractor getLineStringExtractor() const {
  289. return DataExtractor(DObj->getLineStrSection(), false, 0);
  290. }
  291. /// Wraps the returned DIEs for a given address.
  292. struct DIEsForAddress {
  293. DWARFCompileUnit *CompileUnit = nullptr;
  294. DWARFDie FunctionDIE;
  295. DWARFDie BlockDIE;
  296. explicit operator bool() const { return CompileUnit != nullptr; }
  297. };
  298. /// Get the compilation unit, the function DIE and lexical block DIE for the
  299. /// given address where applicable.
  300. /// TODO: change input parameter from "uint64_t Address"
  301. /// into "SectionedAddress Address"
  302. DIEsForAddress getDIEsForAddress(uint64_t Address);
  303. DILineInfo getLineInfoForAddress(
  304. object::SectionedAddress Address,
  305. DILineInfoSpecifier Specifier = DILineInfoSpecifier()) 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. const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
  344. function_ref<void(Error)> getRecoverableErrorHandler() {
  345. return RecoverableErrorHandler;
  346. }
  347. function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
  348. enum class ProcessDebugRelocations { Process, Ignore };
  349. static std::unique_ptr<DWARFContext>
  350. create(const object::ObjectFile &Obj,
  351. ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
  352. const LoadedObjectInfo *L = nullptr, std::string DWPName = "",
  353. std::function<void(Error)> RecoverableErrorHandler =
  354. WithColor::defaultErrorHandler,
  355. std::function<void(Error)> WarningHandler =
  356. WithColor::defaultWarningHandler);
  357. static std::unique_ptr<DWARFContext>
  358. create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
  359. uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost,
  360. std::function<void(Error)> RecoverableErrorHandler =
  361. WithColor::defaultErrorHandler,
  362. std::function<void(Error)> WarningHandler =
  363. WithColor::defaultWarningHandler);
  364. /// Loads register info for the architecture of the provided object file.
  365. /// Improves readability of dumped DWARF expressions. Requires the caller to
  366. /// have initialized the relevant target descriptions.
  367. Error loadRegisterInfo(const object::ObjectFile &Obj);
  368. /// Get address size from CUs.
  369. /// TODO: refactor compile_units() to make this const.
  370. uint8_t getCUAddrSize();
  371. Triple::ArchType getArch() const {
  372. return getDWARFObj().getFile()->getArch();
  373. }
  374. /// Return the compile unit which contains instruction with provided
  375. /// address.
  376. /// TODO: change input parameter from "uint64_t Address"
  377. /// into "SectionedAddress Address"
  378. DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
  379. private:
  380. /// Parse a macro[.dwo] or macinfo[.dwo] section.
  381. std::unique_ptr<DWARFDebugMacro>
  382. parseMacroOrMacinfo(MacroSecType SectionType);
  383. void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
  384. std::vector<DILocal> &Result);
  385. };
  386. } // end namespace llvm
  387. #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  388. #ifdef __GNUC__
  389. #pragma GCC diagnostic pop
  390. #endif