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::AddSignedConstant(int Value) { 163 EmitOp(dwarf::DW_OP_consts); 164 EmitSigned(Value); 165 // The proper way to describe a constant value is 166 // DW_OP_constu <const>, DW_OP_stack_value. 167 // Unfortunately, DW_OP_stack_value was not available until DWARF-4, 168 // so we will continue to generate DW_OP_constu <const> for DWARF-2 169 // and DWARF-3. Technically, this is incorrect since DW_OP_const <const> 170 // actually describes a value at a constant addess, not a constant value. 171 // However, in the past there was no better way to describe a constant 172 // value, so the producers and consumers started to rely on heuristics 173 // to disambiguate the value vs. location status of the expression. 174 // See PR21176 for more details. 175 if (DwarfVersion >= 4) 176 EmitOp(dwarf::DW_OP_stack_value); 177 } 178 179 void DwarfExpression::AddUnsignedConstant(unsigned Value) { 180 EmitOp(dwarf::DW_OP_constu); 181 EmitUnsigned(Value); 182 // cf. comment in DwarfExpression::AddSignedConstant(). 183 if (DwarfVersion >= 4) 184 EmitOp(dwarf::DW_OP_stack_value); 185 } 186 187 static unsigned getOffsetOrZero(unsigned OffsetInBits, 188 unsigned PieceOffsetInBits) { 189 if (OffsetInBits == PieceOffsetInBits) 190 return 0; 191 assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces"); 192 return OffsetInBits; 193 } 194 195 bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr, 196 unsigned MachineReg, 197 unsigned PieceOffsetInBits) { 198 auto I = Expr->expr_op_begin(); 199 auto E = Expr->expr_op_end(); 200 if (I == E) 201 return AddMachineRegPiece(MachineReg); 202 203 // Pattern-match combinations for which more efficient representations exist 204 // first. 205 bool ValidReg = false; 206 switch (I->getOp()) { 207 case dwarf::DW_OP_bit_piece: { 208 unsigned OffsetInBits = I->getArg(0); 209 unsigned SizeInBits = I->getArg(1); 210 // Piece always comes at the end of the expression. 211 return AddMachineRegPiece(MachineReg, SizeInBits, 212 getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); 213 } 214 case dwarf::DW_OP_plus: 215 case dwarf::DW_OP_minus: { 216 // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. 217 // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset]. 218 auto N = I.getNext(); 219 if (N != E && N->getOp() == dwarf::DW_OP_deref) { 220 unsigned Offset = I->getArg(0); 221 ValidReg = AddMachineRegIndirect( 222 MachineReg, I->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); 223 std::advance(I, 2); 224 break; 225 } else 226 ValidReg = AddMachineRegPiece(MachineReg); 227 } 228 case dwarf::DW_OP_deref: { 229 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 230 ValidReg = AddMachineRegIndirect(MachineReg); 231 ++I; 232 break; 233 } 234 default: 235 llvm_unreachable("unsupported operand"); 236 } 237 238 if (!ValidReg) 239 return false; 240 241 // Emit remaining elements of the expression. 242 AddExpression(I, E, PieceOffsetInBits); 243 return true; 244 } 245 246 void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I, 247 DIExpression::expr_op_iterator E, 248 unsigned PieceOffsetInBits) { 249 for (; I != E; ++I) { 250 switch (I->getOp()) { 251 case dwarf::DW_OP_bit_piece: { 252 unsigned OffsetInBits = I->getArg(0); 253 unsigned SizeInBits = I->getArg(1); 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(0)); 260 break; 261 case dwarf::DW_OP_minus: 262 // There is no OP_minus_uconst. 263 EmitOp(dwarf::DW_OP_constu); 264 EmitUnsigned(I->getArg(0)); 265 EmitOp(dwarf::DW_OP_minus); 266 break; 267 case dwarf::DW_OP_deref: 268 EmitOp(dwarf::DW_OP_deref); 269 break; 270 default: 271 llvm_unreachable("unhandled opcode found in expression"); 272 } 273 } 274 } 275