summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2024-06-07 05:16:33 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2024-06-07 05:16:33 +0000
commit5c338d38019823ff68252e2cd7bed174439fad3b (patch)
treefc785b18a93ff80c5317f1fdfb8df8d7cd79249d /gnu
parentdb78e1ab9868ca3dd2e9eb22348709c01fb70017 (diff)
Inside LLVM, Functions become marked with exposesReturnsTwice() if they
call a setjmp-type function (protyped with __attribute__((returns_twice)). LLVM anticipates the longjmp type function will perform a direct branch back (rather of a push;ret combo, almost certainly due to CET shadow-stack coherency difficulties). Since we have CET/IBT enforced, LLVM makes that direct branch legal by placing an endbr64 immediately after the callq. Where I was placing the ret-clean sequence... this blows up badly, in unhibernate / resume situations. In the Functions marked exposesReturnsTwice(), skip doing ret-clean. (placing the ret-clear after that endbr64 is much more difficult) observed by mglocker, diagnosed by mlarkin, kettenis, guenther.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp4
1 files changed, 4 insertions, 0 deletions
diff --git a/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp b/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp
index 623bfede522..4d7e3e3b3cf 100644
--- a/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp
+++ b/gnu/llvm/llvm/lib/Target/X86/X86RetClean.cpp
@@ -96,6 +96,10 @@ bool RetCleanPass::runOnMachineFunction(MachineFunction &MF) {
bool modified = false;
+ // It a setjmp-like function is called by this function, we should not clean
+ if (MF.exposesReturnsTwice())
+ return false;
+
for (auto &MBB : MF) {
std::vector<MachineInstr*> fixups;
bool foundcall = false;