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" 28*0fca6ea1SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h" 30*0fca6ea1SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 31*0fca6ea1SDimitry Andric #include "llvm/MC/MCWinCOFFObjectWriter.h" 320b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 330b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 340b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 350b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 3706c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 380b57cec5SDimitry Andric #include <algorithm> 390b57cec5SDimitry Andric #include <cstdint> 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric using namespace llvm; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric #define DEBUG_TYPE "WinCOFFStreamer" 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, 460b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> MAB, 470b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> CE, 480b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> OW) 490b57cec5SDimitry Andric : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(CE)), 50*0fca6ea1SDimitry Andric CurSymbol(nullptr) { 51*0fca6ea1SDimitry Andric auto *TO = Context.getTargetOptions(); 52*0fca6ea1SDimitry Andric if (TO && TO->MCIncrementalLinkerCompatible) 53*0fca6ea1SDimitry Andric getWriter().setIncrementalLinkerCompatible(true); 54*0fca6ea1SDimitry Andric } 55*0fca6ea1SDimitry Andric 56*0fca6ea1SDimitry Andric WinCOFFObjectWriter &MCWinCOFFStreamer::getWriter() { 57*0fca6ea1SDimitry Andric return static_cast<WinCOFFObjectWriter &>(getAssembler().getWriter()); 58*0fca6ea1SDimitry Andric } 590b57cec5SDimitry Andric 605ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitInstToData(const MCInst &Inst, 610b57cec5SDimitry Andric const MCSubtargetInfo &STI) { 620b57cec5SDimitry Andric MCDataFragment *DF = getOrCreateDataFragment(); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric SmallVector<MCFixup, 4> Fixups; 650b57cec5SDimitry Andric SmallString<256> Code; 6606c3fb27SDimitry Andric getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // Add the fixups and data. 690b57cec5SDimitry Andric for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 700b57cec5SDimitry Andric Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 710b57cec5SDimitry Andric DF->getFixups().push_back(Fixups[i]); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric DF->setHasInstructions(STI); 740b57cec5SDimitry Andric DF->getContents().append(Code.begin(), Code.end()); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 77349cc55cSDimitry Andric void MCWinCOFFStreamer::initSections(bool NoExecStack, 78349cc55cSDimitry Andric const MCSubtargetInfo &STI) { 790b57cec5SDimitry Andric // FIXME: this is identical to the ELF one. 800b57cec5SDimitry Andric // This emulates the same behavior of GNU as. This makes it easier 810b57cec5SDimitry Andric // to compare the output as the major sections are in the same order. 8281ad6265SDimitry Andric switchSection(getContext().getObjectFileInfo()->getTextSection()); 83bdd1243dSDimitry Andric emitCodeAlignment(Align(4), &STI); 840b57cec5SDimitry Andric 8581ad6265SDimitry Andric switchSection(getContext().getObjectFileInfo()->getDataSection()); 86bdd1243dSDimitry Andric emitCodeAlignment(Align(4), &STI); 870b57cec5SDimitry Andric 8881ad6265SDimitry Andric switchSection(getContext().getObjectFileInfo()->getBSSSection()); 89bdd1243dSDimitry Andric emitCodeAlignment(Align(4), &STI); 900b57cec5SDimitry Andric 9181ad6265SDimitry Andric switchSection(getContext().getObjectFileInfo()->getTextSection()); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 94*0fca6ea1SDimitry Andric void MCWinCOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 95*0fca6ea1SDimitry Andric changeSectionImpl(Section, Subsection); 96*0fca6ea1SDimitry Andric // Ensure that the first and the second symbols relative to the section are 97*0fca6ea1SDimitry Andric // the section symbol and the COMDAT symbol. 98*0fca6ea1SDimitry Andric getAssembler().registerSymbol(*Section->getBeginSymbol()); 99*0fca6ea1SDimitry Andric if (auto *Sym = cast<MCSectionCOFF>(Section)->getCOMDATSymbol()) 100*0fca6ea1SDimitry Andric getAssembler().registerSymbol(*Sym); 101*0fca6ea1SDimitry Andric } 102*0fca6ea1SDimitry Andric 1035ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { 1040b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolCOFF>(S); 1055ffd83dbSDimitry Andric MCObjectStreamer::emitLabel(Symbol, Loc); 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1085ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { 1098bcb0991SDimitry Andric // Let the target do whatever target specific stuff it needs to do. 1108bcb0991SDimitry Andric getAssembler().getBackend().handleAssemblerFlag(Flag); 1118bcb0991SDimitry Andric 1128bcb0991SDimitry Andric switch (Flag) { 1138bcb0991SDimitry Andric // None of these require COFF specific handling. 1148bcb0991SDimitry Andric case MCAF_SyntaxUnified: 1158bcb0991SDimitry Andric case MCAF_Code16: 1168bcb0991SDimitry Andric case MCAF_Code32: 1178bcb0991SDimitry Andric case MCAF_Code64: 1188bcb0991SDimitry Andric break; 1198bcb0991SDimitry Andric case MCAF_SubsectionsViaSymbols: 1208bcb0991SDimitry Andric llvm_unreachable("COFF doesn't support .subsections_via_symbols"); 1218bcb0991SDimitry Andric } 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1245ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitThumbFunc(MCSymbol *Func) { 1250b57cec5SDimitry Andric llvm_unreachable("not implemented"); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1285ffd83dbSDimitry Andric bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, 1290b57cec5SDimitry Andric MCSymbolAttr Attribute) { 1300b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolCOFF>(S); 1310b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric switch (Attribute) { 1340b57cec5SDimitry Andric default: return false; 1350b57cec5SDimitry Andric case MCSA_WeakReference: 1360b57cec5SDimitry Andric case MCSA_Weak: 13706c3fb27SDimitry Andric Symbol->setWeakExternalCharacteristics(COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS); 1380b57cec5SDimitry Andric Symbol->setExternal(true); 1390b57cec5SDimitry Andric break; 14006c3fb27SDimitry Andric case MCSA_WeakAntiDep: 14106c3fb27SDimitry Andric Symbol->setWeakExternalCharacteristics(COFF::IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY); 14206c3fb27SDimitry Andric Symbol->setExternal(true); 14306c3fb27SDimitry Andric Symbol->setIsWeakExternal(true); 14406c3fb27SDimitry Andric break; 1450b57cec5SDimitry Andric case MCSA_Global: 1460b57cec5SDimitry Andric Symbol->setExternal(true); 1470b57cec5SDimitry Andric break; 1480b57cec5SDimitry Andric case MCSA_AltEntry: 1490b57cec5SDimitry Andric llvm_unreachable("COFF doesn't support the .alt_entry attribute"); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric return true; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1555ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 1560b57cec5SDimitry Andric llvm_unreachable("not implemented"); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 15981ad6265SDimitry Andric void MCWinCOFFStreamer::beginCOFFSymbolDef(MCSymbol const *S) { 1600b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolCOFF>(S); 1610b57cec5SDimitry Andric if (CurSymbol) 1620b57cec5SDimitry Andric Error("starting a new symbol definition without completing the " 1630b57cec5SDimitry Andric "previous one"); 1640b57cec5SDimitry Andric CurSymbol = Symbol; 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 16781ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolStorageClass(int StorageClass) { 1680b57cec5SDimitry Andric if (!CurSymbol) { 1690b57cec5SDimitry Andric Error("storage class specified outside of symbol definition"); 1700b57cec5SDimitry Andric return; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric if (StorageClass & ~COFF::SSC_Invalid) { 1740b57cec5SDimitry Andric Error("storage class value '" + Twine(StorageClass) + 1750b57cec5SDimitry Andric "' out of range"); 1760b57cec5SDimitry Andric return; 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric getAssembler().registerSymbol(*CurSymbol); 1800b57cec5SDimitry Andric cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 18381ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolType(int Type) { 1840b57cec5SDimitry Andric if (!CurSymbol) { 1850b57cec5SDimitry Andric Error("symbol type specified outside of a symbol definition"); 1860b57cec5SDimitry Andric return; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric if (Type & ~0xffff) { 1900b57cec5SDimitry Andric Error("type value '" + Twine(Type) + "' out of range"); 1910b57cec5SDimitry Andric return; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric getAssembler().registerSymbol(*CurSymbol); 1950b57cec5SDimitry Andric cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 19881ad6265SDimitry Andric void MCWinCOFFStreamer::endCOFFSymbolDef() { 1990b57cec5SDimitry Andric if (!CurSymbol) 2000b57cec5SDimitry Andric Error("ending symbol definition without starting one"); 2010b57cec5SDimitry Andric CurSymbol = nullptr; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 20481ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) { 2050b57cec5SDimitry Andric // SafeSEH is a feature specific to 32-bit x86. It does not exist (and is 2060b57cec5SDimitry Andric // unnecessary) on all platforms which use table-based exception dispatch. 207fe6060f1SDimitry Andric if (getContext().getTargetTriple().getArch() != Triple::x86) 2080b57cec5SDimitry Andric return; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol); 2110b57cec5SDimitry Andric if (CSymbol->isSafeSEH()) 2120b57cec5SDimitry Andric return; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection(); 215*0fca6ea1SDimitry Andric changeSection(SXData); 216bdd1243dSDimitry Andric SXData->ensureMinAlignment(Align(4)); 2170b57cec5SDimitry Andric 218*0fca6ea1SDimitry Andric insert(getContext().allocFragment<MCSymbolIdFragment>(Symbol)); 2190b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 2200b57cec5SDimitry Andric CSymbol->setIsSafeSEH(); 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric // The Microsoft linker requires that the symbol type of a handler be 2230b57cec5SDimitry Andric // function. Go ahead and oblige it here. 2240b57cec5SDimitry Andric CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION 2250b57cec5SDimitry Andric << COFF::SCT_COMPLEX_TYPE_SHIFT); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 22881ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) { 2290b57cec5SDimitry Andric MCSection *Sec = getCurrentSectionOnly(); 230bdd1243dSDimitry Andric Sec->ensureMinAlignment(Align(4)); 2310b57cec5SDimitry Andric 232*0fca6ea1SDimitry Andric insert(getContext().allocFragment<MCSymbolIdFragment>(Symbol)); 2330b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 23681ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) { 2370b57cec5SDimitry Andric visitUsedSymbol(*Symbol); 2380b57cec5SDimitry Andric MCDataFragment *DF = getOrCreateDataFragment(); 2390b57cec5SDimitry Andric const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); 2400b57cec5SDimitry Andric MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2); 2410b57cec5SDimitry Andric DF->getFixups().push_back(Fixup); 2420b57cec5SDimitry Andric DF->getContents().resize(DF->getContents().size() + 2, 0); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 24581ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol, 2460b57cec5SDimitry Andric uint64_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(Symbol, getContext()); 2510b57cec5SDimitry Andric // Add the constant offset, if given. 2520b57cec5SDimitry Andric if (Offset) 2530b57cec5SDimitry Andric MCE = MCBinaryExpr::createAdd( 2540b57cec5SDimitry Andric MCE, MCConstantExpr::create(Offset, getContext()), getContext()); 2550b57cec5SDimitry Andric // Build the secrel32 relocation. 2560b57cec5SDimitry Andric MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_SecRel_4); 2570b57cec5SDimitry Andric // Record the relocation. 2580b57cec5SDimitry Andric DF->getFixups().push_back(Fixup); 2590b57cec5SDimitry Andric // Emit 4 bytes (zeros) to the object file. 2600b57cec5SDimitry Andric DF->getContents().resize(DF->getContents().size() + 4, 0); 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 26381ad6265SDimitry Andric void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol, 2640b57cec5SDimitry Andric int64_t Offset) { 2650b57cec5SDimitry Andric visitUsedSymbol(*Symbol); 2660b57cec5SDimitry Andric MCDataFragment *DF = getOrCreateDataFragment(); 2670b57cec5SDimitry Andric // Create Symbol A for the relocation relative reference. 2680b57cec5SDimitry Andric const MCExpr *MCE = MCSymbolRefExpr::create( 2690b57cec5SDimitry Andric Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext()); 2700b57cec5SDimitry Andric // Add the constant offset, if given. 2710b57cec5SDimitry Andric if (Offset) 2720b57cec5SDimitry Andric MCE = MCBinaryExpr::createAdd( 2730b57cec5SDimitry Andric MCE, MCConstantExpr::create(Offset, getContext()), getContext()); 2740b57cec5SDimitry Andric // Build the imgrel relocation. 2750b57cec5SDimitry Andric MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4); 2760b57cec5SDimitry Andric // Record the relocation. 2770b57cec5SDimitry Andric DF->getFixups().push_back(Fixup); 2780b57cec5SDimitry Andric // Emit 4 bytes (zeros) to the object file. 2790b57cec5SDimitry Andric DF->getContents().resize(DF->getContents().size() + 4, 0); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2825ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size, 283bdd1243dSDimitry Andric Align ByteAlignment) { 2840b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolCOFF>(S); 2850b57cec5SDimitry Andric 286fe6060f1SDimitry Andric const Triple &T = getContext().getTargetTriple(); 2870b57cec5SDimitry Andric if (T.isWindowsMSVCEnvironment()) { 2880b57cec5SDimitry Andric if (ByteAlignment > 32) 2890b57cec5SDimitry Andric report_fatal_error("alignment is limited to 32-bytes"); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // Round size up to alignment so that we will honor the alignment request. 292bdd1243dSDimitry Andric Size = std::max(Size, ByteAlignment.value()); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric getAssembler().registerSymbol(*Symbol); 2960b57cec5SDimitry Andric Symbol->setExternal(true); 2970b57cec5SDimitry Andric Symbol->setCommon(Size, ByteAlignment); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) { 3000b57cec5SDimitry Andric SmallString<128> Directive; 3010b57cec5SDimitry Andric raw_svector_ostream OS(Directive); 3020b57cec5SDimitry Andric const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric OS << " -aligncomm:\"" << Symbol->getName() << "\"," 305bdd1243dSDimitry Andric << Log2_32_Ceil(ByteAlignment.value()); 3060b57cec5SDimitry Andric 30781ad6265SDimitry Andric pushSection(); 30881ad6265SDimitry Andric switchSection(MFI->getDrectveSection()); 3095ffd83dbSDimitry Andric emitBytes(Directive); 31081ad6265SDimitry Andric popSection(); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3145ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size, 315bdd1243dSDimitry Andric Align ByteAlignment) { 3160b57cec5SDimitry Andric auto *Symbol = cast<MCSymbolCOFF>(S); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); 31981ad6265SDimitry Andric pushSection(); 32081ad6265SDimitry Andric switchSection(Section); 3215ffd83dbSDimitry Andric emitValueToAlignment(ByteAlignment, 0, 1, 0); 3225ffd83dbSDimitry Andric emitLabel(Symbol); 3230b57cec5SDimitry Andric Symbol->setExternal(false); 3245ffd83dbSDimitry Andric emitZeros(Size); 32581ad6265SDimitry Andric popSection(); 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 328e8d8bef9SDimitry Andric void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS, 329e8d8bef9SDimitry Andric const MCSymbol *Symbol) { 330e8d8bef9SDimitry Andric auto *Alias = cast<MCSymbolCOFF>(AliasS); 331e8d8bef9SDimitry Andric emitSymbolAttribute(Alias, MCSA_Weak); 332e8d8bef9SDimitry Andric 333e8d8bef9SDimitry Andric getAssembler().registerSymbol(*Symbol); 334e8d8bef9SDimitry Andric Alias->setVariableValue(MCSymbolRefExpr::create( 335e8d8bef9SDimitry Andric Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext())); 336e8d8bef9SDimitry Andric } 337e8d8bef9SDimitry Andric 3385ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol, 339bdd1243dSDimitry Andric uint64_t Size, Align ByteAlignment, 3400b57cec5SDimitry Andric SMLoc Loc) { 3410b57cec5SDimitry Andric llvm_unreachable("not implemented"); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3445ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 345bdd1243dSDimitry Andric uint64_t Size, Align ByteAlignment) { 3460b57cec5SDimitry Andric llvm_unreachable("not implemented"); 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric // TODO: Implement this if you want to emit .comment section in COFF obj files. 3505ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitIdent(StringRef IdentString) { 3510b57cec5SDimitry Andric llvm_unreachable("not implemented"); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 35481ad6265SDimitry Andric void MCWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) { 3550b57cec5SDimitry Andric llvm_unreachable("not implemented"); 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3585ffd83dbSDimitry Andric void MCWinCOFFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, 3595ffd83dbSDimitry Andric const MCSymbolRefExpr *To, 3605ffd83dbSDimitry Andric uint64_t Count) { 3615ffd83dbSDimitry Andric // Ignore temporary symbols for now. 3625ffd83dbSDimitry Andric if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary()) 363*0fca6ea1SDimitry Andric getWriter().getCGProfile().push_back({From, To, Count}); 3645ffd83dbSDimitry Andric } 3655ffd83dbSDimitry Andric 3665ffd83dbSDimitry Andric void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) { 3675ffd83dbSDimitry Andric const MCSymbol *S = &SRE->getSymbol(); 36806c3fb27SDimitry Andric if (getAssembler().registerSymbol(*S)) 3695ffd83dbSDimitry Andric cast<MCSymbolCOFF>(S)->setExternal(true); 3705ffd83dbSDimitry Andric } 3715ffd83dbSDimitry Andric 372*0fca6ea1SDimitry Andric void MCWinCOFFStreamer::finishImpl() { 373*0fca6ea1SDimitry Andric MCAssembler &Asm = getAssembler(); 374*0fca6ea1SDimitry Andric if (Asm.getWriter().getEmitAddrsigSection()) { 375*0fca6ea1SDimitry Andric // Register the section. 376*0fca6ea1SDimitry Andric switchSection(Asm.getContext().getCOFFSection(".llvm_addrsig", 377*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_LNK_REMOVE)); 378*0fca6ea1SDimitry Andric } 379*0fca6ea1SDimitry Andric if (!Asm.getWriter().getCGProfile().empty()) { 380*0fca6ea1SDimitry Andric for (auto &E : Asm.getWriter().getCGProfile()) { 3815ffd83dbSDimitry Andric finalizeCGProfileEntry(E.From); 3825ffd83dbSDimitry Andric finalizeCGProfileEntry(E.To); 3835ffd83dbSDimitry Andric } 384*0fca6ea1SDimitry Andric switchSection(Asm.getContext().getCOFFSection(".llvm.call-graph-profile", 385*0fca6ea1SDimitry Andric COFF::IMAGE_SCN_LNK_REMOVE)); 3865ffd83dbSDimitry Andric } 3875ffd83dbSDimitry Andric 3885ffd83dbSDimitry Andric MCObjectStreamer::finishImpl(); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric void MCWinCOFFStreamer::Error(const Twine &Msg) const { 3920b57cec5SDimitry Andric getContext().reportError(SMLoc(), Msg); 3930b57cec5SDimitry Andric } 394