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