LLVM  4.0.0
DwarfExpression.cpp
Go to the documentation of this file.
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 "DwarfDebug.h"
18 #include "llvm/Support/Dwarf.h"
22 
23 using namespace llvm;
24 
25 void DwarfExpression::AddReg(int DwarfReg, const char *Comment) {
26  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
27  if (DwarfReg < 32) {
28  EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
29  } else {
30  EmitOp(dwarf::DW_OP_regx, Comment);
31  EmitUnsigned(DwarfReg);
32  }
33 }
34 
35 void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) {
36  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
37  if (DwarfReg < 32) {
38  EmitOp(dwarf::DW_OP_breg0 + DwarfReg);
39  } else {
40  EmitOp(dwarf::DW_OP_bregx);
41  EmitUnsigned(DwarfReg);
42  }
43  EmitSigned(Offset);
44  if (Deref)
45  EmitOp(dwarf::DW_OP_deref);
46 }
47 
48 void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
49  if (!SizeInBits)
50  return;
51 
52  const unsigned SizeOfByte = 8;
53  if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
54  EmitOp(dwarf::DW_OP_bit_piece);
55  EmitUnsigned(SizeInBits);
56  EmitUnsigned(OffsetInBits);
57  } else {
58  EmitOp(dwarf::DW_OP_piece);
59  unsigned ByteSize = SizeInBits / SizeOfByte;
60  EmitUnsigned(ByteSize);
61  }
62  this->OffsetInBits += SizeInBits;
63 }
64 
65 void DwarfExpression::AddShr(unsigned ShiftBy) {
66  EmitOp(dwarf::DW_OP_constu);
67  EmitUnsigned(ShiftBy);
68  EmitOp(dwarf::DW_OP_shr);
69 }
70 
72  unsigned MachineReg, int Offset) {
73  if (isFrameRegister(TRI, MachineReg)) {
74  // If variable offset is based in frame register then use fbreg.
75  EmitOp(dwarf::DW_OP_fbreg);
76  EmitSigned(Offset);
77  return true;
78  }
79 
80  int DwarfReg = TRI.getDwarfRegNum(MachineReg, false);
81  if (DwarfReg < 0)
82  return false;
83 
84  AddRegIndirect(DwarfReg, Offset);
85  return true;
86 }
87 
89  unsigned MachineReg, unsigned MaxSize) {
90  if (!TRI.isPhysicalRegister(MachineReg))
91  return false;
92 
93  int Reg = TRI.getDwarfRegNum(MachineReg, false);
94 
95  // If this is a valid register number, emit it.
96  if (Reg >= 0) {
97  AddReg(Reg);
98  return true;
99  }
100 
101  // Walk up the super-register chain until we find a valid number.
102  // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
103  for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
104  Reg = TRI.getDwarfRegNum(*SR, false);
105  if (Reg >= 0) {
106  unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
107  unsigned Size = TRI.getSubRegIdxSize(Idx);
108  unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
109  AddReg(Reg, "super-register");
110  // Use a DW_OP_bit_piece to describe the sub-register.
111  setSubRegisterPiece(Size, RegOffset);
112  return true;
113  }
114  }
115 
116  // Otherwise, attempt to find a covering set of sub-register numbers.
117  // For example, Q0 on ARM is a composition of D0+D1.
118  unsigned CurPos = 0;
119  // The size of the register in bits, assuming 8 bits per byte.
120  unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8;
121  // Keep track of the bits in the register we already emitted, so we
122  // can avoid emitting redundant aliasing subregs.
123  SmallBitVector Coverage(RegSize, false);
124  for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
125  unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
126  unsigned Size = TRI.getSubRegIdxSize(Idx);
127  unsigned Offset = TRI.getSubRegIdxOffset(Idx);
128  Reg = TRI.getDwarfRegNum(*SR, false);
129 
130  // Intersection between the bits we already emitted and the bits
131  // covered by this subregister.
132  SmallBitVector Intersection(RegSize, false);
133  Intersection.set(Offset, Offset + Size);
134  Intersection ^= Coverage;
135 
136  // If this sub-register has a DWARF number and we haven't covered
137  // its range, emit a DWARF piece for it.
138  if (Reg >= 0 && Intersection.any()) {
139  AddReg(Reg, "sub-register");
140  if (Offset >= MaxSize)
141  break;
142  // Emit a piece for the any gap in the coverage.
143  if (Offset > CurPos)
144  AddOpPiece(Offset - CurPos);
145  AddOpPiece(std::min<unsigned>(Size, MaxSize - Offset));
146  CurPos = Offset + Size;
147 
148  // Mark it as emitted.
149  Coverage.set(Offset, Offset + Size);
150  }
151  }
152 
153  return CurPos;
154 }
155 
157  if (DwarfVersion >= 4)
158  EmitOp(dwarf::DW_OP_stack_value);
159 }
160 
162  EmitOp(dwarf::DW_OP_consts);
163  EmitSigned(Value);
164  AddStackValue();
165 }
166 
168  EmitOp(dwarf::DW_OP_constu);
169  EmitUnsigned(Value);
170  AddStackValue();
171 }
172 
174  unsigned Size = Value.getBitWidth();
175  const uint64_t *Data = Value.getRawData();
176 
177  // Chop it up into 64-bit pieces, because that's the maximum that
178  // AddUnsignedConstant takes.
179  unsigned Offset = 0;
180  while (Offset < Size) {
181  AddUnsignedConstant(*Data++);
182  if (Offset == 0 && Size <= 64)
183  break;
184  AddOpPiece(std::min(Size-Offset, 64u), Offset);
185  Offset += 64;
186  }
187 }
188 
190  DIExpressionCursor &ExprCursor,
191  unsigned MachineReg,
192  unsigned FragmentOffsetInBits) {
193  if (!ExprCursor)
194  return AddMachineReg(TRI, MachineReg);
195 
196  // Pattern-match combinations for which more efficient representations exist
197  // first.
198  bool ValidReg = false;
199  auto Op = ExprCursor.peek();
200  switch (Op->getOp()) {
201  default: {
202  auto Fragment = ExprCursor.getFragmentInfo();
203  ValidReg = AddMachineReg(TRI, MachineReg,
204  Fragment ? Fragment->SizeInBits : ~1U);
205  break;
206  }
207  case dwarf::DW_OP_plus:
208  case dwarf::DW_OP_minus: {
209  // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset].
210  // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset].
211  auto N = ExprCursor.peekNext();
212  if (N && N->getOp() == dwarf::DW_OP_deref) {
213  unsigned Offset = Op->getArg(0);
214  ValidReg = AddMachineRegIndirect(
215  TRI, MachineReg, Op->getOp() == dwarf::DW_OP_plus ? Offset : -Offset);
216  ExprCursor.consume(2);
217  } else
218  ValidReg = AddMachineReg(TRI, MachineReg);
219  break;
220  }
221  case dwarf::DW_OP_deref:
222  // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
223  ValidReg = AddMachineRegIndirect(TRI, MachineReg);
224  ExprCursor.take();
225  break;
226  }
227 
228  return ValidReg;
229 }
230 
232  unsigned FragmentOffsetInBits) {
233  while (ExprCursor) {
234  auto Op = ExprCursor.take();
235  switch (Op->getOp()) {
237  unsigned SizeInBits = Op->getArg(1);
238  unsigned FragmentOffset = Op->getArg(0);
239  // The fragment offset must have already been adjusted by emitting an
240  // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
241  // location.
242  assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
243 
244  // If \a AddMachineReg already emitted DW_OP_piece operations to represent
245  // a super-register by splicing together sub-registers, subtract the size
246  // of the pieces that was already emitted.
247  SizeInBits -= OffsetInBits - FragmentOffset;
248 
249  // If \a AddMachineReg requested a DW_OP_bit_piece to stencil out a
250  // sub-register that is smaller than the current fragment's size, use it.
252  SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
253 
254  AddOpPiece(SizeInBits, SubRegisterOffsetInBits);
255  setSubRegisterPiece(0, 0);
256  break;
257  }
258  case dwarf::DW_OP_plus:
259  EmitOp(dwarf::DW_OP_plus_uconst);
260  EmitUnsigned(Op->getArg(0));
261  break;
262  case dwarf::DW_OP_minus:
263  // There is no OP_minus_uconst.
264  EmitOp(dwarf::DW_OP_constu);
265  EmitUnsigned(Op->getArg(0));
266  EmitOp(dwarf::DW_OP_minus);
267  break;
268  case dwarf::DW_OP_deref:
269  EmitOp(dwarf::DW_OP_deref);
270  break;
271  case dwarf::DW_OP_constu:
272  EmitOp(dwarf::DW_OP_constu);
273  EmitUnsigned(Op->getArg(0));
274  break;
275  case dwarf::DW_OP_stack_value:
276  AddStackValue();
277  break;
278  default:
279  llvm_unreachable("unhandled opcode found in expression");
280  }
281  }
282 }
283 
287 }
288 
290  if (!Expr || !Expr->isFragment())
291  return;
292 
293  uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
294  assert(FragmentOffset >= OffsetInBits &&
295  "overlapping or duplicate fragments");
296  if (FragmentOffset > OffsetInBits)
297  AddOpPiece(FragmentOffset - OffsetInBits);
298  OffsetInBits = FragmentOffset;
299 }
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Optional< DIExpression::ExprOperand > peek() const
Return the current operation.
void AddExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg, int Offset=0)
Emit an indirect dwarf register operation for the given machine register.
void AddShr(unsigned ShiftBy)
Emit a shift-right dwarf expression.
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
virtual void EmitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
MCSuperRegIterator enumerates all super-registers of Reg.
Reg
All possible values of the reg field in the ModR/M byte.
Only used in LLVM metadata.
Definition: Dwarf.h:112
Holds a DIExpression and keeps track of how many operands have been consumed so far.
void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits)
Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed to represent a subregister...
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
bool isFragment() const
Return whether this is a piece of an aggregate variable.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Optional< DIExpression::ExprOperand > take()
Consume one operation.
Optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
Optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
uint64_t OffsetInBits
Current Fragment Offset in Bits.
uint32_t Offset
void AddRegIndirect(int DwarfReg, int Offset, bool Deref=false)
Emit an (double-)indirect dwarf register operation.
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1255
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
virtual void EmitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
SmallBitVector & set()
unsigned SubRegisterOffsetInBits
void AddUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
DWARF expression.
Class for arbitrary precision integers.
Definition: APInt.h:77
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void consume(unsigned N)
Consume N operations.
void AddSignedConstant(int64_t Value)
Emit a signed constant.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
Definition: APInt.h:578
void finalize()
This needs to be called last to commit any pending changes.
#define N
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool AddMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
LLVM Value Representation.
Definition: Value.h:71
bool any() const
Returns true if any bit is set.
virtual void EmitSigned(int64_t Value)=0
Emit a raw signed value.
void AddStackValue()
Emit a DW_OP_stack_value, if supported.
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.
void AddReg(int DwarfReg, const char *Comment=nullptr)
Emit a dwarf register operation.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg)=0
Return whether the given machine register is the frame register in the current function.