mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[MC] [Win64EH] Fill in FuncletOrFuncEnd if missing
This can happen e.g. for code that declare .seh_proc/.seh_endproc in assembly, or for code that use .seh_handlerdata (which triggers the unwind info to be emitted before the end of the function). The TextSection field must be made non-const to be able to use it with Streamer.SwitchSection(). Differential Revision: https://reviews.llvm.org/D86528
This commit is contained in:
parent
ccee9bafd6
commit
7550015c23
@ -36,7 +36,7 @@ struct FrameInfo {
|
||||
const MCSymbol *Function = nullptr;
|
||||
const MCSymbol *PrologEnd = nullptr;
|
||||
const MCSymbol *Symbol = nullptr;
|
||||
const MCSection *TextSection = nullptr;
|
||||
MCSection *TextSection = nullptr;
|
||||
|
||||
bool HandlesUnwind = false;
|
||||
bool HandlesExceptions = false;
|
||||
|
@ -692,6 +692,8 @@ void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
|
||||
|
||||
MCSymbol *Label = emitCFILabel();
|
||||
CurFrame->End = Label;
|
||||
if (!CurFrame->FuncletOrFuncEnd)
|
||||
CurFrame->FuncletOrFuncEnd = CurFrame->End;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
|
||||
|
@ -525,9 +525,7 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
|
||||
|
||||
int64_t RawFuncLength;
|
||||
if (!info->FuncletOrFuncEnd) {
|
||||
// FIXME: This is very wrong; we emit SEH data which covers zero bytes
|
||||
// of code. But otherwise test/MC/AArch64/seh.s crashes.
|
||||
RawFuncLength = 0;
|
||||
report_fatal_error("FuncletOrFuncEnd not set");
|
||||
} else {
|
||||
// FIXME: GetAbsDifference tries to compute the length of the function
|
||||
// immediately, before the whole file is emitted, but in general
|
||||
@ -702,6 +700,16 @@ void llvm::Win64EH::ARM64UnwindEmitter::Emit(MCStreamer &Streamer) const {
|
||||
|
||||
void llvm::Win64EH::ARM64UnwindEmitter::EmitUnwindInfo(
|
||||
MCStreamer &Streamer, WinEH::FrameInfo *info) const {
|
||||
// Called if there's an .seh_handlerdata directive before the end of the
|
||||
// function. This forces writing the xdata record already here - and
|
||||
// in this case, the function isn't actually ended already, but the xdata
|
||||
// record needs to know the function length. In these cases, if the funclet
|
||||
// end hasn't been marked yet, the xdata function length won't cover the
|
||||
// whole function, only up to this point.
|
||||
if (!info->FuncletOrFuncEnd) {
|
||||
Streamer.SwitchSection(info->TextSection);
|
||||
info->FuncletOrFuncEnd = Streamer.emitCFILabel();
|
||||
}
|
||||
// Switch sections (the static function above is meant to be called from
|
||||
// here and from Emit().
|
||||
MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
|
||||
|
@ -46,6 +46,12 @@
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
// CHECK-NEXT: UnwindInformation [
|
||||
// CHECK-NEXT: RuntimeFunction {
|
||||
// CHECK-NEXT: Function: func
|
||||
// CHECK-NEXT: ExceptionRecord: .xdata
|
||||
// CHECK-NEXT: ExceptionData {
|
||||
// CHECK-NEXT: FunctionLength: 8
|
||||
|
||||
.text
|
||||
.globl func
|
||||
|
Loading…
Reference in New Issue
Block a user