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) { 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 } 45 46 void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) { 47 if (!SizeInBits) 48 return; 49 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 this->OffsetInBits += SizeInBits; 61 } 62 63 void DwarfExpression::AddShr(unsigned ShiftBy) { 64 EmitOp(dwarf::DW_OP_constu); 65 EmitUnsigned(ShiftBy); 66 EmitOp(dwarf::DW_OP_shr); 67 } 68 69 bool DwarfExpression::AddMachineRegIndirect(const TargetRegisterInfo &TRI, 70 unsigned MachineReg, int Offset) { 71 if (isFrameRegister(TRI, MachineReg)) { 72 // If variable offset is based in frame register then use fbreg. 73 EmitOp(dwarf::DW_OP_fbreg); 74 EmitSigned(Offset); 75 return true; 76 } 77 78 int DwarfReg = TRI.getDwarfRegNum(MachineReg, false); 79 if (DwarfReg < 0) 80 return false; 81 82 AddRegIndirect(DwarfReg, Offset); 83 return true; 84 } 85 86 bool DwarfExpression::AddMachineReg(const TargetRegisterInfo &TRI, 87 unsigned MachineReg, unsigned MaxSize) { 88 if (!TRI.isPhysicalRegister(MachineReg)) 89 return false; 90 91 int Reg = TRI.getDwarfRegNum(MachineReg, false); 92 93 // If this is a valid register number, emit it. 94 if (Reg >= 0) { 95 AddReg(Reg); 96 return true; 97 } 98 99 // Walk up the super-register chain until we find a valid number. 100 // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0. 101 for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 102 Reg = TRI.getDwarfRegNum(*SR, false); 103 if (Reg >= 0) { 104 unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); 105 unsigned Size = TRI.getSubRegIdxSize(Idx); 106 unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); 107 AddReg(Reg, "super-register"); 108 // Use a DW_OP_bit_piece to describe the sub-register. 109 setSubRegisterPiece(Size, RegOffset); 110 return true; 111 } 112 } 113 114 // Otherwise, attempt to find a covering set of sub-register numbers. 115 // For example, Q0 on ARM is a composition of D0+D1. 116 unsigned CurPos = 0; 117 // The size of the register in bits, assuming 8 bits per byte. 118 unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8; 119 // Keep track of the bits in the register we already emitted, so we 120 // can avoid emitting redundant aliasing subregs. 121 SmallBitVector Coverage(RegSize, false); 122 for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 123 unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR); 124 unsigned Size = TRI.getSubRegIdxSize(Idx); 125 unsigned Offset = TRI.getSubRegIdxOffset(Idx); 126 Reg = TRI.getDwarfRegNum(*SR, false); 127 128 // Intersection between the bits we already emitted and the bits 129 // covered by this subregister. 130 SmallBitVector Intersection(RegSize, false); 131 Intersection.set(Offset, Offset + Size); 132 Intersection ^= Coverage; 133 134 // If this sub-register has a DWARF number and we haven't covered 135 // its range, emit a DWARF piece for it. 136 if (Reg >= 0 && Intersection.any()) { 137 AddReg(Reg, "sub-register"); 138 if (Offset >= MaxSize) 139 break; 140 // Emit a piece for the any gap in the coverage. 141 if (Offset > CurPos) 142 AddOpPiece(Offset - CurPos); 143 AddOpPiece(std::min<unsigned>(Size, MaxSize - Offset)); 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 auto Fragment = ExprCursor.getFragmentInfo(); 201 ValidReg = AddMachineReg(TRI, MachineReg, 202 Fragment ? Fragment->SizeInBits : ~1U); 203 break; 204 } 205 case dwarf::DW_OP_plus: 206 case dwarf::DW_OP_minus: { 207 // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset]. 208 // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset]. 209 auto N = ExprCursor.peekNext(); 210 if (N && N->getOp() == dwarf::DW_OP_deref) { 211 unsigned Offset = Op->getArg(0); 212 ValidReg = AddMachineRegIndirect( 213 TRI, MachineReg, Op->getOp() == dwarf::DW_OP_plus ? Offset : -Offset); 214 ExprCursor.consume(2); 215 } else 216 ValidReg = AddMachineReg(TRI, MachineReg); 217 break; 218 } 219 case dwarf::DW_OP_deref: 220 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. 221 ValidReg = AddMachineRegIndirect(TRI, MachineReg); 222 ExprCursor.take(); 223 break; 224 } 225 226 return ValidReg; 227 } 228 229 void DwarfExpression::AddExpression(DIExpressionCursor &&ExprCursor, 230 unsigned FragmentOffsetInBits) { 231 while (ExprCursor) { 232 auto Op = ExprCursor.take(); 233 switch (Op->getOp()) { 234 case dwarf::DW_OP_LLVM_fragment: { 235 unsigned SizeInBits = Op->getArg(1); 236 unsigned FragmentOffset = Op->getArg(0); 237 // The fragment offset must have already been adjusted by emitting an 238 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base 239 // location. 240 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?"); 241 242 // If \a AddMachineReg already emitted DW_OP_piece operations to represent 243 // a super-register by splicing together sub-registers, subtract the size 244 // of the pieces that was already emitted. 245 SizeInBits -= OffsetInBits - FragmentOffset; 246 247 // If \a AddMachineReg requested a DW_OP_bit_piece to stencil out a 248 // sub-register that is smaller than the current fragment's size, use it. 249 if (SubRegisterSizeInBits) 250 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits); 251 252 AddOpPiece(SizeInBits, SubRegisterOffsetInBits); 253 setSubRegisterPiece(0, 0); 254 break; 255 } 256 case dwarf::DW_OP_plus: 257 EmitOp(dwarf::DW_OP_plus_uconst); 258 EmitUnsigned(Op->getArg(0)); 259 break; 260 case dwarf::DW_OP_minus: 261 // There is no OP_minus_uconst. 262 EmitOp(dwarf::DW_OP_constu); 263 EmitUnsigned(Op->getArg(0)); 264 EmitOp(dwarf::DW_OP_minus); 265 break; 266 case dwarf::DW_OP_deref: 267 EmitOp(dwarf::DW_OP_deref); 268 break; 269 case dwarf::DW_OP_constu: 270 EmitOp(dwarf::DW_OP_constu); 271 EmitUnsigned(Op->getArg(0)); 272 break; 273 case dwarf::DW_OP_stack_value: 274 AddStackValue(); 275 break; 276 default: 277 llvm_unreachable("unhandled opcode found in expression"); 278 } 279 } 280 } 281 282 void DwarfExpression::finalize() { 283 if (SubRegisterSizeInBits) 284 AddOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); 285 } 286 287 void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { 288 if (!Expr || !Expr->isFragment()) 289 return; 290 291 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits; 292 assert(FragmentOffset >= OffsetInBits && 293 "overlapping or duplicate fragments"); 294 if (FragmentOffset > OffsetInBits) 295 AddOpPiece(FragmentOffset - OffsetInBits); 296 OffsetInBits = FragmentOffset; 297 } 298