xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCWinCOFFStreamer.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 
13*81ad6265SDimitry 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/Triple.h"
170b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
180b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h"
310b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
320b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
330b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
340b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
350b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.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;
560b57cec5SDimitry Andric   raw_svector_ostream VecOS(Code);
570b57cec5SDimitry Andric   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   // Add the fixups and data.
600b57cec5SDimitry Andric   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
610b57cec5SDimitry Andric     Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
620b57cec5SDimitry Andric     DF->getFixups().push_back(Fixups[i]);
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric   DF->setHasInstructions(STI);
650b57cec5SDimitry Andric   DF->getContents().append(Code.begin(), Code.end());
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
68349cc55cSDimitry Andric void MCWinCOFFStreamer::initSections(bool NoExecStack,
69349cc55cSDimitry Andric                                      const MCSubtargetInfo &STI) {
700b57cec5SDimitry Andric   // FIXME: this is identical to the ELF one.
710b57cec5SDimitry Andric   // This emulates the same behavior of GNU as. This makes it easier
720b57cec5SDimitry Andric   // to compare the output as the major sections are in the same order.
73*81ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
74349cc55cSDimitry Andric   emitCodeAlignment(4, &STI);
750b57cec5SDimitry Andric 
76*81ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getDataSection());
77349cc55cSDimitry Andric   emitCodeAlignment(4, &STI);
780b57cec5SDimitry Andric 
79*81ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getBSSSection());
80349cc55cSDimitry Andric   emitCodeAlignment(4, &STI);
810b57cec5SDimitry Andric 
82*81ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
855ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) {
860b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
875ffd83dbSDimitry Andric   MCObjectStreamer::emitLabel(Symbol, Loc);
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
905ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
918bcb0991SDimitry Andric   // Let the target do whatever target specific stuff it needs to do.
928bcb0991SDimitry Andric   getAssembler().getBackend().handleAssemblerFlag(Flag);
938bcb0991SDimitry Andric 
948bcb0991SDimitry Andric   switch (Flag) {
958bcb0991SDimitry Andric   // None of these require COFF specific handling.
968bcb0991SDimitry Andric   case MCAF_SyntaxUnified:
978bcb0991SDimitry Andric   case MCAF_Code16:
988bcb0991SDimitry Andric   case MCAF_Code32:
998bcb0991SDimitry Andric   case MCAF_Code64:
1008bcb0991SDimitry Andric     break;
1018bcb0991SDimitry Andric   case MCAF_SubsectionsViaSymbols:
1028bcb0991SDimitry Andric     llvm_unreachable("COFF doesn't support .subsections_via_symbols");
1038bcb0991SDimitry Andric   }
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1065ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitThumbFunc(MCSymbol *Func) {
1070b57cec5SDimitry Andric   llvm_unreachable("not implemented");
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1105ffd83dbSDimitry Andric bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S,
1110b57cec5SDimitry Andric                                             MCSymbolAttr Attribute) {
1120b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
1130b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   switch (Attribute) {
1160b57cec5SDimitry Andric   default: return false;
1170b57cec5SDimitry Andric   case MCSA_WeakReference:
1180b57cec5SDimitry Andric   case MCSA_Weak:
1190b57cec5SDimitry Andric     Symbol->setIsWeakExternal();
1200b57cec5SDimitry Andric     Symbol->setExternal(true);
1210b57cec5SDimitry Andric     break;
1220b57cec5SDimitry Andric   case MCSA_Global:
1230b57cec5SDimitry Andric     Symbol->setExternal(true);
1240b57cec5SDimitry Andric     break;
1250b57cec5SDimitry Andric   case MCSA_AltEntry:
1260b57cec5SDimitry Andric     llvm_unreachable("COFF doesn't support the .alt_entry attribute");
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   return true;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
1325ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
1330b57cec5SDimitry Andric   llvm_unreachable("not implemented");
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
136*81ad6265SDimitry Andric void MCWinCOFFStreamer::beginCOFFSymbolDef(MCSymbol const *S) {
1370b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
1380b57cec5SDimitry Andric   if (CurSymbol)
1390b57cec5SDimitry Andric     Error("starting a new symbol definition without completing the "
1400b57cec5SDimitry Andric           "previous one");
1410b57cec5SDimitry Andric   CurSymbol = Symbol;
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
144*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
1450b57cec5SDimitry Andric   if (!CurSymbol) {
1460b57cec5SDimitry Andric     Error("storage class specified outside of symbol definition");
1470b57cec5SDimitry Andric     return;
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   if (StorageClass & ~COFF::SSC_Invalid) {
1510b57cec5SDimitry Andric     Error("storage class value '" + Twine(StorageClass) +
1520b57cec5SDimitry Andric                "' out of range");
1530b57cec5SDimitry Andric     return;
1540b57cec5SDimitry Andric   }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   getAssembler().registerSymbol(*CurSymbol);
1570b57cec5SDimitry Andric   cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
160*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolType(int Type) {
1610b57cec5SDimitry Andric   if (!CurSymbol) {
1620b57cec5SDimitry Andric     Error("symbol type specified outside of a symbol definition");
1630b57cec5SDimitry Andric     return;
1640b57cec5SDimitry Andric   }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   if (Type & ~0xffff) {
1670b57cec5SDimitry Andric     Error("type value '" + Twine(Type) + "' out of range");
1680b57cec5SDimitry Andric     return;
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   getAssembler().registerSymbol(*CurSymbol);
1720b57cec5SDimitry Andric   cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
175*81ad6265SDimitry Andric void MCWinCOFFStreamer::endCOFFSymbolDef() {
1760b57cec5SDimitry Andric   if (!CurSymbol)
1770b57cec5SDimitry Andric     Error("ending symbol definition without starting one");
1780b57cec5SDimitry Andric   CurSymbol = nullptr;
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
181*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
1820b57cec5SDimitry Andric   // SafeSEH is a feature specific to 32-bit x86.  It does not exist (and is
1830b57cec5SDimitry Andric   // unnecessary) on all platforms which use table-based exception dispatch.
184fe6060f1SDimitry Andric   if (getContext().getTargetTriple().getArch() != Triple::x86)
1850b57cec5SDimitry Andric     return;
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
1880b57cec5SDimitry Andric   if (CSymbol->isSafeSEH())
1890b57cec5SDimitry Andric     return;
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection();
1920b57cec5SDimitry Andric   getAssembler().registerSection(*SXData);
1930b57cec5SDimitry Andric   if (SXData->getAlignment() < 4)
1948bcb0991SDimitry Andric     SXData->setAlignment(Align(4));
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, SXData);
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
1990b57cec5SDimitry Andric   CSymbol->setIsSafeSEH();
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   // The Microsoft linker requires that the symbol type of a handler be
2020b57cec5SDimitry Andric   // function. Go ahead and oblige it here.
2030b57cec5SDimitry Andric   CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION
2040b57cec5SDimitry Andric                    << COFF::SCT_COMPLEX_TYPE_SHIFT);
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
207*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
2080b57cec5SDimitry Andric   MCSection *Sec = getCurrentSectionOnly();
2090b57cec5SDimitry Andric   getAssembler().registerSection(*Sec);
2100b57cec5SDimitry Andric   if (Sec->getAlignment() < 4)
2118bcb0991SDimitry Andric     Sec->setAlignment(Align(4));
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
218*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
2190b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2200b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2210b57cec5SDimitry Andric   const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
2220b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
2230b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2240b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 2, 0);
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric 
227*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
2280b57cec5SDimitry Andric                                          uint64_t Offset) {
2290b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2300b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2310b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2320b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
2330b57cec5SDimitry Andric   // Add the constant offset, if given.
2340b57cec5SDimitry Andric   if (Offset)
2350b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2360b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2370b57cec5SDimitry Andric   // Build the secrel32 relocation.
2380b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
2390b57cec5SDimitry Andric   // Record the relocation.
2400b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2410b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2420b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric 
245*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
2460b57cec5SDimitry Andric                                          int64_t Offset) {
2470b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2480b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2490b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2500b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(
2510b57cec5SDimitry Andric       Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
2520b57cec5SDimitry Andric   // Add the constant offset, if given.
2530b57cec5SDimitry Andric   if (Offset)
2540b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2550b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2560b57cec5SDimitry Andric   // Build the imgrel relocation.
2570b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
2580b57cec5SDimitry Andric   // Record the relocation.
2590b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2600b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2610b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2645ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
2650b57cec5SDimitry Andric                                          unsigned ByteAlignment) {
2660b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
2670b57cec5SDimitry Andric 
268fe6060f1SDimitry Andric   const Triple &T = getContext().getTargetTriple();
2690b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment()) {
2700b57cec5SDimitry Andric     if (ByteAlignment > 32)
2710b57cec5SDimitry Andric       report_fatal_error("alignment is limited to 32-bytes");
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric     // Round size up to alignment so that we will honor the alignment request.
2740b57cec5SDimitry Andric     Size = std::max(Size, static_cast<uint64_t>(ByteAlignment));
2750b57cec5SDimitry Andric   }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2780b57cec5SDimitry Andric   Symbol->setExternal(true);
2790b57cec5SDimitry Andric   Symbol->setCommon(Size, ByteAlignment);
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
2820b57cec5SDimitry Andric     SmallString<128> Directive;
2830b57cec5SDimitry Andric     raw_svector_ostream OS(Directive);
2840b57cec5SDimitry Andric     const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric     OS << " -aligncomm:\"" << Symbol->getName() << "\","
2870b57cec5SDimitry Andric        << Log2_32_Ceil(ByteAlignment);
2880b57cec5SDimitry Andric 
289*81ad6265SDimitry Andric     pushSection();
290*81ad6265SDimitry Andric     switchSection(MFI->getDrectveSection());
2915ffd83dbSDimitry Andric     emitBytes(Directive);
292*81ad6265SDimitry Andric     popSection();
2930b57cec5SDimitry Andric   }
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
2965ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
2970b57cec5SDimitry Andric                                               unsigned ByteAlignment) {
2980b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
301*81ad6265SDimitry Andric   pushSection();
302*81ad6265SDimitry Andric   switchSection(Section);
3035ffd83dbSDimitry Andric   emitValueToAlignment(ByteAlignment, 0, 1, 0);
3045ffd83dbSDimitry Andric   emitLabel(Symbol);
3050b57cec5SDimitry Andric   Symbol->setExternal(false);
3065ffd83dbSDimitry Andric   emitZeros(Size);
307*81ad6265SDimitry Andric   popSection();
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric 
310e8d8bef9SDimitry Andric void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
311e8d8bef9SDimitry Andric                                           const MCSymbol *Symbol) {
312e8d8bef9SDimitry Andric   auto *Alias = cast<MCSymbolCOFF>(AliasS);
313e8d8bef9SDimitry Andric   emitSymbolAttribute(Alias, MCSA_Weak);
314e8d8bef9SDimitry Andric 
315e8d8bef9SDimitry Andric   getAssembler().registerSymbol(*Symbol);
316e8d8bef9SDimitry Andric   Alias->setVariableValue(MCSymbolRefExpr::create(
317e8d8bef9SDimitry Andric       Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
318e8d8bef9SDimitry Andric }
319e8d8bef9SDimitry Andric 
3205ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
3210b57cec5SDimitry Andric                                      uint64_t Size, unsigned ByteAlignment,
3220b57cec5SDimitry Andric                                      SMLoc Loc) {
3230b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
3265ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
3270b57cec5SDimitry Andric                                        uint64_t Size, unsigned ByteAlignment) {
3280b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric // TODO: Implement this if you want to emit .comment section in COFF obj files.
3325ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitIdent(StringRef IdentString) {
3330b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
336*81ad6265SDimitry Andric void MCWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
3370b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3405ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
3415ffd83dbSDimitry Andric                                            const MCSymbolRefExpr *To,
3425ffd83dbSDimitry Andric                                            uint64_t Count) {
3435ffd83dbSDimitry Andric   // Ignore temporary symbols for now.
3445ffd83dbSDimitry Andric   if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary())
3455ffd83dbSDimitry Andric     getAssembler().CGProfile.push_back({From, To, Count});
3465ffd83dbSDimitry Andric }
3475ffd83dbSDimitry Andric 
3485ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
3495ffd83dbSDimitry Andric   const MCSymbol *S = &SRE->getSymbol();
3505ffd83dbSDimitry Andric   bool Created;
3515ffd83dbSDimitry Andric   getAssembler().registerSymbol(*S, &Created);
352e8d8bef9SDimitry Andric   if (Created)
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