1 //===- llvm/CodeGen/DwarfExpression.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains support for writing dwarf compile unit. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 14 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 15 16 #include "ByteStreamer.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/None.h" 19 #include "llvm/ADT/Optional.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/IR/DebugInfoMetadata.h" 22 #include <cassert> 23 #include <cstdint> 24 #include <iterator> 25 26 namespace llvm { 27 28 class AsmPrinter; 29 class APInt; 30 class DwarfCompileUnit; 31 class DIELoc; 32 class TargetRegisterInfo; 33 class MachineLocation; 34 35 /// Holds a DIExpression and keeps track of how many operands have been consumed 36 /// so far. 37 class DIExpressionCursor { 38 DIExpression::expr_op_iterator Start, End; 39 40 public: 41 DIExpressionCursor(const DIExpression *Expr) { 42 if (!Expr) { 43 assert(Start == End); 44 return; 45 } 46 Start = Expr->expr_op_begin(); 47 End = Expr->expr_op_end(); 48 } 49 50 DIExpressionCursor(ArrayRef<uint64_t> Expr) 51 : Start(Expr.begin()), End(Expr.end()) {} 52 53 DIExpressionCursor(const DIExpressionCursor &) = default; 54 55 /// Consume one operation. 56 Optional<DIExpression::ExprOperand> take() { 57 if (Start == End) 58 return None; 59 return *(Start++); 60 } 61 62 /// Consume N operations. 63 void consume(unsigned N) { std::advance(Start, N); } 64 65 /// Return the current operation. 66 Optional<DIExpression::ExprOperand> peek() const { 67 if (Start == End) 68 return None; 69 return *(Start); 70 } 71 72 /// Return the next operation. 73 Optional<DIExpression::ExprOperand> peekNext() const { 74 if (Start == End) 75 return None; 76 77 auto Next = Start.getNext(); 78 if (Next == End) 79 return None; 80 81 return *Next; 82 } 83 84 /// Determine whether there are any operations left in this expression. 85 operator bool() const { return Start != End; } 86 87 DIExpression::expr_op_iterator begin() const { return Start; } 88 DIExpression::expr_op_iterator end() const { return End; } 89 90 /// Retrieve the fragment information, if any. 91 Optional<DIExpression::FragmentInfo> getFragmentInfo() const { 92 return DIExpression::getFragmentInfo(Start, End); 93 } 94 }; 95 96 /// Base class containing the logic for constructing DWARF expressions 97 /// independently of whether they are emitted into a DIE or into a .debug_loc 98 /// entry. 99 /// 100 /// Some DWARF operations, e.g. DW_OP_entry_value, need to calculate the size 101 /// of a succeeding DWARF block before the latter is emitted to the output. 102 /// To handle such cases, data can conditionally be emitted to a temporary 103 /// buffer, which can later on be committed to the main output. The size of the 104 /// temporary buffer is queryable, allowing for the size of the data to be 105 /// emitted before the data is committed. 106 class DwarfExpression { 107 protected: 108 /// Holds information about all subregisters comprising a register location. 109 struct Register { 110 int DwarfRegNo; 111 unsigned SubRegSize; 112 const char *Comment; 113 114 /// Create a full register, no extra DW_OP_piece operators necessary. 115 static Register createRegister(int RegNo, const char *Comment) { 116 return {RegNo, 0, Comment}; 117 } 118 119 /// Create a subregister that needs a DW_OP_piece operator with SizeInBits. 120 static Register createSubRegister(int RegNo, unsigned SizeInBits, 121 const char *Comment) { 122 return {RegNo, SizeInBits, Comment}; 123 } 124 125 bool isSubRegister() const { return SubRegSize; } 126 }; 127 128 /// Whether we are currently emitting an entry value operation. 129 bool IsEmittingEntryValue = false; 130 131 DwarfCompileUnit &CU; 132 133 /// The register location, if any. 134 SmallVector<Register, 2> DwarfRegs; 135 136 /// Current Fragment Offset in Bits. 137 uint64_t OffsetInBits = 0; 138 139 /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister. 140 unsigned SubRegisterSizeInBits : 16; 141 unsigned SubRegisterOffsetInBits : 16; 142 143 /// The kind of location description being produced. 144 enum { Unknown = 0, Register, Memory, Implicit }; 145 146 /// Additional location flags which may be combined with any location kind. 147 /// Currently, entry values are not supported for the Memory location kind. 148 enum { EntryValue = 1 << 0, Indirect = 1 << 1, CallSiteParamValue = 1 << 2 }; 149 150 unsigned LocationKind : 3; 151 unsigned SavedLocationKind : 3; 152 unsigned LocationFlags : 3; 153 unsigned DwarfVersion : 4; 154 155 public: 156 /// Set the location (\p Loc) and \ref DIExpression (\p DIExpr) to describe. 157 void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr); 158 159 bool isUnknownLocation() const { return LocationKind == Unknown; } 160 161 bool isMemoryLocation() const { return LocationKind == Memory; } 162 163 bool isRegisterLocation() const { return LocationKind == Register; } 164 165 bool isImplicitLocation() const { return LocationKind == Implicit; } 166 167 bool isEntryValue() const { return LocationFlags & EntryValue; } 168 169 bool isIndirect() const { return LocationFlags & Indirect; } 170 171 bool isParameterValue() { return LocationFlags & CallSiteParamValue; } 172 173 Optional<uint8_t> TagOffset; 174 175 protected: 176 /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed 177 /// to represent a subregister. 178 void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) { 179 assert(SizeInBits < 65536 && OffsetInBits < 65536); 180 SubRegisterSizeInBits = SizeInBits; 181 SubRegisterOffsetInBits = OffsetInBits; 182 } 183 184 /// Add masking operations to stencil out a subregister. 185 void maskSubRegister(); 186 187 /// Output a dwarf operand and an optional assembler comment. 188 virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0; 189 190 /// Emit a raw signed value. 191 virtual void emitSigned(int64_t Value) = 0; 192 193 /// Emit a raw unsigned value. 194 virtual void emitUnsigned(uint64_t Value) = 0; 195 196 virtual void emitData1(uint8_t Value) = 0; 197 198 virtual void emitBaseTypeRef(uint64_t Idx) = 0; 199 200 /// Start emitting data to the temporary buffer. The data stored in the 201 /// temporary buffer can be committed to the main output using 202 /// commitTemporaryBuffer(). 203 virtual void enableTemporaryBuffer() = 0; 204 205 /// Disable emission to the temporary buffer. This does not commit data 206 /// in the temporary buffer to the main output. 207 virtual void disableTemporaryBuffer() = 0; 208 209 /// Return the emitted size, in number of bytes, for the data stored in the 210 /// temporary buffer. 211 virtual unsigned getTemporaryBufferSize() = 0; 212 213 /// Commit the data stored in the temporary buffer to the main output. 214 virtual void commitTemporaryBuffer() = 0; 215 216 /// Emit a normalized unsigned constant. 217 void emitConstu(uint64_t Value); 218 219 /// Return whether the given machine register is the frame register in the 220 /// current function. 221 virtual bool isFrameRegister(const TargetRegisterInfo &TRI, 222 llvm::Register MachineReg) = 0; 223 224 /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF 225 /// register location description. 226 void addReg(int DwarfReg, const char *Comment = nullptr); 227 228 /// Emit a DW_OP_breg operation. 229 void addBReg(int DwarfReg, int Offset); 230 231 /// Emit DW_OP_fbreg <Offset>. 232 void addFBReg(int Offset); 233 234 /// Emit a partial DWARF register operation. 235 /// 236 /// \param MachineReg The register number. 237 /// \param MaxSize If the register must be composed from 238 /// sub-registers this is an upper bound 239 /// for how many bits the emitted DW_OP_piece 240 /// may cover. 241 /// 242 /// If size and offset is zero an operation for the entire register is 243 /// emitted: Some targets do not provide a DWARF register number for every 244 /// register. If this is the case, this function will attempt to emit a DWARF 245 /// register by emitting a fragment of a super-register or by piecing together 246 /// multiple subregisters that alias the register. 247 /// 248 /// \return false if no DWARF register exists for MachineReg. 249 bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, 250 unsigned MaxSize = ~1U); 251 252 /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment. 253 /// \param OffsetInBits This is an optional offset into the location that 254 /// is at the top of the DWARF stack. 255 void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0); 256 257 /// Emit a shift-right dwarf operation. 258 void addShr(unsigned ShiftBy); 259 260 /// Emit a bitwise and dwarf operation. 261 void addAnd(unsigned Mask); 262 263 /// Emit a DW_OP_stack_value, if supported. 264 /// 265 /// The proper way to describe a constant value is DW_OP_constu <const>, 266 /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available 267 /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for 268 /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const 269 /// <const> actually describes a value at a constant address, not a constant 270 /// value. However, in the past there was no better way to describe a 271 /// constant value, so the producers and consumers started to rely on 272 /// heuristics to disambiguate the value vs. location status of the 273 /// expression. See PR21176 for more details. 274 void addStackValue(); 275 276 /// Finalize an entry value by emitting its size operand, and committing the 277 /// DWARF block which has been emitted to the temporary buffer. 278 void finalizeEntryValue(); 279 280 /// Cancel the emission of an entry value. 281 void cancelEntryValue(); 282 283 ~DwarfExpression() = default; 284 285 public: 286 DwarfExpression(unsigned DwarfVersion, DwarfCompileUnit &CU) 287 : CU(CU), SubRegisterSizeInBits(0), SubRegisterOffsetInBits(0), 288 LocationKind(Unknown), SavedLocationKind(Unknown), 289 LocationFlags(Unknown), DwarfVersion(DwarfVersion) {} 290 291 /// This needs to be called last to commit any pending changes. 292 void finalize(); 293 294 /// Emit a signed constant. 295 void addSignedConstant(int64_t Value); 296 297 /// Emit an unsigned constant. 298 void addUnsignedConstant(uint64_t Value); 299 300 /// Emit an unsigned constant. 301 void addUnsignedConstant(const APInt &Value); 302 303 /// Emit an floating point constant. 304 void addConstantFP(const APFloat &Value, const AsmPrinter &AP); 305 306 /// Lock this down to become a memory location description. 307 void setMemoryLocationKind() { 308 assert(isUnknownLocation()); 309 LocationKind = Memory; 310 } 311 312 /// Lock this down to become an entry value location. 313 void setEntryValueFlags(const MachineLocation &Loc); 314 315 /// Lock this down to become a call site parameter location. 316 void setCallSiteParamValueFlag() { LocationFlags |= CallSiteParamValue; } 317 318 /// Emit a machine register location. As an optimization this may also consume 319 /// the prefix of a DwarfExpression if a more efficient representation for 320 /// combining the register location and the first operation exists. 321 /// 322 /// \param FragmentOffsetInBits If this is one fragment out of a 323 /// fragmented 324 /// location, this is the offset of the 325 /// fragment inside the entire variable. 326 /// \return false if no DWARF register exists 327 /// for MachineReg. 328 bool addMachineRegExpression(const TargetRegisterInfo &TRI, 329 DIExpressionCursor &Expr, 330 llvm::Register MachineReg, 331 unsigned FragmentOffsetInBits = 0); 332 333 /// Begin emission of an entry value dwarf operation. The entry value's 334 /// first operand is the size of the DWARF block (its second operand), 335 /// which needs to be calculated at time of emission, so we don't emit 336 /// any operands here. 337 void beginEntryValueExpression(DIExpressionCursor &ExprCursor); 338 339 /// Return the index of a base type with the given properties and 340 /// create one if necessary. 341 unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding); 342 343 /// Emit all remaining operations in the DIExpressionCursor. The 344 /// cursor must not contain any DW_OP_LLVM_arg operations. 345 void addExpression(DIExpressionCursor &&Expr); 346 347 /// Emit all remaining operations in the DIExpressionCursor. 348 /// DW_OP_LLVM_arg operations are resolved by calling (\p InsertArg). 349 // 350 /// \return false if any call to (\p InsertArg) returns false. 351 bool addExpression( 352 DIExpressionCursor &&Expr, 353 llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg); 354 355 /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to 356 /// the fragment described by \c Expr. 357 void addFragmentOffset(const DIExpression *Expr); 358 359 void emitLegacySExt(unsigned FromBits); 360 void emitLegacyZExt(unsigned FromBits); 361 362 /// Emit location information expressed via WebAssembly location + offset 363 /// The Index is an identifier for locals, globals or operand stack. 364 void addWasmLocation(unsigned Index, uint64_t Offset); 365 }; 366 367 /// DwarfExpression implementation for .debug_loc entries. 368 class DebugLocDwarfExpression final : public DwarfExpression { 369 370 struct TempBuffer { 371 SmallString<32> Bytes; 372 std::vector<std::string> Comments; 373 BufferByteStreamer BS; 374 375 TempBuffer(bool GenerateComments) : BS(Bytes, Comments, GenerateComments) {} 376 }; 377 378 std::unique_ptr<TempBuffer> TmpBuf; 379 BufferByteStreamer &OutBS; 380 bool IsBuffering = false; 381 382 /// Return the byte streamer that currently is being emitted to. 383 ByteStreamer &getActiveStreamer() { return IsBuffering ? TmpBuf->BS : OutBS; } 384 385 void emitOp(uint8_t Op, const char *Comment = nullptr) override; 386 void emitSigned(int64_t Value) override; 387 void emitUnsigned(uint64_t Value) override; 388 void emitData1(uint8_t Value) override; 389 void emitBaseTypeRef(uint64_t Idx) override; 390 391 void enableTemporaryBuffer() override; 392 void disableTemporaryBuffer() override; 393 unsigned getTemporaryBufferSize() override; 394 void commitTemporaryBuffer() override; 395 396 bool isFrameRegister(const TargetRegisterInfo &TRI, 397 llvm::Register MachineReg) override; 398 399 public: 400 DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS, 401 DwarfCompileUnit &CU) 402 : DwarfExpression(DwarfVersion, CU), OutBS(BS) {} 403 }; 404 405 /// DwarfExpression implementation for singular DW_AT_location. 406 class DIEDwarfExpression final : public DwarfExpression { 407 const AsmPrinter &AP; 408 DIELoc &OutDIE; 409 DIELoc TmpDIE; 410 bool IsBuffering = false; 411 412 /// Return the DIE that currently is being emitted to. 413 DIELoc &getActiveDIE() { return IsBuffering ? TmpDIE : OutDIE; } 414 415 void emitOp(uint8_t Op, const char *Comment = nullptr) override; 416 void emitSigned(int64_t Value) override; 417 void emitUnsigned(uint64_t Value) override; 418 void emitData1(uint8_t Value) override; 419 void emitBaseTypeRef(uint64_t Idx) override; 420 421 void enableTemporaryBuffer() override; 422 void disableTemporaryBuffer() override; 423 unsigned getTemporaryBufferSize() override; 424 void commitTemporaryBuffer() override; 425 426 bool isFrameRegister(const TargetRegisterInfo &TRI, 427 llvm::Register MachineReg) override; 428 429 public: 430 DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE); 431 432 DIELoc *finalize() { 433 DwarfExpression::finalize(); 434 return &OutDIE; 435 } 436 }; 437 438 } // end namespace llvm 439 440 #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H 441