diff --git a/include/assert.h b/include/assert.h index 3de837a..583dfac 100644 --- a/include/assert.h +++ b/include/assert.h @@ -8,6 +8,6 @@ } \ } while(0) -extern _Noreturn void __assert_fail(const char *file, int line, const char *message); +[[noreturn]] void __assert_fail(const char *file, int line, const char *message); #endif diff --git a/include/bits/setjmp.h b/include/bits/setjmp.h new file mode 100644 index 0000000..6d6e5c8 --- /dev/null +++ b/include/bits/setjmp.h @@ -0,0 +1,7 @@ +#ifndef _YGGDRASIL_SETJMP_H +#define _YGGDRASIL_SETJMP_H 1 + +int setjmp(jmp_buf env); +[[noreturn]] void longjmp(jmp_buf env, int val); + +#endif diff --git a/src/header/mod.rs b/src/header/mod.rs index f629492..5847217 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -1,5 +1,7 @@ #![allow(nonstandard_style, unused_variables)] +// TODO limits.h is compiler-provided + pub mod sys_types; pub mod sys_wait; @@ -10,6 +12,7 @@ pub mod fcntl; pub mod limits; pub mod locale; pub mod math; +pub mod setjmp; pub mod stdio; pub mod stdlib; pub mod string; @@ -43,7 +46,7 @@ NEVER iso646.h - alternative spellings ----- libgen.h - definitions for pattern matching functions PARTIAL limits.h - implementation-defined constants ----- locale.h - category macros ------ math.h - mathematical declarations +----- math.h - mathematical declarations TODO there're parts of libm in yggdrasil-rt ----- monetary.h - monetary types NEVER mqueue.h - message queues (REALTIME) NEVER ndbm.h - definitions for ndbm database operations diff --git a/src/header/setjmp/cbindgen.toml b/src/header/setjmp/cbindgen.toml new file mode 100644 index 0000000..ee66b1b --- /dev/null +++ b/src/header/setjmp/cbindgen.toml @@ -0,0 +1,15 @@ +language = "C" +style = "Type" + +sys_includes = ["stdarg.h", "stddef.h"] +no_includes = true + +include_guard = "_SETJMP_H" +trailer = "#include " + +usize_type = "size_t" +isize_type = "ssize_t" + +[export] +include = ["jmp_buf"] +exclude = [] diff --git a/src/header/setjmp/mod.rs b/src/header/setjmp/mod.rs new file mode 100644 index 0000000..af8bb3b --- /dev/null +++ b/src/header/setjmp/mod.rs @@ -0,0 +1,7 @@ +use core::ffi::c_int; + +#[cfg(target_arch = "x86_64")] +mod x86_64; + +#[cfg(target_arch = "x86_64")] +pub type jmp_buf = *mut x86_64::__jmp_buf; diff --git a/src/header/setjmp/x86_64.S b/src/header/setjmp/x86_64.S new file mode 100644 index 0000000..9858bf0 --- /dev/null +++ b/src/header/setjmp/x86_64.S @@ -0,0 +1,46 @@ +.global setjmp +.global longjmp + +.global _setjmp +.global _longjmp + +.section .text +// args: +// %rdi -- __jmp_buf *env +setjmp: +_setjmp: + movq %rbx, 0(%rdi) + movq %rbp, 8(%rdi) + movq %r12, 16(%rdi) + movq %r13, 24(%rdi) + movq %r14, 32(%rdi) + movq %r15, 40(%rdi) + // Calculate return stack and rip + leaq 8(%rsp), %rax + movq %rax, 48(%rdi) + movq (%rsp), %rax + movq %rax, 56(%rdi) + + movq $0, %rax + ret + +// args: +// %rdi -- __jmp_buf *env +// %rsi -- int val +longjmp: +_longjmp: + // Restore registers + movq 0(%rdi), %rbx + movq 8(%rdi), %rbp + movq 16(%rdi), %r12 + movq 24(%rdi), %r13 + movq 32(%rdi), %r14 + movq 40(%rdi), %r15 + movq 48(%rdi), %rsp + movq 56(%rdi), %rax + pushq %rax + + // Setup return value + movq %rsi, %rax + + ret diff --git a/src/header/setjmp/x86_64.rs b/src/header/setjmp/x86_64.rs new file mode 100644 index 0000000..a6d75f7 --- /dev/null +++ b/src/header/setjmp/x86_64.rs @@ -0,0 +1,15 @@ +use core::{arch::global_asm, ffi::c_int}; + +#[repr(C)] +pub struct __jmp_buf { + rip: usize, + rsp: usize, + r15: usize, + r14: usize, + r13: usize, + r12: usize, + rbp: usize, + rbx: usize, +} + +global_asm!(include_str!("x86_64.S"), options(att_syntax));