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" 16 #include "llvm/ADT/SmallBitVector.h" 17 #include "llvm/CodeGen/AsmPrinter.h" 18 #include "llvm/Support/Dwarf.h" 19 #include "llvm/Target/TargetMachine.h" 20 #include "llvm/Target/TargetRegisterInfo.h" 21 #include "llvm/Target/TargetSubtargetInfo.h" 22 23 using namespace llvm; 24 25 const TargetRegisterInfo *DwarfExpression::getTRI() const { 26 return AP.TM.getSubtargetImpl()->getRegisterInfo(); 27 } 28 29 unsigned DwarfExpression::getDwarfVersion() const { 30 return AP.getDwarfDebug()->getDwarfVersion(); 31 } 32 33 void DwarfExpression::AddReg(int DwarfReg, const char *Comment) { 34 assert(DwarfReg >= 0 && "invalid negative dwarf register number"); 35 if (DwarfReg < 32) { 36 EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment); 37 } else { 38 EmitOp(dwarf::DW_OP_regx, Comment); 39 EmitUnsigned(DwarfReg); 40 } 41 } 42 43 void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) { 44 assert(DwarfReg >= 0 && "invalid negative dwarf register number"); 45 if (DwarfReg < 32) { 46 EmitOp(dwarf::DW_OP_breg0 + DwarfReg); 47 } else { 48 EmitOp(dwarf::DW_OP_bregx); 49 EmitUnsigned(DwarfReg); 50 } 51 EmitSigned(Offset); 52 if (Deref) 53 EmitOp(dwarf::DW_OP_deref); 54 } 55 56 void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) { 57 assert(SizeInBits > 0 && "piece has size zero"); 58 const unsigned SizeOfByte = 8; 59 if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { 60 EmitOp(dwarf::DW_OP_bit_piece); 61 EmitUnsigned(SizeInBits); 62 EmitUnsigned(OffsetInBits); 63 } else { 64 EmitOp(dwarf::DW_OP_piece); 65 unsigned ByteSize = SizeInBits / SizeOfByte; 66 EmitUnsigned(ByteSize); 67 } 68 } 69 70 void DwarfExpression::AddShr(unsigned ShiftBy) { 71 EmitOp(dwarf::DW_OP_constu); 72 EmitUnsigned(ShiftBy); 73 EmitOp(dwarf::DW_OP_shr); 74 } 75 76 bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) { 77 int DwarfReg = getTRI()->getDwarfRegNum(MachineReg, false); 78 if (DwarfReg < 0) 79 return false; 80 81 if (isFrameRegister(MachineReg)) { 82 // If variable offset is based in frame register then use fbreg. 83 EmitOp(dwarf::DW_OP_fbreg); 84 EmitSigned(Offset); 85 } else { 86 AddRegIndirect(DwarfReg, Offset); 87 } 88 return true; 89 } 90 91 bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg, 92 unsigned PieceSizeInBits, 93 unsigned PieceOffsetInBits) { 94 const TargetRegisterInfo *TRI = getTRI(); 95 int Reg = TRI->getDwarfRegNum(MachineReg, false); 96 97 // If this is a valid register number, emit it. 98 if (Reg >= 0) { 99 AddReg(Reg); 100 if (PieceSizeInBits) 101 AddOpPiece(PieceSizeInBits, PieceOffsetInBits); 102 return true; 103 } 104 105 // Walk up the super-register chain until we find a valid number. 106 // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0. 107 for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { 108 Reg = TRI->getDwarfRegNum(*SR, false); 109 if (Reg >= 0) { 110 unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg); 111 unsigned Size = TRI->getSubRegIdxSize(Idx); 112 unsigned RegOffset = TRI->getSubRegIdxOffset(Idx); 113 AddReg(Reg, "super-register"); 114 if (PieceOffsetInBits == RegOffset) { 115 AddOpPiece(Size, RegOffset); 116 } else { 117 // If this is part of a variable in a sub-register at a 118 // non-zero offset, we need to manually shift the value into 119 // place, since the DW_OP_piece describes the part of the 120 // variable, not the position of the subregister. 121 if (RegOffset) 122 AddShr(RegOffset); 123 AddOpPiece(Size, PieceOffsetInBits); 124 } 125 return true; 126 } 127 } 128 129 // Otherwise, attempt to find a covering set of sub-register numbers. 130 // For example, Q0 on ARM is a composition of D0+D1. 131 // 132 // Keep track of the current position so we can emit the more 133 // efficient DW_OP_piece. 134 unsigned CurPos = PieceOffsetInBits; 135 // The size of the register in bits, assuming 8 bits per byte. 136 unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8; 137 // Keep track of the bits in the register we already emitted, so we 138 // can avoid emitting redundant aliasing subregs. 139 SmallBitVector Coverage(RegSize, false); 140 for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { 141 unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR); 142 unsigned Size = TRI->getSubRegIdxSize(Idx); 143 unsigned Offset = TRI->getSubRegIdxOffset(Idx); 144 Reg = TRI->getDwarfRegNum(*SR, false); 145 146 // Intersection between the bits we already emitted and the bits 147 // covered by this subregister. 148 SmallBitVector Intersection(RegSize, false); 149 Intersection.set(Offset, Offset + Size); 150 Intersection ^= Coverage; 151 152 // If this sub-register has a DWARF number and we haven't covered 153 // its range, emit a DWARF piece for it. 154 if (Reg >= 0 && Intersection.any()) { 155 AddReg(Reg, "sub-register"); 156 AddOpPiece(Size, Offset == CurPos ? 0 : Offset); 157 CurPos = Offset + Size; 158 159 // Mark it as emitted. 160 Coverage.set(Offset, Offset + Size); 161 } 162 } 163 164 return CurPos > PieceOffsetInBits; 165 } 166 167 void DwarfExpression::AddSignedConstant(int Value) { 168 EmitOp(dwarf::DW_OP_consts); 169 EmitSigned(Value); 170 // The proper way to describe a constant value is 171 // DW_OP_constu <const>, DW_OP_stack_value. 172 // Unfortunately, DW_OP_stack_value was not available until DWARF-4, 173 // so we will continue to generate DW_OP_constu <const> for DWARF-2 174 // and DWARF-3. Technically, this is incorrect since DW_OP_const <const> 175 // actually describes a value at a constant addess, not a constant value. 176 // However, in the past there was no better way to describe a constant 177 // value, so the producers and consumers started to rely on heuristics 178 // to disambiguate the value vs. location status of the expression. 179 // See PR21176 for more details. 180 if (getDwarfVersion() >= 4) 181 EmitOp(dwarf::DW_OP_stack_value); 182 } 183 184 void DwarfExpression::AddUnsignedConstant(unsigned Value) { 185 EmitOp(dwarf::DW_OP_constu); 186 EmitUnsigned(Value); 187 // cf. comment in DwarfExpression::AddSignedConstant(). 188 if (getDwarfVersion() >= 4) 189 EmitOp(dwarf::DW_OP_stack_value); 190 } 191 192 static unsigned getOffsetOrZero(unsigned OffsetInBits, 193 unsigned PieceOffsetInBits) { 194 if (OffsetInBits == PieceOffsetInBits) 195 return 0; 196 assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces"); 197 return OffsetInBits; 198 } 199 200 bool DwarfExpression::AddMachineRegExpression(DIExpression Expr, 201 unsigned MachineReg, 202 unsigned PieceOffsetInBits) { 203 unsigned N = Expr.getNumElements(); 204 unsigned I = 0; 205 bool ValidReg = false; 206 // Pattern-match combinations for which more efficient representations exist 207 // first. 208 if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_piece) { 209 unsigned SizeOfByte = 8; 210 unsigned OffsetInBits = Expr.getElement(1) * SizeOfByte; 211 unsigned SizeInBits = Expr.getElement(2) * SizeOfByte; 212 ValidReg = 213 AddMachineRegPiece(MachineReg, SizeInBits, 214 getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 215 I = 3; 216 } else if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_plus && 217 Expr.getElement(2) == dwarf::DW_OP_deref) { 218 // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. 219 unsigned Offset = Expr.getElement(1); 220 ValidReg = AddMachineRegIndirect(MachineReg, Offset); 221 I = 3; 222 } else if (N >= 1 && Expr.getElement(0) == dwarf::DW_OP_deref) { 223 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 224 ValidReg = AddMachineRegIndirect(MachineReg); 225 I = 1; 226 } else 227 ValidReg = AddMachineRegPiece(MachineReg); 228 229 if (!ValidReg) 230 return false; 231 232 // Emit remaining elements of the expression. 233 AddExpression(Expr, I); 234 return true; 235 } 236 237 void DwarfExpression::AddExpression(DIExpression Expr, unsigned I, 238 unsigned PieceOffsetInBits) { 239 unsigned N = Expr.getNumElements(); 240 for (; I < N; ++I) { 241 switch (Expr.getElement(I)) { 242 case dwarf::DW_OP_piece: { 243 unsigned SizeOfByte = 8; 244 unsigned OffsetInBits = Expr.getElement(++I) * SizeOfByte; 245 unsigned SizeInBits = Expr.getElement(++I) * SizeOfByte; 246 AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 247 break; 248 } 249 case dwarf::DW_OP_plus: 250 EmitOp(dwarf::DW_OP_plus_uconst); 251 EmitUnsigned(Expr.getElement(++I)); 252 break; 253 case dwarf::DW_OP_deref: 254 EmitOp(dwarf::DW_OP_deref); 255 break; 256 default: 257 llvm_unreachable("unhandled opcode found in DIExpression"); 258 } 259 } 260 } 261