libc: Implement setjmp() and longjmp()

This commit is contained in:
apio 2022-10-17 21:22:18 +02:00
parent 511ad67a9a
commit 3c1146f2c5
4 changed files with 63 additions and 22 deletions

View File

@ -1,4 +1,5 @@
#include <luna.h> #include <luna.h>
#include <setjmp.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -167,11 +168,16 @@ int main()
perror("execv"); perror("execv");
return 1; return 1;
} }
else { printf("Success!! Got PID %ld\n", child); }
jmp_buf env;
int val = setjmp(env);
if (val == 0) { printf("Returning from setjmp!\n"); }
else else
{ {
printf("Success!! Got PID %ld\n", child); printf("Returning from longjmp! val=%d\n", val);
return 0; return 0;
} }
return 0; longjmp(env, 3);
} }

View File

@ -2,19 +2,28 @@
#define _SETJMP_H #define _SETJMP_H
#include <bits/macros.h> #include <bits/macros.h>
#include <stdint.h>
typedef int jmp_buf[1]; typedef uintptr_t jmp_buf[8];
typedef int sigjmp_buf[1]; typedef uintptr_t sigjmp_buf[8];
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
int setjmp(jmp_buf env); // Not implemented. /* Saves the current execution state in env. Returns 0 when called from the first time, or nonzero when returning
int sigsetjmp(sigjmp_buf env, int savesigs); // Not implemented. * from longjmp. */
__lc_noreturn void longjmp(jmp_buf env, int val); // Not implemented. int setjmp(jmp_buf env);
__lc_noreturn void siglongjmp(sigjmp_buf env, int val); // Not implemented.
/* Right now, does the exact same as setjmp() (savesigs is ignored), since signals are not implemented. */
int sigsetjmp(sigjmp_buf env, int savesigs);
/* Restores the execution state saved in env by a setjmp() call. */
__lc_noreturn void longjmp(jmp_buf env, int val);
/* Right now, does the exact same as longjmp(), since signals are not implemented. */
__lc_noreturn void siglongjmp(sigjmp_buf env, int val);
#ifdef __cplusplus #ifdef __cplusplus
} }

36
libs/libc/src/setjmp.asm Normal file
View File

@ -0,0 +1,36 @@
global _setjmp
global setjmp
_setjmp:
setjmp:
mov rsi, 0
mov [rdi], rbx
mov [rdi+8], r12
mov [rdi+16], r13
mov [rdi+24], r14
mov [rdi+32], r15
mov [rdi+40], rbp
mov [rdi+48], rsp
mov rax, [rsp]
mov [rdi+56], rax
xor rax, rax
ret
global _longjmp
global longjmp
_longjmp:
longjmp:
mov rax, rsi
cmp rax, 0
jne .nonzero
mov rax, 1
.nonzero:
mov rbx, [rdi]
mov r12, [rdi+8]
mov r13, [rdi+16]
mov r14, [rdi+24]
mov r15, [rdi+32]
mov rbp, [rdi+40]
mov rsp, [rdi+48]
mov rcx, [rdi+56]
mov [rsp], rcx
ret

View File

@ -3,23 +3,13 @@
extern "C" extern "C"
{ {
int setjmp(jmp_buf) int sigsetjmp(sigjmp_buf env, int)
{ {
NOT_IMPLEMENTED("setjmp"); return setjmp(env);
} }
int sigsetjmp(sigjmp_buf, int) __lc_noreturn void siglongjmp(sigjmp_buf env, int val)
{ {
NOT_IMPLEMENTED("sigsetjmp"); longjmp(env, val);
}
__lc_noreturn void longjmp(jmp_buf, int)
{
NOT_IMPLEMENTED("longjmp");
}
__lc_noreturn void siglongjmp(sigjmp_buf, int)
{
NOT_IMPLEMENTED("siglongjmp");
} }
} }