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