Home | History | Annotate | Download | only in AsmPrinter
      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 "DwarfDebug.h"
     16 #include "DwarfExpression.h"
     17 #include "llvm/ADT/Twine.h"
     18 #include "llvm/CodeGen/AsmPrinter.h"
     19 #include "llvm/CodeGen/DIE.h"
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/CodeGen/MachineModuleInfo.h"
     22 #include "llvm/IR/DataLayout.h"
     23 #include "llvm/MC/MCAsmInfo.h"
     24 #include "llvm/MC/MCRegisterInfo.h"
     25 #include "llvm/MC/MCSection.h"
     26 #include "llvm/MC/MCStreamer.h"
     27 #include "llvm/MC/MCSymbol.h"
     28 #include "llvm/MC/MachineLocation.h"
     29 #include "llvm/Support/Dwarf.h"
     30 #include "llvm/Support/ErrorHandling.h"
     31 #include "llvm/Target/TargetLoweringObjectFile.h"
     32 #include "llvm/Target/TargetMachine.h"
     33 #include "llvm/Target/TargetSubtargetInfo.h"
     34 using namespace llvm;
     35 
     36 #define DEBUG_TYPE "asm-printer"
     37 
     38 //===----------------------------------------------------------------------===//
     39 // Dwarf Emission Helper Routines
     40 //===----------------------------------------------------------------------===//
     41 
     42 /// EmitSLEB128 - emit the specified signed leb128 value.
     43 void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
     44   if (isVerbose() && Desc)
     45     OutStreamer->AddComment(Desc);
     46 
     47   OutStreamer->EmitSLEB128IntValue(Value);
     48 }
     49 
     50 /// EmitULEB128 - emit the specified unsigned leb128 value.
     51 void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc,
     52                              unsigned PadTo) const {
     53   if (isVerbose() && Desc)
     54     OutStreamer->AddComment(Desc);
     55 
     56   OutStreamer->EmitULEB128IntValue(Value, PadTo);
     57 }
     58 
     59 static const char *DecodeDWARFEncoding(unsigned Encoding) {
     60   switch (Encoding) {
     61   case dwarf::DW_EH_PE_absptr:
     62     return "absptr";
     63   case dwarf::DW_EH_PE_omit:
     64     return "omit";
     65   case dwarf::DW_EH_PE_pcrel:
     66     return "pcrel";
     67   case dwarf::DW_EH_PE_udata4:
     68     return "udata4";
     69   case dwarf::DW_EH_PE_udata8:
     70     return "udata8";
     71   case dwarf::DW_EH_PE_sdata4:
     72     return "sdata4";
     73   case dwarf::DW_EH_PE_sdata8:
     74     return "sdata8";
     75   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
     76     return "pcrel udata4";
     77   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
     78     return "pcrel sdata4";
     79   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
     80     return "pcrel udata8";
     81   case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
     82     return "pcrel sdata8";
     83   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
     84       :
     85     return "indirect pcrel udata4";
     86   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     87       :
     88     return "indirect pcrel sdata4";
     89   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
     90       :
     91     return "indirect pcrel udata8";
     92   case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
     93       :
     94     return "indirect pcrel sdata8";
     95   }
     96 
     97   return "<unknown encoding>";
     98 }
     99 
    100 /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
    101 /// encoding.  If verbose assembly output is enabled, we output comments
    102 /// describing the encoding.  Desc is an optional string saying what the
    103 /// encoding is specifying (e.g. "LSDA").
    104 void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
    105   if (isVerbose()) {
    106     if (Desc)
    107       OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
    108                               Twine(DecodeDWARFEncoding(Val)));
    109     else
    110       OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
    111   }
    112 
    113   OutStreamer->EmitIntValue(Val, 1);
    114 }
    115 
    116 /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
    117 unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
    118   if (Encoding == dwarf::DW_EH_PE_omit)
    119     return 0;
    120 
    121   switch (Encoding & 0x07) {
    122   default:
    123     llvm_unreachable("Invalid encoded value.");
    124   case dwarf::DW_EH_PE_absptr:
    125     return MF->getDataLayout().getPointerSize();
    126   case dwarf::DW_EH_PE_udata2:
    127     return 2;
    128   case dwarf::DW_EH_PE_udata4:
    129     return 4;
    130   case dwarf::DW_EH_PE_udata8:
    131     return 8;
    132   }
    133 }
    134 
    135 void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
    136                                     unsigned Encoding) const {
    137   if (GV) {
    138     const TargetLoweringObjectFile &TLOF = getObjFileLowering();
    139 
    140     const MCExpr *Exp =
    141         TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI,
    142                                      *OutStreamer);
    143     OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
    144   } else
    145     OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
    146 }
    147 
    148 void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
    149                                           bool ForceOffset) const {
    150   if (!ForceOffset) {
    151     // On COFF targets, we have to emit the special .secrel32 directive.
    152     if (MAI->needsDwarfSectionOffsetDirective()) {
    153       OutStreamer->EmitCOFFSecRel32(Label);
    154       return;
    155     }
    156 
    157     // If the format uses relocations with dwarf, refer to the symbol directly.
    158     if (MAI->doesDwarfUseRelocationsAcrossSections()) {
    159       OutStreamer->EmitSymbolValue(Label, 4);
    160       return;
    161     }
    162   }
    163 
    164   // Otherwise, emit it as a label difference from the start of the section.
    165   EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
    166 }
    167 
    168 void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
    169   if (MAI->doesDwarfUseRelocationsAcrossSections()) {
    170     emitDwarfSymbolReference(S.getSymbol());
    171     return;
    172   }
    173 
    174   // Just emit the offset directly; no need for symbol math.
    175   EmitInt32(S.getOffset());
    176 }
    177 
    178 /// EmitDwarfRegOp - Emit dwarf register operation.
    179 void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
    180                                 const MachineLocation &MLoc) const {
    181   DebugLocDwarfExpression Expr(getDwarfDebug()->getDwarfVersion(), Streamer);
    182   const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
    183   int Reg = MRI->getDwarfRegNum(MLoc.getReg(), false);
    184   if (Reg < 0) {
    185     // We assume that pointers are always in an addressable register.
    186     if (MLoc.isIndirect())
    187       // FIXME: We have no reasonable way of handling errors in here. The
    188       // caller might be in the middle of a dwarf expression. We should
    189       // probably assert that Reg >= 0 once debug info generation is more
    190       // mature.
    191       return Expr.EmitOp(dwarf::DW_OP_nop,
    192                          "nop (could not find a dwarf register number)");
    193 
    194     // Attempt to find a valid super- or sub-register.
    195     if (!Expr.AddMachineRegPiece(*MF->getSubtarget().getRegisterInfo(),
    196                                  MLoc.getReg()))
    197       Expr.EmitOp(dwarf::DW_OP_nop,
    198                   "nop (could not find a dwarf register number)");
    199     return;
    200   }
    201 
    202   if (MLoc.isIndirect())
    203     Expr.AddRegIndirect(Reg, MLoc.getOffset());
    204   else
    205     Expr.AddReg(Reg);
    206 }
    207 
    208 //===----------------------------------------------------------------------===//
    209 // Dwarf Lowering Routines
    210 //===----------------------------------------------------------------------===//
    211 
    212 void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
    213   switch (Inst.getOperation()) {
    214   default:
    215     llvm_unreachable("Unexpected instruction");
    216   case MCCFIInstruction::OpDefCfaOffset:
    217     OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
    218     break;
    219   case MCCFIInstruction::OpAdjustCfaOffset:
    220     OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
    221     break;
    222   case MCCFIInstruction::OpDefCfa:
    223     OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
    224     break;
    225   case MCCFIInstruction::OpDefCfaRegister:
    226     OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
    227     break;
    228   case MCCFIInstruction::OpOffset:
    229     OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
    230     break;
    231   case MCCFIInstruction::OpRegister:
    232     OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
    233     break;
    234   case MCCFIInstruction::OpWindowSave:
    235     OutStreamer->EmitCFIWindowSave();
    236     break;
    237   case MCCFIInstruction::OpSameValue:
    238     OutStreamer->EmitCFISameValue(Inst.getRegister());
    239     break;
    240   case MCCFIInstruction::OpGnuArgsSize:
    241     OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
    242     break;
    243   case MCCFIInstruction::OpEscape:
    244     OutStreamer->EmitCFIEscape(Inst.getValues());
    245     break;
    246   }
    247 }
    248 
    249 void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
    250   // Emit the code (index) for the abbreviation.
    251   if (isVerbose())
    252     OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
    253                             Twine::utohexstr(Die.getOffset()) + ":0x" +
    254                             Twine::utohexstr(Die.getSize()) + " " +
    255                             dwarf::TagString(Die.getTag()));
    256   EmitULEB128(Die.getAbbrevNumber());
    257 
    258   // Emit the DIE attribute values.
    259   for (const auto &V : Die.values()) {
    260     dwarf::Attribute Attr = V.getAttribute();
    261     assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
    262 
    263     if (isVerbose()) {
    264       OutStreamer->AddComment(dwarf::AttributeString(Attr));
    265       if (Attr == dwarf::DW_AT_accessibility)
    266         OutStreamer->AddComment(
    267             dwarf::AccessibilityString(V.getDIEInteger().getValue()));
    268     }
    269 
    270     // Emit an attribute using the defined form.
    271     V.EmitValue(this);
    272   }
    273 
    274   // Emit the DIE children if any.
    275   if (Die.hasChildren()) {
    276     for (auto &Child : Die.children())
    277       emitDwarfDIE(Child);
    278 
    279     OutStreamer->AddComment("End Of Children Mark");
    280     EmitInt8(0);
    281   }
    282 }
    283 
    284 void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
    285   // Emit the abbreviations code (base 1 index.)
    286   EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
    287 
    288   // Emit the abbreviations data.
    289   Abbrev.Emit(this);
    290 }
    291