brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.9 KiB · 9446814 Raw
792 lines · cpp
1//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/MC/MCObjectStreamer.h"10#include "llvm/MC/MCAsmBackend.h"11#include "llvm/MC/MCAsmInfo.h"12#include "llvm/MC/MCAssembler.h"13#include "llvm/MC/MCCodeEmitter.h"14#include "llvm/MC/MCCodeView.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCDwarf.h"17#include "llvm/MC/MCExpr.h"18#include "llvm/MC/MCObjectFileInfo.h"19#include "llvm/MC/MCObjectWriter.h"20#include "llvm/MC/MCSFrame.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"25using namespace llvm;26 27MCObjectStreamer::MCObjectStreamer(MCContext &Context,28                                   std::unique_ptr<MCAsmBackend> TAB,29                                   std::unique_ptr<MCObjectWriter> OW,30                                   std::unique_ptr<MCCodeEmitter> Emitter)31    : MCStreamer(Context),32      Assembler(std::make_unique<MCAssembler>(33          Context, std::move(TAB), std::move(Emitter), std::move(OW))),34      EmitEHFrame(true), EmitDebugFrame(false), EmitSFrame(false) {35  assert(Assembler->getBackendPtr() && Assembler->getEmitterPtr());36  IsObj = true;37  setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());38  if (Context.getTargetOptions() && Context.getTargetOptions()->MCRelaxAll)39    Assembler->setRelaxAll(true);40}41 42MCObjectStreamer::~MCObjectStreamer() = default;43 44MCAssembler *MCObjectStreamer::getAssemblerPtr() {45  if (getUseAssemblerInfoForParsing())46    return Assembler.get();47  return nullptr;48}49 50constexpr size_t FragBlockSize = 16384;51// Ensure the new fragment can at least store a few bytes.52constexpr size_t NewFragHeadroom = 8;53 54static_assert(NewFragHeadroom >= alignof(MCFragment));55static_assert(FragBlockSize >= sizeof(MCFragment) + NewFragHeadroom);56 57MCFragment *MCObjectStreamer::allocFragSpace(size_t Headroom) {58  auto Size = std::max(FragBlockSize, sizeof(MCFragment) + Headroom);59  FragSpace = Size - sizeof(MCFragment);60  auto Block = std::unique_ptr<uint8_t[]>(new uint8_t[Size]);61  auto *F = reinterpret_cast<MCFragment *>(Block.get());62  FragStorage.push_back(std::move(Block));63  return F;64}65 66void MCObjectStreamer::newFragment() {67  MCFragment *F;68  if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {69    auto End = reinterpret_cast<size_t>(getCurFragEnd());70    F = reinterpret_cast<MCFragment *>(71        alignToPowerOf2(End, alignof(MCFragment)));72    FragSpace -= size_t(F) - End + sizeof(MCFragment);73  } else {74    F = allocFragSpace(0);75  }76  new (F) MCFragment();77  addFragment(F);78}79 80void MCObjectStreamer::ensureHeadroom(size_t Headroom) {81  if (Headroom <= FragSpace)82    return;83  auto *F = allocFragSpace(Headroom);84  new (F) MCFragment();85  addFragment(F);86}87 88void MCObjectStreamer::addSpecialFragment(MCFragment *Frag) {89  assert(Frag->getKind() != MCFragment::FT_Data &&90         "Frag should have a variable-size tail");91  // Frag is not connected to FragSpace. Before modifying CurFrag with92  // addFragment(Frag), allocate an empty fragment to maintain FragSpace93  // connectivity, potentially reusing CurFrag's associated space.94  MCFragment *F;95  if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {96    auto End = reinterpret_cast<size_t>(getCurFragEnd());97    F = reinterpret_cast<MCFragment *>(98        alignToPowerOf2(End, alignof(MCFragment)));99    FragSpace -= size_t(F) - End + sizeof(MCFragment);100  } else {101    F = allocFragSpace(0);102  }103  new (F) MCFragment();104 105  addFragment(Frag);106  addFragment(F);107}108 109void MCObjectStreamer::appendContents(ArrayRef<char> Contents) {110  ensureHeadroom(Contents.size());111  assert(FragSpace >= Contents.size());112  llvm::copy(Contents, getCurFragEnd());113  CurFrag->FixedSize += Contents.size();114  FragSpace -= Contents.size();115}116 117void MCObjectStreamer::appendContents(size_t Num, uint8_t Elt) {118  ensureHeadroom(Num);119  MutableArrayRef<uint8_t> Data(getCurFragEnd(), Num);120  llvm::fill(Data, Elt);121  CurFrag->FixedSize += Num;122  FragSpace -= Num;123}124 125void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind) {126  CurFrag->addFixup(MCFixup::create(getCurFragSize(), Value, Kind));127}128 129// As a compile-time optimization, avoid allocating and evaluating an MCExpr130// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment's fixed131// part.132static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,133                                                  const MCSymbol *Lo) {134  assert(Hi && Lo);135  if (Lo == Hi)136    return 0;137  if (Hi->isVariable() || Lo->isVariable())138    return std::nullopt;139  auto *LoF = Lo->getFragment();140  if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())141    return std::nullopt;142  // If either symbol resides in the variable part, bail out.143  auto Fixed = LoF->getFixedSize();144  if (Lo->getOffset() > Fixed || Hi->getOffset() > Fixed)145    return std::nullopt;146 147  return Hi->getOffset() - Lo->getOffset();148}149 150void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,151                                              const MCSymbol *Lo,152                                              unsigned Size) {153  if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))154    emitIntValue(*Diff, Size);155  else156    MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);157}158 159void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,160                                                       const MCSymbol *Lo) {161  if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))162    emitULEB128IntValue(*Diff);163  else164    MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);165}166 167void MCObjectStreamer::reset() {168  if (Assembler) {169    Assembler->reset();170    if (getContext().getTargetOptions())171      Assembler->setRelaxAll(getContext().getTargetOptions()->MCRelaxAll);172  }173  EmitEHFrame = true;174  EmitDebugFrame = false;175  FragStorage.clear();176  FragSpace = 0;177  SpecialFragAllocator.Reset();178  MCStreamer::reset();179}180 181void MCObjectStreamer::emitFrames() {182  if (!getNumFrameInfos())183    return;184 185  auto *MAB = &getAssembler().getBackend();186  if (EmitEHFrame)187    MCDwarfFrameEmitter::Emit(*this, MAB, true);188 189  if (EmitDebugFrame)190    MCDwarfFrameEmitter::Emit(*this, MAB, false);191 192  if (EmitSFrame || (getContext().getTargetOptions() &&193                     getContext().getTargetOptions()->EmitSFrameUnwind))194    MCSFrameEmitter::emit(*this);195}196 197void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {198  Assembler->registerSymbol(Sym);199}200 201void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {202  MCStreamer::emitCFISections(EH, Debug, SFrame);203  EmitEHFrame = EH;204  EmitDebugFrame = Debug;205  EmitSFrame = SFrame;206}207 208void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,209                                     SMLoc Loc) {210  MCStreamer::emitValueImpl(Value, Size, Loc);211 212  MCDwarfLineEntry::make(this, getCurrentSectionOnly());213 214  // Avoid fixups when possible.215  int64_t AbsValue;216  if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {217    if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {218      getContext().reportError(219          Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");220      return;221    }222    emitIntValue(AbsValue, Size);223    return;224  }225  ensureHeadroom(Size);226  addFixup(Value, MCFixup::getDataKindForSize(Size));227  appendContents(Size, 0);228}229 230MCSymbol *MCObjectStreamer::emitCFILabel() {231  MCSymbol *Label = getContext().createTempSymbol("cfi");232  emitLabel(Label);233  return Label;234}235 236void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {237  // We need to create a local symbol to avoid relocations.238  Frame.Begin = getContext().createTempSymbol();239  emitLabel(Frame.Begin);240}241 242void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {243  Frame.End = getContext().createTempSymbol();244  emitLabel(Frame.End);245}246 247void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {248  MCStreamer::emitLabel(Symbol, Loc);249  // If Symbol is a non-redefiniable variable, emitLabel has reported an error.250  // Bail out.251  if (Symbol->isVariable())252    return;253 254  getAssembler().registerSymbol(*Symbol);255 256  // Set the fragment and offset. This function might be called by257  // changeSection, when the section stack top hasn't been changed to the new258  // section.259  MCFragment *F = CurFrag;260  Symbol->setFragment(F);261  Symbol->setOffset(F->getFixedSize());262 263  emitPendingAssignments(Symbol);264}265 266void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {267  auto Assignments = pendingAssignments.find(Symbol);268  if (Assignments != pendingAssignments.end()) {269    for (const PendingAssignment &A : Assignments->second)270      emitAssignment(A.Symbol, A.Value);271 272    pendingAssignments.erase(Assignments);273  }274}275 276// Emit a label at a previously emitted fragment/offset position. This must be277// within the currently-active section.278void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,279                                      MCFragment &F, uint64_t Offset) {280  assert(F.getParent() == getCurrentSectionOnly());281  MCStreamer::emitLabel(Symbol, Loc);282  getAssembler().registerSymbol(*Symbol);283  Symbol->setFragment(&F);284  Symbol->setOffset(Offset);285}286 287void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {288  int64_t IntValue;289  if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {290    emitULEB128IntValue(IntValue);291    return;292  }293  auto *F = getCurrentFragment();294  F->makeLEB(false, Value);295  newFragment();296}297 298void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {299  int64_t IntValue;300  if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {301    emitSLEB128IntValue(IntValue);302    return;303  }304  auto *F = getCurrentFragment();305  F->makeLEB(true, Value);306  newFragment();307}308 309void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,310                                         const MCSymbol *Target) {311  reportFatalUsageError("this file format doesn't support weak aliases");312}313 314void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {315  assert(Section && "Cannot switch to a null section!");316  getContext().clearDwarfLocSeen();317 318  // Register the section and create an initial fragment for subsection 0319  // if `Subsection` is non-zero.320  bool NewSec = getAssembler().registerSection(*Section);321  MCFragment *F0 = nullptr;322  if (NewSec && Subsection) {323    changeSection(Section, 0);324    F0 = CurFrag;325  }326 327  // To maintain connectivity between CurFrag and FragSpace when CurFrag is328  // modified, allocate an empty fragment and append it to the fragment list.329  // (Subsections[I].second.Tail is not connected to FragSpace.)330  MCFragment *F;331  if (LLVM_LIKELY(sizeof(MCFragment) + NewFragHeadroom <= FragSpace)) {332    auto End = reinterpret_cast<size_t>(getCurFragEnd());333    F = reinterpret_cast<MCFragment *>(334        alignToPowerOf2(End, alignof(MCFragment)));335    FragSpace -= size_t(F) - End + sizeof(MCFragment);336  } else {337    F = allocFragSpace(0);338  }339  new (F) MCFragment();340  F->setParent(Section);341 342  auto &Subsections = Section->Subsections;343  size_t I = 0, E = Subsections.size();344  while (I != E && Subsections[I].first < Subsection)345    ++I;346  // If the subsection number is not in the sorted Subsections list, create a347  // new fragment list.348  if (I == E || Subsections[I].first != Subsection) {349    Subsections.insert(Subsections.begin() + I,350                       {Subsection, MCSection::FragList{F, F}});351    Section->CurFragList = &Subsections[I].second;352    CurFrag = F;353  } else {354    Section->CurFragList = &Subsections[I].second;355    CurFrag = Subsections[I].second.Tail;356    // Ensure CurFrag is associated with FragSpace.357    addFragment(F);358  }359 360  // Define the section symbol at subsection 0's initial fragment if required.361  if (!NewSec)362    return;363  if (auto *Sym = Section->getBeginSymbol()) {364    Sym->setFragment(Subsection ? F0 : CurFrag);365    getAssembler().registerSymbol(*Sym);366  }367}368 369void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {370  getAssembler().registerSymbol(*Symbol);371  MCStreamer::emitAssignment(Symbol, Value);372  emitPendingAssignments(Symbol);373}374 375void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol,376                                                 const MCExpr *Value) {377  const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol();378 379  // If the symbol already exists, emit the assignment. Otherwise, emit it380  // later only if the symbol is also emitted.381  if (Target->isRegistered())382    emitAssignment(Symbol, Value);383  else384    pendingAssignments[Target].push_back({Symbol, Value});385}386 387bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {388  return Sec.hasInstructions();389}390 391void MCObjectStreamer::emitInstruction(const MCInst &Inst,392                                       const MCSubtargetInfo &STI) {393  MCStreamer::emitInstruction(Inst, STI);394 395  MCSection *Sec = getCurrentSectionOnly();396  Sec->setHasInstructions(true);397 398  // Now that a machine instruction has been assembled into this section, make399  // a line entry for any .loc directive that has been seen.400  MCDwarfLineEntry::make(this, getCurrentSectionOnly());401 402  // If this instruction doesn't need relaxation, just emit it as data.403  MCAssembler &Assembler = getAssembler();404  MCAsmBackend &Backend = Assembler.getBackend();405  if (!(Backend.mayNeedRelaxation(Inst.getOpcode(), Inst.getOperands(), STI) ||406        Backend.allowEnhancedRelaxation())) {407    emitInstToData(Inst, STI);408    return;409  }410 411  // Otherwise, relax and emit it as data if RelaxAll is specified.412  if (Assembler.getRelaxAll()) {413    MCInst Relaxed = Inst;414    while (Backend.mayNeedRelaxation(Relaxed.getOpcode(), Relaxed.getOperands(),415                                     STI))416      Backend.relaxInstruction(Relaxed, STI);417    emitInstToData(Relaxed, STI);418    return;419  }420 421  emitInstToFragment(Inst, STI);422}423 424void MCObjectStreamer::emitInstToData(const MCInst &Inst,425                                      const MCSubtargetInfo &STI) {426  MCFragment *F = getCurrentFragment();427 428  // Append the instruction to the data fragment.429  size_t CodeOffset = getCurFragSize();430  SmallString<16> Content;431  SmallVector<MCFixup, 1> Fixups;432  getAssembler().getEmitter().encodeInstruction(Inst, Content, Fixups, STI);433  appendContents(Content);434  if (CurFrag != F) {435    F = CurFrag;436    CodeOffset = 0;437  }438  F->setHasInstructions(STI);439 440  if (Fixups.empty())441    return;442  bool MarkedLinkerRelaxable = false;443  for (auto &Fixup : Fixups) {444    Fixup.setOffset(Fixup.getOffset() + CodeOffset);445    if (!Fixup.isLinkerRelaxable() || MarkedLinkerRelaxable)446      continue;447    MarkedLinkerRelaxable = true;448    // Set the fragment's order within the subsection for use by449    // MCAssembler::relaxAlign.450    auto *Sec = F->getParent();451    if (!Sec->isLinkerRelaxable())452      Sec->setFirstLinkerRelaxable(F->getLayoutOrder());453    // Do not add data after a linker-relaxable instruction. The difference454    // between a new label and a label at or before the linker-relaxable455    // instruction cannot be resolved at assemble-time.456    F->setLinkerRelaxable();457    newFragment();458  }459  F->appendFixups(Fixups);460}461 462void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,463                                          const MCSubtargetInfo &STI) {464  auto *F = getCurrentFragment();465  SmallVector<char, 16> Data;466  SmallVector<MCFixup, 1> Fixups;467  getAssembler().getEmitter().encodeInstruction(Inst, Data, Fixups, STI);468 469  F->Kind = MCFragment::FT_Relaxable;470  F->setHasInstructions(STI);471 472  F->setVarContents(Data);473  F->setInst(Inst);474 475  bool MarkedLinkerRelaxable = false;476  for (auto &Fixup : Fixups) {477    if (!Fixup.isLinkerRelaxable() || MarkedLinkerRelaxable)478      continue;479    MarkedLinkerRelaxable = true;480    auto *Sec = F->getParent();481    if (!Sec->isLinkerRelaxable())482      Sec->setFirstLinkerRelaxable(F->getLayoutOrder());483    F->setLinkerRelaxable();484  }485  F->setVarFixups(Fixups);486 487  newFragment();488}489 490void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,491                                             unsigned Column, unsigned Flags,492                                             unsigned Isa,493                                             unsigned Discriminator,494                                             StringRef FileName,495                                             StringRef Comment) {496  // In case we see two .loc directives in a row, make sure the497  // first one gets a line entry.498  MCDwarfLineEntry::make(this, getCurrentSectionOnly());499 500  this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,501                                          Discriminator, FileName, Comment);502}503 504static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,505                                     const MCSymbol *B, SMLoc Loc) {506  MCContext &Context = OS.getContext();507  const MCExpr *ARef = MCSymbolRefExpr::create(A, Context);508  const MCExpr *BRef = MCSymbolRefExpr::create(B, Context);509  const MCExpr *AddrDelta =510      MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context, Loc);511  return AddrDelta;512}513 514static void emitDwarfSetLineAddr(MCObjectStreamer &OS,515                                 MCDwarfLineTableParams Params,516                                 int64_t LineDelta, const MCSymbol *Label,517                                 int PointerSize) {518  // emit the sequence to set the address519  OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);520  OS.emitULEB128IntValue(PointerSize + 1);521  OS.emitIntValue(dwarf::DW_LNE_set_address, 1);522  OS.emitSymbolValue(Label, PointerSize);523 524  // emit the sequence for the LineDelta (from 1) and a zero address delta.525  MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);526}527 528void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,529                                                const MCSymbol *LastLabel,530                                                const MCSymbol *Label,531                                                unsigned PointerSize) {532  if (!LastLabel) {533    emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,534                         Label, PointerSize);535    return;536  }537 538  // If the two labels are within the same fragment, then the address-offset is539  // already a fixed constant and is not relaxable. Emit the advance-line-addr540  // data immediately to save time and memory.541  if (auto OptAddrDelta = absoluteSymbolDiff(Label, LastLabel)) {542    SmallString<16> Tmp;543    MCDwarfLineAddr::encode(getContext(), Assembler->getDWARFLinetableParams(),544                            LineDelta, *OptAddrDelta, Tmp);545    emitBytes(Tmp);546    return;547  }548 549  auto *F = getCurrentFragment();550  F->Kind = MCFragment::FT_Dwarf;551  F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc()));552  F->setDwarfLineDelta(LineDelta);553  newFragment();554}555 556void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,557                                             MCSymbol *LastLabel,558                                             MCSymbol *EndLabel) {559  // Emit a DW_LNE_end_sequence into the line table. When EndLabel is null, it560  // means we should emit the entry for the end of the section and therefore we561  // use the section end label for the reference label. After having the562  // appropriate reference label, we emit the address delta and use INT64_MAX as563  // the line delta which is the signal that this is actually a564  // DW_LNE_end_sequence.565  if (!EndLabel)566    EndLabel = endSection(Section);567 568  // Switch back the dwarf line section, in case endSection had to switch the569  // section.570  MCContext &Ctx = getContext();571  switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());572 573  const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();574  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,575                           AsmInfo->getCodePointerSize());576}577 578void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,579                                                 const MCSymbol *Label,580                                                 SMLoc Loc) {581  auto *F = getCurrentFragment();582  F->Kind = MCFragment::FT_DwarfFrame;583  F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc));584  newFragment();585}586 587void MCObjectStreamer::emitSFrameCalculateFuncOffset(const MCSymbol *FuncBase,588                                                     const MCSymbol *FREBegin,589                                                     MCFragment *FDEFrag,590                                                     SMLoc Loc) {591  assert(FuncBase && "No function base address");592  assert(FREBegin && "FRE doesn't describe a location");593  auto *F = getCurrentFragment();594  F->Kind = MCFragment::FT_SFrame;595  F->setSFrameAddrDelta(buildSymbolDiff(*this, FREBegin, FuncBase, Loc));596  F->setSFrameFDE(FDEFrag);597  newFragment();598}599 600void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,601                                          unsigned Line, unsigned Column,602                                          bool PrologueEnd, bool IsStmt,603                                          StringRef FileName, SMLoc Loc) {604  // Validate the directive.605  if (!checkCVLocSection(FunctionId, FileNo, Loc))606    return;607 608  // Emit a label at the current position and record it in the CodeViewContext.609  MCSymbol *LineSym = getContext().createTempSymbol();610  emitLabel(LineSym);611  getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,612                                          FileNo, Line, Column, PrologueEnd,613                                          IsStmt);614}615 616void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId,617                                                const MCSymbol *Begin,618                                                const MCSymbol *End) {619  getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,620                                                       End);621  this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End);622}623 624void MCObjectStreamer::emitCVInlineLinetableDirective(625    unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,626    const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {627  getContext().getCVContext().emitInlineLineTableForFunction(628      *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,629      FnEndSym);630  this->MCStreamer::emitCVInlineLinetableDirective(631      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);632}633 634void MCObjectStreamer::emitCVDefRangeDirective(635    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,636    StringRef FixedSizePortion) {637  getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);638  // Attach labels that were pending before we created the defrange fragment to639  // the beginning of the new fragment.640  this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);641}642 643void MCObjectStreamer::emitCVStringTableDirective() {644  getContext().getCVContext().emitStringTable(*this);645}646void MCObjectStreamer::emitCVFileChecksumsDirective() {647  getContext().getCVContext().emitFileChecksums(*this);648}649 650void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {651  getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);652}653 654void MCObjectStreamer::emitBytes(StringRef Data) {655  MCDwarfLineEntry::make(this, getCurrentSectionOnly());656  appendContents(ArrayRef(Data.data(), Data.size()));657}658 659void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill,660                                            uint8_t FillLen,661                                            unsigned MaxBytesToEmit) {662  if (MaxBytesToEmit == 0)663    MaxBytesToEmit = Alignment.value();664  MCFragment *F = getCurrentFragment();665  F->makeAlign(Alignment, Fill, FillLen, MaxBytesToEmit);666  newFragment();667 668  // Update the maximum alignment on the current section if necessary.669  F->getParent()->ensureMinAlignment(Alignment);670}671 672void MCObjectStreamer::emitCodeAlignment(Align Alignment,673                                         const MCSubtargetInfo *STI,674                                         unsigned MaxBytesToEmit) {675  auto *F = getCurrentFragment();676  emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);677  F->u.align.EmitNops = true;678  F->STI = STI;679}680 681void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,682                                         unsigned char Value,683                                         SMLoc Loc) {684  newSpecialFragment<MCOrgFragment>(*Offset, Value, Loc);685}686 687void MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,688                                          const MCExpr *Expr, SMLoc Loc) {689  std::optional<MCFixupKind> MaybeKind =690      Assembler->getBackend().getFixupKind(Name);691  if (!MaybeKind) {692    getContext().reportError(Loc, "unknown relocation name");693    return;694  }695 696  MCFixupKind Kind = *MaybeKind;697  if (Expr)698    visitUsedExpr(*Expr);699  else700    Expr =701        MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());702 703  auto *O = &Offset;704  int64_t Val;705  if (Offset.evaluateAsAbsolute(Val, nullptr)) {706    auto *SecSym = getCurrentSectionOnly()->getBeginSymbol();707    O = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(SecSym, getContext()),708                                O, getContext(), Loc);709  }710  getAssembler().addRelocDirective({*O, Expr, Kind});711}712 713void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,714                                SMLoc Loc) {715  assert(getCurrentSectionOnly() && "need a section");716  newSpecialFragment<MCFillFragment>(FillValue, 1, NumBytes, Loc);717}718 719void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,720                                int64_t Expr, SMLoc Loc) {721  int64_t IntNumValues;722  // Do additional checking now if we can resolve the value.723  if (NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {724    if (IntNumValues < 0) {725      getContext().getSourceManager()->PrintMessage(726          Loc, SourceMgr::DK_Warning,727          "'.fill' directive with negative repeat count has no effect");728      return;729    }730    // Emit now if we can for better errors.731    int64_t NonZeroSize = Size > 4 ? 4 : Size;732    Expr &= ~0ULL >> (64 - NonZeroSize * 8);733    for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {734      emitIntValue(Expr, NonZeroSize);735      if (NonZeroSize < Size)736        emitIntValue(0, Size - NonZeroSize);737    }738    return;739  }740 741  // Otherwise emit as fragment.742  assert(getCurrentSectionOnly() && "need a section");743  newSpecialFragment<MCFillFragment>(Expr, Size, NumValues, Loc);744}745 746void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,747                                SMLoc Loc, const MCSubtargetInfo &STI) {748  assert(getCurrentSectionOnly() && "need a section");749  newSpecialFragment<MCNopsFragment>(NumBytes, ControlledNopLength, Loc, STI);750}751 752void MCObjectStreamer::emitFileDirective(StringRef Filename) {753  MCAssembler &Asm = getAssembler();754  Asm.getWriter().addFileName(Filename);755}756 757void MCObjectStreamer::emitFileDirective(StringRef Filename,758                                         StringRef CompilerVersion,759                                         StringRef TimeStamp,760                                         StringRef Description) {761  MCObjectWriter &W = getAssembler().getWriter();762  W.addFileName(Filename);763  if (CompilerVersion.size())764    W.setCompilerVersion(CompilerVersion);765  // TODO: add TimeStamp and Description to .file symbol table entry766  // with the integrated assembler.767}768 769void MCObjectStreamer::emitAddrsig() {770  getAssembler().getWriter().emitAddrsigSection();771}772 773void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) {774  getAssembler().getWriter().addAddrsigSymbol(Sym);775}776 777void MCObjectStreamer::finishImpl() {778  getContext().RemapDebugPaths();779 780  // If we are generating dwarf for assembly source files dump out the sections.781  if (getContext().getGenDwarfForAssembly())782    MCGenDwarfInfo::Emit(this);783 784  // Dump out the dwarf file & directory tables and line tables.785  MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());786 787  // Emit pseudo probes for the current module.788  MCPseudoProbeTable::emit(this);789 790  getAssembler().Finish();791}792