LLVM API Documentation

AsmPrinterDwarf.cpp
Go to the documentation of this file.
00001 //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Dwarf emissions parts of AsmPrinter.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #define DEBUG_TYPE "asm-printer"
00015 #include "llvm/CodeGen/AsmPrinter.h"
00016 #include "llvm/ADT/Twine.h"
00017 #include "llvm/IR/DataLayout.h"
00018 #include "llvm/MC/MCAsmInfo.h"
00019 #include "llvm/MC/MCSection.h"
00020 #include "llvm/MC/MCStreamer.h"
00021 #include "llvm/MC/MCSymbol.h"
00022 #include "llvm/MC/MachineLocation.h"
00023 #include "llvm/Support/Dwarf.h"
00024 #include "llvm/Support/ErrorHandling.h"
00025 #include "llvm/Target/TargetFrameLowering.h"
00026 #include "llvm/Target/TargetLoweringObjectFile.h"
00027 #include "llvm/Target/TargetMachine.h"
00028 #include "llvm/Target/TargetRegisterInfo.h"
00029 using namespace llvm;
00030 
00031 //===----------------------------------------------------------------------===//
00032 // Dwarf Emission Helper Routines
00033 //===----------------------------------------------------------------------===//
00034 
00035 /// EmitSLEB128 - emit the specified signed leb128 value.
00036 void AsmPrinter::EmitSLEB128(int Value, const char *Desc) const {
00037   if (isVerbose() && Desc)
00038     OutStreamer.AddComment(Desc);
00039 
00040   OutStreamer.EmitSLEB128IntValue(Value);
00041 }
00042 
00043 /// EmitULEB128 - emit the specified signed leb128 value.
00044 void AsmPrinter::EmitULEB128(unsigned Value, const char *Desc,
00045                              unsigned PadTo) const {
00046   if (isVerbose() && Desc)
00047     OutStreamer.AddComment(Desc);
00048 
00049   OutStreamer.EmitULEB128IntValue(Value, PadTo);
00050 }
00051 
00052 /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
00053 void AsmPrinter::EmitCFAByte(unsigned Val) const {
00054   if (isVerbose()) {
00055     if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64)
00056       OutStreamer.AddComment("DW_CFA_offset + Reg (" +
00057                              Twine(Val-dwarf::DW_CFA_offset) + ")");
00058     else
00059       OutStreamer.AddComment(dwarf::CallFrameString(Val));
00060   }
00061   OutStreamer.EmitIntValue(Val, 1);
00062 }
00063 
00064 static const char *DecodeDWARFEncoding(unsigned Encoding) {
00065   switch (Encoding) {
00066   case dwarf::DW_EH_PE_absptr: return "absptr";
00067   case dwarf::DW_EH_PE_omit:   return "omit";
00068   case dwarf::DW_EH_PE_pcrel:  return "pcrel";
00069   case dwarf::DW_EH_PE_udata4: return "udata4";
00070   case dwarf::DW_EH_PE_udata8: return "udata8";
00071   case dwarf::DW_EH_PE_sdata4: return "sdata4";
00072   case dwarf::DW_EH_PE_sdata8: return "sdata8";
00073   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4";
00074   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4";
00075   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8";
00076   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8";
00077   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4:
00078     return "indirect pcrel udata4";
00079   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4:
00080     return "indirect pcrel sdata4";
00081   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8:
00082     return "indirect pcrel udata8";
00083   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8:
00084     return "indirect pcrel sdata8";
00085   }
00086 
00087   return "<unknown encoding>";
00088 }
00089 
00090 
00091 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
00092 /// encoding.  If verbose assembly output is enabled, we output comments
00093 /// describing the encoding.  Desc is an optional string saying what the
00094 /// encoding is specifying (e.g. "LSDA").
00095 void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
00096   if (isVerbose()) {
00097     if (Desc != 0)
00098       OutStreamer.AddComment(Twine(Desc)+" Encoding = " +
00099                              Twine(DecodeDWARFEncoding(Val)));
00100     else
00101       OutStreamer.AddComment(Twine("Encoding = ") +
00102                              DecodeDWARFEncoding(Val));
00103   }
00104 
00105   OutStreamer.EmitIntValue(Val, 1);
00106 }
00107 
00108 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
00109 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
00110   if (Encoding == dwarf::DW_EH_PE_omit)
00111     return 0;
00112 
00113   switch (Encoding & 0x07) {
00114   default: llvm_unreachable("Invalid encoded value.");
00115   case dwarf::DW_EH_PE_absptr: return TM.getDataLayout()->getPointerSize();
00116   case dwarf::DW_EH_PE_udata2: return 2;
00117   case dwarf::DW_EH_PE_udata4: return 4;
00118   case dwarf::DW_EH_PE_udata8: return 8;
00119   }
00120 }
00121 
00122 void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
00123                                     unsigned Encoding) const {
00124   if (GV) {
00125     const TargetLoweringObjectFile &TLOF = getObjFileLowering();
00126 
00127     const MCExpr *Exp =
00128       TLOF.getTTypeGlobalReference(GV, Mang, MMI, Encoding, OutStreamer);
00129     OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
00130   } else
00131     OutStreamer.EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
00132 }
00133 
00134 /// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its
00135 /// section.  This can be done with a special directive if the target supports
00136 /// it (e.g. cygwin) or by emitting it as an offset from a label at the start
00137 /// of the section.
00138 ///
00139 /// SectionLabel is a temporary label emitted at the start of the section that
00140 /// Label lives in.
00141 void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
00142                                    const MCSymbol *SectionLabel) const {
00143   // On COFF targets, we have to emit the special .secrel32 directive.
00144   if (MAI->needsDwarfSectionOffsetDirective()) {
00145     OutStreamer.EmitCOFFSecRel32(Label);
00146     return;
00147   }
00148 
00149   // Get the section that we're referring to, based on SectionLabel.
00150   const MCSection &Section = SectionLabel->getSection();
00151 
00152   // If Label has already been emitted, verify that it is in the same section as
00153   // section label for sanity.
00154   assert((!Label->isInSection() || &Label->getSection() == &Section) &&
00155          "Section offset using wrong section base for label");
00156 
00157   // If the section in question will end up with an address of 0 anyway, we can
00158   // just emit an absolute reference to save a relocation.
00159   if (Section.isBaseAddressKnownZero()) {
00160     OutStreamer.EmitSymbolValue(Label, 4);
00161     return;
00162   }
00163 
00164   // Otherwise, emit it as a label difference from the start of the section.
00165   EmitLabelDifference(Label, SectionLabel, 4);
00166 }
00167 
00168 //===----------------------------------------------------------------------===//
00169 // Dwarf Lowering Routines
00170 //===----------------------------------------------------------------------===//
00171 
00172 void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
00173   switch (Inst.getOperation()) {
00174   default:
00175     llvm_unreachable("Unexpected instruction");
00176   case MCCFIInstruction::OpDefCfaOffset:
00177     OutStreamer.EmitCFIDefCfaOffset(Inst.getOffset());
00178     break;
00179   case MCCFIInstruction::OpDefCfa:
00180     OutStreamer.EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
00181     break;
00182   case MCCFIInstruction::OpDefCfaRegister:
00183     OutStreamer.EmitCFIDefCfaRegister(Inst.getRegister());
00184     break;
00185   case MCCFIInstruction::OpOffset:
00186     OutStreamer.EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
00187     break;
00188   }
00189 }