Line data Source code
1 : //===-- llvm/CodeGen/DwarfUnit.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_DWARFUNIT_H
15 : #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H
16 :
17 : #include "DwarfDebug.h"
18 : #include "llvm/ADT/DenseMap.h"
19 : #include "llvm/ADT/Optional.h"
20 : #include "llvm/ADT/StringMap.h"
21 : #include "llvm/CodeGen/AsmPrinter.h"
22 : #include "llvm/CodeGen/DIE.h"
23 : #include "llvm/IR/DIBuilder.h"
24 : #include "llvm/IR/DebugInfo.h"
25 : #include "llvm/MC/MCDwarf.h"
26 : #include "llvm/MC/MCExpr.h"
27 : #include "llvm/MC/MCSection.h"
28 :
29 : namespace llvm {
30 :
31 : class MachineLocation;
32 : class MachineOperand;
33 : class ConstantInt;
34 : class ConstantFP;
35 : class DbgVariable;
36 : class DwarfCompileUnit;
37 :
38 : // Data structure to hold a range for range lists.
39 : class RangeSpan {
40 : public:
41 326219 : RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {}
42 0 : const MCSymbol *getStart() const { return Start; }
43 0 : const MCSymbol *getEnd() const { return End; }
44 1088 : void setEnd(const MCSymbol *E) { End = E; }
45 :
46 : private:
47 : const MCSymbol *Start, *End;
48 : };
49 :
50 384476 : class RangeSpanList {
51 : private:
52 : // Index for locating within the debug_range section this particular span.
53 : MCSymbol *RangeSym;
54 : // List of ranges.
55 : SmallVector<RangeSpan, 2> Ranges;
56 :
57 : public:
58 : RangeSpanList(MCSymbol *Sym, SmallVector<RangeSpan, 2> Ranges)
59 79462 : : RangeSym(Sym), Ranges(std::move(Ranges)) {}
60 0 : MCSymbol *getSym() const { return RangeSym; }
61 : const SmallVectorImpl<RangeSpan> &getRanges() const { return Ranges; }
62 : void addRange(RangeSpan Range) { Ranges.push_back(Range); }
63 : };
64 :
65 : //===----------------------------------------------------------------------===//
66 : /// This dwarf writer support class manages information associated with a
67 : /// source file.
68 : class DwarfUnit : public DIEUnit {
69 : protected:
70 : /// MDNode for the compile unit.
71 : const DICompileUnit *CUNode;
72 :
73 : // All DIEValues are allocated through this allocator.
74 : BumpPtrAllocator DIEValueAllocator;
75 :
76 : /// Target of Dwarf emission.
77 : AsmPrinter *Asm;
78 :
79 : // Holders for some common dwarf information.
80 : DwarfDebug *DD;
81 : DwarfFile *DU;
82 :
83 : /// An anonymous type for index type. Owned by DIEUnit.
84 : DIE *IndexTyDie;
85 :
86 : /// Tracks the mapping of unit level debug information variables to debug
87 : /// information entries.
88 : DenseMap<const MDNode *, DIE *> MDNodeToDieMap;
89 :
90 : /// A list of all the DIEBlocks in use.
91 : std::vector<DIEBlock *> DIEBlocks;
92 :
93 : /// A list of all the DIELocs in use.
94 : std::vector<DIELoc *> DIELocs;
95 :
96 : /// This map is used to keep track of subprogram DIEs that need
97 : /// DW_AT_containing_type attribute. This attribute points to a DIE that
98 : /// corresponds to the MDNode mapped with the subprogram DIE.
99 : DenseMap<DIE *, const DINode *> ContainingTypeMap;
100 :
101 : DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW,
102 : DwarfFile *DWU);
103 :
104 : bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie);
105 :
106 : bool shareAcrossDWOCUs() const;
107 : bool isShareableAcrossCUs(const DINode *D) const;
108 :
109 : public:
110 : // Accessors.
111 : AsmPrinter* getAsmPrinter() const { return Asm; }
112 42896 : uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
113 0 : const DICompileUnit *getCUNode() const { return CUNode; }
114 :
115 79462 : uint16_t getDwarfVersion() const { return DD->getDwarfVersion(); }
116 :
117 : /// Return true if this compile unit has something to write out.
118 : bool hasContent() const { return getUnitDie().hasChildren(); }
119 :
120 : /// Get string containing language specific context for a global name.
121 : ///
122 : /// Walks the metadata parent chain in a language specific manner (using the
123 : /// compile unit language) and returns it as a string. This is done at the
124 : /// metadata level because DIEs may not currently have been added to the
125 : /// parent context and walking the DIEs looking for names is more expensive
126 : /// than walking the metadata.
127 : std::string getParentContextString(const DIScope *Context) const;
128 :
129 : /// Add a new global name to the compile unit.
130 : virtual void addGlobalName(StringRef Name, const DIE &Die,
131 : const DIScope *Context) = 0;
132 :
133 : /// Add a new global type to the compile unit.
134 : virtual void addGlobalType(const DIType *Ty, const DIE &Die,
135 : const DIScope *Context) = 0;
136 :
137 : /// Returns the DIE map slot for the specified debug variable.
138 : ///
139 : /// We delegate the request to DwarfDebug when the MDNode can be part of the
140 : /// type system, since DIEs for the type system can be shared across CUs and
141 : /// the mappings are kept in DwarfDebug.
142 : DIE *getDIE(const DINode *D) const;
143 :
144 : /// Returns a fresh newly allocated DIELoc.
145 843 : DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; }
146 :
147 : /// Insert DIE into the map.
148 : ///
149 : /// We delegate the request to DwarfDebug when the MDNode can be part of the
150 : /// type system, since DIEs for the type system can be shared across CUs and
151 : /// the mappings are kept in DwarfDebug.
152 : void insertDIE(const DINode *Desc, DIE *D);
153 :
154 : /// Add a flag that is true to the DIE.
155 : void addFlag(DIE &Die, dwarf::Attribute Attribute);
156 :
157 : /// Add an unsigned integer attribute data and value.
158 : void addUInt(DIEValueList &Die, dwarf::Attribute Attribute,
159 : Optional<dwarf::Form> Form, uint64_t Integer);
160 :
161 : void addUInt(DIEValueList &Block, dwarf::Form Form, uint64_t Integer);
162 :
163 : /// Add an signed integer attribute data and value.
164 : void addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
165 : Optional<dwarf::Form> Form, int64_t Integer);
166 :
167 : void addSInt(DIELoc &Die, Optional<dwarf::Form> Form, int64_t Integer);
168 :
169 : /// Add a string attribute data and value.
170 : ///
171 : /// We always emit a reference to the string pool instead of immediate
172 : /// strings so that DIEs have more predictable sizes. In the case of split
173 : /// dwarf we emit an index into another table which gets us the static offset
174 : /// into the string table.
175 : void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
176 :
177 : /// Add a Dwarf label attribute data and value.
178 : DIEValueList::value_iterator addLabel(DIEValueList &Die,
179 : dwarf::Attribute Attribute,
180 : dwarf::Form Form,
181 : const MCSymbol *Label);
182 :
183 : void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label);
184 :
185 : /// Add an offset into a section attribute data and value.
186 : void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer);
187 :
188 : /// Add a dwarf op address data and value using the form given and an
189 : /// op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
190 : void addOpAddress(DIELoc &Die, const MCSymbol *Sym);
191 :
192 : /// Add a label delta attribute data and value.
193 : void addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
194 : const MCSymbol *Lo);
195 :
196 : /// Add a DIE attribute data and value.
197 : void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry);
198 :
199 : /// Add a DIE attribute data and value.
200 : void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry);
201 :
202 : /// Add a type's DW_AT_signature and set the declaration flag.
203 : void addDIETypeSignature(DIE &Die, uint64_t Signature);
204 :
205 : /// Add block data.
206 : void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc);
207 :
208 : /// Add block data.
209 : void addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block);
210 :
211 : /// Add location information to specified debug information entry.
212 : void addSourceLine(DIE &Die, unsigned Line, const DIFile *File);
213 : void addSourceLine(DIE &Die, const DILocalVariable *V);
214 : void addSourceLine(DIE &Die, const DIGlobalVariable *G);
215 : void addSourceLine(DIE &Die, const DISubprogram *SP);
216 : void addSourceLine(DIE &Die, const DILabel *L);
217 : void addSourceLine(DIE &Die, const DIType *Ty);
218 : void addSourceLine(DIE &Die, const DIObjCProperty *Ty);
219 :
220 : /// Add constant value entry in variable DIE.
221 : void addConstantValue(DIE &Die, const MachineOperand &MO, const DIType *Ty);
222 : void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty);
223 : void addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty);
224 : void addConstantValue(DIE &Die, const APInt &Val, bool Unsigned);
225 : void addConstantValue(DIE &Die, bool Unsigned, uint64_t Val);
226 :
227 : /// Add constant value entry in variable DIE.
228 : void addConstantFPValue(DIE &Die, const MachineOperand &MO);
229 : void addConstantFPValue(DIE &Die, const ConstantFP *CFP);
230 :
231 : /// Add a linkage name, if it isn't empty.
232 : void addLinkageName(DIE &Die, StringRef LinkageName);
233 :
234 : /// Add template parameters in buffer.
235 : void addTemplateParams(DIE &Buffer, DINodeArray TParams);
236 :
237 : /// Add thrown types.
238 : void addThrownTypes(DIE &Die, DINodeArray ThrownTypes);
239 :
240 : // FIXME: Should be reformulated in terms of addComplexAddress.
241 : /// Start with the address based on the location provided, and generate the
242 : /// DWARF information necessary to find the actual Block variable (navigating
243 : /// the Block struct) based on the starting location. Add the DWARF
244 : /// information to the die. Obsolete, please use addComplexAddress instead.
245 : void addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
246 : dwarf::Attribute Attribute,
247 : const MachineLocation &Location);
248 :
249 : /// Add a new type attribute to the specified entity.
250 : ///
251 : /// This takes and attribute parameter because DW_AT_friend attributes are
252 : /// also type references.
253 : void addType(DIE &Entity, const DIType *Ty,
254 : dwarf::Attribute Attribute = dwarf::DW_AT_type);
255 :
256 : DIE *getOrCreateNameSpace(const DINamespace *NS);
257 : DIE *getOrCreateModule(const DIModule *M);
258 : DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false);
259 :
260 : void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
261 : bool SkipSPAttributes = false);
262 :
263 : /// Find existing DIE or create new DIE for the given type.
264 : DIE *getOrCreateTypeDIE(const MDNode *TyNode);
265 :
266 : /// Get context owner's DIE.
267 : DIE *getOrCreateContextDIE(const DIScope *Context);
268 :
269 : /// Construct DIEs for types that contain vtables.
270 : void constructContainingTypeDIEs();
271 :
272 : /// Construct function argument DIEs.
273 : void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args);
274 :
275 : /// Create a DIE with the given Tag, add the DIE to its parent, and
276 : /// call insertDIE if MD is not null.
277 : DIE &createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N = nullptr);
278 :
279 0 : bool useSegmentedStringOffsetsTable() const {
280 303085 : return DD->useSegmentedStringOffsetsTable();
281 : }
282 :
283 : /// Compute the size of a header for this unit, not including the initial
284 : /// length field.
285 0 : virtual unsigned getHeaderSize() const {
286 : return sizeof(int16_t) + // DWARF version number
287 : sizeof(int32_t) + // Offset Into Abbrev. Section
288 : sizeof(int8_t) + // Pointer Size (in bytes)
289 4368 : (DD->getDwarfVersion() >= 5 ? sizeof(int8_t)
290 4434 : : 0); // DWARF v5 unit type
291 : }
292 :
293 : /// Emit the header for this unit, not including the initial length field.
294 : virtual void emitHeader(bool UseOffsets) = 0;
295 :
296 : /// Add the DW_AT_str_offsets_base attribute to the unit DIE.
297 : void addStringOffsetsStart();
298 :
299 : /// Add the DW_AT_rnglists_base attribute to the unit DIE.
300 : void addRnglistsBase();
301 :
302 : /// Add the DW_AT_addr_base attribute to the unit DIE.
303 : void addAddrTableBase();
304 :
305 : virtual DwarfCompileUnit &getCU() = 0;
306 :
307 : void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy);
308 :
309 : /// addSectionDelta - Add a label delta attribute data and value.
310 : DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
311 : const MCSymbol *Hi, const MCSymbol *Lo);
312 :
313 : /// Add a Dwarf section label attribute data and value.
314 : DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
315 : const MCSymbol *Label,
316 : const MCSymbol *Sec);
317 :
318 : /// If the \p File has an MD5 checksum, return it as an MD5Result
319 : /// allocated in the MCContext.
320 : MD5::MD5Result *getMD5AsBytes(const DIFile *File) const;
321 :
322 : protected:
323 : ~DwarfUnit();
324 :
325 : /// Create new static data member DIE.
326 : DIE *getOrCreateStaticMemberDIE(const DIDerivedType *DT);
327 :
328 : /// Look up the source ID for the given file. If none currently exists,
329 : /// create a new ID and insert it in the line table.
330 : virtual unsigned getOrCreateSourceID(const DIFile *File) = 0;
331 :
332 : /// Look in the DwarfDebug map for the MDNode that corresponds to the
333 : /// reference.
334 0 : template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
335 0 : return Ref.resolve();
336 : }
337 0 :
338 0 : /// If this is a named finished type then include it in the list of types for
339 : /// the accelerator tables.
340 0 : void updateAcceleratorTables(const DIScope *Context, const DIType *Ty,
341 0 : const DIE &TyDIE);
342 :
343 : /// Emit the common part of the header for this unit.
344 : void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT);
345 :
346 : private:
347 : void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
348 : void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy);
349 : void constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy);
350 : void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
351 : void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
352 : void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
353 : DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
354 : void constructTemplateTypeParameterDIE(DIE &Buffer,
355 : const DITemplateTypeParameter *TP);
356 : void constructTemplateValueParameterDIE(DIE &Buffer,
357 : const DITemplateValueParameter *TVP);
358 :
359 : /// Return the default lower bound for an array.
360 : ///
361 : /// If the DWARF version doesn't handle the language, return -1.
362 : int64_t getDefaultLowerBound() const;
363 :
364 : /// Get an anonymous type for index type.
365 : DIE *getIndexTyDie();
366 :
367 : /// Set D as anonymous type for index which can be reused later.
368 : void setIndexTyDie(DIE *D) { IndexTyDie = D; }
369 :
370 : virtual bool isDwoUnit() const = 0;
371 : const MCSymbol *getCrossSectionRelativeBaseAddress() const override;
372 : };
373 :
374 0 : class DwarfTypeUnit final : public DwarfUnit {
375 : uint64_t TypeSignature;
376 : const DIE *Ty;
377 : DwarfCompileUnit &CU;
378 : MCDwarfDwoLineTable *SplitLineTable;
379 : bool UsedLineTable = false;
380 :
381 : unsigned getOrCreateSourceID(const DIFile *File) override;
382 : bool isDwoUnit() const override;
383 :
384 : public:
385 : DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW,
386 : DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable = nullptr);
387 :
388 44 : void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; }
389 44 : void setType(const DIE *Ty) { this->Ty = Ty; }
390 :
391 : /// Get context owner's DIE.
392 : DIE *createTypeDIE(const DICompositeType *Ty);
393 :
394 : /// Emit the header for this unit, not including the initial length field.
395 : void emitHeader(bool UseOffsets) override;
396 0 : unsigned getHeaderSize() const override {
397 : return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
398 0 : sizeof(uint32_t); // Type DIE Offset
399 : }
400 : void addGlobalName(StringRef Name, const DIE &Die,
401 : const DIScope *Context) override;
402 66 : void addGlobalType(const DIType *Ty, const DIE &Die,
403 : const DIScope *Context) override;
404 66 : DwarfCompileUnit &getCU() override { return CU; }
405 : };
406 : } // end llvm namespace
407 : #endif
|