xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCWinCOFFStreamer.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- llvm/MC/MCWinCOFFStreamer.cpp --------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains an implementation of a Windows COFF object file streamer.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
1381ad6265SDimitry Andric #include "llvm/MC/MCWinCOFFStreamer.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
160b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
170b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h"
300b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
330b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
340b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
35*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
360b57cec5SDimitry Andric #include <algorithm>
370b57cec5SDimitry Andric #include <cstdint>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric using namespace llvm;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric #define DEBUG_TYPE "WinCOFFStreamer"
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context,
440b57cec5SDimitry Andric                                      std::unique_ptr<MCAsmBackend> MAB,
450b57cec5SDimitry Andric                                      std::unique_ptr<MCCodeEmitter> CE,
460b57cec5SDimitry Andric                                      std::unique_ptr<MCObjectWriter> OW)
470b57cec5SDimitry Andric     : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(CE)),
480b57cec5SDimitry Andric       CurSymbol(nullptr) {}
490b57cec5SDimitry Andric 
505ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitInstToData(const MCInst &Inst,
510b57cec5SDimitry Andric                                        const MCSubtargetInfo &STI) {
520b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   SmallVector<MCFixup, 4> Fixups;
550b57cec5SDimitry Andric   SmallString<256> Code;
56*06c3fb27SDimitry Andric   getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   // Add the fixups and data.
590b57cec5SDimitry Andric   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
600b57cec5SDimitry Andric     Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
610b57cec5SDimitry Andric     DF->getFixups().push_back(Fixups[i]);
620b57cec5SDimitry Andric   }
630b57cec5SDimitry Andric   DF->setHasInstructions(STI);
640b57cec5SDimitry Andric   DF->getContents().append(Code.begin(), Code.end());
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
67349cc55cSDimitry Andric void MCWinCOFFStreamer::initSections(bool NoExecStack,
68349cc55cSDimitry Andric                                      const MCSubtargetInfo &STI) {
690b57cec5SDimitry Andric   // FIXME: this is identical to the ELF one.
700b57cec5SDimitry Andric   // This emulates the same behavior of GNU as. This makes it easier
710b57cec5SDimitry Andric   // to compare the output as the major sections are in the same order.
7281ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
73bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
740b57cec5SDimitry Andric 
7581ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getDataSection());
76bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
770b57cec5SDimitry Andric 
7881ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getBSSSection());
79bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
800b57cec5SDimitry Andric 
8181ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
845ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
850b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
865ffd83dbSDimitry Andric   MCObjectStreamer::emitLabel(Symbol, Loc);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
895ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
908bcb0991SDimitry Andric   // Let the target do whatever target specific stuff it needs to do.
918bcb0991SDimitry Andric   getAssembler().getBackend().handleAssemblerFlag(Flag);
928bcb0991SDimitry Andric 
938bcb0991SDimitry Andric   switch (Flag) {
948bcb0991SDimitry Andric   // None of these require COFF specific handling.
958bcb0991SDimitry Andric   case MCAF_SyntaxUnified:
968bcb0991SDimitry Andric   case MCAF_Code16:
978bcb0991SDimitry Andric   case MCAF_Code32:
988bcb0991SDimitry Andric   case MCAF_Code64:
998bcb0991SDimitry Andric     break;
1008bcb0991SDimitry Andric   case MCAF_SubsectionsViaSymbols:
1018bcb0991SDimitry Andric     llvm_unreachable("COFF doesn't support .subsections_via_symbols");
1028bcb0991SDimitry Andric   }
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric 
1055ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitThumbFunc(MCSymbol *Func) {
1060b57cec5SDimitry Andric   llvm_unreachable("not implemented");
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1095ffd83dbSDimitry Andric bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S,
1100b57cec5SDimitry Andric                                             MCSymbolAttr Attribute) {
1110b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
1120b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   switch (Attribute) {
1150b57cec5SDimitry Andric   default: return false;
1160b57cec5SDimitry Andric   case MCSA_WeakReference:
1170b57cec5SDimitry Andric   case MCSA_Weak:
118*06c3fb27SDimitry Andric     Symbol->setWeakExternalCharacteristics(COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
1190b57cec5SDimitry Andric     Symbol->setExternal(true);
1200b57cec5SDimitry Andric     break;
121*06c3fb27SDimitry Andric   case MCSA_WeakAntiDep:
122*06c3fb27SDimitry Andric     Symbol->setWeakExternalCharacteristics(COFF::IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY);
123*06c3fb27SDimitry Andric     Symbol->setExternal(true);
124*06c3fb27SDimitry Andric     Symbol->setIsWeakExternal(true);
125*06c3fb27SDimitry Andric     break;
1260b57cec5SDimitry Andric   case MCSA_Global:
1270b57cec5SDimitry Andric     Symbol->setExternal(true);
1280b57cec5SDimitry Andric     break;
1290b57cec5SDimitry Andric   case MCSA_AltEntry:
1300b57cec5SDimitry Andric     llvm_unreachable("COFF doesn't support the .alt_entry attribute");
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   return true;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1365ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
1370b57cec5SDimitry Andric   llvm_unreachable("not implemented");
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
14081ad6265SDimitry Andric void MCWinCOFFStreamer::beginCOFFSymbolDef(MCSymbol const *S) {
1410b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
1420b57cec5SDimitry Andric   if (CurSymbol)
1430b57cec5SDimitry Andric     Error("starting a new symbol definition without completing the "
1440b57cec5SDimitry Andric           "previous one");
1450b57cec5SDimitry Andric   CurSymbol = Symbol;
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric 
14881ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
1490b57cec5SDimitry Andric   if (!CurSymbol) {
1500b57cec5SDimitry Andric     Error("storage class specified outside of symbol definition");
1510b57cec5SDimitry Andric     return;
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   if (StorageClass & ~COFF::SSC_Invalid) {
1550b57cec5SDimitry Andric     Error("storage class value '" + Twine(StorageClass) +
1560b57cec5SDimitry Andric                "' out of range");
1570b57cec5SDimitry Andric     return;
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   getAssembler().registerSymbol(*CurSymbol);
1610b57cec5SDimitry Andric   cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
16481ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolType(int Type) {
1650b57cec5SDimitry Andric   if (!CurSymbol) {
1660b57cec5SDimitry Andric     Error("symbol type specified outside of a symbol definition");
1670b57cec5SDimitry Andric     return;
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   if (Type & ~0xffff) {
1710b57cec5SDimitry Andric     Error("type value '" + Twine(Type) + "' out of range");
1720b57cec5SDimitry Andric     return;
1730b57cec5SDimitry Andric   }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   getAssembler().registerSymbol(*CurSymbol);
1760b57cec5SDimitry Andric   cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric 
17981ad6265SDimitry Andric void MCWinCOFFStreamer::endCOFFSymbolDef() {
1800b57cec5SDimitry Andric   if (!CurSymbol)
1810b57cec5SDimitry Andric     Error("ending symbol definition without starting one");
1820b57cec5SDimitry Andric   CurSymbol = nullptr;
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
18581ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
1860b57cec5SDimitry Andric   // SafeSEH is a feature specific to 32-bit x86.  It does not exist (and is
1870b57cec5SDimitry Andric   // unnecessary) on all platforms which use table-based exception dispatch.
188fe6060f1SDimitry Andric   if (getContext().getTargetTriple().getArch() != Triple::x86)
1890b57cec5SDimitry Andric     return;
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
1920b57cec5SDimitry Andric   if (CSymbol->isSafeSEH())
1930b57cec5SDimitry Andric     return;
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
1960b57cec5SDimitry Andric   getAssembler().registerSection(*SXData);
197bdd1243dSDimitry Andric   SXData->ensureMinAlignment(Align(4));
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, SXData);
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2020b57cec5SDimitry Andric   CSymbol->setIsSafeSEH();
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   // The Microsoft linker requires that the symbol type of a handler be
2050b57cec5SDimitry Andric   // function. Go ahead and oblige it here.
2060b57cec5SDimitry Andric   CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION
2070b57cec5SDimitry Andric                    << COFF::SCT_COMPLEX_TYPE_SHIFT);
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
21081ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
2110b57cec5SDimitry Andric   MCSection *Sec = getCurrentSectionOnly();
2120b57cec5SDimitry Andric   getAssembler().registerSection(*Sec);
213bdd1243dSDimitry Andric   Sec->ensureMinAlignment(Align(4));
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
22081ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
2210b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2220b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2230b57cec5SDimitry Andric   const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
2240b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
2250b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2260b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 2, 0);
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
22981ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
2300b57cec5SDimitry Andric                                          uint64_t Offset) {
2310b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2320b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2330b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2340b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
2350b57cec5SDimitry Andric   // Add the constant offset, if given.
2360b57cec5SDimitry Andric   if (Offset)
2370b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2380b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2390b57cec5SDimitry Andric   // Build the secrel32 relocation.
2400b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
2410b57cec5SDimitry Andric   // Record the relocation.
2420b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2430b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2440b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric 
24781ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
2480b57cec5SDimitry Andric                                          int64_t Offset) {
2490b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2500b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2510b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2520b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(
2530b57cec5SDimitry Andric       Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
2540b57cec5SDimitry Andric   // Add the constant offset, if given.
2550b57cec5SDimitry Andric   if (Offset)
2560b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2570b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2580b57cec5SDimitry Andric   // Build the imgrel relocation.
2590b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
2600b57cec5SDimitry Andric   // Record the relocation.
2610b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2620b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2630b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
2665ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
267bdd1243dSDimitry Andric                                          Align ByteAlignment) {
2680b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
2690b57cec5SDimitry Andric 
270fe6060f1SDimitry Andric   const Triple &T = getContext().getTargetTriple();
2710b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment()) {
2720b57cec5SDimitry Andric     if (ByteAlignment > 32)
2730b57cec5SDimitry Andric       report_fatal_error("alignment is limited to 32-bytes");
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     // Round size up to alignment so that we will honor the alignment request.
276bdd1243dSDimitry Andric     Size = std::max(Size, ByteAlignment.value());
2770b57cec5SDimitry Andric   }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2800b57cec5SDimitry Andric   Symbol->setExternal(true);
2810b57cec5SDimitry Andric   Symbol->setCommon(Size, ByteAlignment);
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
2840b57cec5SDimitry Andric     SmallString<128> Directive;
2850b57cec5SDimitry Andric     raw_svector_ostream OS(Directive);
2860b57cec5SDimitry Andric     const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric     OS << " -aligncomm:\"" << Symbol->getName() << "\","
289bdd1243dSDimitry Andric        << Log2_32_Ceil(ByteAlignment.value());
2900b57cec5SDimitry Andric 
29181ad6265SDimitry Andric     pushSection();
29281ad6265SDimitry Andric     switchSection(MFI->getDrectveSection());
2935ffd83dbSDimitry Andric     emitBytes(Directive);
29481ad6265SDimitry Andric     popSection();
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
2985ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
299bdd1243dSDimitry Andric                                               Align ByteAlignment) {
3000b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
30381ad6265SDimitry Andric   pushSection();
30481ad6265SDimitry Andric   switchSection(Section);
3055ffd83dbSDimitry Andric   emitValueToAlignment(ByteAlignment, 0, 1, 0);
3065ffd83dbSDimitry Andric   emitLabel(Symbol);
3070b57cec5SDimitry Andric   Symbol->setExternal(false);
3085ffd83dbSDimitry Andric   emitZeros(Size);
30981ad6265SDimitry Andric   popSection();
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
312e8d8bef9SDimitry Andric void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
313e8d8bef9SDimitry Andric                                           const MCSymbol *Symbol) {
314e8d8bef9SDimitry Andric   auto *Alias = cast<MCSymbolCOFF>(AliasS);
315e8d8bef9SDimitry Andric   emitSymbolAttribute(Alias, MCSA_Weak);
316e8d8bef9SDimitry Andric 
317e8d8bef9SDimitry Andric   getAssembler().registerSymbol(*Symbol);
318e8d8bef9SDimitry Andric   Alias->setVariableValue(MCSymbolRefExpr::create(
319e8d8bef9SDimitry Andric       Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
320e8d8bef9SDimitry Andric }
321e8d8bef9SDimitry Andric 
3225ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
323bdd1243dSDimitry Andric                                      uint64_t Size, Align ByteAlignment,
3240b57cec5SDimitry Andric                                      SMLoc Loc) {
3250b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric 
3285ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
329bdd1243dSDimitry Andric                                        uint64_t Size, Align ByteAlignment) {
3300b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric // TODO: Implement this if you want to emit .comment section in COFF obj files.
3345ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitIdent(StringRef IdentString) {
3350b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
33881ad6265SDimitry Andric void MCWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
3390b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3425ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
3435ffd83dbSDimitry Andric                                            const MCSymbolRefExpr *To,
3445ffd83dbSDimitry Andric                                            uint64_t Count) {
3455ffd83dbSDimitry Andric   // Ignore temporary symbols for now.
3465ffd83dbSDimitry Andric   if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary())
3475ffd83dbSDimitry Andric     getAssembler().CGProfile.push_back({From, To, Count});
3485ffd83dbSDimitry Andric }
3495ffd83dbSDimitry Andric 
3505ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
3515ffd83dbSDimitry Andric   const MCSymbol *S = &SRE->getSymbol();
352*06c3fb27SDimitry Andric   if (getAssembler().registerSymbol(*S))
3535ffd83dbSDimitry Andric     cast<MCSymbolCOFF>(S)->setExternal(true);
3545ffd83dbSDimitry Andric }
3555ffd83dbSDimitry Andric 
3565ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfile() {
3575ffd83dbSDimitry Andric   for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) {
3585ffd83dbSDimitry Andric     finalizeCGProfileEntry(E.From);
3595ffd83dbSDimitry Andric     finalizeCGProfileEntry(E.To);
3605ffd83dbSDimitry Andric   }
3615ffd83dbSDimitry Andric }
3625ffd83dbSDimitry Andric 
3635ffd83dbSDimitry Andric void MCWinCOFFStreamer::finishImpl() {
3645ffd83dbSDimitry Andric   finalizeCGProfile();
3655ffd83dbSDimitry Andric 
3665ffd83dbSDimitry Andric   MCObjectStreamer::finishImpl();
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric void MCWinCOFFStreamer::Error(const Twine &Msg) const {
3700b57cec5SDimitry Andric   getContext().reportError(SMLoc(), Msg);
3710b57cec5SDimitry Andric }
372