xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCWinCOFFStreamer.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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/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.
7381ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
74*bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
750b57cec5SDimitry Andric 
7681ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getDataSection());
77*bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
780b57cec5SDimitry Andric 
7981ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getBSSSection());
80*bdd1243dSDimitry Andric   emitCodeAlignment(Align(4), &STI);
810b57cec5SDimitry Andric 
8281ad6265SDimitry 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 
13681ad6265SDimitry 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 
14481ad6265SDimitry 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 
16081ad6265SDimitry 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 
17581ad6265SDimitry 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 
18181ad6265SDimitry 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);
193*bdd1243dSDimitry Andric   SXData->ensureMinAlignment(Align(4));
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, SXData);
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
1980b57cec5SDimitry Andric   CSymbol->setIsSafeSEH();
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   // The Microsoft linker requires that the symbol type of a handler be
2010b57cec5SDimitry Andric   // function. Go ahead and oblige it here.
2020b57cec5SDimitry Andric   CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION
2030b57cec5SDimitry Andric                    << COFF::SCT_COMPLEX_TYPE_SHIFT);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
20681ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
2070b57cec5SDimitry Andric   MCSection *Sec = getCurrentSectionOnly();
2080b57cec5SDimitry Andric   getAssembler().registerSection(*Sec);
209*bdd1243dSDimitry Andric   Sec->ensureMinAlignment(Align(4));
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   new MCSymbolIdFragment(Symbol, getCurrentSectionOnly());
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric 
21681ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
2170b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2180b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2190b57cec5SDimitry Andric   const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
2200b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
2210b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2220b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 2, 0);
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
22581ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
2260b57cec5SDimitry Andric                                          uint64_t Offset) {
2270b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2280b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2290b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2300b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
2310b57cec5SDimitry Andric   // Add the constant offset, if given.
2320b57cec5SDimitry Andric   if (Offset)
2330b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2340b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2350b57cec5SDimitry Andric   // Build the secrel32 relocation.
2360b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4);
2370b57cec5SDimitry Andric   // Record the relocation.
2380b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2390b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2400b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
24381ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
2440b57cec5SDimitry Andric                                          int64_t Offset) {
2450b57cec5SDimitry Andric   visitUsedSymbol(*Symbol);
2460b57cec5SDimitry Andric   MCDataFragment *DF = getOrCreateDataFragment();
2470b57cec5SDimitry Andric   // Create Symbol A for the relocation relative reference.
2480b57cec5SDimitry Andric   const MCExpr *MCE = MCSymbolRefExpr::create(
2490b57cec5SDimitry Andric       Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
2500b57cec5SDimitry Andric   // Add the constant offset, if given.
2510b57cec5SDimitry Andric   if (Offset)
2520b57cec5SDimitry Andric     MCE = MCBinaryExpr::createAdd(
2530b57cec5SDimitry Andric         MCE, MCConstantExpr::create(Offset, getContext()), getContext());
2540b57cec5SDimitry Andric   // Build the imgrel relocation.
2550b57cec5SDimitry Andric   MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
2560b57cec5SDimitry Andric   // Record the relocation.
2570b57cec5SDimitry Andric   DF->getFixups().push_back(Fixup);
2580b57cec5SDimitry Andric   // Emit 4 bytes (zeros) to the object file.
2590b57cec5SDimitry Andric   DF->getContents().resize(DF->getContents().size() + 4, 0);
2600b57cec5SDimitry Andric }
2610b57cec5SDimitry Andric 
2625ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
263*bdd1243dSDimitry Andric                                          Align ByteAlignment) {
2640b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
2650b57cec5SDimitry Andric 
266fe6060f1SDimitry Andric   const Triple &T = getContext().getTargetTriple();
2670b57cec5SDimitry Andric   if (T.isWindowsMSVCEnvironment()) {
2680b57cec5SDimitry Andric     if (ByteAlignment > 32)
2690b57cec5SDimitry Andric       report_fatal_error("alignment is limited to 32-bytes");
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric     // Round size up to alignment so that we will honor the alignment request.
272*bdd1243dSDimitry Andric     Size = std::max(Size, ByteAlignment.value());
2730b57cec5SDimitry Andric   }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   getAssembler().registerSymbol(*Symbol);
2760b57cec5SDimitry Andric   Symbol->setExternal(true);
2770b57cec5SDimitry Andric   Symbol->setCommon(Size, ByteAlignment);
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
2800b57cec5SDimitry Andric     SmallString<128> Directive;
2810b57cec5SDimitry Andric     raw_svector_ostream OS(Directive);
2820b57cec5SDimitry Andric     const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric     OS << " -aligncomm:\"" << Symbol->getName() << "\","
285*bdd1243dSDimitry Andric        << Log2_32_Ceil(ByteAlignment.value());
2860b57cec5SDimitry Andric 
28781ad6265SDimitry Andric     pushSection();
28881ad6265SDimitry Andric     switchSection(MFI->getDrectveSection());
2895ffd83dbSDimitry Andric     emitBytes(Directive);
29081ad6265SDimitry Andric     popSection();
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2945ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
295*bdd1243dSDimitry Andric                                               Align ByteAlignment) {
2960b57cec5SDimitry Andric   auto *Symbol = cast<MCSymbolCOFF>(S);
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
29981ad6265SDimitry Andric   pushSection();
30081ad6265SDimitry Andric   switchSection(Section);
3015ffd83dbSDimitry Andric   emitValueToAlignment(ByteAlignment, 0, 1, 0);
3025ffd83dbSDimitry Andric   emitLabel(Symbol);
3030b57cec5SDimitry Andric   Symbol->setExternal(false);
3045ffd83dbSDimitry Andric   emitZeros(Size);
30581ad6265SDimitry Andric   popSection();
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
308e8d8bef9SDimitry Andric void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
309e8d8bef9SDimitry Andric                                           const MCSymbol *Symbol) {
310e8d8bef9SDimitry Andric   auto *Alias = cast<MCSymbolCOFF>(AliasS);
311e8d8bef9SDimitry Andric   emitSymbolAttribute(Alias, MCSA_Weak);
312e8d8bef9SDimitry Andric 
313e8d8bef9SDimitry Andric   getAssembler().registerSymbol(*Symbol);
314e8d8bef9SDimitry Andric   Alias->setVariableValue(MCSymbolRefExpr::create(
315e8d8bef9SDimitry Andric       Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
316e8d8bef9SDimitry Andric }
317e8d8bef9SDimitry Andric 
3185ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
319*bdd1243dSDimitry Andric                                      uint64_t Size, Align ByteAlignment,
3200b57cec5SDimitry Andric                                      SMLoc Loc) {
3210b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric 
3245ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
325*bdd1243dSDimitry Andric                                        uint64_t Size, Align ByteAlignment) {
3260b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric // TODO: Implement this if you want to emit .comment section in COFF obj files.
3305ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitIdent(StringRef IdentString) {
3310b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
33481ad6265SDimitry Andric void MCWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
3350b57cec5SDimitry Andric   llvm_unreachable("not implemented");
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
3385ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
3395ffd83dbSDimitry Andric                                            const MCSymbolRefExpr *To,
3405ffd83dbSDimitry Andric                                            uint64_t Count) {
3415ffd83dbSDimitry Andric   // Ignore temporary symbols for now.
3425ffd83dbSDimitry Andric   if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary())
3435ffd83dbSDimitry Andric     getAssembler().CGProfile.push_back({From, To, Count});
3445ffd83dbSDimitry Andric }
3455ffd83dbSDimitry Andric 
3465ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
3475ffd83dbSDimitry Andric   const MCSymbol *S = &SRE->getSymbol();
3485ffd83dbSDimitry Andric   bool Created;
3495ffd83dbSDimitry Andric   getAssembler().registerSymbol(*S, &Created);
350e8d8bef9SDimitry Andric   if (Created)
3515ffd83dbSDimitry Andric     cast<MCSymbolCOFF>(S)->setExternal(true);
3525ffd83dbSDimitry Andric }
3535ffd83dbSDimitry Andric 
3545ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfile() {
3555ffd83dbSDimitry Andric   for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) {
3565ffd83dbSDimitry Andric     finalizeCGProfileEntry(E.From);
3575ffd83dbSDimitry Andric     finalizeCGProfileEntry(E.To);
3585ffd83dbSDimitry Andric   }
3595ffd83dbSDimitry Andric }
3605ffd83dbSDimitry Andric 
3615ffd83dbSDimitry Andric void MCWinCOFFStreamer::finishImpl() {
3625ffd83dbSDimitry Andric   finalizeCGProfile();
3635ffd83dbSDimitry Andric 
3645ffd83dbSDimitry Andric   MCObjectStreamer::finishImpl();
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric void MCWinCOFFStreamer::Error(const Twine &Msg) const {
3680b57cec5SDimitry Andric   getContext().reportError(SMLoc(), Msg);
3690b57cec5SDimitry Andric }
370