DWARFUnit.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. //===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===//
  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. #ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H
  10. #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
  11. #include "llvm/ADT/STLExtras.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
  13. #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
  15. #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFSection.h"
  17. #include <vector>
  18. namespace llvm {
  19. namespace object {
  20. class ObjectFile;
  21. }
  22. class DWARFContext;
  23. class DWARFDebugAbbrev;
  24. class DWARFUnit;
  25. class StringRef;
  26. class raw_ostream;
  27. /// Base class for all DWARFUnitSection classes. This provides the
  28. /// functionality common to all unit types.
  29. class DWARFUnitSectionBase {
  30. public:
  31. /// Returns the Unit that contains the given section offset in the
  32. /// same section this Unit originated from.
  33. virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
  34. void parse(DWARFContext &C, const DWARFSection &Section);
  35. void parseDWO(DWARFContext &C, const DWARFSection &DWOSection);
  36. protected:
  37. virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
  38. const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
  39. StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
  40. ~DWARFUnitSectionBase() = default;
  41. };
  42. /// Concrete instance of DWARFUnitSection, specialized for one Unit type.
  43. template<typename UnitType>
  44. class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
  45. public DWARFUnitSectionBase {
  46. struct UnitOffsetComparator {
  47. bool operator()(uint32_t LHS,
  48. const std::unique_ptr<UnitType> &RHS) const {
  49. return LHS < RHS->getNextUnitOffset();
  50. }
  51. };
  52. bool Parsed;
  53. public:
  54. DWARFUnitSection() : Parsed(false) {}
  55. DWARFUnitSection(DWARFUnitSection &&DUS) :
  56. SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {}
  57. typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
  58. typedef typename UnitVector::iterator iterator;
  59. typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
  60. UnitType *getUnitForOffset(uint32_t Offset) const override {
  61. auto *CU = std::upper_bound(this->begin(), this->end(), Offset,
  62. UnitOffsetComparator());
  63. if (CU != this->end())
  64. return CU->get();
  65. return nullptr;
  66. }
  67. private:
  68. void parseImpl(DWARFContext &Context, const DWARFSection &Section,
  69. const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
  70. StringRef SOS, StringRef AOS, bool LE) override {
  71. if (Parsed)
  72. return;
  73. DataExtractor Data(Section.Data, LE, 0);
  74. uint32_t Offset = 0;
  75. while (Data.isValidOffset(Offset)) {
  76. auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
  77. AOS, LE, *this);
  78. if (!U->extract(Data, &Offset))
  79. break;
  80. this->push_back(std::move(U));
  81. Offset = this->back()->getNextUnitOffset();
  82. }
  83. Parsed = true;
  84. }
  85. };
  86. class DWARFUnit {
  87. DWARFContext &Context;
  88. // Section containing this DWARFUnit.
  89. const DWARFSection &InfoSection;
  90. const DWARFDebugAbbrev *Abbrev;
  91. StringRef RangeSection;
  92. uint32_t RangeSectionBase;
  93. StringRef StringSection;
  94. StringRef StringOffsetSection;
  95. StringRef AddrOffsetSection;
  96. uint32_t AddrOffsetSectionBase;
  97. bool isLittleEndian;
  98. const DWARFUnitSectionBase &UnitSection;
  99. uint32_t Offset;
  100. uint32_t Length;
  101. uint16_t Version;
  102. const DWARFAbbreviationDeclarationSet *Abbrevs;
  103. uint8_t AddrSize;
  104. uint64_t BaseAddr;
  105. // The compile unit debug information entry items.
  106. std::vector<DWARFDebugInfoEntryMinimal> DieArray;
  107. class DWOHolder {
  108. object::OwningBinary<object::ObjectFile> DWOFile;
  109. std::unique_ptr<DWARFContext> DWOContext;
  110. DWARFUnit *DWOU;
  111. public:
  112. DWOHolder(StringRef DWOPath);
  113. DWARFUnit *getUnit() const { return DWOU; }
  114. };
  115. std::unique_ptr<DWOHolder> DWO;
  116. protected:
  117. virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
  118. /// Size in bytes of the unit header.
  119. virtual uint32_t getHeaderSize() const { return 11; }
  120. public:
  121. DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
  122. const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
  123. StringRef SOS, StringRef AOS, bool LE,
  124. const DWARFUnitSectionBase &UnitSection);
  125. virtual ~DWARFUnit();
  126. DWARFContext& getContext() const { return Context; }
  127. StringRef getStringSection() const { return StringSection; }
  128. StringRef getStringOffsetSection() const { return StringOffsetSection; }
  129. void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
  130. AddrOffsetSection = AOS;
  131. AddrOffsetSectionBase = Base;
  132. }
  133. void setRangesSection(StringRef RS, uint32_t Base) {
  134. RangeSection = RS;
  135. RangeSectionBase = Base;
  136. }
  137. bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
  138. // FIXME: Result should be uint64_t in DWARF64.
  139. bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
  140. DataExtractor getDebugInfoExtractor() const {
  141. return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
  142. }
  143. DataExtractor getStringExtractor() const {
  144. return DataExtractor(StringSection, false, 0);
  145. }
  146. const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
  147. bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
  148. /// extractRangeList - extracts the range list referenced by this compile
  149. /// unit from .debug_ranges section. Returns true on success.
  150. /// Requires that compile unit is already extracted.
  151. bool extractRangeList(uint32_t RangeListOffset,
  152. DWARFDebugRangeList &RangeList) const;
  153. void clear();
  154. uint32_t getOffset() const { return Offset; }
  155. uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
  156. uint32_t getLength() const { return Length; }
  157. uint16_t getVersion() const { return Version; }
  158. const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
  159. return Abbrevs;
  160. }
  161. uint8_t getAddressByteSize() const { return AddrSize; }
  162. uint64_t getBaseAddress() const { return BaseAddr; }
  163. void setBaseAddress(uint64_t base_addr) {
  164. BaseAddr = base_addr;
  165. }
  166. const DWARFDebugInfoEntryMinimal *getUnitDIE(bool ExtractUnitDIEOnly = true) {
  167. extractDIEsIfNeeded(ExtractUnitDIEOnly);
  168. return DieArray.empty() ? nullptr : &DieArray[0];
  169. }
  170. const char *getCompilationDir();
  171. uint64_t getDWOId();
  172. void collectAddressRanges(DWARFAddressRangesVector &CURanges);
  173. /// getInlinedChainForAddress - fetches inlined chain for a given address.
  174. /// Returns empty chain if there is no subprogram containing address. The
  175. /// chain is valid as long as parsed compile unit DIEs are not cleared.
  176. DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address);
  177. /// getUnitSection - Return the DWARFUnitSection containing this unit.
  178. const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
  179. /// \brief Returns the number of DIEs in the unit. Parses the unit
  180. /// if necessary.
  181. unsigned getNumDIEs() {
  182. extractDIEsIfNeeded(false);
  183. return DieArray.size();
  184. }
  185. /// \brief Return the index of a DIE inside the unit's DIE vector.
  186. ///
  187. /// It is illegal to call this method with a DIE that hasn't be
  188. /// created by this unit. In other word, it's illegal to call this
  189. /// method on a DIE that isn't accessible by following
  190. /// children/sibling links starting from this unit's getUnitDIE().
  191. uint32_t getDIEIndex(const DWARFDebugInfoEntryMinimal *DIE) {
  192. assert(!DieArray.empty() && DIE >= &DieArray[0] &&
  193. DIE < &DieArray[0] + DieArray.size());
  194. return DIE - &DieArray[0];
  195. }
  196. /// \brief Return the DIE object at the given index.
  197. const DWARFDebugInfoEntryMinimal *getDIEAtIndex(unsigned Index) const {
  198. assert(Index < DieArray.size());
  199. return &DieArray[Index];
  200. }
  201. /// \brief Return the DIE object for a given offset inside the
  202. /// unit's DIE vector.
  203. ///
  204. /// The unit needs to have his DIEs extracted for this method to work.
  205. const DWARFDebugInfoEntryMinimal *getDIEForOffset(uint32_t Offset) const {
  206. assert(!DieArray.empty());
  207. auto it = std::lower_bound(
  208. DieArray.begin(), DieArray.end(), Offset,
  209. [=](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) {
  210. return LHS.getOffset() < Offset;
  211. });
  212. return it == DieArray.end() ? nullptr : &*it;
  213. }
  214. private:
  215. /// Size in bytes of the .debug_info data associated with this compile unit.
  216. size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
  217. /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
  218. /// hasn't already been done. Returns the number of DIEs parsed at this call.
  219. size_t extractDIEsIfNeeded(bool CUDieOnly);
  220. /// extractDIEsToVector - Appends all parsed DIEs to a vector.
  221. void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
  222. std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const;
  223. /// setDIERelations - We read in all of the DIE entries into our flat list
  224. /// of DIE entries and now we need to go back through all of them and set the
  225. /// parent, sibling and child pointers for quick DIE navigation.
  226. void setDIERelations();
  227. /// clearDIEs - Clear parsed DIEs to keep memory usage low.
  228. void clearDIEs(bool KeepCUDie);
  229. /// parseDWO - Parses .dwo file for current compile unit. Returns true if
  230. /// it was actually constructed.
  231. bool parseDWO();
  232. /// getSubprogramForAddress - Returns subprogram DIE with address range
  233. /// encompassing the provided address. The pointer is alive as long as parsed
  234. /// compile unit DIEs are not cleared.
  235. const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address);
  236. };
  237. }
  238. #endif