[libc-commits] [libc] b1320d3 - [libc][i386] setjmp/longjmp (#112437)
via libc-commits
libc-commits at lists.llvm.org
Wed Oct 30 13:00:06 PDT 2024
Author: Nick Desaulniers
Date: 2024-10-30T12:59:59-07:00
New Revision: b1320d36339e38b073088fd45013a3c692adb301
URL: https://github.com/llvm/llvm-project/commit/b1320d36339e38b073088fd45013a3c692adb301
DIFF: https://github.com/llvm/llvm-project/commit/b1320d36339e38b073088fd45013a3c692adb301.diff
LOG: [libc][i386] setjmp/longjmp (#112437)
Link: #93709
Added:
Modified:
libc/include/llvm-libc-types/jmp_buf.h
libc/src/setjmp/x86_64/longjmp.cpp
libc/src/setjmp/x86_64/setjmp.cpp
Removed:
################################################################################
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/x86_64/longjmp.cpp b/libc/src/setjmp/x86_64/longjmp.cpp
index c293c55a6f9fb2..143c9deb11e9aa 100644
--- a/libc/src/setjmp/x86_64/longjmp.cpp
+++ b/libc/src/setjmp/x86_64/longjmp.cpp
@@ -11,12 +11,34 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.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(void, longjmp, (jmp_buf, int)) {
+ asm(R"(
+ mov 0x4(%%esp), %%ecx
+ mov 0x8(%%esp), %%eax
+ cmpl $0x1, %%eax
+ adcl $0x0, %%eax
+
+ mov %c[ebx](%%ecx), %%ebx
+ mov %c[esi](%%ecx), %%esi
+ mov %c[edi](%%ecx), %%edi
+ mov %c[ebp](%%ecx), %%ebp
+ mov %c[esp](%%ecx), %%esp
+
+ jmp *%c[eip](%%ecx)
+ )" ::[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)));
+}
+#else
[[gnu::naked]]
LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
asm(R"(
@@ -38,5 +60,6 @@ LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
[r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)),
[rip] "i"(offsetof(__jmp_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..5ac10fa87b39a3 100644
--- a/libc/src/setjmp/x86_64/setjmp.cpp
+++ b/libc/src/setjmp/x86_64/setjmp.cpp
@@ -11,12 +11,37 @@
#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 +66,6 @@ LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
[rip] "i"(offsetof(__jmp_buf, rip))
: "rax");
}
+#endif
} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list