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(StreamerKind Kind, MCContext &Context,
     24                                    MCAsmBackend &TAB, raw_ostream &OS,
     25                                    MCCodeEmitter *Emitter_)
     26     : MCStreamer(Kind, Context),
     27       Assembler(new MCAssembler(Context, TAB, *Emitter_,
     28                                 *TAB.createObjectWriter(OS), OS)),
     29       CurSectionData(0) {}
     30 
     31 MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
     32                                    MCAsmBackend &TAB, raw_ostream &OS,
     33                                    MCCodeEmitter *Emitter_,
     34                                    MCAssembler *_Assembler)
     35     : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
     36 
     37 MCObjectStreamer::~MCObjectStreamer() {
     38   delete &Assembler->getBackend();
     39   delete &Assembler->getEmitter();
     40   delete &Assembler->getWriter();
     41   delete Assembler;
     42 }
     43 
     44 void MCObjectStreamer::reset() {
     45   if (Assembler)
     46     Assembler->reset();
     47   CurSectionData = 0;
     48   MCStreamer::reset();
     49 }
     50 
     51 MCFragment *MCObjectStreamer::getCurrentFragment() const {
     52   assert(getCurrentSectionData() && "No current section!");
     53 
     54   if (!getCurrentSectionData()->empty())
     55     return &getCurrentSectionData()->getFragmentList().back();
     56 
     57   return 0;
     58 }
     59 
     60 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
     61   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     62   // When bundling is enabled, we don't want to add data to a fragment that
     63   // already has instructions (see MCELFStreamer::EmitInstToData for details)
     64   if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions()))
     65     F = new MCDataFragment(getCurrentSectionData());
     66   return F;
     67 }
     68 
     69 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
     70   switch (Value->getKind()) {
     71   case MCExpr::Target:
     72     cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
     73     break;
     74 
     75   case MCExpr::Constant:
     76     break;
     77 
     78   case MCExpr::Binary: {
     79     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
     80     AddValueSymbols(BE->getLHS());
     81     AddValueSymbols(BE->getRHS());
     82     break;
     83   }
     84 
     85   case MCExpr::SymbolRef:
     86     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
     87     break;
     88 
     89   case MCExpr::Unary:
     90     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
     91     break;
     92   }
     93 
     94   return Value;
     95 }
     96 
     97 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     98                                      unsigned AddrSpace) {
     99   assert(AddrSpace == 0 && "Address space must be 0!");
    100   MCDataFragment *DF = getOrCreateDataFragment();
    101 
    102   // Avoid fixups when possible.
    103   int64_t AbsValue;
    104   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
    105     EmitIntValue(AbsValue, Size, AddrSpace);
    106     return;
    107   }
    108   DF->getFixups().push_back(
    109       MCFixup::Create(DF->getContents().size(), Value,
    110                       MCFixup::getKindForSize(Size, false)));
    111   DF->getContents().resize(DF->getContents().size() + Size, 0);
    112 }
    113 
    114 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
    115   RecordProcStart(Frame);
    116 }
    117 
    118 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
    119   RecordProcEnd(Frame);
    120 }
    121 
    122 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
    123   MCStreamer::EmitLabel(Symbol);
    124 
    125   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
    126 
    127   // FIXME: This is wasteful, we don't necessarily need to create a data
    128   // fragment. Instead, we should mark the symbol as pointing into the data
    129   // fragment if it exists, otherwise we should just queue the label and set its
    130   // fragment pointer when we emit the next fragment.
    131   MCDataFragment *F = getOrCreateDataFragment();
    132   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
    133   SD.setFragment(F);
    134   SD.setOffset(F->getContents().size());
    135 }
    136 
    137 void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
    138   EmitLabel(Symbol);
    139 }
    140 
    141 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
    142   int64_t IntValue;
    143   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    144     EmitULEB128IntValue(IntValue);
    145     return;
    146   }
    147   Value = ForceExpAbs(Value);
    148   new MCLEBFragment(*Value, false, getCurrentSectionData());
    149 }
    150 
    151 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
    152   int64_t IntValue;
    153   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
    154     EmitSLEB128IntValue(IntValue);
    155     return;
    156   }
    157   Value = ForceExpAbs(Value);
    158   new MCLEBFragment(*Value, true, getCurrentSectionData());
    159 }
    160 
    161 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
    162                                          const MCSymbol *Symbol) {
    163   report_fatal_error("This file format doesn't support weak aliases.");
    164 }
    165 
    166 void MCObjectStreamer::ChangeSection(const MCSection *Section) {
    167   assert(Section && "Cannot switch to a null section!");
    168 
    169   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
    170 }
    171 
    172 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
    173   getAssembler().getOrCreateSymbolData(*Symbol);
    174   Symbol->setVariableValue(AddValueSymbols(Value));
    175 }
    176 
    177 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
    178   // Scan for values.
    179   for (unsigned i = Inst.getNumOperands(); i--; )
    180     if (Inst.getOperand(i).isExpr())
    181       AddValueSymbols(Inst.getOperand(i).getExpr());
    182 
    183   MCSectionData *SD = getCurrentSectionData();
    184   SD->setHasInstructions(true);
    185 
    186   // Now that a machine instruction has been assembled into this section, make
    187   // a line entry for any .loc directive that has been seen.
    188   MCLineEntry::Make(this, getCurrentSection());
    189 
    190   // If this instruction doesn't need relaxation, just emit it as data.
    191   MCAssembler &Assembler = getAssembler();
    192   if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
    193     EmitInstToData(Inst);
    194     return;
    195   }
    196 
    197   // Otherwise, relax and emit it as data if either:
    198   // - The RelaxAll flag was passed
    199   // - Bundling is enabled and this instruction is inside a bundle-locked
    200   //   group. We want to emit all such instructions into the same data
    201   //   fragment.
    202   if (Assembler.getRelaxAll() ||
    203       (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
    204     MCInst Relaxed;
    205     getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
    206     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
    207       getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
    208     EmitInstToData(Relaxed);
    209     return;
    210   }
    211 
    212   // Otherwise emit to a separate fragment.
    213   EmitInstToFragment(Inst);
    214 }
    215 
    216 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
    217   // Always create a new, separate fragment here, because its size can change
    218   // during relaxation.
    219   MCRelaxableFragment *IF =
    220     new MCRelaxableFragment(Inst, getCurrentSectionData());
    221 
    222   SmallString<128> Code;
    223   raw_svector_ostream VecOS(Code);
    224   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
    225   VecOS.flush();
    226   IF->getContents().append(Code.begin(), Code.end());
    227 }
    228 
    229 #ifndef NDEBUG
    230 static const char *BundlingNotImplementedMsg =
    231   "Aligned bundling is not implemented for this object format";
    232 #endif
    233 
    234 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
    235   llvm_unreachable(BundlingNotImplementedMsg);
    236 }
    237 
    238 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
    239   llvm_unreachable(BundlingNotImplementedMsg);
    240 }
    241 
    242 void MCObjectStreamer::EmitBundleUnlock() {
    243   llvm_unreachable(BundlingNotImplementedMsg);
    244 }
    245 
    246 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
    247                                                 const MCSymbol *LastLabel,
    248                                                 const MCSymbol *Label,
    249                                                 unsigned PointerSize) {
    250   if (!LastLabel) {
    251     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
    252     return;
    253   }
    254   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    255   int64_t Res;
    256   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    257     MCDwarfLineAddr::Emit(this, LineDelta, Res);
    258     return;
    259   }
    260   AddrDelta = ForceExpAbs(AddrDelta);
    261   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
    262 }
    263 
    264 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
    265                                                  const MCSymbol *Label) {
    266   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
    267   int64_t Res;
    268   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
    269     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
    270     return;
    271   }
    272   AddrDelta = ForceExpAbs(AddrDelta);
    273   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
    274 }
    275 
    276 void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
    277   assert(AddrSpace == 0 && "Address space must be 0!");
    278   getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
    279 }
    280 
    281 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
    282                                             int64_t Value,
    283                                             unsigned ValueSize,
    284                                             unsigned MaxBytesToEmit) {
    285   if (MaxBytesToEmit == 0)
    286     MaxBytesToEmit = ByteAlignment;
    287   new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
    288                       getCurrentSectionData());
    289 
    290   // Update the maximum alignment on the current section if necessary.
    291   if (ByteAlignment > getCurrentSectionData()->getAlignment())
    292     getCurrentSectionData()->setAlignment(ByteAlignment);
    293 }
    294 
    295 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
    296                                          unsigned MaxBytesToEmit) {
    297   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
    298   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
    299 }
    300 
    301 bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
    302                                          unsigned char Value) {
    303   int64_t Res;
    304   if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
    305     new MCOrgFragment(*Offset, Value, getCurrentSectionData());
    306     return false;
    307   }
    308 
    309   MCSymbol *CurrentPos = getContext().CreateTempSymbol();
    310   EmitLabel(CurrentPos);
    311   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    312   const MCExpr *Ref =
    313     MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
    314   const MCExpr *Delta =
    315     MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
    316 
    317   if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
    318     return true;
    319   EmitFill(Res, Value);
    320   return false;
    321 }
    322 
    323 // Associate GPRel32 fixup with data and resize data area
    324 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
    325   MCDataFragment *DF = getOrCreateDataFragment();
    326 
    327   DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
    328                                             Value, FK_GPRel_4));
    329   DF->getContents().resize(DF->getContents().size() + 4, 0);
    330 }
    331 
    332 // Associate GPRel32 fixup with data and resize data area
    333 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
    334   MCDataFragment *DF = getOrCreateDataFragment();
    335 
    336   DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
    337                                             Value, FK_GPRel_4));
    338   DF->getContents().resize(DF->getContents().size() + 8, 0);
    339 }
    340 
    341 void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
    342                                 unsigned AddrSpace) {
    343   assert(AddrSpace == 0 && "Address space must be 0!");
    344   // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
    345   //        problems evaluating expressions across multiple fragments.
    346   getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
    347 }
    348 
    349 void MCObjectStreamer::FinishImpl() {
    350   // Dump out the dwarf file & directory tables and line tables.
    351   const MCSymbol *LineSectionSymbol = NULL;
    352   if (getContext().hasDwarfFiles())
    353     LineSectionSymbol = MCDwarfFileTable::Emit(this);
    354 
    355   // If we are generating dwarf for assembly source files dump out the sections.
    356   if (getContext().getGenDwarfForAssembly())
    357     MCGenDwarfInfo::Emit(this, LineSectionSymbol);
    358 
    359   getAssembler().Finish();
    360 }
    361