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