1 | //===- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit -----*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains support for writing dwarf compile unit. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H |
14 | #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H |
15 | |
16 | #include "DwarfDebug.h" |
17 | #include "DwarfUnit.h" |
18 | #include "llvm/ADT/ArrayRef.h" |
19 | #include "llvm/ADT/DenseMap.h" |
20 | #include "llvm/ADT/SmallVector.h" |
21 | #include "llvm/ADT/StringMap.h" |
22 | #include "llvm/ADT/StringRef.h" |
23 | #include "llvm/BinaryFormat/Dwarf.h" |
24 | #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" |
25 | #include "llvm/CodeGen/LexicalScopes.h" |
26 | #include "llvm/IR/DebugInfoMetadata.h" |
27 | #include "llvm/Support/Casting.h" |
28 | #include <cstdint> |
29 | #include <memory> |
30 | |
31 | namespace llvm { |
32 | |
33 | class AsmPrinter; |
34 | class DIE; |
35 | class DIELoc; |
36 | class DIEValueList; |
37 | class DwarfFile; |
38 | class GlobalVariable; |
39 | class MCExpr; |
40 | class MCSymbol; |
41 | class MDNode; |
42 | |
43 | enum class UnitKind { Skeleton, Full }; |
44 | |
45 | class DwarfCompileUnit final : public DwarfUnit { |
46 | bool HasRangeLists = false; |
47 | |
48 | /// The start of the unit line section, this is also |
49 | /// reused in appyStmtList. |
50 | MCSymbol *LineTableStartSym; |
51 | |
52 | /// Skeleton unit associated with this unit. |
53 | DwarfCompileUnit *Skeleton = nullptr; |
54 | |
55 | /// The start of the unit macro info within macro section. |
56 | MCSymbol *MacroLabelBegin; |
57 | |
58 | /// GlobalNames - A map of globally visible named entities for this unit. |
59 | StringMap<const DIE *> GlobalNames; |
60 | |
61 | /// GlobalTypes - A map of globally visible types for this unit. |
62 | StringMap<const DIE *> GlobalTypes; |
63 | |
64 | // List of ranges for a given compile unit. |
65 | SmallVector<RangeSpan, 2> CURanges; |
66 | |
67 | // The base address of this unit, if any. Used for relative references in |
68 | // ranges/locs. |
69 | const MCSymbol *BaseAddress = nullptr; |
70 | |
71 | using MDNodeSetVector = |
72 | SetVector<const MDNode *, SmallVector<const MDNode *, 4>, |
73 | SmallPtrSet<const MDNode *, 4>>; |
74 | |
75 | // List of entities (either static locals, types or imports) that |
76 | // belong to subprograms within this CU. |
77 | MDNodeSetVector DeferredLocalDecls; |
78 | |
79 | // List of concrete lexical block scopes belong to subprograms within this CU. |
80 | DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs; |
81 | |
82 | // List of abstract local scopes (either DISubprogram or DILexicalBlock). |
83 | DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs; |
84 | |
85 | DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities; |
86 | |
87 | /// DWO ID for correlating skeleton and split units. |
88 | uint64_t DWOId = 0; |
89 | |
90 | const DIFile *LastFile = nullptr; |
91 | unsigned LastFileID; |
92 | |
93 | /// \anchor applyConcreteDbgVariableAttribute |
94 | /// \name applyConcreteDbgVariableAttribute |
95 | /// Overload set which applies attributes to \c VariableDie based on |
96 | /// the active variant of \c DV, which is passed as the first argument. |
97 | ///@{ |
98 | |
99 | /// See \ref applyConcreteDbgVariableAttribute |
100 | void applyConcreteDbgVariableAttributes(const Loc::Single &Single, |
101 | const DbgVariable &DV, |
102 | DIE &VariableDie); |
103 | /// See \ref applyConcreteDbgVariableAttribute |
104 | void applyConcreteDbgVariableAttributes(const Loc::Multi &Multi, |
105 | const DbgVariable &DV, |
106 | DIE &VariableDie); |
107 | /// See \ref applyConcreteDbgVariableAttribute |
108 | void applyConcreteDbgVariableAttributes(const Loc::MMI &MMI, |
109 | const DbgVariable &DV, |
110 | DIE &VariableDie); |
111 | /// See \ref applyConcreteDbgVariableAttribute |
112 | void applyConcreteDbgVariableAttributes(const Loc::EntryValue &EntryValue, |
113 | const DbgVariable &DV, |
114 | DIE &VariableDie); |
115 | /// See \ref applyConcreteDbgVariableAttribute |
116 | void applyConcreteDbgVariableAttributes(const std::monostate &, |
117 | const DbgVariable &DV, |
118 | DIE &VariableDie); |
119 | |
120 | ///@} |
121 | |
122 | bool isDwoUnit() const override; |
123 | |
124 | DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() { |
125 | if (isDwoUnit() && !DD->shareAcrossDWOCUs()) |
126 | return AbstractLocalScopeDIEs; |
127 | return DU->getAbstractScopeDIEs(); |
128 | } |
129 | |
130 | DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() { |
131 | if (isDwoUnit() && !DD->shareAcrossDWOCUs()) |
132 | return AbstractEntities; |
133 | return DU->getAbstractEntities(); |
134 | } |
135 | |
136 | void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override; |
137 | |
138 | /// Add info for Wasm-global-based relocation. |
139 | void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName, |
140 | uint64_t GlobalIndex); |
141 | |
142 | public: |
143 | DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, |
144 | DwarfDebug *DW, DwarfFile *DWU, |
145 | UnitKind Kind = UnitKind::Full); |
146 | |
147 | bool hasRangeLists() const { return HasRangeLists; } |
148 | |
149 | DwarfCompileUnit *getSkeleton() const { |
150 | return Skeleton; |
151 | } |
152 | |
153 | bool includeMinimalInlineScopes() const; |
154 | |
155 | void initStmtList(); |
156 | |
157 | /// Apply the DW_AT_stmt_list from this compile unit to the specified DIE. |
158 | void applyStmtList(DIE &D); |
159 | |
160 | /// Get line table start symbol for this unit. |
161 | MCSymbol *getLineTableStartSym() const { return LineTableStartSym; } |
162 | |
163 | /// A pair of GlobalVariable and DIExpression. |
164 | struct GlobalExpr { |
165 | const GlobalVariable *Var; |
166 | const DIExpression *Expr; |
167 | }; |
168 | |
169 | struct BaseTypeRef { |
170 | BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) : |
171 | BitSize(BitSize), Encoding(Encoding) {} |
172 | unsigned BitSize; |
173 | dwarf::TypeKind Encoding; |
174 | DIE *Die = nullptr; |
175 | }; |
176 | |
177 | std::vector<BaseTypeRef> ExprRefedBaseTypes; |
178 | |
179 | /// Get or create global variable DIE. |
180 | DIE * |
181 | getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, |
182 | ArrayRef<GlobalExpr> GlobalExprs); |
183 | |
184 | DIE *getOrCreateCommonBlock(const DICommonBlock *CB, |
185 | ArrayRef<GlobalExpr> GlobalExprs); |
186 | |
187 | void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV, |
188 | ArrayRef<GlobalExpr> GlobalExprs); |
189 | |
190 | /// addLabelAddress - Add a dwarf label attribute data and value using |
191 | /// either DW_FORM_addr or DW_FORM_GNU_addr_index. |
192 | void addLabelAddress(DIE &Die, dwarf::Attribute Attribute, |
193 | const MCSymbol *Label); |
194 | |
195 | /// addLocalLabelAddress - Add a dwarf label attribute data and value using |
196 | /// DW_FORM_addr only. |
197 | void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute, |
198 | const MCSymbol *Label); |
199 | |
200 | DwarfCompileUnit &getCU() override { return *this; } |
201 | |
202 | unsigned getOrCreateSourceID(const DIFile *File) override; |
203 | |
204 | /// addRange - Add an address range to the list of ranges for this unit. |
205 | void addRange(RangeSpan Range); |
206 | |
207 | void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End); |
208 | |
209 | /// Find DIE for the given subprogram and attach appropriate |
210 | /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global |
211 | /// variables in this scope then create and insert DIEs for these |
212 | /// variables. |
213 | DIE &updateSubprogramScopeDIE(const DISubprogram *SP); |
214 | |
215 | void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE); |
216 | |
217 | /// A helper function to construct a RangeSpanList for a given |
218 | /// lexical scope. |
219 | void addScopeRangeList(DIE &ScopeDIE, SmallVector<RangeSpan, 2> Range); |
220 | |
221 | void attachRangesOrLowHighPC(DIE &D, SmallVector<RangeSpan, 2> Ranges); |
222 | |
223 | void attachRangesOrLowHighPC(DIE &D, |
224 | const SmallVectorImpl<InsnRange> &Ranges); |
225 | |
226 | /// This scope represents an inlined body of a function. Construct a |
227 | /// DIE to represent this concrete inlined copy of the function. |
228 | DIE *constructInlinedScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE); |
229 | |
230 | /// Construct new DW_TAG_lexical_block for this scope and |
231 | /// attach DW_AT_low_pc/DW_AT_high_pc labels. |
232 | DIE *constructLexicalScopeDIE(LexicalScope *Scope); |
233 | |
234 | /// Get a DIE for the given DILexicalBlock. |
235 | /// Note that this function assumes that the DIE has been already created |
236 | /// and it's an error, if it hasn't. |
237 | DIE *getLexicalBlockDIE(const DILexicalBlock *LB); |
238 | |
239 | /// Construct a DIE for the given DbgVariable. |
240 | DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false); |
241 | |
242 | /// Convenience overload which writes the DIE pointer into an out variable |
243 | /// ObjectPointer in addition to returning it. |
244 | DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope, |
245 | DIE *&ObjectPointer); |
246 | |
247 | /// Construct a DIE for the given DbgLabel. |
248 | DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope); |
249 | |
250 | void createBaseTypeDIEs(); |
251 | |
252 | /// Construct a DIE for a given scope. |
253 | /// This instance of 'getOrCreateContextDIE()' can handle DILocalScope. |
254 | DIE *getOrCreateContextDIE(const DIScope *Ty) override; |
255 | |
256 | /// Construct a DIE for this subprogram scope. |
257 | DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, |
258 | LexicalScope *Scope); |
259 | |
260 | DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE); |
261 | |
262 | void constructAbstractSubprogramScopeDIE(LexicalScope *Scope); |
263 | |
264 | /// Whether to use the GNU analog for a DWARF5 tag, attribute, or location |
265 | /// atom. Only applicable when emitting otherwise DWARF4-compliant debug info. |
266 | bool useGNUAnalogForDwarf5Feature() const; |
267 | |
268 | /// This takes a DWARF 5 tag and returns it or a GNU analog. |
269 | dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const; |
270 | |
271 | /// This takes a DWARF 5 attribute and returns it or a GNU analog. |
272 | dwarf::Attribute getDwarf5OrGNUAttr(dwarf::Attribute Attr) const; |
273 | |
274 | /// This takes a DWARF 5 location atom and either returns it or a GNU analog. |
275 | dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const; |
276 | |
277 | /// Construct a call site entry DIE describing a call within \p Scope to a |
278 | /// callee described by \p CalleeSP. |
279 | /// \p IsTail specifies whether the call is a tail call. |
280 | /// \p PCAddr points to the PC value after the call instruction. |
281 | /// \p CallAddr points to the PC value at the call instruction (or is null). |
282 | /// \p CallReg is a register location for an indirect call. For direct calls |
283 | /// the \p CallReg is set to 0. |
284 | DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP, |
285 | bool IsTail, const MCSymbol *PCAddr, |
286 | const MCSymbol *CallAddr, unsigned CallReg); |
287 | /// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params |
288 | /// were collected by the \ref collectCallSiteParameters. |
289 | /// Note: The order of parameters does not matter, since debuggers recognize |
290 | /// call site parameters by the DW_AT_location attribute. |
291 | void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE, |
292 | SmallVector<DbgCallSiteParam, 4> &Params); |
293 | |
294 | /// Get or create a DIE for an imported entity. |
295 | DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE); |
296 | DIE *constructImportedEntityDIE(const DIImportedEntity *IE); |
297 | |
298 | void finishSubprogramDefinition(const DISubprogram *SP); |
299 | void finishEntityDefinition(const DbgEntity *Entity); |
300 | |
301 | /// Find abstract variable associated with Var. |
302 | using InlinedEntity = DbgValueHistoryMap::InlinedEntity; |
303 | DbgEntity *getExistingAbstractEntity(const DINode *Node); |
304 | void createAbstractEntity(const DINode *Node, LexicalScope *Scope); |
305 | |
306 | /// Set the skeleton unit associated with this unit. |
307 | void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; } |
308 | |
309 | unsigned () const override { |
310 | // DWARF v5 added the DWO ID to the header for split/skeleton units. |
311 | unsigned DWOIdSize = |
312 | DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t) |
313 | : 0; |
314 | return DwarfUnit::getHeaderSize() + DWOIdSize; |
315 | } |
316 | unsigned getLength() { |
317 | return Asm->getUnitLengthFieldByteSize() + // Length field |
318 | getHeaderSize() + getUnitDie().getSize(); |
319 | } |
320 | |
321 | void (bool UseOffsets) override; |
322 | |
323 | /// Add the DW_AT_addr_base attribute to the unit DIE. |
324 | void addAddrTableBase(); |
325 | |
326 | MCSymbol *getMacroLabelBegin() const { |
327 | return MacroLabelBegin; |
328 | } |
329 | |
330 | /// Add a new global name to the compile unit. |
331 | void addGlobalName(StringRef Name, const DIE &Die, |
332 | const DIScope *Context) override; |
333 | |
334 | /// Add a new global name present in a type unit to this compile unit. |
335 | void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context); |
336 | |
337 | /// Add a new global type to the compile unit. |
338 | void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, |
339 | const DIScope *Context) override; |
340 | |
341 | /// Add a new global type present in a type unit to this compile unit. |
342 | void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context); |
343 | |
344 | const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; } |
345 | const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; } |
346 | |
347 | /// Add DW_AT_location attribute for a DbgVariable based on provided |
348 | /// MachineLocation. |
349 | void addVariableAddress(const DbgVariable &DV, DIE &Die, |
350 | MachineLocation Location); |
351 | /// Add an address attribute to a die based on the location provided. |
352 | void addAddress(DIE &Die, dwarf::Attribute Attribute, |
353 | const MachineLocation &Location); |
354 | |
355 | /// Start with the address based on the location provided, and generate the |
356 | /// DWARF information necessary to find the actual variable (navigating the |
357 | /// extra location information encoded in the type) based on the starting |
358 | /// location. Add the DWARF information to the die. |
359 | void addComplexAddress(const DIExpression *DIExpr, DIE &Die, |
360 | dwarf::Attribute Attribute, |
361 | const MachineLocation &Location); |
362 | |
363 | /// Add a Dwarf loclistptr attribute data and value. |
364 | void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index); |
365 | |
366 | /// Add attributes to \p Var which reflect the common attributes of \p |
367 | /// VariableDie, namely those which are not dependant on the active variant. |
368 | void applyCommonDbgVariableAttributes(const DbgVariable &Var, |
369 | DIE &VariableDie); |
370 | |
371 | /// Add a Dwarf expression attribute data and value. |
372 | void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr); |
373 | |
374 | void applySubprogramAttributesToDefinition(const DISubprogram *SP, |
375 | DIE &SPDie); |
376 | |
377 | void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie); |
378 | |
379 | /// getRanges - Get the list of ranges for this unit. |
380 | const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; } |
381 | SmallVector<RangeSpan, 2> takeRanges() { return std::move(CURanges); } |
382 | |
383 | void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } |
384 | const MCSymbol *getBaseAddress() const { return BaseAddress; } |
385 | |
386 | uint64_t getDWOId() const { return DWOId; } |
387 | void setDWOId(uint64_t DwoId) { DWOId = DwoId; } |
388 | |
389 | bool hasDwarfPubSections() const; |
390 | |
391 | void addBaseTypeRef(DIEValueList &Die, int64_t Idx); |
392 | |
393 | MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; } |
394 | }; |
395 | |
396 | } // end namespace llvm |
397 | |
398 | #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H |
399 | |