Skip to content

[libc][i386] setjmp/longjmp #112437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading