1 //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===// 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 implements the Dwarf emissions parts of AsmPrinter. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ByteStreamer.h" 15 #include "DwarfExpression.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/CodeGen/AsmPrinter.h" 18 #include "llvm/IR/DataLayout.h" 19 #include "llvm/MC/MCAsmInfo.h" 20 #include "llvm/MC/MCSection.h" 21 #include "llvm/MC/MCStreamer.h" 22 #include "llvm/MC/MCSymbol.h" 23 #include "llvm/MC/MachineLocation.h" 24 #include "llvm/Support/Dwarf.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Target/TargetFrameLowering.h" 27 #include "llvm/Target/TargetLoweringObjectFile.h" 28 #include "llvm/Target/TargetMachine.h" 29 #include "llvm/Target/TargetRegisterInfo.h" 30 #include "llvm/Target/TargetSubtargetInfo.h" 31 using namespace llvm; 32 33 #define DEBUG_TYPE "asm-printer" 34 35 void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char *Comment) { 36 BS.EmitInt8( 37 Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op) 38 : dwarf::OperationEncodingString(Op)); 39 } 40 41 void DebugLocDwarfExpression::EmitSigned(int Value) { 42 BS.EmitSLEB128(Value, Twine(Value)); 43 } 44 45 void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) { 46 BS.EmitULEB128(Value, Twine(Value)); 47 } 48 49 bool DebugLocDwarfExpression::isFrameRegister(unsigned MachineReg) { 50 // This information is not available while emitting .debug_loc entries. 51 return false; 52 } 53 54 //===----------------------------------------------------------------------===// 55 // Dwarf Emission Helper Routines 56 //===----------------------------------------------------------------------===// 57 58 /// EmitSLEB128 - emit the specified signed leb128 value. 59 void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const { 60 if (isVerbose() && Desc) 61 OutStreamer.AddComment(Desc); 62 63 OutStreamer.EmitSLEB128IntValue(Value); 64 } 65 66 /// EmitULEB128 - emit the specified signed leb128 value. 67 void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, 68 unsigned PadTo) const { 69 if (isVerbose() && Desc) 70 OutStreamer.AddComment(Desc); 71 72 OutStreamer.EmitULEB128IntValue(Value, PadTo); 73 } 74 75 /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. 76 void AsmPrinter::EmitCFAByte(unsigned Val) const { 77 if (isVerbose()) { 78 if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset + 64) 79 OutStreamer.AddComment("DW_CFA_offset + Reg (" + 80 Twine(Val - dwarf::DW_CFA_offset) + ")"); 81 else 82 OutStreamer.AddComment(dwarf::CallFrameString(Val)); 83 } 84 OutStreamer.EmitIntValue(Val, 1); 85 } 86 87 static const char *DecodeDWARFEncoding(unsigned Encoding) { 88 switch (Encoding) { 89 case dwarf::DW_EH_PE_absptr: 90 return "absptr"; 91 case dwarf::DW_EH_PE_omit: 92 return "omit"; 93 case dwarf::DW_EH_PE_pcrel: 94 return "pcrel"; 95 case dwarf::DW_EH_PE_udata4: 96 return "udata4"; 97 case dwarf::DW_EH_PE_udata8: 98 return "udata8"; 99 case dwarf::DW_EH_PE_sdata4: 100 return "sdata4"; 101 case dwarf::DW_EH_PE_sdata8: 102 return "sdata8"; 103 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: 104 return "pcrel udata4"; 105 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: 106 return "pcrel sdata4"; 107 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: 108 return "pcrel udata8"; 109 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: 110 return "pcrel sdata8"; 111 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4 112 : 113 return "indirect pcrel udata4"; 114 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 115 : 116 return "indirect pcrel sdata4"; 117 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8 118 : 119 return "indirect pcrel udata8"; 120 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8 121 : 122 return "indirect pcrel sdata8"; 123 } 124 125 return "<unknown encoding>"; 126 } 127 128 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an 129 /// encoding. If verbose assembly output is enabled, we output comments 130 /// describing the encoding. Desc is an optional string saying what the 131 /// encoding is specifying (e.g. "LSDA"). 132 void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const { 133 if (isVerbose()) { 134 if (Desc) 135 OutStreamer.AddComment(Twine(Desc) + " Encoding = " + 136 Twine(DecodeDWARFEncoding(Val))); 137 else 138 OutStreamer.AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val)); 139 } 140 141 OutStreamer.EmitIntValue(Val, 1); 142 } 143 144 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. 145 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const { 146 if (Encoding == dwarf::DW_EH_PE_omit) 147 return 0; 148 149 switch (Encoding & 0x07) { 150 default: 151 llvm_unreachable("Invalid encoded value."); 152 case dwarf::DW_EH_PE_absptr: 153 return TM.getDataLayout()->getPointerSize(); 154 case dwarf::DW_EH_PE_udata2: 155 return 2; 156 case dwarf::DW_EH_PE_udata4: 157 return 4; 158 case dwarf::DW_EH_PE_udata8: 159 return 8; 160 } 161 } 162 163 void AsmPrinter::EmitTTypeReference(const GlobalValue *GV, 164 unsigned Encoding) const { 165 if (GV) { 166 const TargetLoweringObjectFile &TLOF = getObjFileLowering(); 167 168 const MCExpr *Exp = 169 TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI, OutStreamer); 170 OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding)); 171 } else 172 OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding)); 173 } 174 175 /// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its 176 /// section. This can be done with a special directive if the target supports 177 /// it (e.g. cygwin) or by emitting it as an offset from a label at the start 178 /// of the section. 179 /// 180 /// SectionLabel is a temporary label emitted at the start of the section that 181 /// Label lives in. 182 void AsmPrinter::EmitSectionOffset(const MCSymbol *Label, 183 const MCSymbol *SectionLabel) const { 184 // On COFF targets, we have to emit the special .secrel32 directive. 185 if (MAI->needsDwarfSectionOffsetDirective()) { 186 OutStreamer.EmitCOFFSecRel32(Label); 187 return; 188 } 189 190 // Get the section that we're referring to, based on SectionLabel. 191 const MCSection &Section = SectionLabel->getSection(); 192 193 // If Label has already been emitted, verify that it is in the same section as 194 // section label for sanity. 195 assert((!Label->isInSection() || &Label->getSection() == &Section) && 196 "Section offset using wrong section base for label"); 197 198 // If the section in question will end up with an address of 0 anyway, we can 199 // just emit an absolute reference to save a relocation. 200 if (Section.isBaseAddressKnownZero()) { 201 OutStreamer.EmitSymbolValue(Label, 4); 202 return; 203 } 204 205 // Otherwise, emit it as a label difference from the start of the section. 206 EmitLabelDifference(Label, SectionLabel, 4); 207 } 208 209 // Some targets do not provide a DWARF register number for every 210 // register. This function attempts to emit a DWARF register by 211 // emitting a piece of a super-register or by piecing together 212 // multiple subregisters that alias the register. 213 void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer, 214 const MachineLocation &MLoc, 215 unsigned PieceSizeInBits, 216 unsigned PieceOffsetInBits) const { 217 assert(MLoc.isReg() && "MLoc must be a register"); 218 DebugLocDwarfExpression Expr(*this, Streamer); 219 Expr.AddMachineRegPiece(MLoc.getReg(), PieceSizeInBits, PieceOffsetInBits); 220 } 221 222 void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer, 223 unsigned PieceSizeInBits, 224 unsigned PieceOffsetInBits) const { 225 DebugLocDwarfExpression Expr(*this, Streamer); 226 Expr.AddOpPiece(PieceSizeInBits, PieceOffsetInBits); 227 } 228 229 /// EmitDwarfRegOp - Emit dwarf register operation. 230 void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer, 231 const MachineLocation &MLoc) const { 232 DebugLocDwarfExpression Expr(*this, Streamer); 233 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo(); 234 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false); 235 if (Reg < 0) { 236 // We assume that pointers are always in an addressable register. 237 if (MLoc.isIndirect()) 238 // FIXME: We have no reasonable way of handling errors in here. The 239 // caller might be in the middle of a dwarf expression. We should 240 // probably assert that Reg >= 0 once debug info generation is more 241 // mature. 242 return Expr.EmitOp(dwarf::DW_OP_nop, 243 "nop (could not find a dwarf register number)"); 244 245 // Attempt to find a valid super- or sub-register. 246 if (!Expr.AddMachineRegPiece(MLoc.getReg())) 247 Expr.EmitOp(dwarf::DW_OP_nop, 248 "nop (could not find a dwarf register number)"); 249 return; 250 } 251 252 if (MLoc.isIndirect()) 253 Expr.AddRegIndirect(Reg, MLoc.getOffset()); 254 else 255 Expr.AddReg(Reg); 256 } 257 258 //===----------------------------------------------------------------------===// 259 // Dwarf Lowering Routines 260 //===----------------------------------------------------------------------===// 261 262 void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { 263 switch (Inst.getOperation()) { 264 default: 265 llvm_unreachable("Unexpected instruction"); 266 case MCCFIInstruction::OpDefCfaOffset: 267 OutStreamer.EmitCFIDefCfaOffset(Inst.getOffset()); 268 break; 269 case MCCFIInstruction::OpDefCfa: 270 OutStreamer.EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset()); 271 break; 272 case MCCFIInstruction::OpDefCfaRegister: 273 OutStreamer.EmitCFIDefCfaRegister(Inst.getRegister()); 274 break; 275 case MCCFIInstruction::OpOffset: 276 OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset()); 277 break; 278 case MCCFIInstruction::OpRegister: 279 OutStreamer.EmitCFIRegister(Inst.getRegister(), Inst.getRegister2()); 280 break; 281 case MCCFIInstruction::OpWindowSave: 282 OutStreamer.EmitCFIWindowSave(); 283 break; 284 case MCCFIInstruction::OpSameValue: 285 OutStreamer.EmitCFISameValue(Inst.getRegister()); 286 break; 287 } 288 } 289