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-10-20 13:21:21 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       12469 : MCObjectStreamer::MCObjectStreamer(MCContext &Context,
      27             :                                    std::unique_ptr<MCAsmBackend> TAB,
      28             :                                    std::unique_ptr<MCObjectWriter> OW,
      29       12469 :                                    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       12469 :       EmitEHFrame(true), EmitDebugFrame(false) {}
      34             : 
      35       16270 : 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     3983670 : MCAssembler *MCObjectStreamer::getAssemblerPtr() {
      41     3983670 :   if (getUseAssemblerInfoForParsing())
      42       17386 :     return Assembler.get();
      43             :   return nullptr;
      44             : }
      45             : 
      46    20228308 : void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
      47    20228308 :   if (PendingLabels.empty())
      48             :     return;
      49      758943 :   if (!F) {
      50       10053 :     F = new MCDataFragment();
      51             :     MCSection *CurSection = getCurrentSectionOnly();
      52             :     CurSection->getFragmentList().insert(CurInsertionPoint, F);
      53             :     F->setParent(CurSection);
      54             :   }
      55     1966354 :   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     1654996 : absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
      66             :   assert(Hi && Lo);
      67     1654996 :   if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
      68             :     return None;
      69             : 
      70     3232021 :   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
      71     3105112 :       Hi->isVariable() || Lo->isVariable())
      72             :     return None;
      73             : 
      74     1450091 :   return Hi->getOffset() - Lo->getOffset();
      75             : }
      76             : 
      77       99356 : void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
      78             :                                               const MCSymbol *Lo,
      79             :                                               unsigned Size) {
      80       99356 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
      81       58390 :     EmitIntValue(*Diff, Size);
      82             :     return;
      83             :   }
      84       40967 :   MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
      85             : }
      86             : 
      87     1555639 : void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
      88             :                                                        const MCSymbol *Lo) {
      89     1555639 :   if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
      90     1391701 :     EmitULEB128IntValue(*Diff);
      91             :     return;
      92             :   }
      93      163938 :   MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
      94             : }
      95             : 
      96        8140 : void MCObjectStreamer::reset() {
      97        8140 :   if (Assembler)
      98        8140 :     Assembler->reset();
      99        8140 :   CurInsertionPoint = MCSection::iterator();
     100        8140 :   EmitEHFrame = true;
     101        8140 :   EmitDebugFrame = false;
     102             :   PendingLabels.clear();
     103        8140 :   MCStreamer::reset();
     104        8140 : }
     105             : 
     106       12356 : void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
     107       12356 :   if (!getNumFrameInfos())
     108             :     return;
     109             : 
     110        6991 :   if (EmitEHFrame)
     111        6892 :     MCDwarfFrameEmitter::Emit(*this, MAB, true);
     112             : 
     113        6991 :   if (EmitDebugFrame)
     114          99 :     MCDwarfFrameEmitter::Emit(*this, MAB, false);
     115             : }
     116             : 
     117    82404031 : MCFragment *MCObjectStreamer::getCurrentFragment() const {
     118             :   assert(getCurrentSectionOnly() && "No current section!");
     119             : 
     120    82404031 :   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    41533764 :   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    30182871 :   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    30182745 :   return !STI || F.getSubtargetInfo() == STI;
     138             : }
     139             : 
     140             : MCDataFragment *
     141    44111480 : MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
     142    44111480 :   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     143         126 :   if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
     144     2577775 :     F = new MCDataFragment();
     145     2577775 :     insert(F);
     146             :   }
     147    44111480 :   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     8765327 : void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
     161     8765327 :   Assembler->registerSymbol(Sym);
     162     8765327 : }
     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     2249943 : void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     171             :                                      SMLoc Loc) {
     172     2249943 :   MCStreamer::EmitValueImpl(Value, Size, Loc);
     173     2249944 :   MCDataFragment *DF = getOrCreateDataFragment();
     174     4499888 :   flushPendingLabels(DF, DF->getContents().size());
     175             : 
     176     2249944 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     177             : 
     178             :   // Avoid fixups when possible.
     179             :   int64_t AbsValue;
     180     2249944 :   if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
     181       14357 :     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       14357 :       return;
     185             :     }
     186       14356 :     EmitIntValue(AbsValue, Size);
     187       14356 :     return;
     188             :   }
     189     4470920 :   DF->getFixups().push_back(
     190     2235587 :       MCFixup::create(DF->getContents().size(), Value,
     191             :                       MCFixup::getKindForSize(Size, false), Loc));
     192     4471174 :   DF->getContents().resize(DF->getContents().size() + Size, 0);
     193             : }
     194             : 
     195      941015 : MCSymbol *MCObjectStreamer::EmitCFILabel() {
     196     1882030 :   MCSymbol *Label = getContext().createTempSymbol("cfi", true);
     197      941015 :   EmitLabel(Label);
     198      941015 :   return Label;
     199             : }
     200             : 
     201      208012 : void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
     202             :   // We need to create a local symbol to avoid relocations.
     203      208012 :   Frame.Begin = getContext().createTempSymbol();
     204      208012 :   EmitLabel(Frame.Begin);
     205      208012 : }
     206             : 
     207      208011 : void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
     208      208011 :   Frame.End = getContext().createTempSymbol();
     209      208011 :   EmitLabel(Frame.End);
     210      208011 : }
     211             : 
     212     7789558 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     213     7789558 :   MCStreamer::EmitLabel(Symbol, Loc);
     214             : 
     215     7789559 :   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     7789560 :   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     221     6582155 :   if (F && !(getAssembler().isBundlingEnabled() &&
     222             :              getAssembler().getRelaxAll())) {
     223     6582140 :     Symbol->setFragment(F);
     224     6582140 :     Symbol->setOffset(F->getContents().size());
     225             :   } else {
     226     1207420 :     PendingLabels.push_back(Symbol);
     227             :   }
     228     7789560 : }
     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      164211 : void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
     241             :   int64_t IntValue;
     242      164211 :   if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
     243         263 :     EmitULEB128IntValue(IntValue);
     244         263 :     return;
     245             :   }
     246      163948 :   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        3941 : void MCObjectStreamer::ChangeSection(MCSection *Section,
     264             :                                      const MCExpr *Subsection) {
     265        3941 :   changeSectionImpl(Section, Subsection);
     266        3941 : }
     267             : 
     268      803448 : bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
     269             :                                          const MCExpr *Subsection) {
     270             :   assert(Section && "Cannot switch to a null section!");
     271      803448 :   flushPendingLabels(nullptr);
     272      803449 :   getContext().clearDwarfLocSeen();
     273             : 
     274      803449 :   bool Created = getAssembler().registerSection(*Section);
     275             : 
     276      803449 :   int64_t IntSubsection = 0;
     277      803455 :   if (Subsection &&
     278           6 :       !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
     279           0 :     report_fatal_error("Cannot evaluate subsection number");
     280      803449 :   if (IntSubsection < 0 || IntSubsection > 8192)
     281           0 :     report_fatal_error("Subsection number out of range");
     282             :   CurInsertionPoint =
     283      803449 :       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
     284      803449 :   return Created;
     285             : }
     286             : 
     287        5821 : void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     288        5821 :   getAssembler().registerSymbol(*Symbol);
     289        5821 :   MCStreamer::EmitAssignment(Symbol, Value);
     290        5821 : }
     291             : 
     292          40 : bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
     293          40 :   return Sec.hasInstructions();
     294             : }
     295             : 
     296    30185752 : void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
     297             :                                        const MCSubtargetInfo &STI, bool) {
     298    30185752 :   getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst);
     299    30185752 :   EmitInstructionImpl(Inst, STI);
     300    30185749 :   getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst);
     301    30185749 : }
     302             : 
     303    30185752 : void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
     304             :                                            const MCSubtargetInfo &STI) {
     305    30185752 :   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    30185752 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     313             : 
     314             :   // If this instruction doesn't need relaxation, just emit it as data.
     315             :   MCAssembler &Assembler = getAssembler();
     316    30185752 :   if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
     317    28085699 :     EmitInstToData(Inst, STI);
     318    28085696 :     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     2100053 :   if (Assembler.getRelaxAll() ||
     327      128057 :       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
     328             :     MCInst Relaxed;
     329     1971998 :     getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
     330     1971998 :     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
     331           0 :       getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
     332     1971998 :     EmitInstToData(Relaxed, STI);
     333             :     return;
     334             :   }
     335             : 
     336             :   // Otherwise emit to a separate fragment.
     337      128055 :   EmitInstToFragment(Inst, STI);
     338             : }
     339             : 
     340      128055 : void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
     341             :                                           const MCSubtargetInfo &STI) {
     342      128055 :   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      128055 :   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
     348      128055 :   insert(IF);
     349             : 
     350             :   SmallString<128> Code;
     351             :   raw_svector_ostream VecOS(Code);
     352      128055 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
     353      128055 :                                                 STI);
     354      128055 :   IF->getContents().append(Code.begin(), Code.end());
     355      128055 : }
     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      620952 : 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      620952 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     382             : 
     383      620952 :   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
     384             :                                           Isa, Discriminator, FileName);
     385      620952 : }
     386             : 
     387     1561448 : static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
     388             :                                      const MCSymbol *B) {
     389     1561448 :   MCContext &Context = OS.getContext();
     390             :   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
     391     1561448 :   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
     392     1561448 :   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
     393             :   const MCExpr *AddrDelta =
     394     1561448 :       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
     395     1561448 :   return AddrDelta;
     396             : }
     397             : 
     398        8072 : 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        8072 :   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
     404        8072 :   OS.EmitULEB128IntValue(PointerSize + 1);
     405        8072 :   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
     406        8072 :   OS.EmitSymbolValue(Label, PointerSize);
     407             : 
     408             :   // emit the sequence for the LineDelta (from 1) and a zero address delta.
     409        8072 :   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
     410        8072 : }
     411             : 
     412      629023 : void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
     413             :                                                 const MCSymbol *LastLabel,
     414             :                                                 const MCSymbol *Label,
     415             :                                                 unsigned PointerSize) {
     416      629023 :   if (!LastLabel) {
     417       16144 :     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
     418             :                          Label, PointerSize);
     419        8412 :     return;
     420             :   }
     421      620951 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     422             :   int64_t Res;
     423      620951 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     424         680 :     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
     425             :                           Res);
     426         340 :     return;
     427             :   }
     428     1241222 :   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
     429             : }
     430             : 
     431      940497 : void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
     432             :                                                  const MCSymbol *Label) {
     433      940497 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     434             :   int64_t Res;
     435      940497 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
     436         348 :     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
     437         348 :     return;
     438             :   }
     439      940149 :   insert(new MCDwarfCallFrameFragment(*AddrDelta));
     440             : }
     441             : 
     442         546 : 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         546 :   if (!checkCVLocSection(FunctionId, FileNo, Loc))
     448             :     return;
     449             : 
     450             :   // Emit a label at the current position and record it in the CodeViewContext.
     451         546 :   MCSymbol *LineSym = getContext().createTempSymbol();
     452         546 :   EmitLabel(LineSym);
     453         546 :   getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
     454             :                                           FileNo, Line, Column, PrologueEnd,
     455             :                                           IsStmt);
     456             : }
     457             : 
     458         158 : void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
     459             :                                                 const MCSymbol *Begin,
     460             :                                                 const MCSymbol *End) {
     461         158 :   getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
     462             :                                                        End);
     463         158 :   this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
     464         158 : }
     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         205 : void MCObjectStreamer::EmitCVDefRangeDirective(
     477             :     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     478             :     StringRef FixedSizePortion) {
     479         205 :   getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
     480         205 :   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
     481         205 : }
     482             : 
     483          94 : void MCObjectStreamer::EmitCVStringTableDirective() {
     484          94 :   getContext().getCVContext().emitStringTable(*this);
     485          94 : }
     486          91 : void MCObjectStreamer::EmitCVFileChecksumsDirective() {
     487          91 :   getContext().getCVContext().emitFileChecksums(*this);
     488          91 : }
     489             : 
     490         182 : void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
     491         182 :   getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
     492         182 : }
     493             : 
     494    11527740 : void MCObjectStreamer::EmitBytes(StringRef Data) {
     495    11527740 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     496    11527741 :   MCDataFragment *DF = getOrCreateDataFragment();
     497    23055486 :   flushPendingLabels(DF, DF->getContents().size());
     498    23055482 :   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    11527741 : }
     506             : 
     507      646094 : void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
     508             :                                             int64_t Value,
     509             :                                             unsigned ValueSize,
     510             :                                             unsigned MaxBytesToEmit) {
     511      646094 :   if (MaxBytesToEmit == 0)
     512             :     MaxBytesToEmit = ByteAlignment;
     513     1292189 :   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
     514             : 
     515             :   // Update the maximum alignment on the current section if necessary.
     516             :   MCSection *CurSec = getCurrentSectionOnly();
     517      646095 :   if (ByteAlignment > CurSec->getAlignment())
     518             :     CurSec->setAlignment(ByteAlignment);
     519      646095 : }
     520             : 
     521      233157 : void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
     522             :                                          unsigned MaxBytesToEmit) {
     523      233157 :   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
     524      233157 :   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
     525      233157 : }
     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     3047534 : void MCObjectStreamer::EmitCodePaddingBasicBlockStart(
     534             :     const MCCodePaddingContext &Context) {
     535     3047534 :   getAssembler().getBackend().handleCodePaddingBasicBlockStart(this, Context);
     536     3047534 : }
     537             : 
     538     3047534 : void MCObjectStreamer::EmitCodePaddingBasicBlockEnd(
     539             :     const MCCodePaddingContext &Context) {
     540     3047534 :   getAssembler().getBackend().handleCodePaddingBasicBlockEnd(Context);
     541     3047534 : }
     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      277914 : void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
     630             :                                 SMLoc Loc) {
     631      277914 :   MCDataFragment *DF = getOrCreateDataFragment();
     632      555828 :   flushPendingLabels(DF, DF->getContents().size());
     633             : 
     634             :   assert(getCurrentSectionOnly() && "need a section");
     635      555828 :   insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
     636      277914 : }
     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        7642 : void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
     669        7642 :   getAssembler().addFileName(Filename);
     670        7642 : }
     671             : 
     672        6215 : void MCObjectStreamer::EmitAddrsig() {
     673        6215 :   getAssembler().getWriter().emitAddrsigSection();
     674        6215 : }
     675             : 
     676      237782 : void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
     677      237782 :   getAssembler().registerSymbol(*Sym);
     678      237782 :   getAssembler().getWriter().addAddrsigSymbol(Sym);
     679      237782 : }
     680             : 
     681       12357 : void MCObjectStreamer::FinishImpl() {
     682       12357 :   getContext().RemapDebugPaths();
     683             : 
     684             :   // If we are generating dwarf for assembly source files dump out the sections.
     685       12357 :   if (getContext().getGenDwarfForAssembly())
     686          33 :     MCGenDwarfInfo::Emit(this);
     687             : 
     688             :   // Dump out the dwarf file & directory tables and line tables.
     689       12357 :   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
     690             : 
     691             :   flushPendingLabels();
     692       12357 :   getAssembler().Finish();
     693       12339 : }

Generated by: LCOV version 1.13