brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.8 KiB · a3bbc83 Raw
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