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/ADT/STLExtras.h"
     12 #include "llvm/MC/MCAsmBackend.h"
     13 #include "llvm/MC/MCAsmInfo.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/MCObjectWriter.h"
     20 #include "llvm/MC/MCSection.h"
     21 #include "llvm/MC/MCSymbol.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include "llvm/Support/TargetRegistry.h"
     24 using namespace llvm;
     25 
     26 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
     27                                    raw_pwrite_stream &OS,
     28                                    MCCodeEmitter *Emitter_)
     29     : MCStreamer(Context),
     30       Assembler(new MCAssembler(Context, TAB, *Emitter_,
     31                                 *TAB.createObjectWriter(OS))),
     32       EmitEHFrame(true), EmitDebugFrame(false) {}
     33 
     34 MCObjectStreamer::~MCObjectStreamer() {
     35   delete &Assembler->getBackend();
     36   delete &Assembler->getEmitter();
     37   delete &Assembler->getWriter();
     38   delete Assembler;
     39 }
     40 
     41 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
     42   if (PendingLabels.empty())
     43     return;
     44   if (!F) {
     45     F = new MCDataFragment();
     46     MCSection *CurSection = getCurrentSectionOnly();
     47     CurSection->getFragmentList().insert(CurInsertionPoint, F);
     48     F->setParent(CurSection);
     49   }
     50   for (MCSymbol *Sym : PendingLabels) {
     51     Sym->setFragment(F);
     52     Sym->setOffset(FOffset);
     53   }
     54   PendingLabels.clear();
     55 }
     56 
     57 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
     58                                               const MCSymbol *Lo,
     59                                               unsigned Size) {
     60   // If not assigned to the same (valid) fragment, fallback.
     61   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
     62       Hi->isVariable() || Lo->isVariable()) {
     63     MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
     64     return;
     65   }
     66 
     67   assert(Hi->getOffset() >= Lo->getOffset() &&
     68          "Expected Hi to be greater than Lo");
     69   EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
     70 }
     71 
     72 void MCObjectStreamer::reset() {
     73   if (Assembler)
     74     Assembler->reset();
     75   CurInsertionPoint = MCSection::iterator();
     76   EmitEHFrame = true;
     77   EmitDebugFrame = false;
     78   PendingLabels.clear();
     79   MCStreamer::reset();
     80 }
     81 
     82 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
     83   if (!getNumFrameInfos())
     84     return;
     85 
     86   if (EmitEHFrame)
     87     MCDwarfFrameEmitter::Emit(*this, MAB, true);
     88 
     89   if (EmitDebugFrame)
     90     MCDwarfFrameEmitter::Emit(*this, MAB, false);
     91 }
     92 
     93 MCFragment *MCObjectStreamer::getCurrentFragment() const {
     94   assert(getCurrentSectionOnly() && "No current section!");
     95 
     96   if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
     97     return &*std::prev(CurInsertionPoint);
     98 
     99   return nullptr;
    100 }
    101 
    102 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
    103   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
    104   // When bundling is enabled, we don't want to add data to a fragment that
    105   // already has instructions (see MCELFStreamer::EmitInstToData for details)
    106   if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() &&
    107              F->hasInstructions())) {
    108     F = new MCDataFragment();
    109     insert(F);
    110   }
    111   return F;
    112 }
    113 
    114 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
    115   Assembler->registerSymbol(Sym);
    116 }
    117 
    118 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
    119   MCStreamer::EmitCFISections(EH, Debug);
    120   EmitEHFrame = EH;
    121   EmitDebugFrame = Debug;
    122 }
    123 
    124 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
    125                                      SMLoc Loc) {
    126   MCStreamer::EmitValueImpl(Value, Size, Loc);
    127   MCDataFragment *DF = getOrCreateDataFragment();
    128   flushPendingLabels(DF, DF->getContents().size());
    129 
    130   MCLineEntry::Make(this, getCurrentSection().first);
    131 
    132   // Avoid fixups when possible.
    133   int64_t AbsValue;
    134   if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) {
    135     EmitIntValue(AbsValue, Size);
    136     return;
    137   }
    138   DF->getFixups().push_back(
    139       MCFixup::create(DF->getContents().size(), Value,
    140                       MCFixup::getKindForSize(Size, false), Loc));
    141   DF->getContents().resize(DF->getContents().size() + Size, 0);
    142 }
    143 
    144 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
    145   // We need to create a local symbol to avoid relocations.
    146   Frame.Begin = getContext().createTempSymbol();
    147   EmitLabel(Frame.Begin);
    148 }
    149 
    150 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
    151   Frame.End = getContext().createTempSymbol();
    152   EmitLabel(Frame.End);
    153 }
    154 
    155 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
    156   MCStreamer::EmitLabel(Symbol);
    157 
    158   getAssembler().registerSymbol(*Symbol);
    159 
    160   // If there is a current fragment, mark the symbol as pointing into it.
    161   // Otherwise queue the label and set its fragment pointer when we emit the
    162   // next fragment.
    163   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
    164   if (F && !(getAssembler().isBundlingEnabled() &&
    165              getAssembler().getRelaxAll())) {
    166     Symbol->setFragment(F);
    167     Symbol->setOffset(F->getContents().size());
    168   } else {
    169     PendingLabels.push_back(Symbol);
    170   }
    171 }
    172 
    173 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
    174   int64_t IntValue;
    175   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
    176     EmitULEB128IntValue(IntValue);
    177     return;
    178   }
    179   insert(new MCLEBFragment(*Value, false));
    180 }
    181 
    182 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
    183   int64_t IntValue;
    184   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
    185     EmitSLEB128IntValue(IntValue);
    186     return;
    187   }
    188   insert(new MCLEBFragment(*Value, true));
    189 }
    190 
    191 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
    192                                          const MCSymbol *Symbol) {
    193   report_fatal_error("This file format doesn't support weak aliases.");
    194 }
    195 
    196 void MCObjectStreamer::ChangeSection(MCSection *Section,
    197                                      const MCExpr *Subsection) {
    198   changeSectionImpl(Section, Subsection);
    199 }
    200 
    201 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
    202                                          const MCExpr *Subsection) {
    203   assert(Section && "Cannot switch to a null section!");
    204   flushPendingLabels(nullptr);
    205 
    206   bool Created = getAssembler().registerSection(*Section);
    207 
    208   int64_t IntSubsection = 0;
    209   if (Subsection &&
    210       !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler()))
    211     report_fatal_error("Cannot evaluate subsection number");
    212   if (IntSubsection < 0 || IntSubsection > 8192)
    213     report_fatal_error("Subsection number out of range");
    214   CurInsertionPoint =
    215       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
    216   return Created;
    217 }
    218 
    219 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
    220   getAssembler().registerSymbol(*Symbol);
    221   MCStreamer::EmitAssignment(Symbol, Value);
    222 }
    223 
    224 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
    225   return Sec.hasInstructions();
    226 }
    227 
    228 void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
    229                                        const MCSubtargetInfo &STI) {
    230   MCStreamer::EmitInstruction(Inst, STI);
    231 
    232   MCSection *Sec = getCurrentSectionOnly();
    233   Sec->setHasInstructions(true);
    234 
    235   // Now that a machine instruction has been assembled into this section, make
    236   // a line entry for any .loc directive that has been seen.
    237   MCLineEntry::Make(this, getCurrentSection().first);
    238 
    239   // If this instruction doesn't need relaxation, just emit it as data.
    240   MCAssembler &Assembler = getAssembler();
    241   if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
    242     EmitInstToData(Inst, STI);
    243     return;
    244   }
    245 
    246   // Otherwise, relax and emit it as data if either:
    247   // - The RelaxAll flag was passed
    248   // - Bundling is enabled and this instruction is inside a bundle-locked
    249   //   group. We want to emit all such instructions into the same data
    250   //   fragment.
    251   if (Assembler.getRelaxAll() ||
    252       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
    253     MCInst Relaxed;
    254     getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
    255     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
    256       getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
    257     EmitInstToData(Relaxed, STI);
    258     return;
    259   }
    260 
    261   // Otherwise emit to a separate fragment.
    262   EmitInstToFragment(Inst, STI);
    263 }
    264 
    265 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
    266                                           const MCSubtargetInfo &STI) {
    267   if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
    268     llvm_unreachable("All instructions should have already been relaxed");
    269 
    270   // Always create a new, separate fragment here, because its size can change
    271   // during relaxation.
    272   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
    273   insert(IF);
    274 
    275   SmallString<128> Code;
    276   raw_svector_ostream VecOS(Code);
    277   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
    278                                                 STI);
    279   IF->getContents().append(Code.begin(), Code.end());
    280 }
    281 
    282 #ifndef NDEBUG
    283 static const char *const BundlingNotImplementedMsg =
    284   "Aligned bundling is not implemented for this object format";
    285 #endif
    286 
    287 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
    288   llvm_unreachable(BundlingNotImplementedMsg);
    289 }
    290 
    291 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
    292   llvm_unreachable(BundlingNotImplementedMsg);
    293 }
    294 
    295 void MCObjectStreamer::EmitBundleUnlock() {
    296   llvm_unreachable(BundlingNotImplementedMsg);
    297 }
    298 
    299 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
    300                                              unsigned Column, unsigned Flags,
    301                                              unsigned Isa,
    302                                              unsigned Discriminator,
    303                                              StringRef FileName) {
    304   // In case we see two .loc directives in a row, make sure the
    305   // first one gets a line entry.
    306   MCLineEntry::Make(this, getCurrentSection().first);
    307 
    308   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
    309                                           Isa, Discriminator, FileName);
    310 }
    311 
    312 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
    313                                      const MCSymbol *B) {
    314   MCContext &Context = OS.getContext();
    315   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
    316   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
    317   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
    318   const MCExpr *AddrDelta =
    319       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
    320   return AddrDelta;
    321 }
    322 
    323 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
    324                                  MCDwarfLineTableParams Params,
    325                                  int64_t LineDelta, const MCSymbol *Label,
    326                                  int PointerSize) {
    327   // emit the sequence to set the address
    328   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
    329   OS.EmitULEB128IntValue(PointerSize + 1);
    330   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
    331   OS.EmitSymbolValue(Label, PointerSize);
    332 
    333   // emit the sequence for the LineDelta (from 1) and a zero address delta.
    334   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
    335 }
    336 
    337 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
    338                                                 const MCSymbol *LastLabel,
    339                                                 const MCSymbol *Label,
    340                                                 unsigned PointerSize) {
    341   if (!LastLabel) {
    342     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
    343                          Label, PointerSize);
    344     return;
    345   }
    346   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
    347   int64_t Res;
    348   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
    349     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
    350                           Res);
    351     return;
    352   }
    353   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
    354 }
    355 
    356 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
    357                                                  const MCSymbol *Label) {
    358   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
    359   int64_t Res;
    360   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
    361     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
    362     return;
    363   }
    364   insert(new MCDwarfCallFrameFragment(*AddrDelta));
    365 }
    366 
    367 void MCObjectStreamer::EmitBytes(StringRef Data) {
    368   MCLineEntry::Make(this, getCurrentSection().first);
    369   MCDataFragment *DF = getOrCreateDataFragment();
    370   flushPendingLabels(DF, DF->getContents().size());
    371   DF->getContents().append(Data.begin(), Data.end());
    372 }
    373 
    374 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
    375                                             int64_t Value,
    376                                             unsigned ValueSize,
    377                                             unsigned MaxBytesToEmit) {
    378   if (MaxBytesToEmit == 0)
    379     MaxBytesToEmit = ByteAlignment;
    380   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
    381 
    382   // Update the maximum alignment on the current section if necessary.
    383   MCSection *CurSec = getCurrentSection().first;
    384   if (ByteAlignment > CurSec->getAlignment())
    385     CurSec->setAlignment(ByteAlignment);
    386 }
    387 
    388 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
    389                                          unsigned MaxBytesToEmit) {
    390   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
    391   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
    392 }
    393 
    394 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
    395                                          unsigned char Value) {
    396   insert(new MCOrgFragment(*Offset, Value));
    397 }
    398 
    399 // Associate GPRel32 fixup with data and resize data area
    400 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
    401   MCDataFragment *DF = getOrCreateDataFragment();
    402   flushPendingLabels(DF, DF->getContents().size());
    403 
    404   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
    405                                             Value, FK_GPRel_4));
    406   DF->getContents().resize(DF->getContents().size() + 4, 0);
    407 }
    408 
    409 // Associate GPRel32 fixup with data and resize data area
    410 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
    411   MCDataFragment *DF = getOrCreateDataFragment();
    412   flushPendingLabels(DF, DF->getContents().size());
    413 
    414   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
    415                                             Value, FK_GPRel_4));
    416   DF->getContents().resize(DF->getContents().size() + 8, 0);
    417 }
    418 
    419 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
    420                                           const MCExpr *Expr, SMLoc Loc) {
    421   int64_t OffsetValue;
    422   if (!Offset.evaluateAsAbsolute(OffsetValue))
    423     llvm_unreachable("Offset is not absolute");
    424 
    425   MCDataFragment *DF = getOrCreateDataFragment();
    426   flushPendingLabels(DF, DF->getContents().size());
    427 
    428   MCFixupKind Kind;
    429   if (!Assembler->getBackend().getFixupKind(Name, Kind))
    430     return true;
    431 
    432   if (Expr == nullptr)
    433     Expr =
    434         MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
    435   DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
    436   return false;
    437 }
    438 
    439 void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
    440   const MCSection *Sec = getCurrentSection().first;
    441   assert(Sec && "need a section");
    442   unsigned ItemSize = Sec->isVirtualSection() ? 0 : 1;
    443   insert(new MCFillFragment(FillValue, ItemSize, NumBytes));
    444 }
    445 
    446 void MCObjectStreamer::FinishImpl() {
    447   // If we are generating dwarf for assembly source files dump out the sections.
    448   if (getContext().getGenDwarfForAssembly())
    449     MCGenDwarfInfo::Emit(this);
    450 
    451   // Dump out the dwarf file & directory tables and line tables.
    452   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
    453 
    454   flushPendingLabels(nullptr);
    455   getAssembler().Finish();
    456 }
    457