diff options
author | Daniel Paoliello <danpao@microsoft.com> | 2021-08-20 21:38:50 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2021-08-20 22:32:12 +0300 |
commit | 8ecce69594b27674946d5a3ec8724afd65b9c99b (patch) | |
tree | 104dd8ed8ca9d14614bc0bf5ed32aec5368fb078 /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
parent | 10020d41eefada835517ccd0a0c418609bfbd2a9 (diff) | |
download | llvm-8ecce69594b27674946d5a3ec8724afd65b9c99b.zip llvm-8ecce69594b27674946d5a3ec8724afd65b9c99b.tar.gz llvm-8ecce69594b27674946d5a3ec8724afd65b9c99b.tar.bz2 |
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
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index b30d9cc1..ef57031 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. } } |