Skip to content

Commit

Permalink
[libc][i386] setjmp/longjmp (#112437)
Browse files Browse the repository at this point in the history
Link: #93709
  • Loading branch information
nickdesaulniers authored Oct 30, 2024
1 parent c616f24 commit b1320d3
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
7 changes: 7 additions & 0 deletions libc/include/llvm-libc-types/jmp_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
25 changes: 24 additions & 1 deletion libc/src/setjmp/x86_64/longjmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"(
Expand All @@ -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
28 changes: 27 additions & 1 deletion libc/src/setjmp/x86_64/setjmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"(
Expand All @@ -41,5 +66,6 @@ LLVM_LIBC_FUNCTION(int, setjmp, (jmp_buf buf)) {
[rip] "i"(offsetof(__jmp_buf, rip))
: "rax");
}
#endif

} // namespace LIBC_NAMESPACE_DECL

0 comments on commit b1320d3

Please sign in to comment.