1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- X86WinCOFFStreamer.cpp - X86 Target WinCOFF Streamer ----*- C++ -*-===//
2dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
3dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//                     The LLVM Compiler Infrastructure
4dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
5dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file is distributed under the University of Illinois Open Source
6dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// License. See LICENSE.TXT for details.
7dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===----------------------------------------------------------------------===//
9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "X86MCTargetDesc.h"
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/MC/MCWin64EH.h"
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCWinCOFFStreamer.h"
13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm;
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace {
17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass X86WinCOFFStreamer : public MCWinCOFFStreamer {
1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Win64EH::UnwindEmitter EHStreamer;
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinespublic:
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  X86WinCOFFStreamer(MCContext &C, MCAsmBackend &AB, MCCodeEmitter *CE,
210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                     raw_pwrite_stream &OS)
220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      : MCWinCOFFStreamer(C, AB, *CE, OS) {}
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
24c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void EmitWinEHHandlerData() override;
2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void EmitWindowsUnwindTables() override;
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void FinishImpl() override;
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines};
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
29c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid X86WinCOFFStreamer::EmitWinEHHandlerData() {
30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MCStreamer::EmitWinEHHandlerData();
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // We have to emit the unwind info now, because this directive
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // actually switches to the .xdata section!
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo());
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid X86WinCOFFStreamer::EmitWindowsUnwindTables() {
3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!getNumWinFrameInfos())
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EHStreamer.Emit(*this);
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid X86WinCOFFStreamer::FinishImpl() {
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  EmitFrames(nullptr);
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  EmitWindowsUnwindTables();
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCWinCOFFStreamer::FinishImpl();
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCStreamer *llvm::createX86WinCOFFStreamer(MCContext &C, MCAsmBackend &AB,
520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                           raw_pwrite_stream &OS,
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                           MCCodeEmitter *CE, bool RelaxAll,
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                           bool IncrementalLinkerCompatible) {
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  X86WinCOFFStreamer *S = new X86WinCOFFStreamer(C, AB, CE, OS);
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  S->getAssembler().setRelaxAll(RelaxAll);
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return S;
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
61