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