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