| 1 | //===- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework --------*- 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 debug info into asm files. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H |
| 14 | #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H |
| 15 | |
| 16 | #include "AddressPool.h" |
| 17 | #include "DebugLocEntry.h" |
| 18 | #include "DebugLocStream.h" |
| 19 | #include "DwarfFile.h" |
| 20 | #include "llvm/ADT/DenseMap.h" |
| 21 | #include "llvm/ADT/DenseSet.h" |
| 22 | #include "llvm/ADT/MapVector.h" |
| 23 | #include "llvm/ADT/SetVector.h" |
| 24 | #include "llvm/ADT/SmallPtrSet.h" |
| 25 | #include "llvm/ADT/SmallVector.h" |
| 26 | #include "llvm/ADT/StringMap.h" |
| 27 | #include "llvm/ADT/StringRef.h" |
| 28 | #include "llvm/BinaryFormat/Dwarf.h" |
| 29 | #include "llvm/CodeGen/AccelTable.h" |
| 30 | #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" |
| 31 | #include "llvm/CodeGen/DebugHandlerBase.h" |
| 32 | #include "llvm/IR/DebugInfoMetadata.h" |
| 33 | #include "llvm/IR/DebugLoc.h" |
| 34 | #include "llvm/IR/Metadata.h" |
| 35 | #include "llvm/MC/MCDwarf.h" |
| 36 | #include "llvm/Support/Allocator.h" |
| 37 | #include "llvm/Target/TargetOptions.h" |
| 38 | #include <cassert> |
| 39 | #include <cstdint> |
| 40 | #include <limits> |
| 41 | #include <memory> |
| 42 | #include <utility> |
| 43 | #include <variant> |
| 44 | #include <vector> |
| 45 | |
| 46 | namespace llvm { |
| 47 | |
| 48 | class AsmPrinter; |
| 49 | class ByteStreamer; |
| 50 | class DIE; |
| 51 | class DwarfCompileUnit; |
| 52 | class DwarfExpression; |
| 53 | class DwarfTypeUnit; |
| 54 | class DwarfUnit; |
| 55 | class LexicalScope; |
| 56 | class MachineFunction; |
| 57 | class MCSection; |
| 58 | class MCSymbol; |
| 59 | class Module; |
| 60 | |
| 61 | //===----------------------------------------------------------------------===// |
| 62 | /// This class is defined as the common parent of DbgVariable and DbgLabel |
| 63 | /// such that it could levarage polymorphism to extract common code for |
| 64 | /// DbgVariable and DbgLabel. |
| 65 | class DbgEntity { |
| 66 | public: |
| 67 | enum DbgEntityKind { |
| 68 | DbgVariableKind, |
| 69 | DbgLabelKind |
| 70 | }; |
| 71 | |
| 72 | private: |
| 73 | const DINode *Entity; |
| 74 | const DILocation *InlinedAt; |
| 75 | DIE *TheDIE = nullptr; |
| 76 | const DbgEntityKind SubclassID; |
| 77 | |
| 78 | public: |
| 79 | DbgEntity(const DINode *N, const DILocation *IA, DbgEntityKind ID) |
| 80 | : Entity(N), InlinedAt(IA), SubclassID(ID) {} |
| 81 | virtual ~DbgEntity() = default; |
| 82 | |
| 83 | /// Accessors. |
| 84 | /// @{ |
| 85 | const DINode *getEntity() const { return Entity; } |
| 86 | const DILocation *getInlinedAt() const { return InlinedAt; } |
| 87 | DIE *getDIE() const { return TheDIE; } |
| 88 | DbgEntityKind getDbgEntityID() const { return SubclassID; } |
| 89 | /// @} |
| 90 | |
| 91 | void setDIE(DIE &D) { TheDIE = &D; } |
| 92 | |
| 93 | static bool classof(const DbgEntity *N) { |
| 94 | switch (N->getDbgEntityID()) { |
| 95 | case DbgVariableKind: |
| 96 | case DbgLabelKind: |
| 97 | return true; |
| 98 | } |
| 99 | llvm_unreachable("Invalid DbgEntityKind" ); |
| 100 | } |
| 101 | }; |
| 102 | |
| 103 | class DbgVariable; |
| 104 | |
| 105 | bool operator<(const struct FrameIndexExpr &LHS, |
| 106 | const struct FrameIndexExpr &RHS); |
| 107 | bool operator<(const struct EntryValueInfo &LHS, |
| 108 | const struct EntryValueInfo &RHS); |
| 109 | |
| 110 | /// Proxy for one MMI entry. |
| 111 | struct FrameIndexExpr { |
| 112 | int FI; |
| 113 | const DIExpression *Expr; |
| 114 | |
| 115 | /// Operator enabling sorting based on fragment offset. |
| 116 | friend bool operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS); |
| 117 | }; |
| 118 | |
| 119 | /// Represents an entry-value location, or a fragment of one. |
| 120 | struct EntryValueInfo { |
| 121 | MCRegister Reg; |
| 122 | const DIExpression &Expr; |
| 123 | |
| 124 | /// Operator enabling sorting based on fragment offset. |
| 125 | friend bool operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS); |
| 126 | }; |
| 127 | |
| 128 | // Namespace for alternatives of a DbgVariable. |
| 129 | namespace Loc { |
| 130 | /// Single value location description. |
| 131 | class Single { |
| 132 | std::unique_ptr<DbgValueLoc> ValueLoc; |
| 133 | const DIExpression *Expr; |
| 134 | |
| 135 | public: |
| 136 | explicit Single(DbgValueLoc ValueLoc); |
| 137 | explicit Single(const MachineInstr *DbgValue); |
| 138 | const DbgValueLoc &getValueLoc() const { return *ValueLoc; } |
| 139 | const DIExpression *getExpr() const { return Expr; } |
| 140 | }; |
| 141 | /// Multi-value location description. |
| 142 | class Multi { |
| 143 | /// Index of the entry list in DebugLocs. |
| 144 | unsigned DebugLocListIndex; |
| 145 | /// DW_OP_LLVM_tag_offset value from DebugLocs. |
| 146 | std::optional<uint8_t> DebugLocListTagOffset; |
| 147 | |
| 148 | public: |
| 149 | explicit Multi(unsigned DebugLocListIndex, |
| 150 | std::optional<uint8_t> DebugLocListTagOffset) |
| 151 | : DebugLocListIndex(DebugLocListIndex), |
| 152 | DebugLocListTagOffset(DebugLocListTagOffset) {} |
| 153 | unsigned getDebugLocListIndex() const { return DebugLocListIndex; } |
| 154 | std::optional<uint8_t> getDebugLocListTagOffset() const { |
| 155 | return DebugLocListTagOffset; |
| 156 | } |
| 157 | }; |
| 158 | /// Single location defined by (potentially multiple) MMI entries. |
| 159 | struct MMI { |
| 160 | std::set<FrameIndexExpr> FrameIndexExprs; |
| 161 | |
| 162 | public: |
| 163 | explicit MMI(const DIExpression *E, int FI) : FrameIndexExprs({{.FI: FI, .Expr: E}}) { |
| 164 | assert((!E || E->isValid()) && "Expected valid expression" ); |
| 165 | assert(FI != std::numeric_limits<int>::max() && "Expected valid index" ); |
| 166 | } |
| 167 | void addFrameIndexExpr(const DIExpression *Expr, int FI); |
| 168 | /// Get the FI entries, sorted by fragment offset. |
| 169 | const std::set<FrameIndexExpr> &getFrameIndexExprs() const; |
| 170 | }; |
| 171 | /// Single location defined by (potentially multiple) EntryValueInfo. |
| 172 | struct EntryValue { |
| 173 | std::set<EntryValueInfo> EntryValues; |
| 174 | explicit EntryValue(MCRegister Reg, const DIExpression &Expr) { |
| 175 | addExpr(Reg, Expr); |
| 176 | }; |
| 177 | // Add the pair Reg, Expr to the list of entry values describing the variable. |
| 178 | // If multiple expressions are added, it is the callers responsibility to |
| 179 | // ensure they are all non-overlapping fragments. |
| 180 | void addExpr(MCRegister Reg, const DIExpression &Expr) { |
| 181 | std::optional<const DIExpression *> NonVariadicExpr = |
| 182 | DIExpression::convertToNonVariadicExpression(Expr: &Expr); |
| 183 | assert(NonVariadicExpr && *NonVariadicExpr); |
| 184 | |
| 185 | EntryValues.insert(x: {.Reg: Reg, .Expr: **NonVariadicExpr}); |
| 186 | } |
| 187 | }; |
| 188 | /// Alias for the std::variant specialization base class of DbgVariable. |
| 189 | using Variant = std::variant<std::monostate, Loc::Single, Loc::Multi, Loc::MMI, |
| 190 | Loc::EntryValue>; |
| 191 | } // namespace Loc |
| 192 | |
| 193 | //===----------------------------------------------------------------------===// |
| 194 | /// This class is used to track local variable information. |
| 195 | /// |
| 196 | /// Variables that have been optimized out hold the \c monostate alternative. |
| 197 | /// This is not distinguished from the case of a constructed \c DbgVariable |
| 198 | /// which has not be initialized yet. |
| 199 | /// |
| 200 | /// Variables can be created from allocas, in which case they're generated from |
| 201 | /// the MMI table. Such variables hold the \c Loc::MMI alternative which can |
| 202 | /// have multiple expressions and frame indices. |
| 203 | /// |
| 204 | /// Variables can be created from the entry value of registers, in which case |
| 205 | /// they're generated from the MMI table. Such variables hold the \c |
| 206 | /// EntryValueLoc alternative which can either have a single expression or |
| 207 | /// multiple *fragment* expressions. |
| 208 | /// |
| 209 | /// Variables can be created from \c DBG_VALUE instructions. Those whose |
| 210 | /// location changes over time hold a \c Loc::Multi alternative which uses \c |
| 211 | /// DebugLocListIndex and (optionally) \c DebugLocListTagOffset, while those |
| 212 | /// with a single location hold a \c Loc::Single alternative which use \c |
| 213 | /// ValueLoc and (optionally) a single \c Expr. |
| 214 | class DbgVariable : public DbgEntity, public Loc::Variant { |
| 215 | |
| 216 | public: |
| 217 | /// To workaround P2162R0 https://github.com/cplusplus/papers/issues/873 the |
| 218 | /// base class subobject needs to be passed directly to std::visit, so expose |
| 219 | /// it directly here. |
| 220 | Loc::Variant &asVariant() { return *static_cast<Loc::Variant *>(this); } |
| 221 | const Loc::Variant &asVariant() const { |
| 222 | return *static_cast<const Loc::Variant *>(this); |
| 223 | } |
| 224 | /// Member shorthand for std::holds_alternative |
| 225 | template <typename T> bool holds() const { |
| 226 | return std::holds_alternative<T>(*this); |
| 227 | } |
| 228 | /// Asserting, noexcept member alternative to std::get |
| 229 | template <typename T> auto &get() noexcept { |
| 230 | assert(holds<T>()); |
| 231 | return *std::get_if<T>(this); |
| 232 | } |
| 233 | /// Asserting, noexcept member alternative to std::get |
| 234 | template <typename T> const auto &get() const noexcept { |
| 235 | assert(holds<T>()); |
| 236 | return *std::get_if<T>(this); |
| 237 | } |
| 238 | |
| 239 | /// Construct a DbgVariable. |
| 240 | /// |
| 241 | /// Creates a variable without any DW_AT_location. |
| 242 | DbgVariable(const DILocalVariable *V, const DILocation *IA) |
| 243 | : DbgEntity(V, IA, DbgVariableKind) {} |
| 244 | |
| 245 | // Accessors. |
| 246 | const DILocalVariable *getVariable() const { |
| 247 | return cast<DILocalVariable>(Val: getEntity()); |
| 248 | } |
| 249 | |
| 250 | StringRef getName() const { return getVariable()->getName(); } |
| 251 | |
| 252 | // Translate tag to proper Dwarf tag. |
| 253 | dwarf::Tag getTag() const { |
| 254 | // FIXME: Why don't we just infer this tag and store it all along? |
| 255 | if (getVariable()->isParameter()) |
| 256 | return dwarf::DW_TAG_formal_parameter; |
| 257 | |
| 258 | return dwarf::DW_TAG_variable; |
| 259 | } |
| 260 | |
| 261 | /// Return true if DbgVariable is artificial. |
| 262 | bool isArtificial() const { |
| 263 | if (getVariable()->isArtificial()) |
| 264 | return true; |
| 265 | if (getType()->isArtificial()) |
| 266 | return true; |
| 267 | return false; |
| 268 | } |
| 269 | |
| 270 | bool isObjectPointer() const { |
| 271 | if (getVariable()->isObjectPointer()) |
| 272 | return true; |
| 273 | if (getType()->isObjectPointer()) |
| 274 | return true; |
| 275 | return false; |
| 276 | } |
| 277 | |
| 278 | const DIType *getType() const; |
| 279 | |
| 280 | static bool classof(const DbgEntity *N) { |
| 281 | return N->getDbgEntityID() == DbgVariableKind; |
| 282 | } |
| 283 | }; |
| 284 | |
| 285 | //===----------------------------------------------------------------------===// |
| 286 | /// This class is used to track label information. |
| 287 | /// |
| 288 | /// Labels are collected from \c DBG_LABEL instructions. |
| 289 | class DbgLabel : public DbgEntity { |
| 290 | const MCSymbol *Sym; /// Symbol before DBG_LABEL instruction. |
| 291 | |
| 292 | public: |
| 293 | /// We need MCSymbol information to generate DW_AT_low_pc. |
| 294 | DbgLabel(const DILabel *L, const DILocation *IA, const MCSymbol *Sym = nullptr) |
| 295 | : DbgEntity(L, IA, DbgLabelKind), Sym(Sym) {} |
| 296 | |
| 297 | /// Accessors. |
| 298 | /// @{ |
| 299 | const DILabel *getLabel() const { return cast<DILabel>(Val: getEntity()); } |
| 300 | const MCSymbol *getSymbol() const { return Sym; } |
| 301 | |
| 302 | StringRef getName() const { return getLabel()->getName(); } |
| 303 | /// @} |
| 304 | |
| 305 | /// Translate tag to proper Dwarf tag. |
| 306 | dwarf::Tag getTag() const { |
| 307 | return dwarf::DW_TAG_label; |
| 308 | } |
| 309 | |
| 310 | static bool classof(const DbgEntity *N) { |
| 311 | return N->getDbgEntityID() == DbgLabelKind; |
| 312 | } |
| 313 | }; |
| 314 | |
| 315 | /// Used for tracking debug info about call site parameters. |
| 316 | class DbgCallSiteParam { |
| 317 | private: |
| 318 | unsigned Register; ///< Parameter register at the callee entry point. |
| 319 | DbgValueLoc Value; ///< Corresponding location for the parameter value at |
| 320 | ///< the call site. |
| 321 | public: |
| 322 | DbgCallSiteParam(unsigned Reg, DbgValueLoc Val) |
| 323 | : Register(Reg), Value(Val) { |
| 324 | assert(Reg && "Parameter register cannot be undef" ); |
| 325 | } |
| 326 | |
| 327 | unsigned getRegister() const { return Register; } |
| 328 | DbgValueLoc getValue() const { return Value; } |
| 329 | }; |
| 330 | |
| 331 | /// Collection used for storing debug call site parameters. |
| 332 | using ParamSet = SmallVector<DbgCallSiteParam, 4>; |
| 333 | |
| 334 | /// Helper used to pair up a symbol and its DWARF compile unit. |
| 335 | struct SymbolCU { |
| 336 | SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {} |
| 337 | |
| 338 | const MCSymbol *Sym; |
| 339 | DwarfCompileUnit *CU; |
| 340 | }; |
| 341 | |
| 342 | /// The kind of accelerator tables we should emit. |
| 343 | enum class AccelTableKind { |
| 344 | Default, ///< Platform default. |
| 345 | None, ///< None. |
| 346 | Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. |
| 347 | Dwarf, ///< DWARF v5 .debug_names. |
| 348 | }; |
| 349 | |
| 350 | /// Collects and handles dwarf debug information. |
| 351 | class DwarfDebug : public DebugHandlerBase { |
| 352 | /// All DIEValues are allocated through this allocator. |
| 353 | BumpPtrAllocator DIEValueAllocator; |
| 354 | |
| 355 | /// Maps MDNode with its corresponding DwarfCompileUnit. |
| 356 | MapVector<const MDNode *, DwarfCompileUnit *> CUMap; |
| 357 | |
| 358 | /// Maps a CU DIE with its corresponding DwarfCompileUnit. |
| 359 | DenseMap<const DIE *, DwarfCompileUnit *> CUDieMap; |
| 360 | |
| 361 | /// List of all labels used in aranges generation. |
| 362 | std::vector<SymbolCU> ArangeLabels; |
| 363 | |
| 364 | /// Size of each symbol emitted (for those symbols that have a specific size). |
| 365 | DenseMap<const MCSymbol *, uint64_t> SymSize; |
| 366 | |
| 367 | /// Collection of abstract variables/labels. |
| 368 | SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities; |
| 369 | |
| 370 | /// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists |
| 371 | /// can refer to them in spite of insertions into this list. |
| 372 | DebugLocStream DebugLocs; |
| 373 | |
| 374 | /// This is a collection of subprogram MDNodes that are processed to |
| 375 | /// create DIEs. |
| 376 | SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes; |
| 377 | |
| 378 | /// Map function-local imported entities to their parent local scope |
| 379 | /// (either DILexicalBlock or DISubprogram) for a processed function |
| 380 | /// (including inlined subprograms). |
| 381 | using MDNodeSet = SetVector<const MDNode *, SmallVector<const MDNode *, 2>, |
| 382 | SmallPtrSet<const MDNode *, 2>>; |
| 383 | DenseMap<const DILocalScope *, MDNodeSet> LocalDeclsPerLS; |
| 384 | |
| 385 | SmallDenseSet<const MachineInstr *> ForceIsStmtInstrs; |
| 386 | |
| 387 | /// If nonnull, stores the current machine function we're processing. |
| 388 | const MachineFunction *CurFn = nullptr; |
| 389 | |
| 390 | /// If nonnull, stores the CU in which the previous subprogram was contained. |
| 391 | const DwarfCompileUnit *PrevCU = nullptr; |
| 392 | |
| 393 | /// As an optimization, there is no need to emit an entry in the directory |
| 394 | /// table for the same directory as DW_AT_comp_dir. |
| 395 | StringRef CompilationDir; |
| 396 | |
| 397 | /// Holder for the file specific debug information. |
| 398 | DwarfFile InfoHolder; |
| 399 | |
| 400 | /// Holders for the various debug information flags that we might need to |
| 401 | /// have exposed. See accessor functions below for description. |
| 402 | |
| 403 | /// Map from MDNodes for user-defined types to their type signatures. Also |
| 404 | /// used to keep track of which types we have emitted type units for. |
| 405 | DenseMap<const MDNode *, uint64_t> TypeSignatures; |
| 406 | |
| 407 | DenseMap<const MCSection *, const MCSymbol *> SectionLabels; |
| 408 | |
| 409 | SmallVector< |
| 410 | std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1> |
| 411 | TypeUnitsUnderConstruction; |
| 412 | |
| 413 | /// Symbol pointing to the current function's DWARF line table entries. |
| 414 | MCSymbol *FunctionLineTableLabel; |
| 415 | |
| 416 | /// Used to set a uniqe ID for a Type Unit. |
| 417 | /// This counter represents number of DwarfTypeUnits created, not necessarily |
| 418 | /// number of type units that will be emitted. |
| 419 | unsigned NumTypeUnitsCreated = 0; |
| 420 | |
| 421 | /// Whether to use the GNU TLS opcode (instead of the standard opcode). |
| 422 | bool UseGNUTLSOpcode; |
| 423 | |
| 424 | /// Whether to use DWARF 2 bitfields (instead of the DWARF 4 format). |
| 425 | bool UseDWARF2Bitfields; |
| 426 | |
| 427 | /// Whether to emit all linkage names, or just abstract subprograms. |
| 428 | bool UseAllLinkageNames; |
| 429 | |
| 430 | /// Use inlined strings. |
| 431 | bool UseInlineStrings = false; |
| 432 | |
| 433 | /// Allow emission of .debug_ranges section. |
| 434 | bool UseRangesSection = true; |
| 435 | |
| 436 | /// True if the sections itself must be used as references and don't create |
| 437 | /// temp symbols inside DWARF sections. |
| 438 | bool UseSectionsAsReferences = false; |
| 439 | |
| 440 | /// Allow emission of .debug_aranges section |
| 441 | bool UseARangesSection = false; |
| 442 | |
| 443 | /// Generate DWARF v4 type units. |
| 444 | bool GenerateTypeUnits; |
| 445 | |
| 446 | /// Emit a .debug_macro section instead of .debug_macinfo. |
| 447 | bool UseDebugMacroSection; |
| 448 | |
| 449 | /// Avoid using DW_OP_convert due to consumer incompatibilities. |
| 450 | bool EnableOpConvert; |
| 451 | |
| 452 | public: |
| 453 | enum class MinimizeAddrInV5 { |
| 454 | Default, |
| 455 | Disabled, |
| 456 | Ranges, |
| 457 | Expressions, |
| 458 | Form, |
| 459 | }; |
| 460 | |
| 461 | enum class DWARF5AccelTableKind { |
| 462 | CU = 0, |
| 463 | TU = 1, |
| 464 | }; |
| 465 | |
| 466 | private: |
| 467 | /// Instructions which should get is_stmt applied because they implement key |
| 468 | /// functionality for a source atom. |
| 469 | SmallDenseSet<const MachineInstr *> KeyInstructions; |
| 470 | |
| 471 | /// Force the use of DW_AT_ranges even for single-entry range lists. |
| 472 | MinimizeAddrInV5 MinimizeAddr = MinimizeAddrInV5::Disabled; |
| 473 | |
| 474 | /// DWARF5 Experimental Options |
| 475 | /// @{ |
| 476 | AccelTableKind TheAccelTableKind; |
| 477 | bool HasAppleExtensionAttributes; |
| 478 | bool HasSplitDwarf; |
| 479 | |
| 480 | /// Whether to generate the DWARF v5 string offsets table. |
| 481 | /// It consists of a series of contributions, each preceded by a header. |
| 482 | /// The pre-DWARF v5 string offsets table for split dwarf is, in contrast, |
| 483 | /// a monolithic sequence of string offsets. |
| 484 | bool UseSegmentedStringOffsetsTable; |
| 485 | |
| 486 | /// Enable production of call site parameters needed to print the debug entry |
| 487 | /// values. Useful for testing purposes when a debugger does not support the |
| 488 | /// feature yet. |
| 489 | bool EmitDebugEntryValues; |
| 490 | |
| 491 | /// Separated Dwarf Variables |
| 492 | /// In general these will all be for bits that are left in the |
| 493 | /// original object file, rather than things that are meant |
| 494 | /// to be in the .dwo sections. |
| 495 | |
| 496 | /// Holder for the skeleton information. |
| 497 | DwarfFile SkeletonHolder; |
| 498 | |
| 499 | /// Store file names for type units under fission in a line table |
| 500 | /// header that will be emitted into debug_line.dwo. |
| 501 | // FIXME: replace this with a map from comp_dir to table so that we |
| 502 | // can emit multiple tables during LTO each of which uses directory |
| 503 | // 0, referencing the comp_dir of all the type units that use it. |
| 504 | MCDwarfDwoLineTable SplitTypeUnitFileTable; |
| 505 | /// @} |
| 506 | |
| 507 | /// True iff there are multiple CUs in this module. |
| 508 | bool SingleCU; |
| 509 | bool IsDarwin; |
| 510 | |
| 511 | /// Map for tracking Fortran deferred CHARACTER lengths. |
| 512 | DenseMap<const DIStringType *, unsigned> StringTypeLocMap; |
| 513 | |
| 514 | AddressPool AddrPool; |
| 515 | |
| 516 | /// Accelerator tables. |
| 517 | DWARF5AccelTable AccelDebugNames; |
| 518 | DWARF5AccelTable AccelTypeUnitsDebugNames; |
| 519 | /// Used to hide which DWARF5AccelTable we are using now. |
| 520 | DWARF5AccelTable *CurrentDebugNames = &AccelDebugNames; |
| 521 | AccelTable<AppleAccelTableOffsetData> AccelNames; |
| 522 | AccelTable<AppleAccelTableOffsetData> AccelObjC; |
| 523 | AccelTable<AppleAccelTableOffsetData> AccelNamespace; |
| 524 | AccelTable<AppleAccelTableTypeData> AccelTypes; |
| 525 | |
| 526 | /// Identify a debugger for "tuning" the debug info. |
| 527 | /// |
| 528 | /// The "tuning" should be used to set defaults for individual feature flags |
| 529 | /// in DwarfDebug; if a given feature has a more specific command-line option, |
| 530 | /// that option should take precedence over the tuning. |
| 531 | DebuggerKind DebuggerTuning = DebuggerKind::Default; |
| 532 | |
| 533 | MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); |
| 534 | |
| 535 | const SmallVectorImpl<std::unique_ptr<DwarfCompileUnit>> &getUnits() { |
| 536 | return InfoHolder.getUnits(); |
| 537 | } |
| 538 | |
| 539 | using InlinedEntity = DbgValueHistoryMap::InlinedEntity; |
| 540 | |
| 541 | void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, |
| 542 | const DINode *Node, |
| 543 | const MDNode *Scope); |
| 544 | |
| 545 | DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU, |
| 546 | LexicalScope &Scope, |
| 547 | const DINode *Node, |
| 548 | const DILocation *Location, |
| 549 | const MCSymbol *Sym = nullptr); |
| 550 | |
| 551 | /// Construct a DIE for this abstract scope. |
| 552 | void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope); |
| 553 | |
| 554 | /// Construct DIEs for call site entries describing the calls in \p MF. |
| 555 | void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU, |
| 556 | DIE &ScopeDIE, const MachineFunction &MF); |
| 557 | |
| 558 | template <typename DataT> |
| 559 | void addAccelNameImpl(const DwarfUnit &Unit, |
| 560 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 561 | AccelTable<DataT> &AppleAccel, StringRef Name, |
| 562 | const DIE &Die); |
| 563 | |
| 564 | void finishEntityDefinitions(); |
| 565 | |
| 566 | void finishSubprogramDefinitions(); |
| 567 | |
| 568 | /// Finish off debug information after all functions have been |
| 569 | /// processed. |
| 570 | void finalizeModuleInfo(); |
| 571 | |
| 572 | /// Emit the debug info section. |
| 573 | void emitDebugInfo(); |
| 574 | |
| 575 | /// Emit the abbreviation section. |
| 576 | void emitAbbreviations(); |
| 577 | |
| 578 | /// Emit the string offsets table header. |
| 579 | void (); |
| 580 | |
| 581 | /// Emit a specified accelerator table. |
| 582 | template <typename AccelTableT> |
| 583 | void emitAccel(AccelTableT &Accel, MCSection *Section, StringRef TableName); |
| 584 | |
| 585 | /// Emit DWARF v5 accelerator table. |
| 586 | void emitAccelDebugNames(); |
| 587 | |
| 588 | /// Emit visible names into a hashed accelerator table section. |
| 589 | void emitAccelNames(); |
| 590 | |
| 591 | /// Emit objective C classes and categories into a hashed |
| 592 | /// accelerator table section. |
| 593 | void emitAccelObjC(); |
| 594 | |
| 595 | /// Emit namespace dies into a hashed accelerator table. |
| 596 | void emitAccelNamespaces(); |
| 597 | |
| 598 | /// Emit type dies into a hashed accelerator table. |
| 599 | void emitAccelTypes(); |
| 600 | |
| 601 | /// Emit visible names and types into debug pubnames and pubtypes sections. |
| 602 | void emitDebugPubSections(); |
| 603 | |
| 604 | void emitDebugPubSection(bool GnuStyle, StringRef Name, |
| 605 | DwarfCompileUnit *TheU, |
| 606 | const StringMap<const DIE *> &Globals); |
| 607 | |
| 608 | /// Emit null-terminated strings into a debug str section. |
| 609 | void emitDebugStr(); |
| 610 | |
| 611 | /// Emit variable locations into a debug loc section. |
| 612 | void emitDebugLoc(); |
| 613 | |
| 614 | /// Emit variable locations into a debug loc dwo section. |
| 615 | void emitDebugLocDWO(); |
| 616 | |
| 617 | void emitDebugLocImpl(MCSection *Sec); |
| 618 | |
| 619 | /// Emit address ranges into a debug aranges section. |
| 620 | void emitDebugARanges(); |
| 621 | |
| 622 | /// Emit address ranges into a debug ranges section. |
| 623 | void emitDebugRanges(); |
| 624 | void emitDebugRangesDWO(); |
| 625 | void emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section); |
| 626 | |
| 627 | /// Emit macros into a debug macinfo section. |
| 628 | void emitDebugMacinfo(); |
| 629 | /// Emit macros into a debug macinfo.dwo section. |
| 630 | void emitDebugMacinfoDWO(); |
| 631 | void emitDebugMacinfoImpl(MCSection *Section); |
| 632 | void emitMacro(DIMacro &M); |
| 633 | void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U); |
| 634 | void emitMacroFileImpl(DIMacroFile &F, DwarfCompileUnit &U, |
| 635 | unsigned StartFile, unsigned EndFile, |
| 636 | StringRef (*MacroFormToString)(unsigned Form)); |
| 637 | void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U); |
| 638 | |
| 639 | /// DWARF 5 Experimental Split Dwarf Emitters |
| 640 | |
| 641 | /// Initialize common features of skeleton units. |
| 642 | void initSkeletonUnit(const DwarfUnit &U, DIE &Die, |
| 643 | std::unique_ptr<DwarfCompileUnit> NewU); |
| 644 | |
| 645 | /// Construct the split debug info compile unit for the debug info section. |
| 646 | /// In DWARF v5, the skeleton unit DIE may have the following attributes: |
| 647 | /// DW_AT_addr_base, DW_AT_comp_dir, DW_AT_dwo_name, DW_AT_high_pc, |
| 648 | /// DW_AT_low_pc, DW_AT_ranges, DW_AT_stmt_list, and DW_AT_str_offsets_base. |
| 649 | /// Prior to DWARF v5 it may also have DW_AT_GNU_dwo_id. DW_AT_GNU_dwo_name |
| 650 | /// is used instead of DW_AT_dwo_name, Dw_AT_GNU_addr_base instead of |
| 651 | /// DW_AT_addr_base, and DW_AT_GNU_ranges_base instead of DW_AT_rnglists_base. |
| 652 | DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU); |
| 653 | |
| 654 | /// Emit the debug info dwo section. |
| 655 | void emitDebugInfoDWO(); |
| 656 | |
| 657 | /// Emit the debug abbrev dwo section. |
| 658 | void emitDebugAbbrevDWO(); |
| 659 | |
| 660 | /// Emit the debug line dwo section. |
| 661 | void emitDebugLineDWO(); |
| 662 | |
| 663 | /// Emit the dwo stringoffsets table header. |
| 664 | void (); |
| 665 | |
| 666 | /// Emit the debug str dwo section. |
| 667 | void emitDebugStrDWO(); |
| 668 | |
| 669 | /// Emit DWO addresses. |
| 670 | void emitDebugAddr(); |
| 671 | |
| 672 | /// Flags to let the linker know we have emitted new style pubnames. Only |
| 673 | /// emit it here if we don't have a skeleton CU for split dwarf. |
| 674 | void addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const; |
| 675 | |
| 676 | /// Create new DwarfCompileUnit for the given metadata node with tag |
| 677 | /// DW_TAG_compile_unit. |
| 678 | DwarfCompileUnit &getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit); |
| 679 | void finishUnitAttributes(const DICompileUnit *DIUnit, |
| 680 | DwarfCompileUnit &NewCU); |
| 681 | |
| 682 | /// Register a source line with debug info. Returns the unique |
| 683 | /// label that was emitted and which provides correspondence to the |
| 684 | /// source line list. |
| 685 | void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope, |
| 686 | unsigned Flags, StringRef Location = {}); |
| 687 | |
| 688 | /// Populate LexicalScope entries with variables' info. |
| 689 | void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, |
| 690 | DenseSet<InlinedEntity> &ProcessedVars); |
| 691 | |
| 692 | /// Build the location list for all DBG_VALUEs in the |
| 693 | /// function that describe the same variable. If the resulting |
| 694 | /// list has only one entry that is valid for entire variable's |
| 695 | /// scope return true. |
| 696 | bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, |
| 697 | const DbgValueHistoryMap::Entries &Entries); |
| 698 | |
| 699 | /// Collect variable information from the side table maintained by MF. |
| 700 | void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU, |
| 701 | DenseSet<InlinedEntity> &P); |
| 702 | |
| 703 | /// Emit the reference to the section. |
| 704 | void emitSectionReference(const DwarfCompileUnit &CU); |
| 705 | |
| 706 | void findForceIsStmtInstrs(const MachineFunction *MF); |
| 707 | |
| 708 | /// Compute instructions which should get is_stmt applied because they |
| 709 | /// implement key functionality for a source location atom, store results in |
| 710 | /// DwarfDebug::KeyInstructions. |
| 711 | void computeKeyInstructions(const MachineFunction *MF); |
| 712 | |
| 713 | protected: |
| 714 | /// Gather pre-function debug information. |
| 715 | void beginFunctionImpl(const MachineFunction *MF) override; |
| 716 | |
| 717 | /// Gather and emit post-function debug information. |
| 718 | void endFunctionImpl(const MachineFunction *MF) override; |
| 719 | |
| 720 | /// Get Dwarf compile unit ID for line table. |
| 721 | unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU); |
| 722 | |
| 723 | void skippedNonDebugFunction() override; |
| 724 | |
| 725 | public: |
| 726 | //===--------------------------------------------------------------------===// |
| 727 | // Main entry points. |
| 728 | // |
| 729 | DwarfDebug(AsmPrinter *A); |
| 730 | |
| 731 | ~DwarfDebug() override; |
| 732 | |
| 733 | /// Emit all Dwarf sections that should come prior to the |
| 734 | /// content. |
| 735 | void beginModule(Module *M) override; |
| 736 | |
| 737 | /// Emit all Dwarf sections that should come after the content. |
| 738 | void endModule() override; |
| 739 | |
| 740 | /// Emits inital debug location directive. Returns instruction at which |
| 741 | /// the function prologue ends. |
| 742 | const MachineInstr *emitInitialLocDirective(const MachineFunction &MF, |
| 743 | unsigned CUID); |
| 744 | |
| 745 | /// Process beginning of an instruction. |
| 746 | void beginInstruction(const MachineInstr *MI) override; |
| 747 | |
| 748 | /// Process beginning of code alignment. |
| 749 | void beginCodeAlignment(const MachineBasicBlock &MBB) override; |
| 750 | |
| 751 | /// Perform an MD5 checksum of \p Identifier and return the lower 64 bits. |
| 752 | static uint64_t makeTypeSignature(StringRef Identifier); |
| 753 | |
| 754 | /// Add a DIE to the set of types that we're going to pull into |
| 755 | /// type units. |
| 756 | void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, |
| 757 | DIE &Die, const DICompositeType *CTy); |
| 758 | |
| 759 | /// Add a label so that arange data can be generated for it. |
| 760 | void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(x: SCU); } |
| 761 | |
| 762 | /// For symbols that have a size designated (e.g. common symbols), |
| 763 | /// this tracks that size. |
| 764 | void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override { |
| 765 | SymSize[Sym] = Size; |
| 766 | } |
| 767 | |
| 768 | /// Returns whether we should emit all DW_AT_[MIPS_]linkage_name. |
| 769 | /// If not, we still might emit certain cases. |
| 770 | bool useAllLinkageNames() const { return UseAllLinkageNames; } |
| 771 | |
| 772 | /// Returns whether to use DW_OP_GNU_push_tls_address, instead of the |
| 773 | /// standard DW_OP_form_tls_address opcode |
| 774 | bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; } |
| 775 | |
| 776 | /// Returns whether to use the DWARF2 format for bitfields instyead of the |
| 777 | /// DWARF4 format. |
| 778 | bool useDWARF2Bitfields() const { return UseDWARF2Bitfields; } |
| 779 | |
| 780 | /// Returns whether to use inline strings. |
| 781 | bool useInlineStrings() const { return UseInlineStrings; } |
| 782 | |
| 783 | /// Returns whether ranges section should be emitted. |
| 784 | bool useRangesSection() const { return UseRangesSection; } |
| 785 | |
| 786 | /// Returns whether range encodings should be used for single entry range |
| 787 | /// lists. |
| 788 | bool alwaysUseRanges(const DwarfCompileUnit &) const; |
| 789 | |
| 790 | // Returns whether novel exprloc addrx+offset encodings should be used to |
| 791 | // reduce debug_addr size. |
| 792 | bool useAddrOffsetExpressions() const { |
| 793 | return MinimizeAddr == MinimizeAddrInV5::Expressions; |
| 794 | } |
| 795 | |
| 796 | // Returns whether addrx+offset LLVM extension form should be used to reduce |
| 797 | // debug_addr size. |
| 798 | bool useAddrOffsetForm() const { |
| 799 | return MinimizeAddr == MinimizeAddrInV5::Form; |
| 800 | } |
| 801 | |
| 802 | /// Returns whether to use sections as labels rather than temp symbols. |
| 803 | bool useSectionsAsReferences() const { |
| 804 | return UseSectionsAsReferences; |
| 805 | } |
| 806 | |
| 807 | /// Returns whether to generate DWARF v4 type units. |
| 808 | bool generateTypeUnits() const { return GenerateTypeUnits; } |
| 809 | |
| 810 | // Experimental DWARF5 features. |
| 811 | |
| 812 | /// Returns what kind (if any) of accelerator tables to emit. |
| 813 | AccelTableKind getAccelTableKind() const { return TheAccelTableKind; } |
| 814 | |
| 815 | /// Seet TheAccelTableKind |
| 816 | void setTheAccelTableKind(AccelTableKind K) { TheAccelTableKind = K; }; |
| 817 | |
| 818 | bool useAppleExtensionAttributes() const { |
| 819 | return HasAppleExtensionAttributes; |
| 820 | } |
| 821 | |
| 822 | /// Returns whether or not to change the current debug info for the |
| 823 | /// split dwarf proposal support. |
| 824 | bool useSplitDwarf() const { return HasSplitDwarf; } |
| 825 | |
| 826 | /// Returns whether to generate a string offsets table with (possibly shared) |
| 827 | /// contributions from each CU and type unit. This implies the use of |
| 828 | /// DW_FORM_strx* indirect references with DWARF v5 and beyond. Note that |
| 829 | /// DW_FORM_GNU_str_index is also an indirect reference, but it is used with |
| 830 | /// a pre-DWARF v5 implementation of split DWARF sections, which uses a |
| 831 | /// monolithic string offsets table. |
| 832 | bool useSegmentedStringOffsetsTable() const { |
| 833 | return UseSegmentedStringOffsetsTable; |
| 834 | } |
| 835 | |
| 836 | bool emitDebugEntryValues() const { |
| 837 | return EmitDebugEntryValues; |
| 838 | } |
| 839 | |
| 840 | bool useOpConvert() const { |
| 841 | return EnableOpConvert; |
| 842 | } |
| 843 | |
| 844 | bool shareAcrossDWOCUs() const; |
| 845 | |
| 846 | /// Returns the Dwarf Version. |
| 847 | uint16_t getDwarfVersion() const; |
| 848 | |
| 849 | /// Returns a suitable DWARF form to represent a section offset, i.e. |
| 850 | /// * DW_FORM_sec_offset for DWARF version >= 4; |
| 851 | /// * DW_FORM_data8 for 64-bit DWARFv3; |
| 852 | /// * DW_FORM_data4 for 32-bit DWARFv3 and DWARFv2. |
| 853 | dwarf::Form getDwarfSectionOffsetForm() const; |
| 854 | |
| 855 | /// Returns the previous CU that was being updated |
| 856 | const DwarfCompileUnit *getPrevCU() const { return PrevCU; } |
| 857 | void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; } |
| 858 | |
| 859 | /// Terminate the line table by adding the last range label. |
| 860 | void terminateLineTable(const DwarfCompileUnit *CU); |
| 861 | |
| 862 | /// Returns the entries for the .debug_loc section. |
| 863 | const DebugLocStream &getDebugLocs() const { return DebugLocs; } |
| 864 | |
| 865 | /// Emit an entry for the debug loc section. This can be used to |
| 866 | /// handle an entry that's going to be emitted into the debug loc section. |
| 867 | void emitDebugLocEntry(ByteStreamer &Streamer, |
| 868 | const DebugLocStream::Entry &Entry, |
| 869 | const DwarfCompileUnit *CU); |
| 870 | |
| 871 | /// Emit the location for a debug loc entry, including the size header. |
| 872 | void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, |
| 873 | const DwarfCompileUnit *CU); |
| 874 | |
| 875 | void addSubprogramNames(const DwarfUnit &Unit, |
| 876 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 877 | const DISubprogram *SP, DIE &Die); |
| 878 | |
| 879 | AddressPool &getAddressPool() { return AddrPool; } |
| 880 | |
| 881 | void addAccelName(const DwarfUnit &Unit, |
| 882 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 883 | StringRef Name, const DIE &Die); |
| 884 | |
| 885 | void addAccelObjC(const DwarfUnit &Unit, |
| 886 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 887 | StringRef Name, const DIE &Die); |
| 888 | |
| 889 | void addAccelNamespace(const DwarfUnit &Unit, |
| 890 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 891 | StringRef Name, const DIE &Die); |
| 892 | |
| 893 | void addAccelType(const DwarfUnit &Unit, |
| 894 | const DICompileUnit::DebugNameTableKind NameTableKind, |
| 895 | StringRef Name, const DIE &Die, char Flags); |
| 896 | |
| 897 | const MachineFunction *getCurrentFunction() const { return CurFn; } |
| 898 | |
| 899 | /// A helper function to check whether the DIE for a given Scope is |
| 900 | /// going to be null. |
| 901 | bool isLexicalScopeDIENull(LexicalScope *Scope); |
| 902 | |
| 903 | /// Find the matching DwarfCompileUnit for the given CU DIE. |
| 904 | DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Val: Die); } |
| 905 | const DwarfCompileUnit *lookupCU(const DIE *Die) const { |
| 906 | return CUDieMap.lookup(Val: Die); |
| 907 | } |
| 908 | |
| 909 | unsigned getStringTypeLoc(const DIStringType *ST) const { |
| 910 | return StringTypeLocMap.lookup(Val: ST); |
| 911 | } |
| 912 | |
| 913 | void addStringTypeLoc(const DIStringType *ST, unsigned Loc) { |
| 914 | assert(ST); |
| 915 | if (Loc) |
| 916 | StringTypeLocMap[ST] = Loc; |
| 917 | } |
| 918 | |
| 919 | /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. |
| 920 | /// |
| 921 | /// Returns whether we are "tuning" for a given debugger. |
| 922 | /// @{ |
| 923 | bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } |
| 924 | bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } |
| 925 | bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } |
| 926 | bool tuneForDBX() const { return DebuggerTuning == DebuggerKind::DBX; } |
| 927 | /// @} |
| 928 | |
| 929 | const MCSymbol *getSectionLabel(const MCSection *S); |
| 930 | void insertSectionLabel(const MCSymbol *S); |
| 931 | |
| 932 | static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, |
| 933 | const DbgValueLoc &Value, |
| 934 | DwarfExpression &DwarfExpr); |
| 935 | |
| 936 | /// If the \p File has an MD5 checksum, return it as an MD5Result |
| 937 | /// allocated in the MCContext. |
| 938 | std::optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const; |
| 939 | |
| 940 | MDNodeSet &getLocalDeclsForScope(const DILocalScope *S) { |
| 941 | return LocalDeclsPerLS[S]; |
| 942 | } |
| 943 | |
| 944 | /// Sets the current DWARF5AccelTable to use. |
| 945 | void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind) { |
| 946 | switch (Kind) { |
| 947 | case DWARF5AccelTableKind::CU: |
| 948 | CurrentDebugNames = &AccelDebugNames; |
| 949 | break; |
| 950 | case DWARF5AccelTableKind::TU: |
| 951 | CurrentDebugNames = &AccelTypeUnitsDebugNames; |
| 952 | } |
| 953 | } |
| 954 | /// Returns either CU or TU DWARF5AccelTable. |
| 955 | DWARF5AccelTable &getCurrentDWARF5AccelTable() { return *CurrentDebugNames; } |
| 956 | }; |
| 957 | |
| 958 | } // end namespace llvm |
| 959 | |
| 960 | #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H |
| 961 | |