DwarfExpression.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
  13. #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
  14. #include "llvm/ADT/ArrayRef.h"
  15. #include "llvm/ADT/None.h"
  16. #include "llvm/ADT/Optional.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. #include "llvm/IR/DebugInfoMetadata.h"
  19. #include <cassert>
  20. #include <cstdint>
  21. #include <iterator>
  22. namespace llvm {
  23. class AsmPrinter;
  24. class APInt;
  25. class ByteStreamer;
  26. class DwarfCompileUnit;
  27. class DIELoc;
  28. class TargetRegisterInfo;
  29. /// Holds a DIExpression and keeps track of how many operands have been consumed
  30. /// so far.
  31. class DIExpressionCursor {
  32. DIExpression::expr_op_iterator Start, End;
  33. public:
  34. DIExpressionCursor(const DIExpression *Expr) {
  35. if (!Expr) {
  36. assert(Start == End);
  37. return;
  38. }
  39. Start = Expr->expr_op_begin();
  40. End = Expr->expr_op_end();
  41. }
  42. DIExpressionCursor(ArrayRef<uint64_t> Expr)
  43. : Start(Expr.begin()), End(Expr.end()) {}
  44. DIExpressionCursor(const DIExpressionCursor &) = default;
  45. /// Consume one operation.
  46. Optional<DIExpression::ExprOperand> take() {
  47. if (Start == End)
  48. return None;
  49. return *(Start++);
  50. }
  51. /// Consume N operations.
  52. void consume(unsigned N) { std::advance(Start, N); }
  53. /// Return the current operation.
  54. Optional<DIExpression::ExprOperand> peek() const {
  55. if (Start == End)
  56. return None;
  57. return *(Start);
  58. }
  59. /// Return the next operation.
  60. Optional<DIExpression::ExprOperand> peekNext() const {
  61. if (Start == End)
  62. return None;
  63. auto Next = Start.getNext();
  64. if (Next == End)
  65. return None;
  66. return *Next;
  67. }
  68. /// Determine whether there are any operations left in this expression.
  69. operator bool() const { return Start != End; }
  70. DIExpression::expr_op_iterator begin() const { return Start; }
  71. DIExpression::expr_op_iterator end() const { return End; }
  72. /// Retrieve the fragment information, if any.
  73. Optional<DIExpression::FragmentInfo> getFragmentInfo() const {
  74. return DIExpression::getFragmentInfo(Start, End);
  75. }
  76. };
  77. /// Base class containing the logic for constructing DWARF expressions
  78. /// independently of whether they are emitted into a DIE or into a .debug_loc
  79. /// entry.
  80. class DwarfExpression {
  81. protected:
  82. /// Holds information about all subregisters comprising a register location.
  83. struct Register {
  84. int DwarfRegNo;
  85. unsigned Size;
  86. const char *Comment;
  87. };
  88. DwarfCompileUnit &CU;
  89. /// The register location, if any.
  90. SmallVector<Register, 2> DwarfRegs;
  91. /// Current Fragment Offset in Bits.
  92. uint64_t OffsetInBits = 0;
  93. /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
  94. unsigned SubRegisterSizeInBits : 16;
  95. unsigned SubRegisterOffsetInBits : 16;
  96. /// The kind of location description being produced.
  97. enum { Unknown = 0, Register, Memory, Implicit };
  98. /// The flags of location description being produced.
  99. enum { EntryValue = 1, CallSiteParamValue };
  100. unsigned LocationKind : 3;
  101. unsigned LocationFlags : 2;
  102. unsigned DwarfVersion : 4;
  103. public:
  104. bool isUnknownLocation() const {
  105. return LocationKind == Unknown;
  106. }
  107. bool isMemoryLocation() const {
  108. return LocationKind == Memory;
  109. }
  110. bool isRegisterLocation() const {
  111. return LocationKind == Register;
  112. }
  113. bool isImplicitLocation() const {
  114. return LocationKind == Implicit;
  115. }
  116. bool isEntryValue() const {
  117. return LocationFlags & EntryValue;
  118. }
  119. bool isParameterValue() {
  120. return LocationFlags & CallSiteParamValue;
  121. }
  122. Optional<uint8_t> TagOffset;
  123. protected:
  124. /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
  125. /// to represent a subregister.
  126. void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
  127. assert(SizeInBits < 65536 && OffsetInBits < 65536);
  128. SubRegisterSizeInBits = SizeInBits;
  129. SubRegisterOffsetInBits = OffsetInBits;
  130. }
  131. /// Add masking operations to stencil out a subregister.
  132. void maskSubRegister();
  133. /// Output a dwarf operand and an optional assembler comment.
  134. virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0;
  135. /// Emit a raw signed value.
  136. virtual void emitSigned(int64_t Value) = 0;
  137. /// Emit a raw unsigned value.
  138. virtual void emitUnsigned(uint64_t Value) = 0;
  139. virtual void emitData1(uint8_t Value) = 0;
  140. virtual void emitBaseTypeRef(uint64_t Idx) = 0;
  141. /// Emit a normalized unsigned constant.
  142. void emitConstu(uint64_t Value);
  143. /// Return whether the given machine register is the frame register in the
  144. /// current function.
  145. virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
  146. /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
  147. /// register location description.
  148. void addReg(int DwarfReg, const char *Comment = nullptr);
  149. /// Emit a DW_OP_breg operation.
  150. void addBReg(int DwarfReg, int Offset);
  151. /// Emit DW_OP_fbreg <Offset>.
  152. void addFBReg(int Offset);
  153. /// Emit a partial DWARF register operation.
  154. ///
  155. /// \param MachineReg The register number.
  156. /// \param MaxSize If the register must be composed from
  157. /// sub-registers this is an upper bound
  158. /// for how many bits the emitted DW_OP_piece
  159. /// may cover.
  160. ///
  161. /// If size and offset is zero an operation for the entire register is
  162. /// emitted: Some targets do not provide a DWARF register number for every
  163. /// register. If this is the case, this function will attempt to emit a DWARF
  164. /// register by emitting a fragment of a super-register or by piecing together
  165. /// multiple subregisters that alias the register.
  166. ///
  167. /// \return false if no DWARF register exists for MachineReg.
  168. bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
  169. unsigned MaxSize = ~1U);
  170. /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
  171. /// \param OffsetInBits This is an optional offset into the location that
  172. /// is at the top of the DWARF stack.
  173. void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
  174. /// Emit a shift-right dwarf operation.
  175. void addShr(unsigned ShiftBy);
  176. /// Emit a bitwise and dwarf operation.
  177. void addAnd(unsigned Mask);
  178. /// Emit a DW_OP_stack_value, if supported.
  179. ///
  180. /// The proper way to describe a constant value is DW_OP_constu <const>,
  181. /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available
  182. /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
  183. /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
  184. /// <const> actually describes a value at a constant address, not a constant
  185. /// value. However, in the past there was no better way to describe a
  186. /// constant value, so the producers and consumers started to rely on
  187. /// heuristics to disambiguate the value vs. location status of the
  188. /// expression. See PR21176 for more details.
  189. void addStackValue();
  190. ~DwarfExpression() = default;
  191. public:
  192. DwarfExpression(unsigned DwarfVersion, DwarfCompileUnit &CU)
  193. : CU(CU), SubRegisterSizeInBits(0), SubRegisterOffsetInBits(0),
  194. LocationKind(Unknown), LocationFlags(Unknown),
  195. DwarfVersion(DwarfVersion) {}
  196. /// This needs to be called last to commit any pending changes.
  197. void finalize();
  198. /// Emit a signed constant.
  199. void addSignedConstant(int64_t Value);
  200. /// Emit an unsigned constant.
  201. void addUnsignedConstant(uint64_t Value);
  202. /// Emit an unsigned constant.
  203. void addUnsignedConstant(const APInt &Value);
  204. /// Lock this down to become a memory location description.
  205. void setMemoryLocationKind() {
  206. assert(isUnknownLocation());
  207. LocationKind = Memory;
  208. }
  209. /// Lock this down to become an entry value location.
  210. void setEntryValueFlag() {
  211. LocationFlags |= EntryValue;
  212. }
  213. /// Lock this down to become a call site parameter location.
  214. void setCallSiteParamValueFlag() {
  215. LocationFlags |= CallSiteParamValue;
  216. }
  217. /// Emit a machine register location. As an optimization this may also consume
  218. /// the prefix of a DwarfExpression if a more efficient representation for
  219. /// combining the register location and the first operation exists.
  220. ///
  221. /// \param FragmentOffsetInBits If this is one fragment out of a
  222. /// fragmented
  223. /// location, this is the offset of the
  224. /// fragment inside the entire variable.
  225. /// \return false if no DWARF register exists
  226. /// for MachineReg.
  227. bool addMachineRegExpression(const TargetRegisterInfo &TRI,
  228. DIExpressionCursor &Expr, unsigned MachineReg,
  229. unsigned FragmentOffsetInBits = 0);
  230. /// Emit entry value dwarf operation.
  231. void addEntryValueExpression(DIExpressionCursor &ExprCursor);
  232. /// Emit all remaining operations in the DIExpressionCursor.
  233. ///
  234. /// \param FragmentOffsetInBits If this is one fragment out of multiple
  235. /// locations, this is the offset of the
  236. /// fragment inside the entire variable.
  237. void addExpression(DIExpressionCursor &&Expr,
  238. unsigned FragmentOffsetInBits = 0);
  239. /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
  240. /// the fragment described by \c Expr.
  241. void addFragmentOffset(const DIExpression *Expr);
  242. void emitLegacySExt(unsigned FromBits);
  243. void emitLegacyZExt(unsigned FromBits);
  244. };
  245. /// DwarfExpression implementation for .debug_loc entries.
  246. class DebugLocDwarfExpression final : public DwarfExpression {
  247. ByteStreamer &BS;
  248. void emitOp(uint8_t Op, const char *Comment = nullptr) override;
  249. void emitSigned(int64_t Value) override;
  250. void emitUnsigned(uint64_t Value) override;
  251. void emitData1(uint8_t Value) override;
  252. void emitBaseTypeRef(uint64_t Idx) override;
  253. bool isFrameRegister(const TargetRegisterInfo &TRI,
  254. unsigned MachineReg) override;
  255. public:
  256. DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS, DwarfCompileUnit &CU)
  257. : DwarfExpression(DwarfVersion, CU), BS(BS) {}
  258. };
  259. /// DwarfExpression implementation for singular DW_AT_location.
  260. class DIEDwarfExpression final : public DwarfExpression {
  261. const AsmPrinter &AP;
  262. DIELoc &DIE;
  263. void emitOp(uint8_t Op, const char *Comment = nullptr) override;
  264. void emitSigned(int64_t Value) override;
  265. void emitUnsigned(uint64_t Value) override;
  266. void emitData1(uint8_t Value) override;
  267. void emitBaseTypeRef(uint64_t Idx) override;
  268. bool isFrameRegister(const TargetRegisterInfo &TRI,
  269. unsigned MachineReg) override;
  270. public:
  271. DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE);
  272. DIELoc *finalize() {
  273. DwarfExpression::finalize();
  274. return &DIE;
  275. }
  276. };
  277. } // end namespace llvm
  278. #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H