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/MCObjectStreamer.h"
     11 #include "llvm/MC/MCAsmBackend.h"
     12 #include "llvm/MC/MCAsmInfo.h"
     13 #include "llvm/MC/MCAssembler.h"
     14 #include "llvm/MC/MCCodeEmitter.h"
     15 #include "llvm/MC/MCContext.h"
     16 #include "llvm/MC/MCDwarf.h"
     17 #include "llvm/MC/MCExpr.h"
     18 #include "llvm/MC/MCObjectWriter.h"
     19 #include "llvm/MC/MCSymbol.h"
     20 #include "llvm/Support/ErrorHandling.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::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
    109   RecordProcStart(Frame);
    110 }
    111 
    112 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
    113   RecordProcEnd(Frame);
    114 }
    115 
    116 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
    117   MCStreamer::EmitLabel(Symbol);
    118 
    119   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
    120 
    121   // FIXME: This is wasteful, we don't necessarily need to create a data
    122   // fragment. Instead, we should mark the symbol as pointing into the data
    123   // fragment if it exists, otherwise we should just queue the label and set its
    124   // fragment pointer when we emit the next fragment.
    125   MCDataFragment *F = getOrCreateDataFragment();
    126   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
    127   SD.setFragment(F);
    128   SD.setOffset(F->getContents().size());
    129 }
    130 
    131 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
    132   int64_t IntValue;
    133   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    134     EmitULEB128IntValue(IntValue);
    135     return;
    136   }
    137   Value = ForceExpAbs(Value);
    138   new MCLEBFragment(*Value, false, getCurrentSectionData());
    139 }
    140 
    141 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
    142   int64_t IntValue;
    143   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    144     EmitSLEB128IntValue(IntValue);
    145     return;
    146   }
    147   Value = ForceExpAbs(Value);
    148   new MCLEBFragment(*Value, true, getCurrentSectionData());
    149 }
    150 
    151 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
    152                                          const MCSymbol *Symbol) {
    153   report_fatal_error("This file format doesn't support weak aliases.");
    154 }
    155 
    156 void MCObjectStreamer::ChangeSection(const MCSection *Section) {
    157   assert(Section && "Cannot switch to a null section!");
    158 
    159   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
    160 }
    161 
    162 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
    163   // Scan for values.
    164   for (unsigned i = Inst.getNumOperands(); i--; )
    165     if (Inst.getOperand(i).isExpr())
    166       AddValueSymbols(Inst.getOperand(i).getExpr());
    167 
    168   getCurrentSectionData()->setHasInstructions(true);
    169 
    170   // Now that a machine instruction has been assembled into this section, make
    171   // a line entry for any .loc directive that has been seen.
    172   MCLineEntry::Make(this, getCurrentSection());
    173 
    174   // If this instruction doesn't need relaxation, just emit it as data.
    175   if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) {
    176     EmitInstToData(Inst);
    177     return;
    178   }
    179 
    180   // Otherwise, if we are relaxing everything, relax the instruction as much as
    181   // possible and emit it as data.
    182   if (getAssembler().getRelaxAll()) {
    183     MCInst Relaxed;
    184     getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
    185     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
    186       getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
    187     EmitInstToData(Relaxed);
    188     return;
    189   }
    190 
    191   // Otherwise emit to a separate fragment.
    192   EmitInstToFragment(Inst);
    193 }
    194 
    195 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
    196   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
    197 
    198   SmallString<128> Code;
    199   raw_svector_ostream VecOS(Code);
    200   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
    201   VecOS.flush();
    202   IF->getCode().append(Code.begin(), Code.end());
    203 }
    204 
    205 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
    206                                                 const MCSymbol *LastLabel,
    207                                                 const MCSymbol *Label,
    208                                                 unsigned PointerSize) {
    209   if (!LastLabel) {
    210     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
    211     return;
    212   }
    213   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    214   int64_t Res;
    215   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    216     MCDwarfLineAddr::Emit(this, LineDelta, Res);
    217     return;
    218   }
    219   AddrDelta = ForceExpAbs(AddrDelta);
    220   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
    221 }
    222 
    223 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
    224                                                  const MCSymbol *Label) {
    225   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    226   int64_t Res;
    227   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    228     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
    229     return;
    230   }
    231   AddrDelta = ForceExpAbs(AddrDelta);
    232   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
    233 }
    234 
    235 bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
    236                                          unsigned char Value) {
    237   int64_t Res;
    238   if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
    239     new MCOrgFragment(*Offset, Value, getCurrentSectionData());
    240     return false;
    241   }
    242 
    243   MCSymbol *CurrentPos = getContext().CreateTempSymbol();
    244   EmitLabel(CurrentPos);
    245   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    246   const MCExpr *Ref =
    247     MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
    248   const MCExpr *Delta =
    249     MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
    250 
    251   if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
    252     return true;
    253   EmitFill(Res, Value, 0);
    254   return false;
    255 }
    256 
    257 // Associate GPRel32 fixup with data and resize data area
    258 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
    259   MCDataFragment *DF = getOrCreateDataFragment();
    260 
    261   DF->addFixup(MCFixup::Create(DF->getContents().size(),
    262                                Value,
    263                                FK_GPRel_4));
    264   DF->getContents().resize(DF->getContents().size() + 4, 0);
    265 }
    266 
    267 void MCObjectStreamer::FinishImpl() {
    268   // Dump out the dwarf file & directory tables and line tables.
    269   const MCSymbol *LineSectionSymbol = NULL;
    270   if (getContext().hasDwarfFiles())
    271     LineSectionSymbol = MCDwarfFileTable::Emit(this);
    272 
    273   // If we are generating dwarf for assembly source files dump out the sections.
    274   if (getContext().getGenDwarfForAssembly())
    275     MCGenDwarfInfo::Emit(this, LineSectionSymbol);
    276 
    277   getAssembler().Finish();
    278 }
    279