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 if (!TRI->isPhysicalRegister(MachineReg)) 96 return false; 97 98 int Reg = TRI->getDwarfRegNum(MachineReg, false); 99 100 // If this is a valid register number, emit it. 101 if (Reg >= 0) { 102 AddReg(Reg); 103 if (PieceSizeInBits) 104 AddOpPiece(PieceSizeInBits, PieceOffsetInBits); 105 return true; 106 } 107 108 // Walk up the super-register chain until we find a valid number. 109 // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0. 110 for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { 111 Reg = TRI->getDwarfRegNum(*SR, false); 112 if (Reg >= 0) { 113 unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg); 114 unsigned Size = TRI->getSubRegIdxSize(Idx); 115 unsigned RegOffset = TRI->getSubRegIdxOffset(Idx); 116 AddReg(Reg, "super-register"); 117 if (PieceOffsetInBits == RegOffset) { 118 AddOpPiece(Size, RegOffset); 119 } else { 120 // If this is part of a variable in a sub-register at a 121 // non-zero offset, we need to manually shift the value into 122 // place, since the DW_OP_piece describes the part of the 123 // variable, not the position of the subregister. 124 if (RegOffset) 125 AddShr(RegOffset); 126 AddOpPiece(Size, PieceOffsetInBits); 127 } 128 return true; 129 } 130 } 131 132 // Otherwise, attempt to find a covering set of sub-register numbers. 133 // For example, Q0 on ARM is a composition of D0+D1. 134 // 135 // Keep track of the current position so we can emit the more 136 // efficient DW_OP_piece. 137 unsigned CurPos = PieceOffsetInBits; 138 // The size of the register in bits, assuming 8 bits per byte. 139 unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8; 140 // Keep track of the bits in the register we already emitted, so we 141 // can avoid emitting redundant aliasing subregs. 142 SmallBitVector Coverage(RegSize, false); 143 for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) { 144 unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR); 145 unsigned Size = TRI->getSubRegIdxSize(Idx); 146 unsigned Offset = TRI->getSubRegIdxOffset(Idx); 147 Reg = TRI->getDwarfRegNum(*SR, false); 148 149 // Intersection between the bits we already emitted and the bits 150 // covered by this subregister. 151 SmallBitVector Intersection(RegSize, false); 152 Intersection.set(Offset, Offset + Size); 153 Intersection ^= Coverage; 154 155 // If this sub-register has a DWARF number and we haven't covered 156 // its range, emit a DWARF piece for it. 157 if (Reg >= 0 && Intersection.any()) { 158 AddReg(Reg, "sub-register"); 159 AddOpPiece(Size, Offset == CurPos ? 0 : Offset); 160 CurPos = Offset + Size; 161 162 // Mark it as emitted. 163 Coverage.set(Offset, Offset + Size); 164 } 165 } 166 167 return CurPos > PieceOffsetInBits; 168 } 169 170 void DwarfExpression::AddSignedConstant(int Value) { 171 EmitOp(dwarf::DW_OP_consts); 172 EmitSigned(Value); 173 // The proper way to describe a constant value is 174 // DW_OP_constu <const>, DW_OP_stack_value. 175 // Unfortunately, DW_OP_stack_value was not available until DWARF-4, 176 // so we will continue to generate DW_OP_constu <const> for DWARF-2 177 // and DWARF-3. Technically, this is incorrect since DW_OP_const <const> 178 // actually describes a value at a constant addess, not a constant value. 179 // However, in the past there was no better way to describe a constant 180 // value, so the producers and consumers started to rely on heuristics 181 // to disambiguate the value vs. location status of the expression. 182 // See PR21176 for more details. 183 if (getDwarfVersion() >= 4) 184 EmitOp(dwarf::DW_OP_stack_value); 185 } 186 187 void DwarfExpression::AddUnsignedConstant(unsigned Value) { 188 EmitOp(dwarf::DW_OP_constu); 189 EmitUnsigned(Value); 190 // cf. comment in DwarfExpression::AddSignedConstant(). 191 if (getDwarfVersion() >= 4) 192 EmitOp(dwarf::DW_OP_stack_value); 193 } 194 195 static unsigned getOffsetOrZero(unsigned OffsetInBits, 196 unsigned PieceOffsetInBits) { 197 if (OffsetInBits == PieceOffsetInBits) 198 return 0; 199 assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces"); 200 return OffsetInBits; 201 } 202 203 bool DwarfExpression::AddMachineRegExpression(DIExpression Expr, 204 unsigned MachineReg, 205 unsigned PieceOffsetInBits) { 206 auto I = Expr.begin(); 207 // Pattern-match combinations for which more efficient representations exist 208 // first. 209 if (I == Expr.end()) 210 return AddMachineRegPiece(MachineReg); 211 212 bool ValidReg = false; 213 switch (*I) { 214 case dwarf::DW_OP_bit_piece: { 215 unsigned OffsetInBits = I->getArg(1); 216 unsigned SizeInBits = I->getArg(2); 217 // Piece always comes at the end of the expression. 218 return AddMachineRegPiece(MachineReg, SizeInBits, 219 getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 220 } 221 case dwarf::DW_OP_plus: 222 // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. 223 if (I->getNext() == dwarf::DW_OP_deref) { 224 unsigned Offset = I->getArg(1); 225 ValidReg = AddMachineRegIndirect(MachineReg, Offset); 226 std::advance(I, 2); 227 break; 228 } else 229 ValidReg = AddMachineRegPiece(MachineReg); 230 case dwarf::DW_OP_deref: 231 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 232 ValidReg = AddMachineRegIndirect(MachineReg); 233 ++I; 234 break; 235 default: 236 llvm_unreachable("unsupported operand"); 237 } 238 239 if (!ValidReg) 240 return false; 241 242 // Emit remaining elements of the expression. 243 AddExpression(I, PieceOffsetInBits); 244 return true; 245 } 246 247 void DwarfExpression::AddExpression(DIExpression::iterator I, 248 unsigned PieceOffsetInBits) { 249 for (; I != DIExpression::iterator(); ++I) { 250 switch (*I) { 251 case dwarf::DW_OP_bit_piece: { 252 unsigned OffsetInBits = I->getArg(1); 253 unsigned SizeInBits = I->getArg(2); 254 AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 255 break; 256 } 257 case dwarf::DW_OP_plus: 258 EmitOp(dwarf::DW_OP_plus_uconst); 259 EmitUnsigned(I->getArg(1)); 260 break; 261 case dwarf::DW_OP_deref: 262 EmitOp(dwarf::DW_OP_deref); 263 break; 264 default: 265 llvm_unreachable("unhandled opcode found in DIExpression"); 266 } 267 } 268 } 269