[llvm] 8ecce69 - Fix SEH table addresses for Windows
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 20 12:32:56 PDT 2021
Author: Daniel Paoliello
Date: 2021-08-20T22:32:12+03:00
New Revision: 8ecce69594b27674946d5a3ec8724afd65b9c99b
URL: https://github.com/llvm/llvm-project/commit/8ecce69594b27674946d5a3ec8724afd65b9c99b
DIFF: https://github.com/llvm/llvm-project/commit/8ecce69594b27674946d5a3ec8724afd65b9c99b.diff
LOG: Fix SEH table addresses for Windows
Issue Details:
The addresses for SEH tables for Windows are incorrect as 1 was unconditionally being added to all addresses. +1 is required for the SEH end address (as it is exclusive), but the SEH start addresses is inclusive and so should be used as-is.
In the IP2State tables, the addresses are +1 for AMD64 to handle the return address for a call being after the actual call instruction but are as-is for ARM and ARM64 as the `StateFromIp` function in the VC runtime automatically takes this into account and adjusts the address that is it looking up.
Fix Details:
* Split the `getLabel` function into two: `getLabel` (used for the SEH start address and ARM+ARM64 IP2State addresses) and `getLabelPlusOne` (for the SEH end address, and AMD64 IP2State addresses).
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D107784
Added:
Modified:
llvm/lib/CodeGen/AsmPrinter/WinException.cpp
llvm/lib/CodeGen/AsmPrinter/WinException.h
llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
llvm/test/CodeGen/X86/seh-catchpad.ll
llvm/test/CodeGen/X86/seh-except-finally.ll
llvm/test/CodeGen/X86/seh-finally.ll
llvm/test/CodeGen/X86/seh-safe-div.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index b30d9cc12abcc..ef57031c7294e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -43,6 +43,7 @@ WinException::WinException(AsmPrinter *A) : EHStreamer(A) {
// platforms use an imagerel32 relocation to refer to symbols.
useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
isAArch64 = Asm->TM.getTargetTriple().isAArch64();
+ isThumb = Asm->TM.getTargetTriple().isThumb();
}
WinException::~WinException() {}
@@ -330,10 +331,12 @@ const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
}
const MCExpr *WinException::getLabel(const MCSymbol *Label) {
- if (isAArch64)
- return MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_COFF_IMGREL32,
- Asm->OutContext);
- return MCBinaryExpr::createAdd(create32bitRef(Label),
+ return MCSymbolRefExpr::create(Label, MCSymbolRefExpr::VK_COFF_IMGREL32,
+ Asm->OutContext);
+}
+
+const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {
+ return MCBinaryExpr::createAdd(getLabel(Label),
MCConstantExpr::create(1, Asm->OutContext),
Asm->OutContext);
}
@@ -561,8 +564,8 @@ InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {
/// struct Table {
/// int NumEntries;
/// struct Entry {
-/// imagerel32 LabelStart;
-/// imagerel32 LabelEnd;
+/// imagerel32 LabelStart; // Inclusive
+/// imagerel32 LabelEnd; // Exclusive
/// imagerel32 FilterOrFinally; // One means catch-all.
/// imagerel32 LabelLPad; // Zero means __finally.
/// } Entries[NumEntries];
@@ -664,7 +667,7 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
AddComment("LabelStart");
OS.emitValue(getLabel(BeginLabel), 4);
AddComment("LabelEnd");
- OS.emitValue(getLabel(EndLabel), 4);
+ OS.emitValue(getLabelPlusOne(EndLabel), 4);
AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
: "CatchAll");
OS.emitValue(FilterOrFinally, 4);
@@ -949,8 +952,15 @@ void WinException::computeIP2StateTable(
if (!ChangeLabel)
ChangeLabel = StateChange.PreviousEndLabel;
// Emit an entry indicating that PCs after 'Label' have this EH state.
+ // NOTE: On ARM architectures, the StateFromIp automatically takes into
+ // account that the return address is after the call instruction (whose EH
+ // state we should be using), but on other platforms we need to +1 to the
+ // label so that we are using the correct EH state.
+ const MCExpr *LabelExpression = (isAArch64 || isThumb)
+ ? getLabel(ChangeLabel)
+ : getLabelPlusOne(ChangeLabel);
IPToStateTable.push_back(
- std::make_pair(getLabel(ChangeLabel), StateChange.NewState));
+ std::make_pair(LabelExpression, StateChange.NewState));
// FIXME: assert that NewState is between CatchLow and CatchHigh.
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h
index feea05ba63adb..638589adf0ddc 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h
@@ -39,6 +39,9 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
/// True if we are generating exception handling on Windows for ARM64.
bool isAArch64 = false;
+ /// True if we are generating exception handling on Windows for ARM (Thumb).
+ bool isThumb = false;
+
/// Pointer to the current funclet entry BB.
const MachineBasicBlock *CurrentFuncletEntry = nullptr;
@@ -77,6 +80,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
const MCExpr *create32bitRef(const MCSymbol *Value);
const MCExpr *create32bitRef(const GlobalValue *GV);
const MCExpr *getLabel(const MCSymbol *Label);
+ const MCExpr *getLabelPlusOne(const MCSymbol *Label);
const MCExpr *getOffset(const MCSymbol *OffsetOf, const MCSymbol *OffsetFrom);
const MCExpr *getOffsetPlusOne(const MCSymbol *OffsetOf,
const MCSymbol *OffsetFrom);
diff --git a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
index 7d4d833aa9ba9..836062da2dda5 100644
--- a/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-noret-cleanup.ll
@@ -61,19 +61,19 @@ catch.body.2:
; SEH-LABEL: test:
; SEH-LABEL: .Llsda_begin0:
-; SEH-NEXT: .long .Ltmp0 at IMGREL+1
+; SEH-NEXT: .long .Ltmp0 at IMGREL
; SEH-NEXT: .long .Ltmp1 at IMGREL+1
; SEH-NEXT: .long dummy_filter at IMGREL
; SEH-NEXT: .long .LBB0_3 at IMGREL
-; SEH-NEXT: .long .Ltmp0 at IMGREL+1
+; SEH-NEXT: .long .Ltmp0 at IMGREL
; SEH-NEXT: .long .Ltmp1 at IMGREL+1
; SEH-NEXT: .long dummy_filter at IMGREL
; SEH-NEXT: .long .LBB0_5 at IMGREL
-; SEH-NEXT: .long .Ltmp2 at IMGREL+1
+; SEH-NEXT: .long .Ltmp2 at IMGREL
; SEH-NEXT: .long .Ltmp3 at IMGREL+1
; SEH-NEXT: .long "?dtor$2@?0?test at 4HA"@IMGREL
; SEH-NEXT: .long 0
-; SEH-NEXT: .long .Ltmp2 at IMGREL+1
+; SEH-NEXT: .long .Ltmp2 at IMGREL
; SEH-NEXT: .long .Ltmp3 at IMGREL+1
; SEH-NEXT: .long dummy_filter at IMGREL
; SEH-NEXT: .long .LBB0_5 at IMGREL
diff --git a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
index ef8caf36a68c6..a4db3e9fa8333 100644
--- a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
+++ b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
@@ -47,7 +47,7 @@ return: ; preds = %catch, %entry
; CHECK-NEXT: .set .Lfoo$parent_frame_offset, 32
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long .LBB0_[[catch]]@IMGREL
diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll
index cb558e23c00f9..584c37a3bb7ce 100644
--- a/llvm/test/CodeGen/X86/seh-catchpad.ll
+++ b/llvm/test/CodeGen/X86/seh-catchpad.ll
@@ -120,23 +120,23 @@ __except.ret: ; preds = %catch.dispatch.7
; CHECK-NEXT: .set .Lmain$parent_frame_offset, 32
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long .LBB1_[[except1bb]]@IMGREL
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_[[except2bb]]@IMGREL
-; CHECK-NEXT: .long .Ltmp2 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp2 at IMGREL
; CHECK-NEXT: .long .Ltmp3 at IMGREL+1
; CHECK-NEXT: .long "?dtor$[[finbb:[0-9]+]]@?0?main at 4HA"@IMGREL
; CHECK-NEXT: .long 0
-; CHECK-NEXT: .long .Ltmp2 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp2 at IMGREL
; CHECK-NEXT: .long .Ltmp3 at IMGREL+1
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_3 at IMGREL
-; CHECK-NEXT: .long .Ltmp6 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp6 at IMGREL
; CHECK-NEXT: .long .Ltmp7 at IMGREL+1
; CHECK-NEXT: .long "?filt$0 at 0@main@@"@IMGREL
; CHECK-NEXT: .long .LBB1_3 at IMGREL
diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll
index 0a1e02217b791..759d655192772 100644
--- a/llvm/test/CodeGen/X86/seh-except-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-except-finally.ll
@@ -82,15 +82,15 @@ __try.cont: ; preds = %__except, %invoke.c
; CHECK-NEXT: .Luse_both$parent_frame_offset
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long "?dtor$2@?0?use_both at 4HA"@IMGREL
; CHECK-NEXT: .long 0
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long "?filt$0 at 0@use_both@@"@IMGREL
; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
-; CHECK-NEXT: .long .Ltmp4 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp4 at IMGREL
; CHECK-NEXT: .long .Ltmp5 at IMGREL+1
; CHECK-NEXT: .long "?filt$0 at 0@use_both@@"@IMGREL
; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll
index ff6c25770b405..bd005406bd9cd 100644
--- a/llvm/test/CodeGen/X86/seh-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-finally.ll
@@ -29,7 +29,7 @@ lpad: ; preds = %entry
; X64-NEXT: .set .Lmain$parent_frame_offset, 32
; X64-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 # Number of call sites
; X64-NEXT: .Llsda_begin0:
-; X64-NEXT: .long .Ltmp0 at IMGREL+1 # LabelStart
+; X64-NEXT: .long .Ltmp0 at IMGREL # LabelStart
; X64-NEXT: .long .Ltmp1 at IMGREL+1 # LabelEnd
; X64-NEXT: .long "?dtor$2@?0?main at 4HA"@IMGREL # FinallyFunclet
; X64-NEXT: .long 0 # Null
diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll
index d46e235c59ac0..7e4156a8ffc63 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div.ll
@@ -81,11 +81,11 @@ __try.cont:
; CHECK-NEXT: .Lsafe_div$parent_frame_offset
; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
; CHECK-NEXT: .Llsda_begin0:
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long safe_div_filt0 at IMGREL
; CHECK-NEXT: .long [[handler0]]@IMGREL
-; CHECK-NEXT: .long .Ltmp0 at IMGREL+1
+; CHECK-NEXT: .long .Ltmp0 at IMGREL
; CHECK-NEXT: .long .Ltmp1 at IMGREL+1
; CHECK-NEXT: .long safe_div_filt1 at IMGREL
; CHECK-NEXT: .long [[handler1]]@IMGREL
More information about the llvm-commits
mailing list