Skip to content

Commit 8cc8e7f

Browse files
[libc][i386] setjmp/longjmp
Link: #93709
1 parent f405c68 commit 8cc8e7f

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

libc/include/llvm-libc-types/jmp_buf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ typedef struct {
1919
__UINT64_TYPE__ r15;
2020
__UINTPTR_TYPE__ rsp;
2121
__UINTPTR_TYPE__ rip;
22+
#elif defined(__i386__)
23+
long ebx;
24+
long esi;
25+
long edi;
26+
long ebp;
27+
long esp;
28+
long eip;
2229
#elif defined(__riscv)
2330
/* Program counter. */
2431
long int __pc;

libc/src/setjmp/x86_64/longjmp.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,34 @@
1111
#include "src/__support/common.h"
1212
#include "src/__support/macros/config.h"
1313

14-
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
14+
#if !defined(LIBC_TARGET_ARCH_IS_X86)
1515
#error "Invalid file include"
1616
#endif
1717

1818
namespace LIBC_NAMESPACE_DECL {
1919

20+
#ifdef __i386__
21+
[[gnu::naked]]
22+
LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
23+
asm(R"(
24+
mov 0x4(%%esp), %%ecx
25+
mov 0x8(%%esp), %%eax
26+
cmpl $0x1, %%eax
27+
adcl $0x0, %%eax
28+
29+
mov %c[ebx](%%ecx), %%ebx
30+
mov %c[esi](%%ecx), %%esi
31+
mov %c[edi](%%ecx), %%edi
32+
mov %c[ebp](%%ecx), %%ebp
33+
mov %c[esp](%%ecx), %%esp
34+
35+
jmp *%c[eip](%%ecx)
36+
)" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
37+
[esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
38+
[ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
39+
[eip] "i"(offsetof(__jmp_buf, eip)));
40+
}
41+
#else
2042
[[gnu::naked]]
2143
LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
2244
asm(R"(
@@ -38,5 +60,6 @@ LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) {
3860
[r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)),
3961
[rip] "i"(offsetof(__jmp_buf, rip)));
4062
}
63+
#endif
4164

4265
} // namespace LIBC_NAMESPACE_DECL

libc/src/setjmp/x86_64/setjmp.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,37 @@
1111
#include "src/__support/macros/config.h"
1212
#include "src/setjmp/setjmp_impl.h"
1313

14-
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
14+
#if !defined(LIBC_TARGET_ARCH_IS_X86)
1515
#error "Invalid file include"
1616
#endif
1717

1818
namespace LIBC_NAMESPACE_DECL {
1919

20+
#ifdef __i386__
21+
[[gnu::naked]]
22+
LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
23+
asm(R"(
24+
mov 4(%%esp), %%eax
25+
26+
mov %%ebx, %c[ebx](%%eax)
27+
mov %%esi, %c[esi](%%eax)
28+
mov %%edi, %c[edi](%%eax)
29+
mov %%ebp, %c[ebp](%%eax)
30+
31+
lea 4(%%esp), %%ecx
32+
mov %%ecx, %c[esp](%%eax)
33+
34+
mov (%%esp), %%ecx
35+
mov %%ecx, %c[eip](%%eax)
36+
37+
xorl %%eax, %%eax
38+
retl)" ::[ebx] "i"(offsetof(__jmp_buf, ebx)),
39+
[esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)),
40+
[ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)),
41+
[eip] "i"(offsetof(__jmp_buf, eip))
42+
: "eax", "ecx");
43+
}
44+
#else
2045
[[gnu::naked]]
2146
LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
2247
asm(R"(
@@ -41,5 +66,6 @@ LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
4166
[rip] "i"(offsetof(__jmp_buf, rip))
4267
: "rax");
4368
}
69+
#endif
4470

4571
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)