432 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains support for writing dwarf compile unit.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H14#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H15 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 31namespace llvm {32 33class AsmPrinter;34class DIE;35class DIELoc;36class DIEValueList;37class DwarfFile;38class GlobalVariable;39class MCExpr;40class MCSymbol;41class MDNode;42 43enum class UnitKind { Skeleton, Full };44 45class DwarfCompileUnit final : public DwarfUnit {46 bool HasRangeLists = false;47 48 /// The start of the unit line section, this is also49 /// 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 in68 // 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) that76 // 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 SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;85 86 // List of inlined lexical block scopes that belong to subprograms within this87 // CU.88 DenseMap<const DILocalScope *, SmallVector<DIE *, 2>> InlinedLocalScopeDIEs;89 90 DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;91 92 /// DWO ID for correlating skeleton and split units.93 uint64_t DWOId = 0;94 95 const DIFile *LastFile = nullptr;96 unsigned LastFileID;97 98 /// \anchor applyConcreteDbgVariableAttribute99 /// \name applyConcreteDbgVariableAttribute100 /// Overload set which applies attributes to \c VariableDie based on101 /// the active variant of \c DV, which is passed as the first argument.102 ///@{103 104 /// See \ref applyConcreteDbgVariableAttribute105 void applyConcreteDbgVariableAttributes(const Loc::Single &Single,106 const DbgVariable &DV,107 DIE &VariableDie);108 /// See \ref applyConcreteDbgVariableAttribute109 void applyConcreteDbgVariableAttributes(const Loc::Multi &Multi,110 const DbgVariable &DV,111 DIE &VariableDie);112 /// See \ref applyConcreteDbgVariableAttribute113 void applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,114 const DbgVariable &DV,115 DIE &VariableDie);116 /// See \ref applyConcreteDbgVariableAttribute117 void applyConcreteDbgVariableAttributes(const Loc::EntryValue &EntryValue,118 const DbgVariable &DV,119 DIE &VariableDie);120 /// See \ref applyConcreteDbgVariableAttribute121 void applyConcreteDbgVariableAttributes(const std::monostate &,122 const DbgVariable &DV,123 DIE &VariableDie);124 125 ///@}126 127 bool isDwoUnit() const override;128 129 DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {130 if (isDwoUnit() && !DD->shareAcrossDWOCUs())131 return AbstractLocalScopeDIEs;132 return DU->getAbstractScopeDIEs();133 }134 135 DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {136 if (isDwoUnit() && !DD->shareAcrossDWOCUs())137 return AbstractEntities;138 return DU->getAbstractEntities();139 }140 141 auto &getFinalizedAbstractSubprograms() {142 if (isDwoUnit() && !DD->shareAcrossDWOCUs())143 return FinalizedAbstractSubprograms;144 return DU->getFinalizedAbstractSubprograms();145 }146 147 void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;148 149 /// Add info for Wasm-global-based relocation.150 void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,151 uint64_t GlobalIndex);152 153 /// Create context DIE for abstract subprogram.154 /// \returns The context DIE and the compile unit where abstract155 /// DIE should be constructed.156 std::pair<DIE *, DwarfCompileUnit *>157 getOrCreateAbstractSubprogramContextDIE(const DISubprogram *SP);158 159 /// Create new DIE for abstract subprogram.160 DIE &createAbstractSubprogramDIE(const DISubprogram *SP, DIE *ContextDIE,161 DwarfCompileUnit *ContextCU);162 163public:164 DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,165 DwarfDebug *DW, DwarfFile *DWU,166 UnitKind Kind = UnitKind::Full);167 168 bool hasRangeLists() const { return HasRangeLists; }169 170 DwarfCompileUnit *getSkeleton() const {171 return Skeleton;172 }173 174 bool includeMinimalInlineScopes() const;175 176 bool emitFuncLineTableOffsets() const;177 178 void initStmtList();179 180 /// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.181 void applyStmtList(DIE &D);182 183 /// Get line table start symbol for this unit.184 MCSymbol *getLineTableStartSym() const { return LineTableStartSym; }185 186 /// A pair of GlobalVariable and DIExpression.187 struct GlobalExpr {188 const GlobalVariable *Var;189 const DIExpression *Expr;190 };191 192 struct BaseTypeRef {193 BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) :194 BitSize(BitSize), Encoding(Encoding) {}195 unsigned BitSize;196 dwarf::TypeKind Encoding;197 DIE *Die = nullptr;198 };199 200 std::vector<BaseTypeRef> ExprRefedBaseTypes;201 202 /// Get or create global variable DIE.203 DIE *204 getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,205 ArrayRef<GlobalExpr> GlobalExprs);206 207 DIE *getOrCreateCommonBlock(const DICommonBlock *CB,208 ArrayRef<GlobalExpr> GlobalExprs);209 210 void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV,211 ArrayRef<GlobalExpr> GlobalExprs);212 213 /// addLabelAddress - Add a dwarf label attribute data and value using214 /// either DW_FORM_addr or DW_FORM_GNU_addr_index.215 void addLabelAddress(DIE &Die, dwarf::Attribute Attribute,216 const MCSymbol *Label);217 218 /// addLocalLabelAddress - Add a dwarf label attribute data and value using219 /// DW_FORM_addr only.220 void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute,221 const MCSymbol *Label);222 223 DwarfCompileUnit &getCU() override { return *this; }224 225 unsigned getOrCreateSourceID(const DIFile *File) override;226 227 /// addRange - Add an address range to the list of ranges for this unit.228 void addRange(RangeSpan Range);229 230 void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End);231 232 /// Find DIE for the given subprogram and attach appropriate233 /// DW_AT_low_pc, DW_AT_high_pc and DW_AT_LLVM_stmt_sequence attributes.234 /// If there are global variables in this scope then create and insert DIEs235 /// for these variables.236 DIE &updateSubprogramScopeDIE(const DISubprogram *SP, const Function &F,237 MCSymbol *LineTableSym);238 239 void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);240 241 /// A helper function to construct a RangeSpanList for a given242 /// lexical scope.243 void addScopeRangeList(DIE &ScopeDIE, SmallVector<RangeSpan, 2> Range);244 245 void attachRangesOrLowHighPC(DIE &D, SmallVector<RangeSpan, 2> Ranges);246 247 void attachRangesOrLowHighPC(DIE &D,248 const SmallVectorImpl<InsnRange> &Ranges);249 250 /// This scope represents an inlined body of a function. Construct a251 /// DIE to represent this concrete inlined copy of the function.252 DIE *constructInlinedScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);253 254 /// Construct new DW_TAG_lexical_block for this scope and255 /// attach DW_AT_low_pc/DW_AT_high_pc labels.256 DIE *constructLexicalScopeDIE(LexicalScope *Scope);257 258 /// Get a DIE for the given DILexicalBlock.259 /// Note that this function assumes that the DIE has been already created260 /// and it's an error, if it hasn't.261 DIE *getLexicalBlockDIE(const DILexicalBlock *LB);262 263 /// Construct a DIE for the given DbgVariable.264 DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);265 266 /// Convenience overload which writes the DIE pointer into an out variable267 /// ObjectPointer in addition to returning it.268 DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,269 DIE *&ObjectPointer);270 271 /// Construct a DIE for the given DbgLabel.272 DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope);273 274 void createBaseTypeDIEs();275 276 /// Construct a DIE for a given scope.277 /// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.278 DIE *getOrCreateContextDIE(const DIScope *Ty) override;279 280 DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *F,281 bool Minimal = false) override;282 283 /// Construct a DIE for this subprogram scope.284 DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F,285 LexicalScope *Scope, MCSymbol *LineTableSym);286 287 DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);288 289 /// Create an abstract subprogram DIE, that should later be populated290 /// by \ref constructAbstractSubprogramScopeDIE.291 DIE &getOrCreateAbstractSubprogramDIE(const DISubprogram *SP);292 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);293 294 /// Whether to use the GNU analog for a DWARF5 tag, attribute, or location295 /// atom. Only applicable when emitting otherwise DWARF4-compliant debug info.296 bool useGNUAnalogForDwarf5Feature() const;297 298 /// This takes a DWARF 5 tag and returns it or a GNU analog.299 dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const;300 301 /// This takes a DWARF 5 attribute and returns it or a GNU analog.302 dwarf::Attribute getDwarf5OrGNUAttr(dwarf::Attribute Attr) const;303 304 /// This takes a DWARF 5 location atom and either returns it or a GNU analog.305 dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;306 307 /// Construct a call site entry DIE describing a call within \p Scope to a308 /// callee described by \p CalleeSP and \p CalleeF.309 /// \p IsTail specifies whether the call is a tail call.310 /// \p PCAddr points to the PC value after the call instruction.311 /// \p CallAddr points to the PC value at the call instruction (or is null).312 /// \p CallReg is a register location for an indirect call. For direct calls313 /// the \p CallReg is set to 0.314 DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,315 const Function *CalleeF, bool IsTail,316 const MCSymbol *PCAddr,317 const MCSymbol *CallAddr, unsigned CallReg,318 DIType *AllocSiteTy);319 /// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params320 /// were collected by the \ref collectCallSiteParameters.321 /// Note: The order of parameters does not matter, since debuggers recognize322 /// call site parameters by the DW_AT_location attribute.323 void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,324 SmallVector<DbgCallSiteParam, 4> &Params);325 326 /// Get or create a DIE for an imported entity.327 DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);328 DIE *constructImportedEntityDIE(const DIImportedEntity *IE);329 330 void finishSubprogramDefinition(const DISubprogram *SP);331 void finishEntityDefinition(const DbgEntity *Entity);332 void attachLexicalScopesAbstractOrigins();333 334 /// Find abstract variable associated with Var.335 using InlinedEntity = DbgValueHistoryMap::InlinedEntity;336 DbgEntity *getExistingAbstractEntity(const DINode *Node);337 void createAbstractEntity(const DINode *Node, LexicalScope *Scope);338 339 /// Set the skeleton unit associated with this unit.340 void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }341 342 unsigned getHeaderSize() const override {343 // DWARF v5 added the DWO ID to the header for split/skeleton units.344 unsigned DWOIdSize =345 DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t)346 : 0;347 return DwarfUnit::getHeaderSize() + DWOIdSize;348 }349 unsigned getLength() {350 return Asm->getUnitLengthFieldByteSize() + // Length field351 getHeaderSize() + getUnitDie().getSize();352 }353 354 void emitHeader(bool UseOffsets) override;355 356 /// Add the DW_AT_addr_base attribute to the unit DIE.357 void addAddrTableBase();358 359 MCSymbol *getMacroLabelBegin() const {360 return MacroLabelBegin;361 }362 363 /// Add a new global name to the compile unit.364 void addGlobalName(StringRef Name, const DIE &Die,365 const DIScope *Context) override;366 367 /// Add a new global name present in a type unit to this compile unit.368 void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context);369 370 /// Add a new global type to the compile unit.371 void addGlobalTypeImpl(const DIType *Ty, const DIE &Die,372 const DIScope *Context) override;373 374 /// Add a new global type present in a type unit to this compile unit.375 void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context);376 377 const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }378 const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }379 380 /// Add DW_AT_location attribute for a DbgVariable based on provided381 /// MachineLocation.382 void addVariableAddress(const DbgVariable &DV, DIE &Die,383 MachineLocation Location);384 /// Add an address attribute to a die based on the location provided.385 void addAddress(DIE &Die, dwarf::Attribute Attribute,386 const MachineLocation &Location);387 388 /// Start with the address based on the location provided, and generate the389 /// DWARF information necessary to find the actual variable (navigating the390 /// extra location information encoded in the type) based on the starting391 /// location. Add the DWARF information to the die.392 void addComplexAddress(const DIExpression *DIExpr, DIE &Die,393 dwarf::Attribute Attribute,394 const MachineLocation &Location);395 396 /// Add a Dwarf loclistptr attribute data and value.397 void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index);398 399 /// Add attributes to \p Var which reflect the common attributes of \p400 /// VariableDie, namely those which are not dependant on the active variant.401 void applyCommonDbgVariableAttributes(const DbgVariable &Var,402 DIE &VariableDie);403 404 /// Add a Dwarf expression attribute data and value.405 void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);406 407 void applySubprogramAttributesToDefinition(const DISubprogram *SP,408 DIE &SPDie);409 410 void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);411 412 /// getRanges - Get the list of ranges for this unit.413 const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }414 SmallVector<RangeSpan, 2> takeRanges() { return std::move(CURanges); }415 416 void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }417 const MCSymbol *getBaseAddress() const { return BaseAddress; }418 419 uint64_t getDWOId() const { return DWOId; }420 void setDWOId(uint64_t DwoId) { DWOId = DwoId; }421 422 bool hasDwarfPubSections() const;423 424 void addBaseTypeRef(DIEValueList &Die, int64_t Idx);425 426 MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; }427};428 429} // end namespace llvm430 431#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H432