From 05c13612833425c040b0a74db5f690e2d2987509 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 8 Aug 2024 19:31:20 -0700 Subject: [PATCH] [libc] Implement setjmp/longjmp Add a very simple setjmp/longjmp implementation. No destructors or other cleanup is handled. --- src/libraries/libc/arch/amd64/crt/crt0.s | 7 +++ src/libraries/libc/include/setjmp.h | 8 ++- src/libraries/libc/setjmp/setjmp.s | 76 ++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/libraries/libc/setjmp/setjmp.s diff --git a/src/libraries/libc/arch/amd64/crt/crt0.s b/src/libraries/libc/arch/amd64/crt/crt0.s index 05e5e29..4004d4c 100644 --- a/src/libraries/libc/arch/amd64/crt/crt0.s +++ b/src/libraries/libc/arch/amd64/crt/crt0.s @@ -1,3 +1,10 @@ +; This file is part of the C standard library for the jsix operating +; system. +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at https://mozilla.org/MPL/2.0/. + extern _GLOBAL_OFFSET_TABLE_ extern main diff --git a/src/libraries/libc/include/setjmp.h b/src/libraries/libc/include/setjmp.h index cd4aef3..7357565 100644 --- a/src/libraries/libc/include/setjmp.h +++ b/src/libraries/libc/include/setjmp.h @@ -10,4 +10,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#error setjmp.h is not yet implemented. +#include +#include + +typedef uint64_t jmp_buf[9]; + +int setjmp(jmp_buf env); +_Noreturn void longjmp(jmp_buf env, int val); diff --git a/src/libraries/libc/setjmp/setjmp.s b/src/libraries/libc/setjmp/setjmp.s new file mode 100644 index 0000000..f06fee6 --- /dev/null +++ b/src/libraries/libc/setjmp/setjmp.s @@ -0,0 +1,76 @@ +; This file is part of the C standard library for the jsix operating +; system. +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, You can obtain one at https://mozilla.org/MPL/2.0/. + +struc JMPBUF +.rbx: resq 1 +.rsp: resq 1 +.rbp: resq 1 +.r12: resq 1 +.r13: resq 1 +.r14: resq 1 +.r15: resq 1 + +.retaddr: resq 1 + +.mxcsr: resd 1 +.fcw: resw 1 + +endstruc + +global setjmp: function (setjmp.end - setjmp) +setjmp: + push rbp + mov rbp, rsp + + mov rax, [rsp + 8] + mov [rdi + JMPBUF.retaddr], rax + + mov [rdi + JMPBUF.rbx], rbx + mov [rdi + JMPBUF.rsp], rsp + mov [rdi + JMPBUF.rbp], rbp + mov [rdi + JMPBUF.r12], r12 + mov [rdi + JMPBUF.r13], r13 + mov [rdi + JMPBUF.r14], r14 + mov [rdi + JMPBUF.r15], r15 + + stmxcsr [rdi + JMPBUF.mxcsr] + fnstcw [rdi + JMPBUF.fcw] + + mov rax, 0 ; actual setjmp returns 0 + + pop rbp + ret +.end: + + +global longjmp: function (longjmp.end - longjmp) +longjmp: + push rbp + mov rbp, rsp + + mov rbx, [rdi + JMPBUF.rbx] + mov rbp, [rdi + JMPBUF.rbp] + mov r12, [rdi + JMPBUF.r12] + mov r13, [rdi + JMPBUF.r13] + mov r14, [rdi + JMPBUF.r14] + mov r15, [rdi + JMPBUF.r15] + + ldmxcsr [rdi + JMPBUF.mxcsr] + fnclex + fldcw [rdi + JMPBUF.fcw] + + mov rsp, [rdi + JMPBUF.rsp] + + mov rax, rsi + cmp rax, 0 + jne .done + mov rax, 1 + +.done: + pop rbp + ret +.end: