Home | History | Annotate | Download | only in MC
      1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
      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 #include "llvm/MC/MCAsmInfo.h"
     11 #include "llvm/MC/MCObjectStreamer.h"
     12 
     13 #include "llvm/Support/ErrorHandling.h"
     14 #include "llvm/MC/MCAssembler.h"
     15 #include "llvm/MC/MCCodeEmitter.h"
     16 #include "llvm/MC/MCContext.h"
     17 #include "llvm/MC/MCDwarf.h"
     18 #include "llvm/MC/MCExpr.h"
     19 #include "llvm/MC/MCSymbol.h"
     20 #include "llvm/MC/MCAsmBackend.h"
     21 using namespace llvm;
     22 
     23 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
     24                                    raw_ostream &OS, MCCodeEmitter *Emitter_)
     25   : MCStreamer(Context),
     26     Assembler(new MCAssembler(Context, TAB,
     27                               *Emitter_, *TAB.createObjectWriter(OS),
     28                               OS)),
     29     CurSectionData(0)
     30 {
     31 }
     32 
     33 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
     34                                    raw_ostream &OS, MCCodeEmitter *Emitter_,
     35                                    MCAssembler *_Assembler)
     36   : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
     37 {
     38 }
     39 
     40 MCObjectStreamer::~MCObjectStreamer() {
     41   delete &Assembler->getBackend();
     42   delete &Assembler->getEmitter();
     43   delete &Assembler->getWriter();
     44   delete Assembler;
     45 }
     46 
     47 MCFragment *MCObjectStreamer::getCurrentFragment() const {
     48   assert(getCurrentSectionData() && "No current section!");
     49 
     50   if (!getCurrentSectionData()->empty())
     51     return &getCurrentSectionData()->getFragmentList().back();
     52 
     53   return 0;
     54 }
     55 
     56 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
     57   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     58   if (!F)
     59     F = new MCDataFragment(getCurrentSectionData());
     60   return F;
     61 }
     62 
     63 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
     64   switch (Value->getKind()) {
     65   case MCExpr::Target:
     66     cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
     67     break;
     68 
     69   case MCExpr::Constant:
     70     break;
     71 
     72   case MCExpr::Binary: {
     73     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
     74     AddValueSymbols(BE->getLHS());
     75     AddValueSymbols(BE->getRHS());
     76     break;
     77   }
     78 
     79   case MCExpr::SymbolRef:
     80     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
     81     break;
     82 
     83   case MCExpr::Unary:
     84     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
     85     break;
     86   }
     87 
     88   return Value;
     89 }
     90 
     91 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     92                                      unsigned AddrSpace) {
     93   assert(AddrSpace == 0 && "Address space must be 0!");
     94   MCDataFragment *DF = getOrCreateDataFragment();
     95 
     96   // Avoid fixups when possible.
     97   int64_t AbsValue;
     98   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
     99     EmitIntValue(AbsValue, Size, AddrSpace);
    100     return;
    101   }
    102   DF->addFixup(MCFixup::Create(DF->getContents().size(),
    103                                Value,
    104                                MCFixup::getKindForSize(Size, false)));
    105   DF->getContents().resize(DF->getContents().size() + Size, 0);
    106 }
    107 
    108 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
    109   MCStreamer::EmitLabel(Symbol);
    110 
    111   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
    112 
    113   // FIXME: This is wasteful, we don't necessarily need to create a data
    114   // fragment. Instead, we should mark the symbol as pointing into the data
    115   // fragment if it exists, otherwise we should just queue the label and set its
    116   // fragment pointer when we emit the next fragment.
    117   MCDataFragment *F = getOrCreateDataFragment();
    118   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
    119   SD.setFragment(F);
    120   SD.setOffset(F->getContents().size());
    121 }
    122 
    123 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
    124   int64_t IntValue;
    125   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    126     EmitULEB128IntValue(IntValue);
    127     return;
    128   }
    129   Value = ForceExpAbs(Value);
    130   new MCLEBFragment(*Value, false, getCurrentSectionData());
    131 }
    132 
    133 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
    134   int64_t IntValue;
    135   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    136     EmitSLEB128IntValue(IntValue);
    137     return;
    138   }
    139   Value = ForceExpAbs(Value);
    140   new MCLEBFragment(*Value, true, getCurrentSectionData());
    141 }
    142 
    143 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
    144                                          const MCSymbol *Symbol) {
    145   report_fatal_error("This file format doesn't support weak aliases.");
    146 }
    147 
    148 void MCObjectStreamer::ChangeSection(const MCSection *Section) {
    149   assert(Section && "Cannot switch to a null section!");
    150 
    151   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
    152 }
    153 
    154 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
    155   // Scan for values.
    156   for (unsigned i = Inst.getNumOperands(); i--; )
    157     if (Inst.getOperand(i).isExpr())
    158       AddValueSymbols(Inst.getOperand(i).getExpr());
    159 
    160   getCurrentSectionData()->setHasInstructions(true);
    161 
    162   // Now that a machine instruction has been assembled into this section, make
    163   // a line entry for any .loc directive that has been seen.
    164   MCLineEntry::Make(this, getCurrentSection());
    165 
    166   // If this instruction doesn't need relaxation, just emit it as data.
    167   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
    168     EmitInstToData(Inst);
    169     return;
    170   }
    171 
    172   // Otherwise, if we are relaxing everything, relax the instruction as much as
    173   // possible and emit it as data.
    174   if (getAssembler().getRelaxAll()) {
    175     MCInst Relaxed;
    176     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
    177     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
    178       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
    179     EmitInstToData(Relaxed);
    180     return;
    181   }
    182 
    183   // Otherwise emit to a separate fragment.
    184   EmitInstToFragment(Inst);
    185 }
    186 
    187 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
    188   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
    189 
    190   SmallString<128> Code;
    191   raw_svector_ostream VecOS(Code);
    192   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
    193   VecOS.flush();
    194   IF->getCode().append(Code.begin(), Code.end());
    195 }
    196 
    197 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
    198                                                 const MCSymbol *LastLabel,
    199                                                 const MCSymbol *Label,
    200                                                 unsigned PointerSize) {
    201   if (!LastLabel) {
    202     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
    203     return;
    204   }
    205   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    206   int64_t Res;
    207   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    208     MCDwarfLineAddr::Emit(this, LineDelta, Res);
    209     return;
    210   }
    211   AddrDelta = ForceExpAbs(AddrDelta);
    212   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
    213 }
    214 
    215 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
    216                                                  const MCSymbol *Label) {
    217   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    218   int64_t Res;
    219   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    220     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
    221     return;
    222   }
    223   AddrDelta = ForceExpAbs(AddrDelta);
    224   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
    225 }
    226 
    227 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
    228                                         unsigned char Value) {
    229   int64_t Res;
    230   if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
    231     new MCOrgFragment(*Offset, Value, getCurrentSectionData());
    232     return;
    233   }
    234 
    235   MCSymbol *CurrentPos = getContext().CreateTempSymbol();
    236   EmitLabel(CurrentPos);
    237   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    238   const MCExpr *Ref =
    239     MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
    240   const MCExpr *Delta =
    241     MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
    242 
    243   if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
    244     report_fatal_error("expected assembly-time absolute expression");
    245   EmitFill(Res, Value, 0);
    246 }
    247 
    248 void MCObjectStreamer::Finish() {
    249   // Dump out the dwarf file & directory tables and line tables.
    250   if (getContext().hasDwarfFiles())
    251     MCDwarfFileTable::Emit(this);
    252 
    253   getAssembler().Finish();
    254 }
    255