LCOV - code coverage report
Current view: top level - lib/MC - MCObjectStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 324 345 93.9 %
Date: 2018-09-23 13:06:45 Functions: 59 65 90.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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/MCAssembler.h"
      14             : #include "llvm/MC/MCCodeEmitter.h"
      15             : #include "llvm/MC/MCCodeView.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/SourceMgr.h"
      24             : using namespace llvm;
      25             : 
      26       13613 : MCObjectStreamer::MCObjectStreamer(MCContext &Context,
      27             :                                    std::unique_ptr<MCAsmBackend> TAB,
      28             :                                    std::unique_ptr<MCObjectWriter> OW,
      29       13613 :                                    std::unique_ptr<MCCodeEmitter> Emitter)
      30             :     : MCStreamer(Context),
      31             :       Assembler(llvm::make_unique<MCAssembler>(
      32             :           Context, std::move(TAB), std::move(Emitter), std::move(OW))),
      33       13613 :       EmitEHFrame(true), EmitDebugFrame(false) {}
      34             : 
      35       18873 : MCObjectStreamer::~MCObjectStreamer() {}
      36             : 
      37             : // AssemblerPtr is used for evaluation of expressions and causes
      38             : // difference between asm and object outputs. Return nullptr to in
      39             : // inline asm mode to limit divergence to assembly inputs.
      40     5050627 : MCAssembler *MCObjectStreamer::getAssemblerPtr() {
      41     5050627 :   if (getUseAssemblerInfoForParsing())
      42       17001 :     return Assembler.get();
      43             :   return nullptr;
      44             : }
      45             : 
      46    28535870 : void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
      47    28535870 :   if (PendingLabels.empty())
      48             :     return;
      49      823230 :   if (!F) {
      50       12772 :     F = new MCDataFragment();
      51             :     MCSection *CurSection = getCurrentSectionOnly();
      52             :     CurSection->getFragmentList().insert(CurInsertionPoint, F);
      53             :     F->setParent(CurSection);
      54             :   }
      55     2183797 :   for (MCSymbol *Sym : PendingLabels) {
      56             :     Sym->setFragment(F);
      57             :     Sym->setOffset(FOffset);
      58             :   }
      59             :   PendingLabels.clear();
      60             : }
      61             : 
      62             : // As a compile-time optimization, avoid allocating and evaluating an MCExpr
      63             : // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
      64             : static Optional<uint64_t>
      65     1713147 : absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
      66             :   assert(Hi && Lo);
      67     1713147 :   if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
      68           0 :     return None;
      69             : 
      70     3342370 :   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
      71     3213024 :       Hi->isVariable() || Lo->isVariable())
      72      213287 :     return None;
      73             : 
      74     1499860 :   return Hi->getOffset() - Lo->getOffset();
      75             : }
      76             : 
      77      132360 : void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
      78             :                                               const MCSymbol *Lo,
      79             :                                               unsigned Size) {
      80      132360 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
      81       89975 :     EmitIntValue(*Diff, Size);
      82       89975 :     return;
      83             :   }
      84       42385 :   MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
      85             : }
      86             : 
      87     1580787 : void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
      88             :                                                        const MCSymbol *Lo) {
      89     1580787 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
      90     1409885 :     EmitULEB128IntValue(*Diff);
      91     1409885 :     return;
      92             :   }
      93      170902 :   MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
      94             : }
      95             : 
      96        9343 : void MCObjectStreamer::reset() {
      97        9343 :   if (Assembler)
      98        9343 :     Assembler->reset();
      99        9343 :   CurInsertionPoint = MCSection::iterator();
     100        9343 :   EmitEHFrame = true;
     101        9343 :   EmitDebugFrame = false;
     102             :   PendingLabels.clear();
     103        9343 :   MCStreamer::reset();
     104        9343 : }
     105             : 
     106       13501 : void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
     107       13501 :   if (!getNumFrameInfos())
     108             :     return;
     109             : 
     110        8184 :   if (EmitEHFrame)
     111        8084 :     MCDwarfFrameEmitter::Emit(*this, MAB, true);
     112             : 
     113        8184 :   if (EmitDebugFrame)
     114         100 :     MCDwarfFrameEmitter::Emit(*this, MAB, false);
     115             : }
     116             : 
     117    91743622 : MCFragment *MCObjectStreamer::getCurrentFragment() const {
     118             :   assert(getCurrentSectionOnly() && "No current section!");
     119             : 
     120    91743622 :   if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
     121             :     return &*std::prev(CurInsertionPoint);
     122             : 
     123             :   return nullptr;
     124             : }
     125             : 
     126             : static bool CanReuseDataFragment(const MCDataFragment &F,
     127             :                                  const MCAssembler &Assembler,
     128             :                                  const MCSubtargetInfo *STI) {
     129    48929716 :   if (!F.hasInstructions())
     130             :     return true;
     131             :   // When bundling is enabled, we don't want to add data to a fragment that
     132             :   // already has instructions (see MCELFStreamer::EmitInstToData for details)
     133    30543575 :   if (Assembler.isBundlingEnabled())
     134             :     return Assembler.getRelaxAll();
     135             :   // If the subtarget is changed mid fragment we start a new fragment to record
     136             :   // the new STI.
     137    30543449 :   return !STI || F.getSubtargetInfo() == STI;
     138             : }
     139             : 
     140             : MCDataFragment *
     141    51871298 : MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
     142    51871298 :   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     143         126 :   if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
     144     2941642 :     F = new MCDataFragment();
     145     2941641 :     insert(F);
     146             :   }
     147    51871299 :   return F;
     148             : }
     149             : 
     150           0 : MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() {
     151             :   MCPaddingFragment *F =
     152           0 :       dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment());
     153             :   if (!F) {
     154           0 :     F = new MCPaddingFragment();
     155           0 :     insert(F);
     156             :   }
     157           0 :   return F;
     158             : }
     159             : 
     160     9665887 : void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
     161     9665887 :   Assembler->registerSymbol(Sym);
     162     9665887 : }
     163             : 
     164         100 : void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
     165         100 :   MCStreamer::EmitCFISections(EH, Debug);
     166         100 :   EmitEHFrame = EH;
     167         100 :   EmitDebugFrame = Debug;
     168         100 : }
     169             : 
     170     2973255 : void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     171             :                                      SMLoc Loc) {
     172     2973255 :   MCStreamer::EmitValueImpl(Value, Size, Loc);
     173     2973255 :   MCDataFragment *DF = getOrCreateDataFragment();
     174     5946510 :   flushPendingLabels(DF, DF->getContents().size());
     175             : 
     176     2973255 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     177             : 
     178             :   // Avoid fixups when possible.
     179             :   int64_t AbsValue;
     180     2973255 :   if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
     181       14433 :     if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
     182           2 :       getContext().reportError(
     183           1 :           Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
     184       14433 :       return;
     185             :     }
     186       14432 :     EmitIntValue(AbsValue, Size);
     187       14432 :     return;
     188             :   }
     189     5917416 :   DF->getFixups().push_back(
     190     2958822 :       MCFixup::create(DF->getContents().size(), Value,
     191             :                       MCFixup::getKindForSize(Size, false), Loc));
     192     5917644 :   DF->getContents().resize(DF->getContents().size() + Size, 0);
     193             : }
     194             : 
     195     1043990 : MCSymbol *MCObjectStreamer::EmitCFILabel() {
     196     2087980 :   MCSymbol *Label = getContext().createTempSymbol("cfi", true);
     197     1043990 :   EmitLabel(Label);
     198     1043990 :   return Label;
     199             : }
     200             : 
     201      233475 : void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
     202             :   // We need to create a local symbol to avoid relocations.
     203      233475 :   Frame.Begin = getContext().createTempSymbol();
     204      233475 :   EmitLabel(Frame.Begin);
     205      233475 : }
     206             : 
     207      233474 : void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
     208      233474 :   Frame.End = getContext().createTempSymbol();
     209      233474 :   EmitLabel(Frame.End);
     210      233474 : }
     211             : 
     212     8951485 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     213     8951485 :   MCStreamer::EmitLabel(Symbol, Loc);
     214             : 
     215     8951486 :   getAssembler().registerSymbol(*Symbol);
     216             : 
     217             :   // If there is a current fragment, mark the symbol as pointing into it.
     218             :   // Otherwise queue the label and set its fragment pointer when we emit the
     219             :   // next fragment.
     220     8951487 :   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     221     7590925 :   if (F && !(getAssembler().isBundlingEnabled() &&
     222             :              getAssembler().getRelaxAll())) {
     223     7590910 :     Symbol->setFragment(F);
     224     7590910 :     Symbol->setOffset(F->getContents().size());
     225             :   } else {
     226     1360577 :     PendingLabels.push_back(Symbol);
     227             :   }
     228     8951485 : }
     229             : 
     230          10 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
     231          10 :   MCStreamer::EmitLabel(Symbol, Loc);
     232          10 :   getAssembler().registerSymbol(*Symbol);
     233             :   auto *DF = dyn_cast_or_null<MCDataFragment>(F);
     234             :   if (DF)
     235          10 :     Symbol->setFragment(F);
     236             :   else
     237           0 :     PendingLabels.push_back(Symbol);
     238          10 : }
     239             : 
     240      171175 : void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
     241             :   int64_t IntValue;
     242      171175 :   if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
     243         263 :     EmitULEB128IntValue(IntValue);
     244         263 :     return;
     245             :   }
     246      170912 :   insert(new MCLEBFragment(*Value, false));
     247             : }
     248             : 
     249          57 : void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
     250             :   int64_t IntValue;
     251          57 :   if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
     252          55 :     EmitSLEB128IntValue(IntValue);
     253          55 :     return;
     254             :   }
     255           2 :   insert(new MCLEBFragment(*Value, true));
     256             : }
     257             : 
     258           0 : void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
     259             :                                          const MCSymbol *Symbol) {
     260           0 :   report_fatal_error("This file format doesn't support weak aliases.");
     261             : }
     262             : 
     263        3687 : void MCObjectStreamer::ChangeSection(MCSection *Section,
     264             :                                      const MCExpr *Subsection) {
     265        3687 :   changeSectionImpl(Section, Subsection);
     266        3687 : }
     267             : 
     268      965828 : bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
     269             :                                          const MCExpr *Subsection) {
     270             :   assert(Section && "Cannot switch to a null section!");
     271      965828 :   flushPendingLabels(nullptr);
     272      965829 :   getContext().clearDwarfLocSeen();
     273             : 
     274      965829 :   bool Created = getAssembler().registerSection(*Section);
     275             : 
     276      965829 :   int64_t IntSubsection = 0;
     277      965835 :   if (Subsection &&
     278           6 :       !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
     279           0 :     report_fatal_error("Cannot evaluate subsection number");
     280      965829 :   if (IntSubsection < 0 || IntSubsection > 8192)
     281           0 :     report_fatal_error("Subsection number out of range");
     282             :   CurInsertionPoint =
     283      965829 :       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
     284      965828 :   return Created;
     285             : }
     286             : 
     287        6029 : void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     288        6029 :   getAssembler().registerSymbol(*Symbol);
     289        6029 :   MCStreamer::EmitAssignment(Symbol, Value);
     290        6029 : }
     291             : 
     292          34 : bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
     293          34 :   return Sec.hasInstructions();
     294             : }
     295             : 
     296    30574856 : void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
     297             :                                        const MCSubtargetInfo &STI, bool) {
     298    30574856 :   getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
     299    30574856 :   EmitInstructionImpl(Inst, STI);
     300    30574852 :   getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
     301    30574853 : }
     302             : 
     303    30574856 : void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
     304             :                                            const MCSubtargetInfo &STI) {
     305    30574856 :   MCStreamer::EmitInstruction(Inst, STI);
     306             : 
     307             :   MCSection *Sec = getCurrentSectionOnly();
     308             :   Sec->setHasInstructions(true);
     309             : 
     310             :   // Now that a machine instruction has been assembled into this section, make
     311             :   // a line entry for any .loc directive that has been seen.
     312    30574855 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     313             : 
     314             :   // If this instruction doesn't need relaxation, just emit it as data.
     315             :   MCAssembler &Assembler = getAssembler();
     316    30574855 :   if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
     317    28462675 :     EmitInstToData(Inst, STI);
     318    28462672 :     return;
     319             :   }
     320             : 
     321             :   // Otherwise, relax and emit it as data if either:
     322             :   // - The RelaxAll flag was passed
     323             :   // - Bundling is enabled and this instruction is inside a bundle-locked
     324             :   //   group. We want to emit all such instructions into the same data
     325             :   //   fragment.
     326     2112181 :   if (Assembler.getRelaxAll() ||
     327      129791 :       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
     328             :     MCInst Relaxed;
     329     1982392 :     getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
     330     1982392 :     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
     331           0 :       getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
     332     1982392 :     EmitInstToData(Relaxed, STI);
     333             :     return;
     334             :   }
     335             : 
     336             :   // Otherwise emit to a separate fragment.
     337      129789 :   EmitInstToFragment(Inst, STI);
     338             : }
     339             : 
     340      129789 : void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
     341             :                                           const MCSubtargetInfo &STI) {
     342      129789 :   if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
     343           0 :     llvm_unreachable("All instructions should have already been relaxed");
     344             : 
     345             :   // Always create a new, separate fragment here, because its size can change
     346             :   // during relaxation.
     347      129789 :   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
     348      129789 :   insert(IF);
     349             : 
     350             :   SmallString<128> Code;
     351             :   raw_svector_ostream VecOS(Code);
     352      129789 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
     353      129789 :                                                 STI);
     354      129789 :   IF->getContents().append(Code.begin(), Code.end());
     355      129789 : }
     356             : 
     357             : #ifndef NDEBUG
     358             : static const char *const BundlingNotImplementedMsg =
     359             :   "Aligned bundling is not implemented for this object format";
     360             : #endif
     361             : 
     362           0 : void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
     363           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     364             : }
     365             : 
     366           0 : void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
     367           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     368             : }
     369             : 
     370           0 : void MCObjectStreamer::EmitBundleUnlock() {
     371           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     372             : }
     373             : 
     374      854857 : void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
     375             :                                              unsigned Column, unsigned Flags,
     376             :                                              unsigned Isa,
     377             :                                              unsigned Discriminator,
     378             :                                              StringRef FileName) {
     379             :   // In case we see two .loc directives in a row, make sure the
     380             :   // first one gets a line entry.
     381      854857 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     382             : 
     383      854857 :   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
     384             :                                           Isa, Discriminator, FileName);
     385      854857 : }
     386             : 
     387     1898349 : static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
     388             :                                      const MCSymbol *B) {
     389     1898349 :   MCContext &Context = OS.getContext();
     390             :   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
     391     1898349 :   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
     392     1898349 :   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
     393             :   const MCExpr *AddrDelta =
     394     1898349 :       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
     395     1898349 :   return AddrDelta;
     396             : }
     397             : 
     398       33660 : static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
     399             :                                  MCDwarfLineTableParams Params,
     400             :                                  int64_t LineDelta, const MCSymbol *Label,
     401             :                                  int PointerSize) {
     402             :   // emit the sequence to set the address
     403       33660 :   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
     404       33660 :   OS.EmitULEB128IntValue(PointerSize + 1);
     405       33660 :   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
     406       33660 :   OS.EmitSymbolValue(Label, PointerSize);
     407             : 
     408             :   // emit the sequence for the LineDelta (from 1) and a zero address delta.
     409       33660 :   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
     410       33660 : }
     411             : 
     412      888516 : void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
     413             :                                                 const MCSymbol *LastLabel,
     414             :                                                 const MCSymbol *Label,
     415             :                                                 unsigned PointerSize) {
     416      888516 :   if (!LastLabel) {
     417       67320 :     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
     418             :                          Label, PointerSize);
     419       33994 :     return;
     420             :   }
     421      854856 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     422             :   int64_t Res;
     423      854856 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     424         668 :     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
     425             :                           Res);
     426         334 :     return;
     427             :   }
     428     1709044 :   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
     429             : }
     430             : 
     431     1043493 : void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
     432             :                                                  const MCSymbol *Label) {
     433     1043493 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     434             :   int64_t Res;
     435     1043493 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     436         347 :     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
     437         347 :     return;
     438             :   }
     439     1043146 :   insert(new MCDwarfCallFrameFragment(*AddrDelta));
     440             : }
     441             : 
     442         486 : void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
     443             :                                           unsigned Line, unsigned Column,
     444             :                                           bool PrologueEnd, bool IsStmt,
     445             :                                           StringRef FileName, SMLoc Loc) {
     446             :   // Validate the directive.
     447         486 :   if (!checkCVLocSection(FunctionId, FileNo, Loc))
     448             :     return;
     449             : 
     450             :   // Emit a label at the current position and record it in the CodeViewContext.
     451         486 :   MCSymbol *LineSym = getContext().createTempSymbol();
     452         486 :   EmitLabel(LineSym);
     453         486 :   getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
     454             :                                           FileNo, Line, Column, PrologueEnd,
     455             :                                           IsStmt);
     456             : }
     457             : 
     458         132 : void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
     459             :                                                 const MCSymbol *Begin,
     460             :                                                 const MCSymbol *End) {
     461         132 :   getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
     462             :                                                        End);
     463         132 :   this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
     464         132 : }
     465             : 
     466          24 : void MCObjectStreamer::EmitCVInlineLinetableDirective(
     467             :     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
     468             :     const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
     469          24 :   getContext().getCVContext().emitInlineLineTableForFunction(
     470             :       *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
     471             :       FnEndSym);
     472          24 :   this->MCStreamer::EmitCVInlineLinetableDirective(
     473             :       PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
     474          24 : }
     475             : 
     476         179 : void MCObjectStreamer::EmitCVDefRangeDirective(
     477             :     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     478             :     StringRef FixedSizePortion) {
     479         179 :   getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
     480         179 :   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
     481         179 : }
     482             : 
     483          87 : void MCObjectStreamer::EmitCVStringTableDirective() {
     484          87 :   getContext().getCVContext().emitStringTable(*this);
     485          87 : }
     486          84 : void MCObjectStreamer::EmitCVFileChecksumsDirective() {
     487          84 :   getContext().getCVContext().emitFileChecksums(*this);
     488          84 : }
     489             : 
     490         156 : void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
     491         156 :   getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
     492         156 : }
     493             : 
     494    18177020 : void MCObjectStreamer::EmitBytes(StringRef Data) {
     495    18177020 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     496    18177020 :   MCDataFragment *DF = getOrCreateDataFragment();
     497    36354040 :   flushPendingLabels(DF, DF->getContents().size());
     498    36354040 :   DF->getContents().append(Data.begin(), Data.end());
     499             : 
     500             :   // EmitBytes might not cover all possible ways we emit data (or could be used
     501             :   // to emit executable code in some cases), but is the best method we have
     502             :   // right now for checking this.
     503             :   MCSection *Sec = getCurrentSectionOnly();
     504             :   Sec->setHasData(true);
     505    18177019 : }
     506             : 
     507      708080 : void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
     508             :                                             int64_t Value,
     509             :                                             unsigned ValueSize,
     510             :                                             unsigned MaxBytesToEmit) {
     511      708080 :   if (MaxBytesToEmit == 0)
     512             :     MaxBytesToEmit = ByteAlignment;
     513     1416162 :   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
     514             : 
     515             :   // Update the maximum alignment on the current section if necessary.
     516             :   MCSection *CurSec = getCurrentSectionOnly();
     517      708082 :   if (ByteAlignment > CurSec->getAlignment())
     518             :     CurSec->setAlignment(ByteAlignment);
     519      708082 : }
     520             : 
     521      259460 : void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
     522             :                                          unsigned MaxBytesToEmit) {
     523      259460 :   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
     524      259460 :   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
     525      259459 : }
     526             : 
     527          19 : void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
     528             :                                          unsigned char Value,
     529             :                                          SMLoc Loc) {
     530          19 :   insert(new MCOrgFragment(*Offset, Value, Loc));
     531          19 : }
     532             : 
     533     3091427 : void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
     534             :     const MCCodePaddingContext &Context) {
     535     3091427 :   getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
     536     3091428 : }
     537             : 
     538     3091428 : void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
     539             :     const MCCodePaddingContext &Context) {
     540     3091428 :   getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
     541     3091428 : }
     542             : 
     543             : // Associate DTPRel32 fixup with data and resize data area
     544           4 : void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
     545           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     546           8 :   flushPendingLabels(DF, DF->getContents().size());
     547             : 
     548           8 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     549             :                                             Value, FK_DTPRel_4));
     550           8 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     551           4 : }
     552             : 
     553             : // Associate DTPRel64 fixup with data and resize data area
     554           4 : void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
     555           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     556           8 :   flushPendingLabels(DF, DF->getContents().size());
     557             : 
     558           8 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     559             :                                             Value, FK_DTPRel_8));
     560           8 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     561           4 : }
     562             : 
     563             : // Associate TPRel32 fixup with data and resize data area
     564           3 : void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
     565           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     566           6 :   flushPendingLabels(DF, DF->getContents().size());
     567             : 
     568           6 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     569             :                                             Value, FK_TPRel_4));
     570           6 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     571           3 : }
     572             : 
     573             : // Associate TPRel64 fixup with data and resize data area
     574           3 : void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
     575           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     576           6 :   flushPendingLabels(DF, DF->getContents().size());
     577             : 
     578           6 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     579             :                                             Value, FK_TPRel_8));
     580           6 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     581           3 : }
     582             : 
     583             : // Associate GPRel32 fixup with data and resize data area
     584          12 : void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
     585          12 :   MCDataFragment *DF = getOrCreateDataFragment();
     586          24 :   flushPendingLabels(DF, DF->getContents().size());
     587             : 
     588          12 :   DF->getFixups().push_back(
     589          12 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     590          24 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     591          12 : }
     592             : 
     593             : // Associate GPRel64 fixup with data and resize data area
     594          13 : void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
     595          13 :   MCDataFragment *DF = getOrCreateDataFragment();
     596          26 :   flushPendingLabels(DF, DF->getContents().size());
     597             : 
     598          13 :   DF->getFixups().push_back(
     599          13 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     600          26 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     601          13 : }
     602             : 
     603         107 : bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
     604             :                                           const MCExpr *Expr, SMLoc Loc,
     605             :                                           const MCSubtargetInfo &STI) {
     606             :   int64_t OffsetValue;
     607         107 :   if (!Offset.evaluateAsAbsolute(OffsetValue))
     608           0 :     llvm_unreachable("Offset is not absolute");
     609             : 
     610         107 :   if (OffsetValue < 0)
     611           0 :     llvm_unreachable("Offset is negative");
     612             : 
     613         107 :   MCDataFragment *DF = getOrCreateDataFragment(&STI);
     614         214 :   flushPendingLabels(DF, DF->getContents().size());
     615             : 
     616         107 :   Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
     617         107 :   if (!MaybeKind.hasValue())
     618             :     return true;
     619             : 
     620         107 :   MCFixupKind Kind = *MaybeKind;
     621             : 
     622         107 :   if (Expr == nullptr)
     623             :     Expr =
     624           3 :         MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
     625         214 :   DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
     626         107 :   return false;
     627             : }
     628             : 
     629      277895 : void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
     630             :                                 SMLoc Loc) {
     631      277895 :   MCDataFragment *DF = getOrCreateDataFragment();
     632      555790 :   flushPendingLabels(DF, DF->getContents().size());
     633             : 
     634             :   assert(getCurrentSectionOnly() && "need a section");
     635      555790 :   insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
     636      277895 : }
     637             : 
     638         546 : void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
     639             :                                 int64_t Expr, SMLoc Loc) {
     640             :   int64_t IntNumValues;
     641             :   // Do additional checking now if we can resolve the value.
     642         546 :   if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
     643         541 :     if (IntNumValues < 0) {
     644           4 :       getContext().getSourceManager()->PrintMessage(
     645             :           Loc, SourceMgr::DK_Warning,
     646             :           "'.fill' directive with negative repeat count has no effect");
     647         541 :       return;
     648             :     }
     649             :     // Emit now if we can for better errors.
     650         539 :     int64_t NonZeroSize = Size > 4 ? 4 : Size;
     651         539 :     Expr &= ~0ULL >> (64 - NonZeroSize * 8);
     652     1746601 :     for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
     653     1746062 :       EmitIntValue(Expr, NonZeroSize);
     654     1746062 :       if (NonZeroSize < Size)
     655           7 :         EmitIntValue(0, Size - NonZeroSize);
     656             :     }
     657             :     return;
     658             :   }
     659             : 
     660             :   // Otherwise emit as fragment.
     661           5 :   MCDataFragment *DF = getOrCreateDataFragment();
     662          10 :   flushPendingLabels(DF, DF->getContents().size());
     663             : 
     664             :   assert(getCurrentSectionOnly() && "need a section");
     665           5 :   insert(new MCFillFragment(Expr, Size, NumValues, Loc));
     666             : }
     667             : 
     668        8848 : void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
     669        8848 :   getAssembler().addFileName(Filename);
     670        8848 : }
     671             : 
     672        7426 : void MCObjectStreamer::EmitAddrsig() {
     673        7426 :   getAssembler().getWriter().emitAddrsigSection();
     674        7426 : }
     675             : 
     676      260897 : void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
     677      260897 :   getAssembler().registerSymbol(*Sym);
     678      260897 :   getAssembler().getWriter().addAddrsigSymbol(Sym);
     679      260897 : }
     680             : 
     681       13501 : void MCObjectStreamer::FinishImpl() {
     682       13501 :   getContext().RemapDebugPaths();
     683             : 
     684             :   // If we are generating dwarf for assembly source files dump out the sections.
     685       13500 :   if (getContext().getGenDwarfForAssembly())
     686          27 :     MCGenDwarfInfo::Emit(this);
     687             : 
     688             :   // Dump out the dwarf file & directory tables and line tables.
     689       13500 :   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
     690             : 
     691             :   flushPendingLabels();
     692       13501 :   getAssembler().Finish();
     693       13483 : }

Generated by: LCOV version 1.13