109467b48Spatrick //===- llvm/MC/MCWinCOFFStreamer.cpp --------------------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains an implementation of a Windows COFF object file streamer.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
13*d415bd75Srobert #include "llvm/MC/MCWinCOFFStreamer.h"
1409467b48Spatrick #include "llvm/ADT/SmallString.h"
1509467b48Spatrick #include "llvm/ADT/SmallVector.h"
1609467b48Spatrick #include "llvm/ADT/Triple.h"
1709467b48Spatrick #include "llvm/ADT/Twine.h"
1809467b48Spatrick #include "llvm/BinaryFormat/COFF.h"
1909467b48Spatrick #include "llvm/MC/MCAsmBackend.h"
2009467b48Spatrick #include "llvm/MC/MCAssembler.h"
2109467b48Spatrick #include "llvm/MC/MCCodeEmitter.h"
2209467b48Spatrick #include "llvm/MC/MCContext.h"
2309467b48Spatrick #include "llvm/MC/MCExpr.h"
2409467b48Spatrick #include "llvm/MC/MCFixup.h"
2509467b48Spatrick #include "llvm/MC/MCFragment.h"
2609467b48Spatrick #include "llvm/MC/MCObjectFileInfo.h"
2709467b48Spatrick #include "llvm/MC/MCObjectStreamer.h"
2809467b48Spatrick #include "llvm/MC/MCObjectWriter.h"
2909467b48Spatrick #include "llvm/MC/MCSection.h"
3009467b48Spatrick #include "llvm/MC/MCSymbolCOFF.h"
3109467b48Spatrick #include "llvm/Support/Casting.h"
3209467b48Spatrick #include "llvm/Support/ErrorHandling.h"
3309467b48Spatrick #include "llvm/Support/MathExtras.h"
3409467b48Spatrick #include "llvm/Support/SMLoc.h"
3509467b48Spatrick #include "llvm/Support/raw_ostream.h"
3609467b48Spatrick #include <algorithm>
3709467b48Spatrick #include <cstdint>
3809467b48Spatrick 
3909467b48Spatrick using namespace llvm;
4009467b48Spatrick 
4109467b48Spatrick #define DEBUG_TYPE "WinCOFFStreamer"
4209467b48Spatrick 
MCWinCOFFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCCodeEmitter> CE,std::unique_ptr<MCObjectWriter> OW)4309467b48Spatrick MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context,
4409467b48Spatrick                                      std::unique_ptr<MCAsmBackend> MAB,
4509467b48Spatrick                                      std::unique_ptr<MCCodeEmitter> CE,
4609467b48Spatrick                                      std::unique_ptr<MCObjectWriter> OW)
4709467b48Spatrick     : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(CE)),
4809467b48Spatrick       CurSymbol(nullptr) {}
4909467b48Spatrick 
emitInstToData(const MCInst & Inst,const MCSubtargetInfo & STI)50097a140dSpatrick void MCWinCOFFStreamer::emitInstToData(const MCInst &Inst,
5109467b48Spatrick                                        const MCSubtargetInfo &STI) {
5209467b48Spatrick   MCDataFragment *DF = getOrCreateDataFragment();
5309467b48Spatrick 
5409467b48Spatrick   SmallVector<MCFixup, 4> Fixups;
5509467b48Spatrick   SmallString<256> Code;
5609467b48Spatrick   raw_svector_ostream VecOS(Code);
5709467b48Spatrick   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
5809467b48Spatrick 
5909467b48Spatrick   // Add the fixups and data.
6009467b48Spatrick   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
6109467b48Spatrick     Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
6209467b48Spatrick     DF->getFixups().push_back(Fixups[i]);
6309467b48Spatrick   }
6409467b48Spatrick   DF->setHasInstructions(STI);
6509467b48Spatrick   DF->getContents().append(Code.begin(), Code.end());
6609467b48Spatrick }
6709467b48Spatrick 
initSections(bool NoExecStack,const MCSubtargetInfo & STI)68*d415bd75Srobert void MCWinCOFFStreamer::initSections(bool NoExecStack,
69*d415bd75Srobert                                      const MCSubtargetInfo &STI) {
7009467b48Spatrick   // FIXME: this is identical to the ELF one.
7109467b48Spatrick   // This emulates the same behavior of GNU as. This makes it easier
7209467b48Spatrick   // to compare the output as the major sections are in the same order.
73*d415bd75Srobert   switchSection(getContext().getObjectFileInfo()->getTextSection());
74*d415bd75Srobert   emitCodeAlignment(Align(4), &STI);
7509467b48Spatrick 
76*d415bd75Srobert   switchSection(getContext().getObjectFileInfo()->getDataSection());
77*d415bd75Srobert   emitCodeAlignment(Align(4), &STI);
7809467b48Spatrick 
79*d415bd75Srobert   switchSection(getContext().getObjectFileInfo()->getBSSSection());
80*d415bd75Srobert   emitCodeAlignment(Align(4), &STI);
8109467b48Spatrick 
82*d415bd75Srobert   switchSection(getContext().getObjectFileInfo()->getTextSection());
8309467b48Spatrick }
8409467b48Spatrick 
emitLabel(MCSymbol * S,SMLoc Loc)85097a140dSpatrick void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
8609467b48Spatrick   auto *Symbol = cast<MCSymbolCOFF>(S);
87097a140dSpatrick   MCObjectStreamer::emitLabel(Symbol, Loc);
8809467b48Spatrick }
8909467b48Spatrick 
emitAssemblerFlag(MCAssemblerFlag Flag)90097a140dSpatrick void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
9109467b48Spatrick   // Let the target do whatever target specific stuff it needs to do.
9209467b48Spatrick   getAssembler().getBackend().handleAssemblerFlag(Flag);
9309467b48Spatrick 
9409467b48Spatrick   switch (Flag) {
9509467b48Spatrick   // None of these require COFF specific handling.
9609467b48Spatrick   case MCAF_SyntaxUnified:
9709467b48Spatrick   case MCAF_Code16:
9809467b48Spatrick   case MCAF_Code32:
9909467b48Spatrick   case MCAF_Code64:
10009467b48Spatrick     break;
10109467b48Spatrick   case MCAF_SubsectionsViaSymbols:
10209467b48Spatrick     llvm_unreachable("COFF doesn't support .subsections_via_symbols");
10309467b48Spatrick   }
10409467b48Spatrick }
10509467b48Spatrick 
emitThumbFunc(MCSymbol * Func)106097a140dSpatrick void MCWinCOFFStreamer::emitThumbFunc(MCSymbol *Func) {
10709467b48Spatrick   llvm_unreachable("not implemented");
10809467b48Spatrick }
10909467b48Spatrick 
emitSymbolAttribute(MCSymbol * S,MCSymbolAttr Attribute)110097a140dSpatrick bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S,
11109467b48Spatrick                                             MCSymbolAttr Attribute) {
11209467b48Spatrick   auto *Symbol = cast<MCSymbolCOFF>(S);
11309467b48Spatrick   getAssembler().registerSymbol(*Symbol);
11409467b48Spatrick 
11509467b48Spatrick   switch (Attribute) {
11609467b48Spatrick   default: return false;
11709467b48Spatrick   case MCSA_WeakReference:
11809467b48Spatrick   case MCSA_Weak:
11909467b48Spatrick     Symbol->setIsWeakExternal();
12009467b48Spatrick     Symbol->setExternal(true);
12109467b48Spatrick     break;
12209467b48Spatrick   case MCSA_Global:
12309467b48Spatrick     Symbol->setExternal(true);
12409467b48Spatrick     break;
12509467b48Spatrick   case MCSA_AltEntry:
12609467b48Spatrick     llvm_unreachable("COFF doesn't support the .alt_entry attribute");
12709467b48Spatrick   }
12809467b48Spatrick 
12909467b48Spatrick   return true;
13009467b48Spatrick }
13109467b48Spatrick 
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)132097a140dSpatrick void MCWinCOFFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
13309467b48Spatrick   llvm_unreachable("not implemented");
13409467b48Spatrick }
13509467b48Spatrick 
beginCOFFSymbolDef(MCSymbol const * S)136*d415bd75Srobert void MCWinCOFFStreamer::beginCOFFSymbolDef(MCSymbol const *S) {
13709467b48Spatrick   auto *Symbol = cast<MCSymbolCOFF>(S);
13809467b48Spatrick   if (CurSymbol)
13909467b48Spatrick     Error("starting a new symbol definition without completing the "
14009467b48Spatrick           "previous one");
14109467b48Spatrick   CurSymbol = Symbol;
14209467b48Spatrick }
14309467b48Spatrick 
emitCOFFSymbolStorageClass(int StorageClass)144*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
14509467b48Spatrick   if (!CurSymbol) {
14609467b48Spatrick     Error("storage class specified outside of symbol definition");
14709467b48Spatrick     return;
14809467b48Spatrick   }
14909467b48Spatrick 
15009467b48Spatrick   if (StorageClass & ~COFF::SSC_Invalid) {
15109467b48Spatrick     Error("storage class value '" + Twine(StorageClass) +
15209467b48Spatrick                "' out of range");
15309467b48Spatrick     return;
15409467b48Spatrick   }
15509467b48Spatrick 
15609467b48Spatrick   getAssembler().registerSymbol(*CurSymbol);
15709467b48Spatrick   cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
15809467b48Spatrick }
15909467b48Spatrick 
emitCOFFSymbolType(int Type)160*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSymbolType(int Type) {
16109467b48Spatrick   if (!CurSymbol) {
16209467b48Spatrick     Error("symbol type specified outside of a symbol definition");
16309467b48Spatrick     return;
16409467b48Spatrick   }
16509467b48Spatrick 
16609467b48Spatrick   if (Type & ~0xffff) {
16709467b48Spatrick     Error("type value '" + Twine(Type) + "' out of range");
16809467b48Spatrick     return;
16909467b48Spatrick   }
17009467b48Spatrick 
17109467b48Spatrick   getAssembler().registerSymbol(*CurSymbol);
17209467b48Spatrick   cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
17309467b48Spatrick }
17409467b48Spatrick 
endCOFFSymbolDef()175*d415bd75Srobert void MCWinCOFFStreamer::endCOFFSymbolDef() {
17609467b48Spatrick   if (!CurSymbol)
17709467b48Spatrick     Error("ending symbol definition without starting one");
17809467b48Spatrick   CurSymbol = nullptr;
17909467b48Spatrick }
18009467b48Spatrick 
emitCOFFSafeSEH(MCSymbol const * Symbol)181*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
18209467b48Spatrick   // SafeSEH is a feature specific to 32-bit x86.  It does not exist (and is
18309467b48Spatrick   // unnecessary) on all platforms which use table-based exception dispatch.
18473471bf0Spatrick   if (getContext().getTargetTriple().getArch() != Triple::x86)
18509467b48Spatrick     return;
18609467b48Spatrick 
18709467b48Spatrick   const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
18809467b48Spatrick   if (CSymbol->isSafeSEH())
18909467b48Spatrick     return;
19009467b48Spatrick 
19109467b48Spatrick   MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
19209467b48Spatrick   getAssembler().registerSection(*SXData);
193*d415bd75Srobert   SXData->ensureMinAlignment(Align(4));
19409467b48Spatrick 
19509467b48Spatrick   new MCSymbolIdFragment(Symbol, SXData);
19609467b48Spatrick 
19709467b48Spatrick   getAssembler().registerSymbol(*Symbol);
19809467b48Spatrick   CSymbol->setIsSafeSEH();
19909467b48Spatrick 
20009467b48Spatrick   // The Microsoft linker requires that the symbol type of a handler be
20109467b48Spatrick   // function. Go ahead and oblige it here.
20209467b48Spatrick   CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION
20309467b48Spatrick                    << COFF::SCT_COMPLEX_TYPE_SHIFT);
20409467b48Spatrick }
20509467b48Spatrick 
emitCOFFSymbolIndex(MCSymbol const * Symbol)206*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
20709467b48Spatrick   MCSection *Sec = getCurrentSectionOnly();
20809467b48Spatrick   getAssembler().registerSection(*Sec);
209*d415bd75Srobert   Sec->ensureMinAlignment(Align(4));
21009467b48Spatrick 
21109467b48Spatrick   new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
21209467b48Spatrick 
21309467b48Spatrick   getAssembler().registerSymbol(*Symbol);
21409467b48Spatrick }
21509467b48Spatrick 
emitCOFFSectionIndex(const MCSymbol * Symbol)216*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
21709467b48Spatrick   visitUsedSymbol(*Symbol);
21809467b48Spatrick   MCDataFragment *DF = getOrCreateDataFragment();
21909467b48Spatrick   const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
22009467b48Spatrick   MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
22109467b48Spatrick   DF->getFixups().push_back(Fixup);
22209467b48Spatrick   DF->getContents().resize(DF->getContents().size() + 2, 0);
22309467b48Spatrick }
22409467b48Spatrick 
emitCOFFSecRel32(const MCSymbol * Symbol,uint64_t Offset)225*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
22609467b48Spatrick                                          uint64_t Offset) {
22709467b48Spatrick   visitUsedSymbol(*Symbol);
22809467b48Spatrick   MCDataFragment *DF = getOrCreateDataFragment();
22909467b48Spatrick   // Create Symbol A for the relocation relative reference.
23009467b48Spatrick   const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
23109467b48Spatrick   // Add the constant offset, if given.
23209467b48Spatrick   if (Offset)
23309467b48Spatrick     MCE = MCBinaryExpr::createAdd(
23409467b48Spatrick         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
23509467b48Spatrick   // Build the secrel32 relocation.
23609467b48Spatrick   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
23709467b48Spatrick   // Record the relocation.
23809467b48Spatrick   DF->getFixups().push_back(Fixup);
23909467b48Spatrick   // Emit 4 bytes (zeros) to the object file.
24009467b48Spatrick   DF->getContents().resize(DF->getContents().size() + 4, 0);
24109467b48Spatrick }
24209467b48Spatrick 
emitCOFFImgRel32(const MCSymbol * Symbol,int64_t Offset)243*d415bd75Srobert void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
24409467b48Spatrick                                          int64_t Offset) {
24509467b48Spatrick   visitUsedSymbol(*Symbol);
24609467b48Spatrick   MCDataFragment *DF = getOrCreateDataFragment();
24709467b48Spatrick   // Create Symbol A for the relocation relative reference.
24809467b48Spatrick   const MCExpr *MCE = MCSymbolRefExpr::create(
24909467b48Spatrick       Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
25009467b48Spatrick   // Add the constant offset, if given.
25109467b48Spatrick   if (Offset)
25209467b48Spatrick     MCE = MCBinaryExpr::createAdd(
25309467b48Spatrick         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
25409467b48Spatrick   // Build the imgrel relocation.
25509467b48Spatrick   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
25609467b48Spatrick   // Record the relocation.
25709467b48Spatrick   DF->getFixups().push_back(Fixup);
25809467b48Spatrick   // Emit 4 bytes (zeros) to the object file.
25909467b48Spatrick   DF->getContents().resize(DF->getContents().size() + 4, 0);
26009467b48Spatrick }
26109467b48Spatrick 
emitCommonSymbol(MCSymbol * S,uint64_t Size,Align ByteAlignment)262097a140dSpatrick void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
263*d415bd75Srobert                                          Align ByteAlignment) {
26409467b48Spatrick   auto *Symbol = cast<MCSymbolCOFF>(S);
26509467b48Spatrick 
26673471bf0Spatrick   const Triple &T = getContext().getTargetTriple();
26709467b48Spatrick   if (T.isWindowsMSVCEnvironment()) {
26809467b48Spatrick     if (ByteAlignment > 32)
26909467b48Spatrick       report_fatal_error("alignment is limited to 32-bytes");
27009467b48Spatrick 
27109467b48Spatrick     // Round size up to alignment so that we will honor the alignment request.
272*d415bd75Srobert     Size = std::max(Size, ByteAlignment.value());
27309467b48Spatrick   }
27409467b48Spatrick 
27509467b48Spatrick   getAssembler().registerSymbol(*Symbol);
27609467b48Spatrick   Symbol->setExternal(true);
27709467b48Spatrick   Symbol->setCommon(Size, ByteAlignment);
27809467b48Spatrick 
27909467b48Spatrick   if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
28009467b48Spatrick     SmallString<128> Directive;
28109467b48Spatrick     raw_svector_ostream OS(Directive);
28209467b48Spatrick     const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
28309467b48Spatrick 
28409467b48Spatrick     OS << " -aligncomm:\"" << Symbol->getName() << "\","
285*d415bd75Srobert        << Log2_32_Ceil(ByteAlignment.value());
28609467b48Spatrick 
287*d415bd75Srobert     pushSection();
288*d415bd75Srobert     switchSection(MFI->getDrectveSection());
289097a140dSpatrick     emitBytes(Directive);
290*d415bd75Srobert     popSection();
29109467b48Spatrick   }
29209467b48Spatrick }
29309467b48Spatrick 
emitLocalCommonSymbol(MCSymbol * S,uint64_t Size,Align ByteAlignment)294097a140dSpatrick void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
295*d415bd75Srobert                                               Align ByteAlignment) {
29609467b48Spatrick   auto *Symbol = cast<MCSymbolCOFF>(S);
29709467b48Spatrick 
29809467b48Spatrick   MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
299*d415bd75Srobert   pushSection();
300*d415bd75Srobert   switchSection(Section);
301097a140dSpatrick   emitValueToAlignment(ByteAlignment, 0, 1, 0);
302097a140dSpatrick   emitLabel(Symbol);
30309467b48Spatrick   Symbol->setExternal(false);
304097a140dSpatrick   emitZeros(Size);
305*d415bd75Srobert   popSection();
30609467b48Spatrick }
30709467b48Spatrick 
emitWeakReference(MCSymbol * AliasS,const MCSymbol * Symbol)30873471bf0Spatrick void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
30973471bf0Spatrick                                           const MCSymbol *Symbol) {
31073471bf0Spatrick   auto *Alias = cast<MCSymbolCOFF>(AliasS);
31173471bf0Spatrick   emitSymbolAttribute(Alias, MCSA_Weak);
31273471bf0Spatrick 
31373471bf0Spatrick   getAssembler().registerSymbol(*Symbol);
31473471bf0Spatrick   Alias->setVariableValue(MCSymbolRefExpr::create(
31573471bf0Spatrick       Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
31673471bf0Spatrick }
31773471bf0Spatrick 
emitZerofill(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment,SMLoc Loc)318097a140dSpatrick void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
319*d415bd75Srobert                                      uint64_t Size, Align ByteAlignment,
32009467b48Spatrick                                      SMLoc Loc) {
32109467b48Spatrick   llvm_unreachable("not implemented");
32209467b48Spatrick }
32309467b48Spatrick 
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)324097a140dSpatrick void MCWinCOFFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
325*d415bd75Srobert                                        uint64_t Size, Align ByteAlignment) {
32609467b48Spatrick   llvm_unreachable("not implemented");
32709467b48Spatrick }
32809467b48Spatrick 
32909467b48Spatrick // TODO: Implement this if you want to emit .comment section in COFF obj files.
emitIdent(StringRef IdentString)330097a140dSpatrick void MCWinCOFFStreamer::emitIdent(StringRef IdentString) {
33109467b48Spatrick   llvm_unreachable("not implemented");
33209467b48Spatrick }
33309467b48Spatrick 
emitWinEHHandlerData(SMLoc Loc)334*d415bd75Srobert void MCWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
33509467b48Spatrick   llvm_unreachable("not implemented");
33609467b48Spatrick }
33709467b48Spatrick 
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)338097a140dSpatrick void MCWinCOFFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
339097a140dSpatrick                                            const MCSymbolRefExpr *To,
340097a140dSpatrick                                            uint64_t Count) {
341097a140dSpatrick   // Ignore temporary symbols for now.
342097a140dSpatrick   if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary())
343097a140dSpatrick     getAssembler().CGProfile.push_back({From, To, Count});
344097a140dSpatrick }
345097a140dSpatrick 
finalizeCGProfileEntry(const MCSymbolRefExpr * & SRE)346097a140dSpatrick void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
347097a140dSpatrick   const MCSymbol *S = &SRE->getSymbol();
348097a140dSpatrick   bool Created;
349097a140dSpatrick   getAssembler().registerSymbol(*S, &Created);
35073471bf0Spatrick   if (Created)
351097a140dSpatrick     cast<MCSymbolCOFF>(S)->setExternal(true);
352097a140dSpatrick }
353097a140dSpatrick 
finalizeCGProfile()354097a140dSpatrick void MCWinCOFFStreamer::finalizeCGProfile() {
355097a140dSpatrick   for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) {
356097a140dSpatrick     finalizeCGProfileEntry(E.From);
357097a140dSpatrick     finalizeCGProfileEntry(E.To);
358097a140dSpatrick   }
359097a140dSpatrick }
360097a140dSpatrick 
finishImpl()361097a140dSpatrick void MCWinCOFFStreamer::finishImpl() {
362097a140dSpatrick   finalizeCGProfile();
363097a140dSpatrick 
364097a140dSpatrick   MCObjectStreamer::finishImpl();
36509467b48Spatrick }
36609467b48Spatrick 
Error(const Twine & Msg) const36709467b48Spatrick void MCWinCOFFStreamer::Error(const Twine &Msg) const {
36809467b48Spatrick   getContext().reportError(SMLoc(), Msg);
36909467b48Spatrick }
370