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 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 assert(SizeInBits > 0 && "piece has size zero"); 50 const unsigned SizeOfByte = 8; 51 if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { 52 EmitOp(dwarf::DW_OP_bit_piece); 53 EmitUnsigned(SizeInBits); 54 EmitUnsigned(OffsetInBits); 55 } else { 56 EmitOp(dwarf::DW_OP_piece); 57 unsigned ByteSize = SizeInBits / SizeOfByte; 58 EmitUnsigned(ByteSize); 59 } 60 } 61 62 void DwarfExpression::AddShr(unsigned ShiftBy) { 63 EmitOp(dwarf::DW_OP_constu); 64 EmitUnsigned(ShiftBy); 65 EmitOp(dwarf::DW_OP_shr); 66 } 67 68 bool DwarfExpression::AddMachineRegIndirect(const TargetRegisterInfo &TRI, 69 unsigned MachineReg, int Offset) { 70 if (isFrameRegister(TRI, MachineReg)) { 71 // If variable offset is based in frame register then use fbreg. 72 EmitOp(dwarf::DW_OP_fbreg); 73 EmitSigned(Offset); 74 return true; 75 } 76 77 int DwarfReg = TRI.getDwarfRegNum(MachineReg, false); 78 if (DwarfReg < 0) 79 return false; 80 81 AddRegIndirect(DwarfReg, Offset); 82 return true; 83 } 84 85 bool DwarfExpression::AddMachineRegPiece(const TargetRegisterInfo &TRI, 86 unsigned MachineReg, 87 unsigned PieceSizeInBits, 88 unsigned PieceOffsetInBits) { 89 if (!TRI.isPhysicalRegister(MachineReg)) 90 return false; 91 92 int Reg = TRI.getDwarfRegNum(MachineReg, false); 93 94 // If this is a valid register number, emit it. 95 if (Reg >= 0) { 96 AddReg(Reg); 97 if (PieceSizeInBits) 98 AddOpPiece(PieceSizeInBits, PieceOffsetInBits); 99 return true; 100 } 101 102 // Walk up the super-register chain until we find a valid number. 103 // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0. 104 for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 105 Reg = TRI.getDwarfRegNum(*SR, false); 106 if (Reg >= 0) { 107 unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); 108 unsigned Size = TRI.getSubRegIdxSize(Idx); 109 unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); 110 AddReg(Reg, "super-register"); 111 if (PieceOffsetInBits == RegOffset) { 112 AddOpPiece(Size, RegOffset); 113 } else { 114 // If this is part of a variable in a sub-register at a 115 // non-zero offset, we need to manually shift the value into 116 // place, since the DW_OP_piece describes the part of the 117 // variable, not the position of the subregister. 118 if (RegOffset) 119 AddShr(RegOffset); 120 AddOpPiece(Size, PieceOffsetInBits); 121 } 122 return true; 123 } 124 } 125 126 // Otherwise, attempt to find a covering set of sub-register numbers. 127 // For example, Q0 on ARM is a composition of D0+D1. 128 // 129 // Keep track of the current position so we can emit the more 130 // efficient DW_OP_piece. 131 unsigned CurPos = PieceOffsetInBits; 132 // The size of the register in bits, assuming 8 bits per byte. 133 unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8; 134 // Keep track of the bits in the register we already emitted, so we 135 // can avoid emitting redundant aliasing subregs. 136 SmallBitVector Coverage(RegSize, false); 137 for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 138 unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR); 139 unsigned Size = TRI.getSubRegIdxSize(Idx); 140 unsigned Offset = TRI.getSubRegIdxOffset(Idx); 141 Reg = TRI.getDwarfRegNum(*SR, false); 142 143 // Intersection between the bits we already emitted and the bits 144 // covered by this subregister. 145 SmallBitVector Intersection(RegSize, false); 146 Intersection.set(Offset, Offset + Size); 147 Intersection ^= Coverage; 148 149 // If this sub-register has a DWARF number and we haven't covered 150 // its range, emit a DWARF piece for it. 151 if (Reg >= 0 && Intersection.any()) { 152 AddReg(Reg, "sub-register"); 153 AddOpPiece(Size, Offset == CurPos ? 0 : Offset); 154 CurPos = Offset + Size; 155 156 // Mark it as emitted. 157 Coverage.set(Offset, Offset + Size); 158 } 159 } 160 161 return CurPos > PieceOffsetInBits; 162 } 163 164 void DwarfExpression::AddStackValue() { 165 if (DwarfVersion >= 4) 166 EmitOp(dwarf::DW_OP_stack_value); 167 } 168 169 void DwarfExpression::AddSignedConstant(int64_t Value) { 170 EmitOp(dwarf::DW_OP_consts); 171 EmitSigned(Value); 172 AddStackValue(); 173 } 174 175 void DwarfExpression::AddUnsignedConstant(uint64_t Value) { 176 EmitOp(dwarf::DW_OP_constu); 177 EmitUnsigned(Value); 178 AddStackValue(); 179 } 180 181 void DwarfExpression::AddUnsignedConstant(const APInt &Value) { 182 unsigned Size = Value.getBitWidth(); 183 const uint64_t *Data = Value.getRawData(); 184 185 // Chop it up into 64-bit pieces, because that's the maximum that 186 // AddUnsignedConstant takes. 187 unsigned Offset = 0; 188 while (Offset < Size) { 189 AddUnsignedConstant(*Data++); 190 if (Offset == 0 && Size <= 64) 191 break; 192 AddOpPiece(std::min(Size-Offset, 64u), Offset); 193 Offset += 64; 194 } 195 } 196 197 static unsigned getOffsetOrZero(unsigned OffsetInBits, 198 unsigned PieceOffsetInBits) { 199 if (OffsetInBits == PieceOffsetInBits) 200 return 0; 201 assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces"); 202 return OffsetInBits; 203 } 204 205 bool DwarfExpression::AddMachineRegExpression(const TargetRegisterInfo &TRI, 206 const DIExpression *Expr, 207 unsigned MachineReg, 208 unsigned PieceOffsetInBits) { 209 auto I = Expr->expr_op_begin(); 210 auto E = Expr->expr_op_end(); 211 if (I == E) 212 return AddMachineRegPiece(TRI, MachineReg); 213 214 // Pattern-match combinations for which more efficient representations exist 215 // first. 216 bool ValidReg = false; 217 switch (I->getOp()) { 218 case dwarf::DW_OP_bit_piece: { 219 unsigned OffsetInBits = I->getArg(0); 220 unsigned SizeInBits = I->getArg(1); 221 // Piece always comes at the end of the expression. 222 return AddMachineRegPiece(TRI, MachineReg, SizeInBits, 223 getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 224 } 225 case dwarf::DW_OP_plus: 226 case dwarf::DW_OP_minus: { 227 // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. 228 // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset]. 229 auto N = I.getNext(); 230 if (N != E && N->getOp() == dwarf::DW_OP_deref) { 231 unsigned Offset = I->getArg(0); 232 ValidReg = AddMachineRegIndirect( 233 TRI, MachineReg, I->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); 234 std::advance(I, 2); 235 break; 236 } else 237 ValidReg = AddMachineRegPiece(TRI, MachineReg); 238 } 239 case dwarf::DW_OP_deref: { 240 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 241 ValidReg = AddMachineRegIndirect(TRI, MachineReg); 242 ++I; 243 break; 244 } 245 default: 246 llvm_unreachable("unsupported operand"); 247 } 248 249 if (!ValidReg) 250 return false; 251 252 // Emit remaining elements of the expression. 253 AddExpression(I, E, PieceOffsetInBits); 254 return true; 255 } 256 257 void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I, 258 DIExpression::expr_op_iterator E, 259 unsigned PieceOffsetInBits) { 260 for (; I != E; ++I) { 261 switch (I->getOp()) { 262 case dwarf::DW_OP_bit_piece: { 263 unsigned OffsetInBits = I->getArg(0); 264 unsigned SizeInBits = I->getArg(1); 265 AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 266 break; 267 } 268 case dwarf::DW_OP_plus: 269 EmitOp(dwarf::DW_OP_plus_uconst); 270 EmitUnsigned(I->getArg(0)); 271 break; 272 case dwarf::DW_OP_minus: 273 // There is no OP_minus_uconst. 274 EmitOp(dwarf::DW_OP_constu); 275 EmitUnsigned(I->getArg(0)); 276 EmitOp(dwarf::DW_OP_minus); 277 break; 278 case dwarf::DW_OP_deref: 279 EmitOp(dwarf::DW_OP_deref); 280 break; 281 default: 282 llvm_unreachable("unhandled opcode found in expression"); 283 } 284 } 285 } 286