| //===-- X86WinCOFFStreamer.cpp - X86 Target WinCOFF Streamer ----*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "X86MCTargetDesc.h" | |
| #include "X86TargetStreamer.h" | |
| #include "llvm/MC/MCAsmBackend.h" | |
| #include "llvm/MC/MCAssembler.h" | |
| #include "llvm/MC/MCCodeEmitter.h" | |
| #include "llvm/MC/MCObjectWriter.h" | |
| #include "llvm/MC/MCWin64EH.h" | |
| #include "llvm/MC/MCWinCOFFStreamer.h" | |
| using namespace llvm; | |
| namespace { | |
| class X86WinCOFFStreamer : public MCWinCOFFStreamer { | |
| Win64EH::UnwindEmitter EHStreamer; | |
| public: | |
| X86WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB, | |
| std::unique_ptr<MCCodeEmitter> CE, | |
| std::unique_ptr<MCObjectWriter> OW) | |
| : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {} | |
| void emitWinEHHandlerData(SMLoc Loc) override; | |
| void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override; | |
| void emitWindowsUnwindTables() override; | |
| void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) override; | |
| void finishImpl() override; | |
| }; | |
| void X86WinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) { | |
| MCStreamer::emitWinEHHandlerData(Loc); | |
| // We have to emit the unwind info now, because this directive | |
| // actually switches to the .xdata section. | |
| if (WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo()) | |
| EHStreamer.EmitUnwindInfo(*this, CurFrame, /* HandlerData = */ true); | |
| } | |
| void X86WinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) { | |
| EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false); | |
| } | |
| void X86WinCOFFStreamer::emitWindowsUnwindTables() { | |
| if (!getNumWinFrameInfos()) | |
| return; | |
| EHStreamer.Emit(*this); | |
| } | |
| void X86WinCOFFStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc) { | |
| X86TargetStreamer *XTS = | |
| static_cast<X86TargetStreamer *>(getTargetStreamer()); | |
| XTS->emitFPOData(ProcSym, Loc); | |
| } | |
| void X86WinCOFFStreamer::finishImpl() { | |
| emitFrames(nullptr); | |
| emitWindowsUnwindTables(); | |
| MCWinCOFFStreamer::finishImpl(); | |
| } | |
| } // namespace | |
| MCStreamer *llvm::createX86WinCOFFStreamer(MCContext &C, | |
| std::unique_ptr<MCAsmBackend> &&AB, | |
| std::unique_ptr<MCObjectWriter> &&OW, | |
| std::unique_ptr<MCCodeEmitter> &&CE, | |
| bool RelaxAll, | |
| bool IncrementalLinkerCompatible) { | |
| X86WinCOFFStreamer *S = | |
| new X86WinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)); | |
| S->getAssembler().setRelaxAll(RelaxAll); | |
| S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible); | |
| return S; | |
| } | |