This reapplies 36c64af9d7 in updated
form.
Emit the xdata for each function at .seh_endproc. This keeps the
exact same output header order for most code generated by the LLVM
CodeGen layer. (Sections still change order for code built from
assembly where functions lack an explicit .seh_handlerdata
directive, and functions with chained unwind info.)
The practical effect should be that assembly output lacks
superfluous ".seh_handlerdata; .text" pairs at the end of functions
that don't handle exceptions, which allows such functions to use
the AArch64 packed unwind format again.
Differential Revision: https://reviews.llvm.org/D87448
81 lines
2.8 KiB
C++
81 lines
2.8 KiB
C++
//===-- 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/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;
|
|
}
|
|
|