• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
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 debug info into asm files.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "DwarfExpression.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallBitVector.h"
17 #include "llvm/BinaryFormat/Dwarf.h"
18 #include "llvm/CodeGen/TargetRegisterInfo.h"
19 #include "llvm/IR/DebugInfoMetadata.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include <algorithm>
22 #include <cassert>
23 #include <cstdint>
24 
25 using namespace llvm;
26 
addReg(int DwarfReg,const char * Comment)27 void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
28  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
29  assert((LocationKind == Unknown || LocationKind == Register) &&
30         "location description already locked down");
31  LocationKind = Register;
32  if (DwarfReg < 32) {
33    emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
34   } else {
35     emitOp(dwarf::DW_OP_regx, Comment);
36     emitUnsigned(DwarfReg);
37   }
38 }
39 
addBReg(int DwarfReg,int Offset)40 void DwarfExpression::addBReg(int DwarfReg, int Offset) {
41   assert(DwarfReg >= 0 && "invalid negative dwarf register number");
42   assert(LocationKind != Register && "location description already locked down");
43   if (DwarfReg < 32) {
44     emitOp(dwarf::DW_OP_breg0 + DwarfReg);
45   } else {
46     emitOp(dwarf::DW_OP_bregx);
47     emitUnsigned(DwarfReg);
48   }
49   emitSigned(Offset);
50 }
51 
addFBReg(int Offset)52 void DwarfExpression::addFBReg(int Offset) {
53   emitOp(dwarf::DW_OP_fbreg);
54   emitSigned(Offset);
55 }
56 
addOpPiece(unsigned SizeInBits,unsigned OffsetInBits)57 void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
58   if (!SizeInBits)
59     return;
60 
61   const unsigned SizeOfByte = 8;
62   if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
63     emitOp(dwarf::DW_OP_bit_piece);
64     emitUnsigned(SizeInBits);
65     emitUnsigned(OffsetInBits);
66   } else {
67     emitOp(dwarf::DW_OP_piece);
68     unsigned ByteSize = SizeInBits / SizeOfByte;
69     emitUnsigned(ByteSize);
70   }
71   this->OffsetInBits += SizeInBits;
72 }
73 
addShr(unsigned ShiftBy)74 void DwarfExpression::addShr(unsigned ShiftBy) {
75   emitOp(dwarf::DW_OP_constu);
76   emitUnsigned(ShiftBy);
77   emitOp(dwarf::DW_OP_shr);
78 }
79 
addAnd(unsigned Mask)80 void DwarfExpression::addAnd(unsigned Mask) {
81   emitOp(dwarf::DW_OP_constu);
82   emitUnsigned(Mask);
83   emitOp(dwarf::DW_OP_and);
84 }
85 
addMachineReg(const TargetRegisterInfo & TRI,unsigned MachineReg,unsigned MaxSize)86 bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
87                                     unsigned MachineReg, unsigned MaxSize) {
88   if (!TRI.isPhysicalRegister(MachineReg)) {
89     if (isFrameRegister(TRI, MachineReg)) {
90       DwarfRegs.push_back({-1, 0, nullptr});
91       return true;
92     }
93     return false;
94   }
95 
96   int Reg = TRI.getDwarfRegNum(MachineReg, false);
97 
98   // If this is a valid register number, emit it.
99   if (Reg >= 0) {
100     DwarfRegs.push_back({Reg, 0, nullptr});
101     return true;
102   }
103 
104   // Walk up the super-register chain until we find a valid number.
105   // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
106   for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
107     Reg = TRI.getDwarfRegNum(*SR, false);
108     if (Reg >= 0) {
109       unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
110       unsigned Size = TRI.getSubRegIdxSize(Idx);
111       unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
112       DwarfRegs.push_back({Reg, 0, "super-register"});
113       // Use a DW_OP_bit_piece to describe the sub-register.
114       setSubRegisterPiece(Size, RegOffset);
115       return true;
116     }
117   }
118 
119   // Otherwise, attempt to find a covering set of sub-register numbers.
120   // For example, Q0 on ARM is a composition of D0+D1.
121   unsigned CurPos = 0;
122   // The size of the register in bits.
123   const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
124   unsigned RegSize = TRI.getRegSizeInBits(*RC);
125   // Keep track of the bits in the register we already emitted, so we
126   // can avoid emitting redundant aliasing subregs. Because this is
127   // just doing a greedy scan of all subregisters, it is possible that
128   // this doesn't find a combination of subregisters that fully cover
129   // the register (even though one may exist).
130   SmallBitVector Coverage(RegSize, false);
131   for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
132     unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
133     unsigned Size = TRI.getSubRegIdxSize(Idx);
134     unsigned Offset = TRI.getSubRegIdxOffset(Idx);
135     Reg = TRI.getDwarfRegNum(*SR, false);
136     if (Reg < 0)
137       continue;
138 
139     // Intersection between the bits we already emitted and the bits
140     // covered by this subregister.
141     SmallBitVector CurSubReg(RegSize, false);
142     CurSubReg.set(Offset, Offset + Size);
143 
144     // If this sub-register has a DWARF number and we haven't covered
145     // its range, emit a DWARF piece for it.
146     if (CurSubReg.test(Coverage)) {
147       // Emit a piece for any gap in the coverage.
148       if (Offset > CurPos)
149         DwarfRegs.push_back({-1, Offset - CurPos, "no DWARF register encoding"});
150       DwarfRegs.push_back(
151           {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
152       if (Offset >= MaxSize)
153         break;
154 
155       // Mark it as emitted.
156       Coverage.set(Offset, Offset + Size);
157       CurPos = Offset + Size;
158     }
159   }
160   // Failed to find any DWARF encoding.
161   if (CurPos == 0)
162     return false;
163   // Found a partial or complete DWARF encoding.
164   if (CurPos < RegSize)
165     DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"});
166   return true;
167 }
168 
addStackValue()169 void DwarfExpression::addStackValue() {
170   if (DwarfVersion >= 4)
171     emitOp(dwarf::DW_OP_stack_value);
172 }
173 
addSignedConstant(int64_t Value)174 void DwarfExpression::addSignedConstant(int64_t Value) {
175   assert(LocationKind == Implicit || LocationKind == Unknown);
176   LocationKind = Implicit;
177   emitOp(dwarf::DW_OP_consts);
178   emitSigned(Value);
179 }
180 
addUnsignedConstant(uint64_t Value)181 void DwarfExpression::addUnsignedConstant(uint64_t Value) {
182   assert(LocationKind == Implicit || LocationKind == Unknown);
183   LocationKind = Implicit;
184   emitOp(dwarf::DW_OP_constu);
185   emitUnsigned(Value);
186 }
187 
addUnsignedConstant(const APInt & Value)188 void DwarfExpression::addUnsignedConstant(const APInt &Value) {
189   assert(LocationKind == Implicit || LocationKind == Unknown);
190   LocationKind = Implicit;
191 
192   unsigned Size = Value.getBitWidth();
193   const uint64_t *Data = Value.getRawData();
194 
195   // Chop it up into 64-bit pieces, because that's the maximum that
196   // addUnsignedConstant takes.
197   unsigned Offset = 0;
198   while (Offset < Size) {
199     addUnsignedConstant(*Data++);
200     if (Offset == 0 && Size <= 64)
201       break;
202     addStackValue();
203     addOpPiece(std::min(Size - Offset, 64u), Offset);
204     Offset += 64;
205   }
206 }
207 
addMachineRegExpression(const TargetRegisterInfo & TRI,DIExpressionCursor & ExprCursor,unsigned MachineReg,unsigned FragmentOffsetInBits)208 bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
209                                               DIExpressionCursor &ExprCursor,
210                                               unsigned MachineReg,
211                                               unsigned FragmentOffsetInBits) {
212   auto Fragment = ExprCursor.getFragmentInfo();
213   if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
214     LocationKind = Unknown;
215     return false;
216   }
217 
218   bool HasComplexExpression = false;
219   auto Op = ExprCursor.peek();
220   if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
221     HasComplexExpression = true;
222 
223   // If the register can only be described by a complex expression (i.e.,
224   // multiple subregisters) it doesn't safely compose with another complex
225   // expression. For example, it is not possible to apply a DW_OP_deref
226   // operation to multiple DW_OP_pieces.
227   if (HasComplexExpression && DwarfRegs.size() > 1) {
228     DwarfRegs.clear();
229     LocationKind = Unknown;
230     return false;
231   }
232 
233   // Handle simple register locations.
234   if (LocationKind != Memory && !HasComplexExpression) {
235     for (auto &Reg : DwarfRegs) {
236       if (Reg.DwarfRegNo >= 0)
237         addReg(Reg.DwarfRegNo, Reg.Comment);
238       addOpPiece(Reg.Size);
239     }
240     DwarfRegs.clear();
241     return true;
242   }
243 
244   // Don't emit locations that cannot be expressed without DW_OP_stack_value.
245   if (DwarfVersion < 4)
246     if (std::any_of(ExprCursor.begin(), ExprCursor.end(),
247                     [](DIExpression::ExprOperand Op) -> bool {
248                       return Op.getOp() == dwarf::DW_OP_stack_value;
249                     })) {
250       DwarfRegs.clear();
251       LocationKind = Unknown;
252       return false;
253     }
254 
255   assert(DwarfRegs.size() == 1);
256   auto Reg = DwarfRegs[0];
257   bool FBReg = isFrameRegister(TRI, MachineReg);
258   int SignedOffset = 0;
259   assert(Reg.Size == 0 && "subregister has same size as superregister");
260 
261   // Pattern-match combinations for which more efficient representations exist.
262   // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
263   if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
264     SignedOffset = Op->getArg(0);
265     ExprCursor.take();
266   }
267 
268   // [Reg, DW_OP_constu, Offset, DW_OP_plus]  --> [DW_OP_breg, Offset]
269   // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
270   // If Reg is a subregister we need to mask it out before subtracting.
271   if (Op && Op->getOp() == dwarf::DW_OP_constu) {
272     auto N = ExprCursor.peekNext();
273     if (N && (N->getOp() == dwarf::DW_OP_plus ||
274              (N->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
275       int Offset = Op->getArg(0);
276       SignedOffset = (N->getOp() == dwarf::DW_OP_minus) ? -Offset : Offset;
277       ExprCursor.consume(2);
278     }
279   }
280 
281   if (FBReg)
282     addFBReg(SignedOffset);
283   else
284     addBReg(Reg.DwarfRegNo, SignedOffset);
285   DwarfRegs.clear();
286   return true;
287 }
288 
289 /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
isMemoryLocation(DIExpressionCursor ExprCursor)290 static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
291   while (ExprCursor) {
292     auto Op = ExprCursor.take();
293     switch (Op->getOp()) {
294     case dwarf::DW_OP_deref:
295     case dwarf::DW_OP_LLVM_fragment:
296       break;
297     default:
298       return false;
299     }
300   }
301   return true;
302 }
303 
addExpression(DIExpressionCursor && ExprCursor,unsigned FragmentOffsetInBits)304 void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
305                                     unsigned FragmentOffsetInBits) {
306   // If we need to mask out a subregister, do it now, unless the next
307   // operation would emit an OpPiece anyway.
308   auto N = ExprCursor.peek();
309   if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
310     maskSubRegister();
311 
312   while (ExprCursor) {
313     auto Op = ExprCursor.take();
314     switch (Op->getOp()) {
315     case dwarf::DW_OP_LLVM_fragment: {
316       unsigned SizeInBits = Op->getArg(1);
317       unsigned FragmentOffset = Op->getArg(0);
318       // The fragment offset must have already been adjusted by emitting an
319       // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
320       // location.
321       assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
322 
323       // If addMachineReg already emitted DW_OP_piece operations to represent
324       // a super-register by splicing together sub-registers, subtract the size
325       // of the pieces that was already emitted.
326       SizeInBits -= OffsetInBits - FragmentOffset;
327 
328       // If addMachineReg requested a DW_OP_bit_piece to stencil out a
329       // sub-register that is smaller than the current fragment's size, use it.
330       if (SubRegisterSizeInBits)
331         SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
332 
333       // Emit a DW_OP_stack_value for implicit location descriptions.
334       if (LocationKind == Implicit)
335         addStackValue();
336 
337       // Emit the DW_OP_piece.
338       addOpPiece(SizeInBits, SubRegisterOffsetInBits);
339       setSubRegisterPiece(0, 0);
340       // Reset the location description kind.
341       LocationKind = Unknown;
342       return;
343     }
344     case dwarf::DW_OP_plus_uconst:
345       assert(LocationKind != Register);
346       emitOp(dwarf::DW_OP_plus_uconst);
347       emitUnsigned(Op->getArg(0));
348       break;
349     case dwarf::DW_OP_plus:
350     case dwarf::DW_OP_minus:
351     case dwarf::DW_OP_mul:
352     case dwarf::DW_OP_div:
353     case dwarf::DW_OP_mod:
354     case dwarf::DW_OP_or:
355     case dwarf::DW_OP_and:
356     case dwarf::DW_OP_xor:
357     case dwarf::DW_OP_shl:
358     case dwarf::DW_OP_shr:
359     case dwarf::DW_OP_shra:
360     case dwarf::DW_OP_lit0:
361     case dwarf::DW_OP_not:
362     case dwarf::DW_OP_dup:
363       emitOp(Op->getOp());
364       break;
365     case dwarf::DW_OP_deref:
366       assert(LocationKind != Register);
367       if (LocationKind != Memory && ::isMemoryLocation(ExprCursor))
368         // Turning this into a memory location description makes the deref
369         // implicit.
370         LocationKind = Memory;
371       else
372         emitOp(dwarf::DW_OP_deref);
373       break;
374     case dwarf::DW_OP_constu:
375       assert(LocationKind != Register);
376       emitOp(dwarf::DW_OP_constu);
377       emitUnsigned(Op->getArg(0));
378       break;
379     case dwarf::DW_OP_stack_value:
380       LocationKind = Implicit;
381       break;
382     case dwarf::DW_OP_swap:
383       assert(LocationKind != Register);
384       emitOp(dwarf::DW_OP_swap);
385       break;
386     case dwarf::DW_OP_xderef:
387       assert(LocationKind != Register);
388       emitOp(dwarf::DW_OP_xderef);
389       break;
390     default:
391       llvm_unreachable("unhandled opcode found in expression");
392     }
393   }
394 
395   if (LocationKind == Implicit)
396     // Turn this into an implicit location description.
397     addStackValue();
398 }
399 
400 /// add masking operations to stencil out a subregister.
maskSubRegister()401 void DwarfExpression::maskSubRegister() {
402   assert(SubRegisterSizeInBits && "no subregister was registered");
403   if (SubRegisterOffsetInBits > 0)
404     addShr(SubRegisterOffsetInBits);
405   uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
406   addAnd(Mask);
407 }
408 
finalize()409 void DwarfExpression::finalize() {
410   assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
411   // Emit any outstanding DW_OP_piece operations to mask out subregisters.
412   if (SubRegisterSizeInBits == 0)
413     return;
414   // Don't emit a DW_OP_piece for a subregister at offset 0.
415   if (SubRegisterOffsetInBits == 0)
416     return;
417   addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
418 }
419 
addFragmentOffset(const DIExpression * Expr)420 void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
421   if (!Expr || !Expr->isFragment())
422     return;
423 
424   uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
425   assert(FragmentOffset >= OffsetInBits &&
426          "overlapping or duplicate fragments");
427   if (FragmentOffset > OffsetInBits)
428     addOpPiece(FragmentOffset - OffsetInBits);
429   OffsetInBits = FragmentOffset;
430 }
431