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