LCOV - code coverage report
Current view: top level - lib/MC - MCObjectStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 321 341 94.1 %
Date: 2018-06-17 00:07:59 Functions: 57 63 90.5 %
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        7954 : MCObjectStreamer::MCObjectStreamer(MCContext &Context,
      27             :                                    std::unique_ptr<MCAsmBackend> TAB,
      28             :                                    std::unique_ptr<MCObjectWriter> OW,
      29        7954 :                                    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       23862 :       EmitEHFrame(true), EmitDebugFrame(false) {}
      34             : 
      35       15840 : 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     2771103 : MCAssembler *MCObjectStreamer::getAssemblerPtr() {
      41     2771103 :   if (getUseAssemblerInfoForParsing())
      42       15947 :     return Assembler.get();
      43             :   return nullptr;
      44             : }
      45             : 
      46    20501236 : void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
      47    20501236 :   if (PendingLabels.empty())
      48             :     return;
      49      238140 :   if (!F) {
      50        7297 :     F = new MCDataFragment();
      51             :     MCSection *CurSection = getCurrentSectionOnly();
      52             :     CurSection->getFragmentList().insert(CurInsertionPoint, F);
      53             :     F->setParent(CurSection);
      54             :   }
      55     1134774 :   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      216939 : static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
      65             :                                              const MCSymbol *Lo) {
      66             :   assert(Hi && Lo);
      67      547218 :   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
      68      349275 :       Hi->isVariable() || Lo->isVariable())
      69             :     return None;
      70             : 
      71      132319 :   return Hi->getOffset() - Lo->getOffset();
      72             : }
      73             : 
      74      103032 : void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
      75             :                                               const MCSymbol *Lo,
      76             :                                               unsigned Size) {
      77      103032 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
      78       77442 :     EmitIntValue(*Diff, Size);
      79             :     return;
      80             :   }
      81       25590 :   MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
      82             : }
      83             : 
      84      113907 : void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
      85             :                                                        const MCSymbol *Lo) {
      86      113907 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
      87       54877 :     EmitULEB128IntValue(*Diff);
      88             :     return;
      89             :   }
      90       59030 :   MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
      91             : }
      92             : 
      93        4344 : void MCObjectStreamer::reset() {
      94        4344 :   if (Assembler)
      95        4344 :     Assembler->reset();
      96        4344 :   CurInsertionPoint = MCSection::iterator();
      97        4344 :   EmitEHFrame = true;
      98        4344 :   EmitDebugFrame = false;
      99             :   PendingLabels.clear();
     100        4344 :   MCStreamer::reset();
     101        4344 : }
     102             : 
     103        7847 : void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
     104        7847 :   if (!getNumFrameInfos())
     105             :     return;
     106             : 
     107        3173 :   if (EmitEHFrame)
     108        3079 :     MCDwarfFrameEmitter::Emit(*this, MAB, true);
     109             : 
     110        3173 :   if (EmitDebugFrame)
     111          94 :     MCDwarfFrameEmitter::Emit(*this, MAB, false);
     112             : }
     113             : 
     114    24107367 : MCFragment *MCObjectStreamer::getCurrentFragment() const {
     115             :   assert(getCurrentSectionOnly() && "No current section!");
     116             : 
     117    24107367 :   if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
     118             :     return &*std::prev(CurInsertionPoint);
     119             : 
     120             :   return nullptr;
     121             : }
     122             : 
     123             : static bool CanReuseDataFragment(const MCDataFragment &F,
     124             :                                  const MCAssembler &Assembler,
     125             :                                  const MCSubtargetInfo *STI) {
     126    17761785 :   if (!F.hasInstructions())
     127             :     return true;
     128             :   // When bundling is enabled, we don't want to add data to a fragment that
     129             :   // already has instructions (see MCELFStreamer::EmitInstToData for details)
     130     2377228 :   if (Assembler.isBundlingEnabled())
     131             :     return Assembler.getRelaxAll();
     132             :   // If the subtarget is changed mid fragment we start a new fragment to record
     133             :   // the new STI.
     134     2377102 :   return !STI || F.getSubtargetInfo() == STI;
     135             : }
     136             : 
     137             : MCDataFragment *
     138    19120083 : MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
     139    19120083 :   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     140         126 :   if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
     141     1358357 :     F = new MCDataFragment();
     142     1358357 :     insert(F);
     143             :   }
     144    19120083 :   return F;
     145             : }
     146             : 
     147           0 : MCPaddingFragment *MCObjectStreamer::getOrCreatePaddingFragment() {
     148             :   MCPaddingFragment *F =
     149           0 :       dyn_cast_or_null<MCPaddingFragment>(getCurrentFragment());
     150             :   if (!F) {
     151           0 :     F = new MCPaddingFragment();
     152           0 :     insert(F);
     153             :   }
     154           0 :   return F;
     155             : }
     156             : 
     157     2800398 : void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
     158     2800398 :   Assembler->registerSymbol(Sym);
     159     2800398 : }
     160             : 
     161          94 : void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
     162          94 :   MCStreamer::EmitCFISections(EH, Debug);
     163          94 :   EmitEHFrame = EH;
     164          94 :   EmitDebugFrame = Debug;
     165          94 : }
     166             : 
     167     1723290 : void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     168             :                                      SMLoc Loc) {
     169     1723290 :   MCStreamer::EmitValueImpl(Value, Size, Loc);
     170     1723290 :   MCDataFragment *DF = getOrCreateDataFragment();
     171     1723290 :   flushPendingLabels(DF, DF->getContents().size());
     172             : 
     173     1723290 :   MCCVLineEntry::Make(this);
     174     1723290 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     175             : 
     176             :   // Avoid fixups when possible.
     177             :   int64_t AbsValue;
     178     1723290 :   if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
     179        3284 :     if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
     180           2 :       getContext().reportError(
     181           1 :           Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
     182        3285 :       return;
     183             :     }
     184        3283 :     EmitIntValue(AbsValue, Size);
     185        3283 :     return;
     186             :   }
     187     3440012 :   DF->getFixups().push_back(
     188     1720006 :       MCFixup::create(DF->getContents().size(), Value,
     189     1720006 :                       MCFixup::getKindForSize(Size, false), Loc));
     190     3440012 :   DF->getContents().resize(DF->getContents().size() + Size, 0);
     191             : }
     192             : 
     193      260354 : MCSymbol *MCObjectStreamer::EmitCFILabel() {
     194      520708 :   MCSymbol *Label = getContext().createTempSymbol("cfi", true);
     195      260354 :   EmitLabel(Label);
     196      260354 :   return Label;
     197             : }
     198             : 
     199       45937 : void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
     200             :   // We need to create a local symbol to avoid relocations.
     201       45937 :   Frame.Begin = getContext().createTempSymbol();
     202       45937 :   EmitLabel(Frame.Begin);
     203       45937 : }
     204             : 
     205       45936 : void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
     206       45936 :   Frame.End = getContext().createTempSymbol();
     207       45936 :   EmitLabel(Frame.End);
     208       45936 : }
     209             : 
     210     2806474 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     211     2806474 :   MCStreamer::EmitLabel(Symbol, Loc);
     212             : 
     213     2806474 :   getAssembler().registerSymbol(*Symbol);
     214             : 
     215             :   // If there is a current fragment, mark the symbol as pointing into it.
     216             :   // Otherwise queue the label and set its fragment pointer when we emit the
     217             :   // next fragment.
     218     2806474 :   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     219     2358189 :   if (F && !(getAssembler().isBundlingEnabled() &&
     220             :              getAssembler().getRelaxAll())) {
     221     2358148 :     Symbol->setFragment(F);
     222             :     Symbol->setOffset(F->getContents().size());
     223             :   } else {
     224      448326 :     PendingLabels.push_back(Symbol);
     225             :   }
     226     2806474 : }
     227             : 
     228          10 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
     229          10 :   MCStreamer::EmitLabel(Symbol, Loc);
     230          10 :   getAssembler().registerSymbol(*Symbol);
     231             :   auto *DF = dyn_cast_or_null<MCDataFragment>(F);
     232             :   if (DF)
     233          10 :     Symbol->setFragment(F);
     234             :   else
     235           0 :     PendingLabels.push_back(Symbol);
     236          10 : }
     237             : 
     238       59252 : void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
     239             :   int64_t IntValue;
     240       59252 :   if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
     241         212 :     EmitULEB128IntValue(IntValue);
     242         212 :     return;
     243             :   }
     244       59040 :   insert(new MCLEBFragment(*Value, false));
     245             : }
     246             : 
     247          57 : void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
     248             :   int64_t IntValue;
     249          57 :   if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
     250          55 :     EmitSLEB128IntValue(IntValue);
     251          55 :     return;
     252             :   }
     253           2 :   insert(new MCLEBFragment(*Value, true));
     254             : }
     255             : 
     256           0 : void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
     257             :                                          const MCSymbol *Symbol) {
     258           0 :   report_fatal_error("This file format doesn't support weak aliases.");
     259             : }
     260             : 
     261        3386 : void MCObjectStreamer::ChangeSection(MCSection *Section,
     262             :                                      const MCExpr *Subsection) {
     263        3386 :   changeSectionImpl(Section, Subsection);
     264        3386 : }
     265             : 
     266      550124 : bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
     267             :                                          const MCExpr *Subsection) {
     268             :   assert(Section && "Cannot switch to a null section!");
     269      550124 :   flushPendingLabels(nullptr);
     270      550124 :   getContext().clearCVLocSeen();
     271      550124 :   getContext().clearDwarfLocSeen();
     272             : 
     273      550124 :   bool Created = getAssembler().registerSection(*Section);
     274             : 
     275      550124 :   int64_t IntSubsection = 0;
     276      550130 :   if (Subsection &&
     277           6 :       !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
     278           0 :     report_fatal_error("Cannot evaluate subsection number");
     279      550124 :   if (IntSubsection < 0 || IntSubsection > 8192)
     280           0 :     report_fatal_error("Subsection number out of range");
     281      550124 :   CurInsertionPoint =
     282      550124 :       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
     283      550124 :   return Created;
     284             : }
     285             : 
     286        5224 : void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     287        5224 :   getAssembler().registerSymbol(*Symbol);
     288        5224 :   MCStreamer::EmitAssignment(Symbol, Value);
     289        5224 : }
     290             : 
     291          30 : bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
     292          30 :   return Sec.hasInstructions();
     293             : }
     294             : 
     295     2094339 : void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
     296             :                                        const MCSubtargetInfo &STI, bool) {
     297     2094339 :   getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
     298     2094339 :   EmitInstructionImpl(Inst, STI);
     299     2094336 :   getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
     300     2094336 : }
     301             : 
     302     2094339 : void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
     303             :                                            const MCSubtargetInfo &STI) {
     304     2094339 :   MCStreamer::EmitInstruction(Inst, STI);
     305             : 
     306             :   MCSection *Sec = getCurrentSectionOnly();
     307             :   Sec->setHasInstructions(true);
     308             : 
     309             :   // Now that a machine instruction has been assembled into this section, make
     310             :   // a line entry for any .loc directive that has been seen.
     311     2094339 :   MCCVLineEntry::Make(this);
     312     2094339 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     313             : 
     314             :   // If this instruction doesn't need relaxation, just emit it as data.
     315             :   MCAssembler &Assembler = getAssembler();
     316     2094339 :   if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
     317     1992313 :     EmitInstToData(Inst, STI);
     318     1992310 :     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      164496 :   if (Assembler.getRelaxAll() ||
     327       62475 :       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
     328             :     MCInst Relaxed;
     329       39558 :     getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
     330       39558 :     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
     331           0 :       getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
     332       39558 :     EmitInstToData(Relaxed, STI);
     333             :     return;
     334             :   }
     335             : 
     336             :   // Otherwise emit to a separate fragment.
     337       62468 :   EmitInstToFragment(Inst, STI);
     338             : }
     339             : 
     340       62468 : void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
     341             :                                           const MCSubtargetInfo &STI) {
     342       62468 :   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       62468 :   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
     348       62468 :   insert(IF);
     349             : 
     350             :   SmallString<128> Code;
     351             :   raw_svector_ostream VecOS(Code);
     352       62468 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
     353       62468 :                                                 STI);
     354       62468 :   IF->getContents().append(Code.begin(), Code.end());
     355       62468 : }
     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      721404 : 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      721404 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     382             : 
     383      721404 :   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
     384             :                                           Isa, Discriminator, FileName);
     385      721404 : }
     386             : 
     387      981276 : static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
     388             :                                      const MCSymbol *B) {
     389      981276 :   MCContext &Context = OS.getContext();
     390             :   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
     391      981276 :   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
     392      981276 :   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
     393             :   const MCExpr *AddrDelta =
     394      981276 :       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
     395      981276 :   return AddrDelta;
     396             : }
     397             : 
     398       38790 : 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       38790 :   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
     404       38790 :   OS.EmitULEB128IntValue(PointerSize + 1);
     405       38790 :   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
     406       38790 :   OS.EmitSymbolValue(Label, PointerSize);
     407             : 
     408             :   // emit the sequence for the LineDelta (from 1) and a zero address delta.
     409       38790 :   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
     410       38790 : }
     411             : 
     412      760193 : void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
     413             :                                                 const MCSymbol *LastLabel,
     414             :                                                 const MCSymbol *Label,
     415             :                                                 unsigned PointerSize) {
     416      760193 :   if (!LastLabel) {
     417       77580 :     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
     418             :                          Label, PointerSize);
     419       38790 :     return;
     420             :   }
     421      721403 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     422             :   int64_t Res;
     423      721403 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     424         582 :     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
     425             :                           Res);
     426         291 :     return;
     427             :   }
     428      721112 :   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
     429             : }
     430             : 
     431      259873 : void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
     432             :                                                  const MCSymbol *Label) {
     433      259873 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     434             :   int64_t Res;
     435      259873 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     436         324 :     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
     437         324 :     return;
     438             :   }
     439      259549 :   insert(new MCDwarfCallFrameFragment(*AddrDelta));
     440             : }
     441             : 
     442         483 : void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
     443             :                                           unsigned Line, unsigned Column,
     444             :                                           bool PrologueEnd, bool IsStmt,
     445             :                                           StringRef FileName, SMLoc Loc) {
     446             :   // In case we see two .cv_loc directives in a row, make sure the
     447             :   // first one gets a line entry.
     448         483 :   MCCVLineEntry::Make(this);
     449             : 
     450         483 :   this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
     451             :                                        PrologueEnd, IsStmt, FileName, Loc);
     452         483 : }
     453             : 
     454         131 : void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
     455             :                                                 const MCSymbol *Begin,
     456             :                                                 const MCSymbol *End) {
     457         131 :   getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
     458             :                                                        End);
     459         131 :   this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
     460         131 : }
     461             : 
     462          23 : void MCObjectStreamer::EmitCVInlineLinetableDirective(
     463             :     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
     464             :     const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
     465          23 :   getContext().getCVContext().emitInlineLineTableForFunction(
     466             :       *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
     467             :       FnEndSym);
     468          23 :   this->MCStreamer::EmitCVInlineLinetableDirective(
     469             :       PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
     470          23 : }
     471             : 
     472         181 : void MCObjectStreamer::EmitCVDefRangeDirective(
     473             :     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     474             :     StringRef FixedSizePortion) {
     475         181 :   getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
     476         181 :   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
     477         181 : }
     478             : 
     479          85 : void MCObjectStreamer::EmitCVStringTableDirective() {
     480          85 :   getContext().getCVContext().emitStringTable(*this);
     481          85 : }
     482          83 : void MCObjectStreamer::EmitCVFileChecksumsDirective() {
     483          83 :   getContext().getCVContext().emitFileChecksums(*this);
     484          83 : }
     485             : 
     486         154 : void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
     487         154 :   getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
     488         154 : }
     489             : 
     490    15166824 : void MCObjectStreamer::EmitBytes(StringRef Data) {
     491    15166824 :   MCCVLineEntry::Make(this);
     492    15166824 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     493    15166824 :   MCDataFragment *DF = getOrCreateDataFragment();
     494    15166824 :   flushPendingLabels(DF, DF->getContents().size());
     495    15166824 :   DF->getContents().append(Data.begin(), Data.end());
     496    15166824 : }
     497             : 
     498      190063 : void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
     499             :                                             int64_t Value,
     500             :                                             unsigned ValueSize,
     501             :                                             unsigned MaxBytesToEmit) {
     502      190063 :   if (MaxBytesToEmit == 0)
     503             :     MaxBytesToEmit = ByteAlignment;
     504      380126 :   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
     505             : 
     506             :   // Update the maximum alignment on the current section if necessary.
     507             :   MCSection *CurSec = getCurrentSectionOnly();
     508      190063 :   if (ByteAlignment > CurSec->getAlignment())
     509             :     CurSec->setAlignment(ByteAlignment);
     510      190063 : }
     511             : 
     512       61362 : void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
     513             :                                          unsigned MaxBytesToEmit) {
     514       61362 :   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
     515       61362 :   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
     516       61362 : }
     517             : 
     518          19 : void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
     519             :                                          unsigned char Value,
     520             :                                          SMLoc Loc) {
     521          38 :   insert(new MCOrgFragment(*Offset, Value, Loc));
     522          19 : }
     523             : 
     524      220412 : void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
     525             :     const MCCodePaddingContext &Context) {
     526      220412 :   getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
     527      220412 : }
     528             : 
     529      220412 : void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
     530             :     const MCCodePaddingContext &Context) {
     531      220412 :   getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
     532      220412 : }
     533             : 
     534             : // Associate DTPRel32 fixup with data and resize data area
     535           4 : void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
     536           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     537           4 :   flushPendingLabels(DF, DF->getContents().size());
     538             : 
     539           8 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     540           4 :                                             Value, FK_DTPRel_4));
     541           8 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     542           4 : }
     543             : 
     544             : // Associate DTPRel64 fixup with data and resize data area
     545           4 : void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
     546           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     547           4 :   flushPendingLabels(DF, DF->getContents().size());
     548             : 
     549           8 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     550           4 :                                             Value, FK_DTPRel_8));
     551           8 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     552           4 : }
     553             : 
     554             : // Associate TPRel32 fixup with data and resize data area
     555           3 : void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
     556           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     557           3 :   flushPendingLabels(DF, DF->getContents().size());
     558             : 
     559           6 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     560           3 :                                             Value, FK_TPRel_4));
     561           6 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     562           3 : }
     563             : 
     564             : // Associate TPRel64 fixup with data and resize data area
     565           3 : void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
     566           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     567           3 :   flushPendingLabels(DF, DF->getContents().size());
     568             : 
     569           6 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     570           3 :                                             Value, FK_TPRel_8));
     571           6 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     572           3 : }
     573             : 
     574             : // Associate GPRel32 fixup with data and resize data area
     575          11 : void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
     576          11 :   MCDataFragment *DF = getOrCreateDataFragment();
     577          11 :   flushPendingLabels(DF, DF->getContents().size());
     578             : 
     579          22 :   DF->getFixups().push_back(
     580          22 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     581          22 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     582          11 : }
     583             : 
     584             : // Associate GPRel64 fixup with data and resize data area
     585          13 : void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
     586          13 :   MCDataFragment *DF = getOrCreateDataFragment();
     587          13 :   flushPendingLabels(DF, DF->getContents().size());
     588             : 
     589          26 :   DF->getFixups().push_back(
     590          26 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     591          26 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     592          13 : }
     593             : 
     594         107 : bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
     595             :                                           const MCExpr *Expr, SMLoc Loc,
     596             :                                           const MCSubtargetInfo &STI) {
     597             :   int64_t OffsetValue;
     598         107 :   if (!Offset.evaluateAsAbsolute(OffsetValue))
     599           0 :     llvm_unreachable("Offset is not absolute");
     600             : 
     601         107 :   if (OffsetValue < 0)
     602           0 :     llvm_unreachable("Offset is negative");
     603             : 
     604         107 :   MCDataFragment *DF = getOrCreateDataFragment(&STI);
     605         107 :   flushPendingLabels(DF, DF->getContents().size());
     606             : 
     607         107 :   Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
     608         107 :   if (!MaybeKind.hasValue())
     609             :     return true;
     610             : 
     611         107 :   MCFixupKind Kind = *MaybeKind;
     612             : 
     613         107 :   if (Expr == nullptr)
     614             :     Expr =
     615           3 :         MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
     616         214 :   DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
     617         107 :   return false;
     618             : }
     619             : 
     620      200129 : void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
     621             :                                 SMLoc Loc) {
     622      200129 :   MCDataFragment *DF = getOrCreateDataFragment();
     623      200129 :   flushPendingLabels(DF, DF->getContents().size());
     624             : 
     625             :   assert(getCurrentSectionOnly() && "need a section");
     626      400258 :   insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
     627      200129 : }
     628             : 
     629         540 : void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
     630             :                                 int64_t Expr, SMLoc Loc) {
     631             :   int64_t IntNumValues;
     632             :   // Do additional checking now if we can resolve the value.
     633         540 :   if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
     634         535 :     if (IntNumValues < 0) {
     635           4 :       getContext().getSourceManager()->PrintMessage(
     636             :           Loc, SourceMgr::DK_Warning,
     637             :           "'.fill' directive with negative repeat count has no effect");
     638         537 :       return;
     639             :     }
     640             :     // Emit now if we can for better errors.
     641         533 :     int64_t NonZeroSize = Size > 4 ? 4 : Size;
     642         533 :     Expr &= ~0ULL >> (64 - NonZeroSize * 8);
     643     1746003 :     for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
     644     1745470 :       EmitIntValue(Expr, NonZeroSize);
     645     1745470 :       if (NonZeroSize < Size)
     646           7 :         EmitIntValue(0, Size - NonZeroSize);
     647             :     }
     648             :     return;
     649             :   }
     650             : 
     651             :   // Otherwise emit as fragment.
     652           5 :   MCDataFragment *DF = getOrCreateDataFragment();
     653           5 :   flushPendingLabels(DF, DF->getContents().size());
     654             : 
     655             :   assert(getCurrentSectionOnly() && "need a section");
     656          10 :   insert(new MCFillFragment(Expr, Size, NumValues, Loc));
     657             : }
     658             : 
     659        3848 : void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
     660        3848 :   getAssembler().addFileName(Filename);
     661        3848 : }
     662             : 
     663        7847 : void MCObjectStreamer::FinishImpl() {
     664             :   // If we are generating dwarf for assembly source files dump out the sections.
     665        7847 :   if (getContext().getGenDwarfForAssembly())
     666          23 :     MCGenDwarfInfo::Emit(this);
     667             : 
     668             :   // Dump out the dwarf file & directory tables and line tables.
     669        7847 :   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
     670             : 
     671        7847 :   flushPendingLabels(nullptr);
     672        7847 :   getAssembler().Finish();
     673        7829 : }

Generated by: LCOV version 1.13