LCOV - code coverage report
Current view: top level - lib/MC - MCObjectStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 314 335 93.7 %
Date: 2017-09-14 15:23:50 Functions: 50 55 90.9 %
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/MCAsmInfo.h"
      14             : #include "llvm/MC/MCAssembler.h"
      15             : #include "llvm/MC/MCCodeEmitter.h"
      16             : #include "llvm/MC/MCCodeView.h"
      17             : #include "llvm/MC/MCContext.h"
      18             : #include "llvm/MC/MCDwarf.h"
      19             : #include "llvm/MC/MCExpr.h"
      20             : #include "llvm/MC/MCObjectWriter.h"
      21             : #include "llvm/MC/MCSection.h"
      22             : #include "llvm/MC/MCSymbol.h"
      23             : #include "llvm/Support/ErrorHandling.h"
      24             : #include "llvm/Support/SourceMgr.h"
      25             : #include "llvm/Support/TargetRegistry.h"
      26             : using namespace llvm;
      27             : 
      28        4147 : MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
      29             :                                    raw_pwrite_stream &OS,
      30        4147 :                                    MCCodeEmitter *Emitter_)
      31             :     : MCStreamer(Context),
      32             :       Assembler(new MCAssembler(Context, TAB, *Emitter_,
      33        4147 :                                 *TAB.createObjectWriter(OS))),
      34       16588 :       EmitEHFrame(true), EmitDebugFrame(false) {}
      35             : 
      36       12362 : MCObjectStreamer::~MCObjectStreamer() {
      37        4120 :   delete &Assembler->getBackend();
      38        4121 :   delete &Assembler->getEmitter();
      39        4121 :   delete &Assembler->getWriter();
      40        4121 :   delete Assembler;
      41        4121 : }
      42             : 
      43     7632828 : void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
      44     7632828 :   if (PendingLabels.empty())
      45             :     return;
      46      122244 :   if (!F) {
      47        4700 :     F = new MCDataFragment();
      48        4700 :     MCSection *CurSection = getCurrentSectionOnly();
      49        4700 :     CurSection->getFragmentList().insert(CurInsertionPoint, F);
      50        2350 :     F->setParent(CurSection);
      51             :   }
      52      572621 :   for (MCSymbol *Sym : PendingLabels) {
      53      205889 :     Sym->setFragment(F);
      54      205889 :     Sym->setOffset(FOffset);
      55             :   }
      56      122244 :   PendingLabels.clear();
      57             : }
      58             : 
      59      119067 : void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
      60             :                                               const MCSymbol *Lo,
      61             :                                               unsigned Size) {
      62             :   // If not assigned to the same (valid) fragment, fallback.
      63      293629 :   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
      64      233766 :       Hi->isVariable() || Lo->isVariable()) {
      65       61737 :     MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
      66       61737 :     return;
      67             :   }
      68             : 
      69       57330 :   EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
      70             : }
      71             : 
      72        1582 : void MCObjectStreamer::reset() {
      73        1582 :   if (Assembler)
      74        1582 :     Assembler->reset();
      75        1582 :   CurInsertionPoint = MCSection::iterator();
      76        1582 :   EmitEHFrame = true;
      77        1582 :   EmitDebugFrame = false;
      78        3164 :   PendingLabels.clear();
      79        1582 :   MCStreamer::reset();
      80        1582 : }
      81             : 
      82        4050 : void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
      83        8100 :   if (!getNumFrameInfos())
      84             :     return;
      85             : 
      86         960 :   if (EmitEHFrame)
      87         874 :     MCDwarfFrameEmitter::Emit(*this, MAB, true);
      88             : 
      89         960 :   if (EmitDebugFrame)
      90          86 :     MCDwarfFrameEmitter::Emit(*this, MAB, false);
      91             : }
      92             : 
      93     9621590 : MCFragment *MCObjectStreamer::getCurrentFragment() const {
      94             :   assert(getCurrentSectionOnly() && "No current section!");
      95             : 
      96    38486360 :   if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
      97             :     return &*std::prev(CurInsertionPoint);
      98             : 
      99             :   return nullptr;
     100             : }
     101             : 
     102     8276434 : MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
     103    16396363 :   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     104             :   // When bundling is enabled, we don't want to add data to a fragment that
     105             :   // already has instructions (see MCELFStreamer::EmitInstToData for details)
     106     8126847 :   if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() &&
     107        3391 :              F->hasInstructions())) {
     108      313012 :     F = new MCDataFragment();
     109      156506 :     insert(F);
     110             :   }
     111     8276434 :   return F;
     112             : }
     113             : 
     114     1526052 : void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
     115     1526052 :   Assembler->registerSymbol(Sym);
     116     1526052 : }
     117             : 
     118          86 : void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
     119          86 :   MCStreamer::EmitCFISections(EH, Debug);
     120          86 :   EmitEHFrame = EH;
     121          86 :   EmitDebugFrame = Debug;
     122          86 : }
     123             : 
     124      695679 : void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     125             :                                      SMLoc Loc) {
     126      695679 :   MCStreamer::EmitValueImpl(Value, Size, Loc);
     127      695679 :   MCDataFragment *DF = getOrCreateDataFragment();
     128     1391358 :   flushPendingLabels(DF, DF->getContents().size());
     129             : 
     130      695679 :   MCCVLineEntry::Make(this);
     131     1391358 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     132             : 
     133             :   // Avoid fixups when possible.
     134             :   int64_t AbsValue;
     135      695679 :   if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) {
     136        5844 :     if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
     137           2 :       getContext().reportError(
     138           6 :           Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
     139        5842 :       return;
     140             :     }
     141        5840 :     EmitIntValue(AbsValue, Size);
     142        5840 :     return;
     143             :   }
     144     1379676 :   DF->getFixups().push_back(
     145     2759352 :       MCFixup::create(DF->getContents().size(), Value,
     146     1379676 :                       MCFixup::getKindForSize(Size, false), Loc));
     147     2069514 :   DF->getContents().resize(DF->getContents().size() + Size, 0);
     148             : }
     149             : 
     150        7079 : void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
     151             :   // We need to create a local symbol to avoid relocations.
     152        7079 :   Frame.Begin = getContext().createTempSymbol();
     153        7079 :   EmitLabel(Frame.Begin);
     154        7079 : }
     155             : 
     156        7079 : void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
     157        7079 :   Frame.End = getContext().createTempSymbol();
     158        7079 :   EmitLabel(Frame.End);
     159        7079 : }
     160             : 
     161     1265999 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
     162     1265999 :   MCStreamer::EmitLabel(Symbol, Loc);
     163             : 
     164     1266000 :   getAssembler().registerSymbol(*Symbol);
     165             : 
     166             :   // If there is a current fragment, mark the symbol as pointing into it.
     167             :   // Otherwise queue the label and set its fragment pointer when we emit the
     168             :   // next fragment.
     169     2326118 :   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
     170     1060144 :   if (F && !(getAssembler().isBundlingEnabled() &&
     171          52 :              getAssembler().getRelaxAll())) {
     172     2120206 :     Symbol->setFragment(F);
     173     2120206 :     Symbol->setOffset(F->getContents().size());
     174             :   } else {
     175      205897 :     PendingLabels.push_back(Symbol);
     176             :   }
     177     1266000 : }
     178             : 
     179          10 : void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
     180          10 :   MCStreamer::EmitLabel(Symbol, Loc);
     181          10 :   getAssembler().registerSymbol(*Symbol);
     182          10 :   auto *DF = dyn_cast_or_null<MCDataFragment>(F);
     183             :   if (DF)
     184          10 :     Symbol->setFragment(F);
     185             :   else
     186           0 :     PendingLabels.push_back(Symbol);
     187          10 : }
     188             : 
     189          72 : void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
     190             :   int64_t IntValue;
     191          72 :   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
     192          71 :     EmitULEB128IntValue(IntValue);
     193          71 :     return;
     194             :   }
     195           1 :   insert(new MCLEBFragment(*Value, false));
     196             : }
     197             : 
     198          43 : void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
     199             :   int64_t IntValue;
     200          43 :   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
     201          41 :     EmitSLEB128IntValue(IntValue);
     202          41 :     return;
     203             :   }
     204           2 :   insert(new MCLEBFragment(*Value, true));
     205             : }
     206             : 
     207           0 : void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
     208             :                                          const MCSymbol *Symbol) {
     209           0 :   report_fatal_error("This file format doesn't support weak aliases.");
     210             : }
     211             : 
     212        2022 : void MCObjectStreamer::ChangeSection(MCSection *Section,
     213             :                                      const MCExpr *Subsection) {
     214        2022 :   changeSectionImpl(Section, Subsection);
     215        2022 : }
     216             : 
     217      396279 : bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
     218             :                                          const MCExpr *Subsection) {
     219             :   assert(Section && "Cannot switch to a null section!");
     220      396279 :   flushPendingLabels(nullptr);
     221      396280 :   getContext().clearDwarfLocSeen();
     222             : 
     223      396280 :   bool Created = getAssembler().registerSection(*Section);
     224             : 
     225      396280 :   int64_t IntSubsection = 0;
     226      396286 :   if (Subsection &&
     227           6 :       !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler()))
     228           0 :     report_fatal_error("Cannot evaluate subsection number");
     229      396280 :   if (IntSubsection < 0 || IntSubsection > 8192)
     230           0 :     report_fatal_error("Subsection number out of range");
     231      396280 :   CurInsertionPoint =
     232      396280 :       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
     233      396280 :   return Created;
     234             : }
     235             : 
     236        2949 : void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
     237        2949 :   getAssembler().registerSymbol(*Symbol);
     238        2949 :   MCStreamer::EmitAssignment(Symbol, Value);
     239        2949 : }
     240             : 
     241          31 : bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
     242          31 :   return Sec.hasInstructions();
     243             : }
     244             : 
     245     1480043 : void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
     246             :                                        const MCSubtargetInfo &STI, bool) {
     247     1480043 :   MCStreamer::EmitInstruction(Inst, STI);
     248             : 
     249     2960086 :   MCSection *Sec = getCurrentSectionOnly();
     250     1480043 :   Sec->setHasInstructions(true);
     251             : 
     252             :   // Now that a machine instruction has been assembled into this section, make
     253             :   // a line entry for any .loc directive that has been seen.
     254     1480043 :   MCCVLineEntry::Make(this);
     255     2960086 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     256             : 
     257             :   // If this instruction doesn't need relaxation, just emit it as data.
     258     1480042 :   MCAssembler &Assembler = getAssembler();
     259     1480042 :   if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
     260     1422767 :     EmitInstToData(Inst, STI);
     261     1422767 :     return;
     262             :   }
     263             : 
     264             :   // Otherwise, relax and emit it as data if either:
     265             :   // - The RelaxAll flag was passed
     266             :   // - Bundling is enabled and this instruction is inside a bundle-locked
     267             :   //   group. We want to emit all such instructions into the same data
     268             :   //   fragment.
     269       57276 :   if (Assembler.getRelaxAll() ||
     270           5 :       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
     271          16 :     MCInst Relaxed;
     272           8 :     getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
     273           0 :     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
     274           0 :       getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
     275           8 :     EmitInstToData(Relaxed, STI);
     276             :     return;
     277             :   }
     278             : 
     279             :   // Otherwise emit to a separate fragment.
     280       57268 :   EmitInstToFragment(Inst, STI);
     281             : }
     282             : 
     283       57268 : void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
     284             :                                           const MCSubtargetInfo &STI) {
     285      114536 :   if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
     286           0 :     llvm_unreachable("All instructions should have already been relaxed");
     287             : 
     288             :   // Always create a new, separate fragment here, because its size can change
     289             :   // during relaxation.
     290       57268 :   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
     291       57268 :   insert(IF);
     292             : 
     293      114536 :   SmallString<128> Code;
     294      114536 :   raw_svector_ostream VecOS(Code);
     295      171804 :   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
     296       57268 :                                                 STI);
     297      229072 :   IF->getContents().append(Code.begin(), Code.end());
     298       57268 : }
     299             : 
     300             : #ifndef NDEBUG
     301             : static const char *const BundlingNotImplementedMsg =
     302             :   "Aligned bundling is not implemented for this object format";
     303             : #endif
     304             : 
     305           0 : void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
     306           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     307             : }
     308             : 
     309           0 : void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
     310           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     311             : }
     312             : 
     313           0 : void MCObjectStreamer::EmitBundleUnlock() {
     314           0 :   llvm_unreachable(BundlingNotImplementedMsg);
     315             : }
     316             : 
     317      420575 : void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
     318             :                                              unsigned Column, unsigned Flags,
     319             :                                              unsigned Isa,
     320             :                                              unsigned Discriminator,
     321             :                                              StringRef FileName) {
     322             :   // In case we see two .loc directives in a row, make sure the
     323             :   // first one gets a line entry.
     324      841150 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     325             : 
     326      420575 :   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
     327             :                                           Isa, Discriminator, FileName);
     328      420575 : }
     329             : 
     330      601860 : static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
     331             :                                      const MCSymbol *B) {
     332      601860 :   MCContext &Context = OS.getContext();
     333      601860 :   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
     334      601860 :   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
     335      601860 :   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
     336             :   const MCExpr *AddrDelta =
     337      601860 :       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
     338      601860 :   return AddrDelta;
     339             : }
     340             : 
     341        5472 : static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
     342             :                                  MCDwarfLineTableParams Params,
     343             :                                  int64_t LineDelta, const MCSymbol *Label,
     344             :                                  int PointerSize) {
     345             :   // emit the sequence to set the address
     346        5472 :   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
     347        5472 :   OS.EmitULEB128IntValue(PointerSize + 1);
     348        5472 :   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
     349        5472 :   OS.EmitSymbolValue(Label, PointerSize);
     350             : 
     351             :   // emit the sequence for the LineDelta (from 1) and a zero address delta.
     352        5472 :   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
     353        5472 : }
     354             : 
     355      426046 : void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
     356             :                                                 const MCSymbol *LastLabel,
     357             :                                                 const MCSymbol *Label,
     358             :                                                 unsigned PointerSize) {
     359      426046 :   if (!LastLabel) {
     360       10944 :     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
     361             :                          Label, PointerSize);
     362        5472 :     return;
     363             :   }
     364      420574 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     365             :   int64_t Res;
     366      420574 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
     367      737616 :     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
     368             :                           Res);
     369      368808 :     return;
     370             :   }
     371       51766 :   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
     372             : }
     373             : 
     374      181286 : void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
     375             :                                                  const MCSymbol *Label) {
     376      181286 :   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
     377             :   int64_t Res;
     378      181286 :   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
     379      178937 :     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
     380      178937 :     return;
     381             :   }
     382        2349 :   insert(new MCDwarfCallFrameFragment(*AddrDelta));
     383             : }
     384             : 
     385         330 : void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
     386             :                                           unsigned Line, unsigned Column,
     387             :                                           bool PrologueEnd, bool IsStmt,
     388             :                                           StringRef FileName, SMLoc Loc) {
     389             :   // In case we see two .cv_loc directives in a row, make sure the
     390             :   // first one gets a line entry.
     391         330 :   MCCVLineEntry::Make(this);
     392             : 
     393         330 :   this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
     394             :                                        PrologueEnd, IsStmt, FileName, Loc);
     395         330 : }
     396             : 
     397          92 : void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
     398             :                                                 const MCSymbol *Begin,
     399             :                                                 const MCSymbol *End) {
     400          92 :   getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
     401             :                                                        End);
     402          92 :   this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
     403          92 : }
     404             : 
     405          22 : void MCObjectStreamer::EmitCVInlineLinetableDirective(
     406             :     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
     407             :     const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
     408          22 :   getContext().getCVContext().emitInlineLineTableForFunction(
     409             :       *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
     410             :       FnEndSym);
     411          22 :   this->MCStreamer::EmitCVInlineLinetableDirective(
     412             :       PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
     413          22 : }
     414             : 
     415         106 : void MCObjectStreamer::EmitCVDefRangeDirective(
     416             :     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     417             :     StringRef FixedSizePortion) {
     418         106 :   getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
     419         106 :   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
     420         106 : }
     421             : 
     422          66 : void MCObjectStreamer::EmitCVStringTableDirective() {
     423          66 :   getContext().getCVContext().emitStringTable(*this);
     424          66 : }
     425          66 : void MCObjectStreamer::EmitCVFileChecksumsDirective() {
     426          66 :   getContext().getCVContext().emitFileChecksums(*this);
     427          66 : }
     428             : 
     429             : 
     430     6160143 : void MCObjectStreamer::EmitBytes(StringRef Data) {
     431     6160143 :   MCCVLineEntry::Make(this);
     432    12320286 :   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
     433     6160143 :   MCDataFragment *DF = getOrCreateDataFragment();
     434    12320286 :   flushPendingLabels(DF, DF->getContents().size());
     435    18480429 :   DF->getContents().append(Data.begin(), Data.end());
     436     6160143 : }
     437             : 
     438       80758 : void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
     439             :                                             int64_t Value,
     440             :                                             unsigned ValueSize,
     441             :                                             unsigned MaxBytesToEmit) {
     442       80758 :   if (MaxBytesToEmit == 0)
     443       80742 :     MaxBytesToEmit = ByteAlignment;
     444      161517 :   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
     445             : 
     446             :   // Update the maximum alignment on the current section if necessary.
     447      161516 :   MCSection *CurSec = getCurrentSectionOnly();
     448       80758 :   if (ByteAlignment > CurSec->getAlignment())
     449       41796 :     CurSec->setAlignment(ByteAlignment);
     450       80758 : }
     451             : 
     452       17096 : void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
     453             :                                          unsigned MaxBytesToEmit) {
     454       17096 :   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
     455       51288 :   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
     456       17096 : }
     457             : 
     458          19 : void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
     459             :                                          unsigned char Value,
     460             :                                          SMLoc Loc) {
     461          38 :   insert(new MCOrgFragment(*Offset, Value, Loc));
     462          19 : }
     463             : 
     464             : // Associate DTPRel32 fixup with data and resize data area
     465           4 : void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
     466           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     467           8 :   flushPendingLabels(DF, DF->getContents().size());
     468             : 
     469          16 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     470           8 :                                             Value, FK_DTPRel_4));
     471          12 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     472           4 : }
     473             : 
     474             : // Associate DTPRel64 fixup with data and resize data area
     475           4 : void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
     476           4 :   MCDataFragment *DF = getOrCreateDataFragment();
     477           8 :   flushPendingLabels(DF, DF->getContents().size());
     478             : 
     479          16 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     480           8 :                                             Value, FK_DTPRel_8));
     481          12 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     482           4 : }
     483             : 
     484             : // Associate TPRel32 fixup with data and resize data area
     485           3 : void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
     486           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     487           6 :   flushPendingLabels(DF, DF->getContents().size());
     488             : 
     489          12 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     490           6 :                                             Value, FK_TPRel_4));
     491           9 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     492           3 : }
     493             : 
     494             : // Associate TPRel64 fixup with data and resize data area
     495           3 : void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
     496           3 :   MCDataFragment *DF = getOrCreateDataFragment();
     497           6 :   flushPendingLabels(DF, DF->getContents().size());
     498             : 
     499          12 :   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
     500           6 :                                             Value, FK_TPRel_8));
     501           9 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     502           3 : }
     503             : 
     504             : // Associate GPRel32 fixup with data and resize data area
     505          11 : void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
     506          11 :   MCDataFragment *DF = getOrCreateDataFragment();
     507          22 :   flushPendingLabels(DF, DF->getContents().size());
     508             : 
     509          22 :   DF->getFixups().push_back(
     510          44 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     511          33 :   DF->getContents().resize(DF->getContents().size() + 4, 0);
     512          11 : }
     513             : 
     514             : // Associate GPRel64 fixup with data and resize data area
     515          13 : void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
     516          13 :   MCDataFragment *DF = getOrCreateDataFragment();
     517          26 :   flushPendingLabels(DF, DF->getContents().size());
     518             : 
     519          26 :   DF->getFixups().push_back(
     520          52 :       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
     521          39 :   DF->getContents().resize(DF->getContents().size() + 8, 0);
     522          13 : }
     523             : 
     524          22 : bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
     525             :                                           const MCExpr *Expr, SMLoc Loc) {
     526             :   int64_t OffsetValue;
     527          22 :   if (!Offset.evaluateAsAbsolute(OffsetValue))
     528           0 :     llvm_unreachable("Offset is not absolute");
     529             : 
     530          22 :   if (OffsetValue < 0)
     531           0 :     llvm_unreachable("Offset is negative");
     532             : 
     533          22 :   MCDataFragment *DF = getOrCreateDataFragment();
     534          44 :   flushPendingLabels(DF, DF->getContents().size());
     535             : 
     536          44 :   Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
     537          22 :   if (!MaybeKind.hasValue())
     538             :     return true;
     539             : 
     540          22 :   MCFixupKind Kind = *MaybeKind;
     541             : 
     542          22 :   if (Expr == nullptr)
     543           3 :     Expr =
     544           3 :         MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
     545          44 :   DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
     546          22 :   return false;
     547             : }
     548             : 
     549       25856 : void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
     550             :   assert(getCurrentSectionOnly() && "need a section");
     551       51712 :   insert(new MCFillFragment(FillValue, NumBytes));
     552       25856 : }
     553             : 
     554         198 : void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
     555             :                                 SMLoc Loc) {
     556         198 :   MCDataFragment *DF = getOrCreateDataFragment();
     557         396 :   flushPendingLabels(DF, DF->getContents().size());
     558             : 
     559             :   int64_t IntNumBytes;
     560         198 :   if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
     561           0 :     getContext().reportError(Loc, "expected absolute expression");
     562           0 :     return;
     563             :   }
     564             : 
     565         198 :   if (IntNumBytes <= 0) {
     566           0 :     getContext().reportError(Loc, "invalid number of bytes");
     567           0 :     return;
     568             :   }
     569             : 
     570         198 :   emitFill(IntNumBytes, FillValue);
     571             : }
     572             : 
     573         507 : void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
     574             :                                 int64_t Expr, SMLoc Loc) {
     575             :   int64_t IntNumValues;
     576         507 :   if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {
     577           0 :     getContext().reportError(Loc, "expected absolute expression");
     578           2 :     return;
     579             :   }
     580             : 
     581         507 :   if (IntNumValues < 0) {
     582           8 :     getContext().getSourceManager()->PrintMessage(
     583             :         Loc, SourceMgr::DK_Warning,
     584             :         "'.fill' directive with negative repeat count has no effect");
     585           2 :     return;
     586             :   }
     587             : 
     588         505 :   MCStreamer::emitFill(IntNumValues, Size, Expr);
     589             : }
     590             : 
     591        1225 : void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
     592        1225 :   getAssembler().addFileName(Filename);
     593        1225 : }
     594             : 
     595        4076 : void MCObjectStreamer::FinishImpl() {
     596             :   // If we are generating dwarf for assembly source files dump out the sections.
     597        4076 :   if (getContext().getGenDwarfForAssembly())
     598          24 :     MCGenDwarfInfo::Emit(this);
     599             : 
     600             :   // Dump out the dwarf file & directory tables and line tables.
     601        8152 :   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
     602             : 
     603        4076 :   flushPendingLabels(nullptr);
     604        4076 :   getAssembler().Finish();
     605        4062 : }

Generated by: LCOV version 1.13