[libc-commits] [libc] [libc][i386] setjmp/longjmp (PR #112437)
Nick Desaulniers via libc-commits
libc-commits at lists.llvm.org
Tue Oct 15 14:06:30 PDT 2024
https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/112437
>From 1d9d3d408ab24edfb58e2019e59c26a7b9aca9d2 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 3 Oct 2024 09:24:24 -0700
Subject: [PATCH 1/3] [libc][i386] setjmp/longjmp
Link: #93709
---
libc/include/llvm-libc-types/jmp_buf.h | 7 ++++++
libc/src/setjmp/longjmp.h | 1 +
libc/src/setjmp/x86_64/longjmp.cpp | 33 ++++++++++++++++++++++++--
libc/src/setjmp/x86_64/setjmp.cpp | 31 +++++++++++++++++++++++-
4 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index 60e033c6c65a95..f246e6491cf554 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -19,6 +19,13 @@ typedef struct {
__UINT64_TYPE__ r15;
__UINTPTR_TYPE__ rsp;
__UINTPTR_TYPE__ rip;
+#elif defined(__i386__)
+ long ebx;
+ long esi;
+ long edi;
+ long ebp;
+ long esp;
+ long eip;
#elif defined(__riscv)
/* Program counter. */
long int __pc;
diff --git a/libc/src/setjmp/longjmp.h b/libc/src/setjmp/longjmp.h
index 7cb12b3392ae16..e8d6985f44ee4d 100644
--- a/libc/src/setjmp/longjmp.h
+++ b/libc/src/setjmp/longjmp.h
@@ -14,6 +14,7 @@
namespace LIBC_NAMESPACE_DECL {
+[[noreturn]]
void longjmp(jmp_buf buf, int val);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/x86_64/longjmp.cpp b/libc/src/setjmp/x86_64/longjmp.cpp
index d4b55565cb2187..f27e5f055d6f99 100644
--- a/libc/src/setjmp/x86_64/longjmp.cpp
+++ b/libc/src/setjmp/x86_64/longjmp.cpp
@@ -6,16 +6,44 @@
//
//===----------------------------------------------------------------------===//
-#include "src/setjmp/longjmp.h"
+#include "include/llvm-libc-macros/offsetof-macro.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/setjmp/longjmp.h"
-#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
+#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid file include"
#endif
namespace LIBC_NAMESPACE_DECL {
+#ifdef __i386__
+[[noreturn]]
+LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int val)) {
+ asm(R"(
+ mov 4(%%esp), %%edx
+
+ mov %c[ebx](%%edx), %%ebx
+ mov %c[esi](%%edx), %%esi
+ mov %c[edi](%%edx), %%edi
+ mov %c[ebp](%%edx), %%ebp
+ mov %c[esp](%%edx), %%esp
+
+ jmp *%c[eip](%%edx)
+ )"
+ ::
+ [ebx] "i"(offsetof(__jmp_buf, ebx)),
+ [esi] "i"(offsetof(__jmp_buf, esi)),
+ [edi] "i"(offsetof(__jmp_buf, edi)),
+ [ebp] "i"(offsetof(__jmp_buf, ebp)),
+ [esp] "i"(offsetof(__jmp_buf, esp)),
+ [eip] "i"(offsetof(__jmp_buf, eip)),
+ [val] "a"(val == 0 ? 1 : val) :
+ "edx");
+ __builtin_unreachable();
+}
+#else
+[[noreturn]]
LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) {
register __UINT64_TYPE__ rbx __asm__("rbx");
register __UINT64_TYPE__ rbp __asm__("rbp");
@@ -41,5 +69,6 @@ LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) {
LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rsp) : "m"(buf->rsp) :);
LIBC_INLINE_ASM("jmp *%0\n\t" : : "m"(buf->rip));
}
+#endif
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/x86_64/setjmp.cpp b/libc/src/setjmp/x86_64/setjmp.cpp
index f6e82642edd7da..90532c5654b33b 100644
--- a/libc/src/setjmp/x86_64/setjmp.cpp
+++ b/libc/src/setjmp/x86_64/setjmp.cpp
@@ -11,12 +11,40 @@
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
-#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
+#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid file include"
#endif
namespace LIBC_NAMESPACE_DECL {
+#ifdef __i386__
+[[gnu::naked]]
+LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
+ asm(R"(
+ mov 4(%%esp), %%eax
+
+ mov %%ebx, %c[ebx](%%eax)
+ mov %%esi, %c[esi](%%eax)
+ mov %%edi, %c[edi](%%eax)
+ mov %%ebp, %c[ebp](%%eax)
+
+ lea 4(%%esp), %%ecx
+ mov %%ecx, %c[esp](%%eax)
+
+ mov (%%esp), %%ecx
+ mov %%ecx, %c[eip](%%eax)
+
+ xorl %%eax, %%eax
+ retl)" ::
+ [ebx] "i"(offsetof(__jmp_buf, ebx)),
+ [esi] "i"(offsetof(__jmp_buf, esi)),
+ [edi] "i"(offsetof(__jmp_buf, edi)),
+ [ebp] "i"(offsetof(__jmp_buf, ebp)),
+ [esp] "i"(offsetof(__jmp_buf, esp)),
+ [eip] "i"(offsetof(__jmp_buf, eip))
+ : "eax", "ecx");
+}
+#else
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
asm(R"(
@@ -41,5 +69,6 @@ LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
[rip] "i"(offsetof(__jmp_buf, rip))
: "rax");
}
+#endif
} // namespace LIBC_NAMESPACE_DECL
>From 28d030ebff4728cd068dce0e25056b7cef8d08e4 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 15 Oct 2024 14:06:04 -0700
Subject: [PATCH 2/3] use buf
---
libc/src/setjmp/x86_64/longjmp.cpp | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/libc/src/setjmp/x86_64/longjmp.cpp b/libc/src/setjmp/x86_64/longjmp.cpp
index f27e5f055d6f99..d0145e5f4fe9fd 100644
--- a/libc/src/setjmp/x86_64/longjmp.cpp
+++ b/libc/src/setjmp/x86_64/longjmp.cpp
@@ -19,17 +19,15 @@ namespace LIBC_NAMESPACE_DECL {
#ifdef __i386__
[[noreturn]]
-LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int val)) {
+LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) {
asm(R"(
- mov 4(%%esp), %%edx
-
- mov %c[ebx](%%edx), %%ebx
- mov %c[esi](%%edx), %%esi
- mov %c[edi](%%edx), %%edi
- mov %c[ebp](%%edx), %%ebp
- mov %c[esp](%%edx), %%esp
+ mov %c[ebx](%[buf]), %%ebx
+ mov %c[esi](%[buf]), %%esi
+ mov %c[edi](%[buf]), %%edi
+ mov %c[ebp](%[buf]), %%ebp
+ mov %c[esp](%[buf]), %%esp
- jmp *%c[eip](%%edx)
+ jmp *%c[eip](%[buf])
)"
::
[ebx] "i"(offsetof(__jmp_buf, ebx)),
@@ -38,6 +36,7 @@ LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int val)) {
[ebp] "i"(offsetof(__jmp_buf, ebp)),
[esp] "i"(offsetof(__jmp_buf, esp)),
[eip] "i"(offsetof(__jmp_buf, eip)),
+ [buf] "r"(buf),
[val] "a"(val == 0 ? 1 : val) :
"edx");
__builtin_unreachable();
>From 5716c9e74be72843a6fdc12ffca03d927b7f6750 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Tue, 15 Oct 2024 14:06:14 -0700
Subject: [PATCH 3/3] reformat
---
libc/src/setjmp/x86_64/longjmp.cpp | 19 +++++++------------
libc/src/setjmp/x86_64/setjmp.cpp | 9 +++------
2 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/libc/src/setjmp/x86_64/longjmp.cpp b/libc/src/setjmp/x86_64/longjmp.cpp
index d0145e5f4fe9fd..817672c038bbeb 100644
--- a/libc/src/setjmp/x86_64/longjmp.cpp
+++ b/libc/src/setjmp/x86_64/longjmp.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
+#include "src/setjmp/longjmp.h"
#include "include/llvm-libc-macros/offsetof-macro.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/setjmp/longjmp.h"
#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid file include"
@@ -28,17 +28,12 @@ LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) {
mov %c[esp](%[buf]), %%esp
jmp *%c[eip](%[buf])
- )"
- ::
- [ebx] "i"(offsetof(__jmp_buf, ebx)),
- [esi] "i"(offsetof(__jmp_buf, esi)),
- [edi] "i"(offsetof(__jmp_buf, edi)),
- [ebp] "i"(offsetof(__jmp_buf, ebp)),
- [esp] "i"(offsetof(__jmp_buf, esp)),
- [eip] "i"(offsetof(__jmp_buf, eip)),
- [buf] "r"(buf),
- [val] "a"(val == 0 ? 1 : val) :
- "edx");
+ )" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
+ [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
+ [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
+ [eip] "i"(offsetof(__jmp_buf, eip)), [buf] "r"(buf),
+ [val] "a"(val == 0 ? 1 : val)
+ : "edx");
__builtin_unreachable();
}
#else
diff --git a/libc/src/setjmp/x86_64/setjmp.cpp b/libc/src/setjmp/x86_64/setjmp.cpp
index 90532c5654b33b..5ac10fa87b39a3 100644
--- a/libc/src/setjmp/x86_64/setjmp.cpp
+++ b/libc/src/setjmp/x86_64/setjmp.cpp
@@ -35,12 +35,9 @@ LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
mov %%ecx, %c[eip](%%eax)
xorl %%eax, %%eax
- retl)" ::
- [ebx] "i"(offsetof(__jmp_buf, ebx)),
- [esi] "i"(offsetof(__jmp_buf, esi)),
- [edi] "i"(offsetof(__jmp_buf, edi)),
- [ebp] "i"(offsetof(__jmp_buf, ebp)),
- [esp] "i"(offsetof(__jmp_buf, esp)),
+ retl)" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
+ [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
+ [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
[eip] "i"(offsetof(__jmp_buf, eip))
: "eax", "ecx");
}
More information about the libc-commits
mailing list