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, unsigned MaxSize) { 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 if (Offset >= MaxSize) 141 break; 142 // Emit a piece for the any gap in the coverage. 143 if (Offset > CurPos) 144 AddOpPiece(Offset - CurPos); 145 AddOpPiece(std::min<unsigned>(Size, MaxSize - Offset)); 146 CurPos = Offset + Size; 147 148 // Mark it as emitted. 149 Coverage.set(Offset, Offset + Size); 150 } 151 } 152 153 return CurPos; 154 } 155 156 void DwarfExpression::AddStackValue() { 157 if (DwarfVersion >= 4) 158 EmitOp(dwarf::DW_OP_stack_value); 159 } 160 161 void DwarfExpression::AddSignedConstant(int64_t Value) { 162 EmitOp(dwarf::DW_OP_consts); 163 EmitSigned(Value); 164 AddStackValue(); 165 } 166 167 void DwarfExpression::AddUnsignedConstant(uint64_t Value) { 168 EmitOp(dwarf::DW_OP_constu); 169 EmitUnsigned(Value); 170 AddStackValue(); 171 } 172 173 void DwarfExpression::AddUnsignedConstant(const APInt &Value) { 174 unsigned Size = Value.getBitWidth(); 175 const uint64_t *Data = Value.getRawData(); 176 177 // Chop it up into 64-bit pieces, because that's the maximum that 178 // AddUnsignedConstant takes. 179 unsigned Offset = 0; 180 while (Offset < Size) { 181 AddUnsignedConstant(*Data++); 182 if (Offset == 0 && Size <= 64) 183 break; 184 AddOpPiece(std::min(Size-Offset, 64u), Offset); 185 Offset += 64; 186 } 187 } 188 189 bool DwarfExpression::AddMachineRegExpression(const TargetRegisterInfo &TRI, 190 DIExpressionCursor &ExprCursor, 191 unsigned MachineReg, 192 unsigned FragmentOffsetInBits) { 193 if (!ExprCursor) 194 return AddMachineReg(TRI, MachineReg); 195 196 // Pattern-match combinations for which more efficient representations exist 197 // first. 198 bool ValidReg = false; 199 auto Op = ExprCursor.peek(); 200 switch (Op->getOp()) { 201 default: { 202 auto Fragment = ExprCursor.getFragmentInfo(); 203 ValidReg = AddMachineReg(TRI, MachineReg, 204 Fragment ? Fragment->SizeInBits : ~1U); 205 break; 206 } 207 case dwarf::DW_OP_plus: 208 case dwarf::DW_OP_minus: { 209 // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. 210 // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset]. 211 auto N = ExprCursor.peekNext(); 212 if (N && N->getOp() == dwarf::DW_OP_deref) { 213 unsigned Offset = Op->getArg(0); 214 ValidReg = AddMachineRegIndirect( 215 TRI, MachineReg, Op->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); 216 ExprCursor.consume(2); 217 } else 218 ValidReg = AddMachineReg(TRI, MachineReg); 219 break; 220 } 221 case dwarf::DW_OP_deref: 222 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 223 ValidReg = AddMachineRegIndirect(TRI, MachineReg); 224 ExprCursor.take(); 225 break; 226 } 227 228 return ValidReg; 229 } 230 231 void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor, 232 unsigned FragmentOffsetInBits) { 233 while (ExprCursor) { 234 auto Op = ExprCursor.take(); 235 switch (Op->getOp()) { 236 case dwarf::DW_OP_LLVM_fragment: { 237 unsigned SizeInBits = Op->getArg(1); 238 unsigned FragmentOffset = Op->getArg(0); 239 // The fragment offset must have already been adjusted by emitting an 240 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base 241 // location. 242 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?"); 243 244 // If \a AddMachineReg already emitted DW_OP_piece operations to represent 245 // a super-register by splicing together sub-registers, subtract the size 246 // of the pieces that was already emitted. 247 SizeInBits -= OffsetInBits - FragmentOffset; 248 249 // If \a AddMachineReg requested a DW_OP_bit_piece to stencil out a 250 // sub-register that is smaller than the current fragment's size, use it. 251 if (SubRegisterSizeInBits) 252 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits); 253 254 AddOpPiece(SizeInBits, SubRegisterOffsetInBits); 255 setSubRegisterPiece(0, 0); 256 break; 257 } 258 case dwarf::DW_OP_plus: 259 EmitOp(dwarf::DW_OP_plus_uconst); 260 EmitUnsigned(Op->getArg(0)); 261 break; 262 case dwarf::DW_OP_minus: 263 // There is no OP_minus_uconst. 264 EmitOp(dwarf::DW_OP_constu); 265 EmitUnsigned(Op->getArg(0)); 266 EmitOp(dwarf::DW_OP_minus); 267 break; 268 case dwarf::DW_OP_deref: 269 EmitOp(dwarf::DW_OP_deref); 270 break; 271 case dwarf::DW_OP_constu: 272 EmitOp(dwarf::DW_OP_constu); 273 EmitUnsigned(Op->getArg(0)); 274 break; 275 case dwarf::DW_OP_stack_value: 276 AddStackValue(); 277 break; 278 default: 279 llvm_unreachable("unhandled opcode found in expression"); 280 } 281 } 282 } 283 284 void DwarfExpression::finalize() { 285 if (SubRegisterSizeInBits) 286 AddOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); 287 } 288 289 void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { 290 if (!Expr || !Expr->isFragment()) 291 return; 292 293 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits; 294 assert(FragmentOffset >= OffsetInBits && 295 "overlapping or duplicate fragments"); 296 if (FragmentOffset > OffsetInBits) 297 AddOpPiece(FragmentOffset - OffsetInBits); 298 OffsetInBits = FragmentOffset; 299 } 300