1 //===- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit -----*- 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 // This file contains support for writing dwarf compile unit.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
16 
17 #include "DwarfDebug.h"
18 #include "DwarfUnit.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/BinaryFormat/Dwarf.h"
25 #include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
26 #include "llvm/CodeGen/DIE.h"
27 #include "llvm/CodeGen/LexicalScopes.h"
28 #include "llvm/IR/DebugInfoMetadata.h"
29 #include "llvm/Support/Casting.h"
30 #include <algorithm>
31 #include <cassert>
32 #include <cstdint>
33 #include <memory>
34 
35 namespace llvm {
36 
37 class AsmPrinter;
38 class DwarfFile;
39 class GlobalVariable;
40 class MCExpr;
41 class MCSymbol;
42 class MDNode;
43 
44 class DwarfCompileUnit final : public DwarfUnit {
45   /// A numeric ID unique among all CUs in the module
46   unsigned UniqueID;
47   bool HasRangeLists = false;
48 
49   /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding
50   /// the need to search for it in applyStmtList.
51   DIE::value_iterator StmtListValue;
52 
53   /// Skeleton unit associated with this unit.
54   DwarfCompileUnit *Skeleton = nullptr;
55 
56   /// The start of the unit within its section.
57   MCSymbol *LabelBegin;
58 
59   /// The start of the unit macro info within macro section.
60   MCSymbol *MacroLabelBegin;
61 
62   using ImportedEntityList = SmallVector<const MDNode *, 8>;
63   using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>;
64 
65   ImportedEntityMap ImportedEntities;
66 
67   /// GlobalNames - A map of globally visible named entities for this unit.
68   StringMap<const DIE *> GlobalNames;
69 
70   /// GlobalTypes - A map of globally visible types for this unit.
71   StringMap<const DIE *> GlobalTypes;
72 
73   // List of ranges for a given compile unit.
74   SmallVector<RangeSpan, 2> CURanges;
75 
76   // The base address of this unit, if any. Used for relative references in
77   // ranges/locs.
78   const MCSymbol *BaseAddress = nullptr;
79 
80   DenseMap<const MDNode *, DIE *> AbstractSPDies;
81   DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
82 
83   /// DWO ID for correlating skeleton and split units.
84   uint64_t DWOId = 0;
85 
86   /// Construct a DIE for the given DbgVariable without initializing the
87   /// DbgVariable's DIE reference.
88   DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
89 
90   bool isDwoUnit() const override;
91 
getAbstractSPDies()92   DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
93     if (isDwoUnit() && !DD->shareAcrossDWOCUs())
94       return AbstractSPDies;
95     return DU->getAbstractSPDies();
96   }
97 
getAbstractEntities()98   DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
99     if (isDwoUnit() && !DD->shareAcrossDWOCUs())
100       return AbstractEntities;
101     return DU->getAbstractEntities();
102   }
103 
104 public:
105   DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
106                    DwarfDebug *DW, DwarfFile *DWU);
107 
hasRangeLists()108   bool hasRangeLists() const { return HasRangeLists; }
getUniqueID()109   unsigned getUniqueID() const { return UniqueID; }
110 
getSkeleton()111   DwarfCompileUnit *getSkeleton() const {
112     return Skeleton;
113   }
114 
115   bool includeMinimalInlineScopes() const;
116 
117   void initStmtList();
118 
119   /// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
120   void applyStmtList(DIE &D);
121 
122   /// A pair of GlobalVariable and DIExpression.
123   struct GlobalExpr {
124     const GlobalVariable *Var;
125     const DIExpression *Expr;
126   };
127 
128   /// Get or create global variable DIE.
129   DIE *
130   getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
131                                ArrayRef<GlobalExpr> GlobalExprs);
132 
133   /// addLabelAddress - Add a dwarf label attribute data and value using
134   /// either DW_FORM_addr or DW_FORM_GNU_addr_index.
135   void addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
136                        const MCSymbol *Label);
137 
138   /// addLocalLabelAddress - Add a dwarf label attribute data and value using
139   /// DW_FORM_addr only.
140   void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute,
141                             const MCSymbol *Label);
142 
getCU()143   DwarfCompileUnit &getCU() override { return *this; }
144 
145   unsigned getOrCreateSourceID(const DIFile *File) override;
146 
addImportedEntity(const DIImportedEntity * IE)147   void addImportedEntity(const DIImportedEntity* IE) {
148     DIScope *Scope = IE->getScope();
149     assert(Scope && "Invalid Scope encoding!");
150     if (!isa<DILocalScope>(Scope))
151       // No need to add imported enities that are not local declaration.
152       return;
153 
154     auto *LocalScope = cast<DILocalScope>(Scope)->getNonLexicalBlockFileScope();
155     ImportedEntities[LocalScope].push_back(IE);
156   }
157 
158   /// addRange - Add an address range to the list of ranges for this unit.
159   void addRange(RangeSpan Range);
160 
161   void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End);
162 
163   /// Find DIE for the given subprogram and attach appropriate
164   /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
165   /// variables in this scope then create and insert DIEs for these
166   /// variables.
167   DIE &updateSubprogramScopeDIE(const DISubprogram *SP);
168 
169   void constructScopeDIE(LexicalScope *Scope,
170                          SmallVectorImpl<DIE *> &FinalChildren);
171 
172   /// A helper function to construct a RangeSpanList for a given
173   /// lexical scope.
174   void addScopeRangeList(DIE &ScopeDIE, SmallVector<RangeSpan, 2> Range);
175 
176   void attachRangesOrLowHighPC(DIE &D, SmallVector<RangeSpan, 2> Ranges);
177 
178   void attachRangesOrLowHighPC(DIE &D,
179                                const SmallVectorImpl<InsnRange> &Ranges);
180 
181   /// This scope represents inlined body of a function. Construct
182   /// DIE to represent this concrete inlined copy of the function.
183   DIE *constructInlinedScopeDIE(LexicalScope *Scope);
184 
185   /// Construct new DW_TAG_lexical_block for this scope and
186   /// attach DW_AT_low_pc/DW_AT_high_pc labels.
187   DIE *constructLexicalScopeDIE(LexicalScope *Scope);
188 
189   /// constructVariableDIE - Construct a DIE for the given DbgVariable.
190   DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
191 
192   DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
193                             DIE *&ObjectPointer);
194 
195   /// Construct a DIE for the given DbgLabel.
196   DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope);
197 
198   /// A helper function to create children of a Scope DIE.
199   DIE *createScopeChildrenDIE(LexicalScope *Scope,
200                               SmallVectorImpl<DIE *> &Children,
201                               bool *HasNonScopeChildren = nullptr);
202 
203   /// Construct a DIE for this subprogram scope.
204   DIE &constructSubprogramScopeDIE(const DISubprogram *Sub,
205                                    LexicalScope *Scope);
206 
207   DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);
208 
209   void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
210 
211   /// Construct a call site entry DIE describing a call within \p Scope to a
212   /// callee described by \p CalleeSP. \p IsTail specifies whether the call is
213   /// a tail call. \p PCOffset must be non-zero for non-tail calls or be the
214   /// function-local offset to PC value after the call instruction.
215   DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP,
216                                  bool IsTail, const MCExpr *PCOffset);
217 
218   /// Construct import_module DIE.
219   DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
220 
221   void finishSubprogramDefinition(const DISubprogram *SP);
222   void finishEntityDefinition(const DbgEntity *Entity);
223 
224   /// Find abstract variable associated with Var.
225   using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
226   DbgEntity *getExistingAbstractEntity(const DINode *Node);
227   void createAbstractEntity(const DINode *Node, LexicalScope *Scope);
228 
229   /// Set the skeleton unit associated with this unit.
setSkeleton(DwarfCompileUnit & Skel)230   void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }
231 
getHeaderSize()232   unsigned getHeaderSize() const override {
233     // DWARF v5 added the DWO ID to the header for split/skeleton units.
234     unsigned DWOIdSize =
235         DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t)
236                                                           : 0;
237     return DwarfUnit::getHeaderSize() + DWOIdSize;
238   }
getLength()239   unsigned getLength() {
240     return sizeof(uint32_t) + // Length field
241         getHeaderSize() + getUnitDie().getSize();
242   }
243 
244   void emitHeader(bool UseOffsets) override;
245 
246   /// Add the DW_AT_addr_base attribute to the unit DIE.
247   void addAddrTableBase();
248 
getLabelBegin()249   MCSymbol *getLabelBegin() const {
250     assert(getSection());
251     return LabelBegin;
252   }
253 
getMacroLabelBegin()254   MCSymbol *getMacroLabelBegin() const {
255     return MacroLabelBegin;
256   }
257 
258   /// Add a new global name to the compile unit.
259   void addGlobalName(StringRef Name, const DIE &Die,
260                      const DIScope *Context) override;
261 
262   /// Add a new global name present in a type unit to this compile unit.
263   void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context);
264 
265   /// Add a new global type to the compile unit.
266   void addGlobalType(const DIType *Ty, const DIE &Die,
267                      const DIScope *Context) override;
268 
269   /// Add a new global type present in a type unit to this compile unit.
270   void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context);
271 
getGlobalNames()272   const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }
getGlobalTypes()273   const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }
274 
275   /// Add DW_AT_location attribute for a DbgVariable based on provided
276   /// MachineLocation.
277   void addVariableAddress(const DbgVariable &DV, DIE &Die,
278                           MachineLocation Location);
279   /// Add an address attribute to a die based on the location provided.
280   void addAddress(DIE &Die, dwarf::Attribute Attribute,
281                   const MachineLocation &Location);
282 
283   /// Start with the address based on the location provided, and generate the
284   /// DWARF information necessary to find the actual variable (navigating the
285   /// extra location information encoded in the type) based on the starting
286   /// location.  Add the DWARF information to the die.
287   void addComplexAddress(const DbgVariable &DV, DIE &Die,
288                          dwarf::Attribute Attribute,
289                          const MachineLocation &Location);
290 
291   /// Add a Dwarf loclistptr attribute data and value.
292   void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index);
293   void applyVariableAttributes(const DbgVariable &Var, DIE &VariableDie);
294 
295   /// Add a Dwarf expression attribute data and value.
296   void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);
297 
298   /// Add an attribute containing an address expression to \p Die.
299   void addAddressExpr(DIE &Die, dwarf::Attribute Attribute, const MCExpr *Expr);
300 
301   void applySubprogramAttributesToDefinition(const DISubprogram *SP,
302                                              DIE &SPDie);
303 
304   void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);
305 
306   /// getRanges - Get the list of ranges for this unit.
getRanges()307   const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }
takeRanges()308   SmallVector<RangeSpan, 2> takeRanges() { return std::move(CURanges); }
309 
setBaseAddress(const MCSymbol * Base)310   void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }
getBaseAddress()311   const MCSymbol *getBaseAddress() const { return BaseAddress; }
312 
getDWOId()313   uint64_t getDWOId() const { return DWOId; }
setDWOId(uint64_t DwoId)314   void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
315 
316   bool hasDwarfPubSections() const;
317 };
318 
319 } // end namespace llvm
320 
321 #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
322