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