libc: proper linkage for setjmp/longjmp
This commit is contained in:
parent
8160f2ab1a
commit
088659ce6c
19
test.c
19
test.c
@ -1,11 +1,22 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
void will_fail(jmp_buf a) {
|
||||
printf("FAIL!!!\n");
|
||||
longjmp(a, 123);
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
double x = round(1234.123);
|
||||
assert(fabs(x - 1234.000) < 0.00001);
|
||||
double y = round(1234.5678);
|
||||
assert(fabs(y - 1235.000) < 0.00001);
|
||||
jmp_buf a;
|
||||
int res = setjmp(a);
|
||||
|
||||
printf("setjmp = %d\n", res);
|
||||
|
||||
if (res == 0) {
|
||||
will_fail(a);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ impl RelocationExt for Rela {
|
||||
// Direct 64 bit
|
||||
elf::abi::R_X86_64_64 => Ok(Some(RelValue::QWord(base_value + self.r_addend))),
|
||||
elf::abi::R_X86_64_JUMP_SLOT => Ok(Some(RelValue::QWord(base_value))),
|
||||
elf::abi::R_X86_64_COPY => todo!("{:?}: R_X86_64_COPY", symbol.name),
|
||||
// GLOB_DAT
|
||||
elf::abi::R_X86_64_GLOB_DAT => Ok(Some(RelValue::QWord(base_value))),
|
||||
// Adjust by image base
|
||||
|
@ -22,12 +22,7 @@
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "ld.lld",
|
||||
|
||||
"late-link-args-static": {
|
||||
"ld.lld": [
|
||||
"--gc-sections"
|
||||
]
|
||||
},
|
||||
"late-link-args-dynamic": {
|
||||
"pre-link-args": {
|
||||
"ld.lld": [
|
||||
"--dynamic-linker=/libexec/dyn-loader"
|
||||
]
|
||||
|
@ -1,7 +0,0 @@
|
||||
#ifndef _YGGDRASIL_SETJMP_H
|
||||
#define _YGGDRASIL_SETJMP_H 1
|
||||
|
||||
int setjmp(jmp_buf env);
|
||||
[[noreturn]] void longjmp(jmp_buf env, int val);
|
||||
|
||||
#endif
|
14
userspace/lib/ygglibc/include/dlfcn.h
Normal file
14
userspace/lib/ygglibc/include/dlfcn.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _DLFCN_H
|
||||
#define _DLFCN_H 1
|
||||
|
||||
#define RTLD_LAZY (1 << 0)
|
||||
#define RTLD_NOW (0 << 0)
|
||||
#define RTLD_GLOBAL (1 << 1)
|
||||
#define RTLD_LOCAL (0 << 1)
|
||||
|
||||
int dlclose(void *ptr);
|
||||
char *dlerror(void);
|
||||
void *dlopen(const char *path, int mode);
|
||||
void *dlsym(void *handle, const char *sym);
|
||||
|
||||
#endif
|
@ -18,9 +18,7 @@
|
||||
// Math
|
||||
// <complex.h> -
|
||||
// <fenv.h> -
|
||||
// <float.h> -
|
||||
// <math.h> -
|
||||
// <tgmath.h> -
|
||||
// <math.h> +
|
||||
|
||||
// I/O utilities
|
||||
// <cpio.h> !
|
||||
|
@ -1,7 +1,7 @@
|
||||
language = "C"
|
||||
style = "Type"
|
||||
|
||||
sys_includes = ["stdarg.h", "stddef.h"]
|
||||
sys_includes = ["stddef.h"]
|
||||
no_includes = true
|
||||
|
||||
include_guard = "_SETJMP_H"
|
||||
@ -12,4 +12,11 @@ isize_type = "ssize_t"
|
||||
|
||||
[export]
|
||||
include = ["jmp_buf"]
|
||||
exclude = []
|
||||
exclude = [
|
||||
"setjmp",
|
||||
"longjmp",
|
||||
"_setjmp",
|
||||
"_longjmp",
|
||||
"__x86_64_setjmp",
|
||||
"__x86_64_longjmp"
|
||||
]
|
||||
|
@ -1,5 +1,9 @@
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
mod x86_64;
|
||||
use core::ffi::c_int;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
pub type jmp_buf = *mut x86_64::__jmp_buf;
|
||||
pub mod x86_64;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
pub use x86_64::__jmp_buf;
|
||||
|
||||
pub type jmp_buf = __jmp_buf;
|
||||
|
@ -1,46 +0,0 @@
|
||||
.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
|
@ -1,15 +1,53 @@
|
||||
use core::arch::global_asm;
|
||||
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,
|
||||
pub type __jmp_buf = [usize; 8];
|
||||
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
unsafe extern "C" fn setjmp(buf: __jmp_buf) -> c_int {
|
||||
// %rdi -- jmp_buf pointer
|
||||
core::arch::naked_asm!(
|
||||
r#"
|
||||
// Preserve callee-saved registers
|
||||
movq %rbx, 0(%rdi) // jmp_buf[0] = %rbx
|
||||
movq %rbp, 8(%rdi) // jmp_buf[1] = %rbp
|
||||
movq %r12, 16(%rdi) // jmp_buf[2] = %r12
|
||||
movq %r13, 24(%rdi) // jmp_buf[3] = %r13
|
||||
movq %r14, 32(%rdi) // jmp_buf[4] = %r14
|
||||
movq %r15, 40(%rdi) // jmp_buf[5] = %r15
|
||||
// Calculate return stack and rip
|
||||
leaq 8(%rsp), %rax
|
||||
movq %rax, 48(%rdi) // jmp_buf[6] = %rsp + 8 (return stack)
|
||||
movq (%rsp), %rax // jmp_buf[7] = return address
|
||||
movq %rax, 56(%rdi)
|
||||
|
||||
movq $0, %rax
|
||||
ret
|
||||
"#,
|
||||
options(att_syntax)
|
||||
)
|
||||
}
|
||||
|
||||
global_asm!(include_str!("x86_64.S"), options(att_syntax));
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
unsafe extern "C" fn longjmp(buf: __jmp_buf, val: c_int) -> c_int {
|
||||
// %rdi -- jmp_buf pointer
|
||||
// %rsi -- return value
|
||||
core::arch::naked_asm!(r#"
|
||||
// Restore the 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 fake return address
|
||||
|
||||
// Setup return value
|
||||
movq %rsi, %rax
|
||||
|
||||
ret
|
||||
"#, options(att_syntax))
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
language = "C"
|
||||
style = "Type"
|
||||
style = "Tag"
|
||||
|
||||
sys_includes = [
|
||||
"stddef.h",
|
||||
"stdint.h",
|
||||
"time.h",
|
||||
"sys/types.h",
|
||||
"bits/signal.h"
|
||||
]
|
||||
@ -15,5 +16,5 @@ usize_type = "size_t"
|
||||
isize_type = "ssize_t"
|
||||
|
||||
[export]
|
||||
include = ["sig_handler_t", "SIGABRT"]
|
||||
include = ["sig_handler_t", "sigaction", "sigevent", "SIGABRT"]
|
||||
exclude = []
|
||||
|
@ -1,11 +1,59 @@
|
||||
use core::ffi::c_int;
|
||||
use core::ffi::{c_char, c_int, c_long, c_void};
|
||||
|
||||
use yggdrasil_rt::process::Signal;
|
||||
|
||||
use super::sys_types::pid_t;
|
||||
use super::{
|
||||
sys_time::__ygg_timespec_t,
|
||||
sys_types::{pid_t, uid_t},
|
||||
};
|
||||
|
||||
pub type sig_handler_t = unsafe extern "C" fn(SigNumber);
|
||||
|
||||
pub type sigset_t = u64;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigevent {
|
||||
pub sigev_notify: c_int,
|
||||
pub sigev_signo: c_int,
|
||||
pub sigev_value: sigval,
|
||||
pub sigev_notify_function: unsafe extern "C" fn(sigval),
|
||||
// TODO pthread_attr_t *
|
||||
pub sigev_notify_attributes: *mut c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_handler: unsafe extern "C" fn(c_int),
|
||||
pub sa_mask: sigset_t,
|
||||
pub sa_flags: c_int,
|
||||
pub sa_sigaction: unsafe extern "C" fn(c_int, *mut siginfo_t, *mut c_void),
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct siginfo {
|
||||
pub si_signo: c_int,
|
||||
pub si_code: c_int,
|
||||
pub si_errno: c_int,
|
||||
pub si_pid: pid_t,
|
||||
pub si_uid: uid_t,
|
||||
pub si_addr: *mut c_void,
|
||||
pub si_status: c_int,
|
||||
pub si_band: c_long,
|
||||
pub si_value: sigval,
|
||||
}
|
||||
|
||||
pub type siginfo_t = siginfo;
|
||||
|
||||
#[repr(C)]
|
||||
pub union sigval {
|
||||
pub sival_int: c_int,
|
||||
pub sival_ptr: *mut c_void,
|
||||
}
|
||||
|
||||
// TODO sig_atomic_t
|
||||
|
||||
// SIG_DFL, SIG_ERR, SIG_HOLD, SIG_IGN are in <bits/signal.h>
|
||||
|
||||
extern "C" {
|
||||
fn __sig_terminate(_: SigNumber);
|
||||
fn __sig_ignore(_: SigNumber);
|
||||
@ -15,6 +63,10 @@ extern "C" {
|
||||
#[repr(transparent)]
|
||||
pub struct SigNumber(pub c_int);
|
||||
|
||||
pub const SIGEV_NONE: c_int = 0;
|
||||
pub const SIGEV_SIGNAL: c_int = 1;
|
||||
pub const SIGEV_THREAD: c_int = 2;
|
||||
|
||||
// TODO generate these based on the ABI
|
||||
pub const SIGSEGV: SigNumber = SigNumber(1);
|
||||
pub const SIGABRT: SigNumber = SigNumber(2);
|
||||
@ -77,30 +129,159 @@ impl From<Signal> for SigNumber {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn kill(_pid: pid_t, _signum: SigNumber) -> c_int {
|
||||
unsafe extern "C" fn kill(_pid: pid_t, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn killpg(_pid: pid_t, _signum: SigNumber) -> c_int {
|
||||
unsafe extern "C" fn killpg(_pgid: pid_t, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn raise(_signum: SigNumber) -> c_int {
|
||||
unsafe extern "C" fn psiginfo(_info: *const siginfo_t, _m: *const c_char) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn signal(_signum: SigNumber, _handler: sig_handler_t) -> sig_handler_t {
|
||||
unsafe extern "C" fn psignal(_signum: c_int, _m: *const c_char) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// TODO pthread_t
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn pthread_kill(_pt: *mut c_void, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn pthread_sigmask(
|
||||
_a: c_int,
|
||||
_new: *const sigset_t,
|
||||
_old: *mut sigset_t,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn raise(_signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigaction(
|
||||
_signum: c_int,
|
||||
_new: *const sigaction,
|
||||
_old: *mut sigaction,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigaddset(_mask: *mut sigset_t, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// TODO: stack_t
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigaltstack(_new: *const c_void, _old: *const c_void) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigdelset(_mask: *mut sigset_t, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigemptyset(_mask: *mut sigset_t) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigfillset(_mask: *mut sigset_t) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sighold(_signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigignore(_signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn siginterrupt(_signum: c_int, _b: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigismember(_mask: *const sigset_t, _signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn signal(_handler: sig_handler_t, _signum: c_int) -> sig_handler_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigpause(_signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigpending(_mask: *mut sigset_t) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigprocmask(
|
||||
_signum: c_int,
|
||||
_new: *const sigset_t,
|
||||
_old: *mut sigset_t,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigqueue(_pid: pid_t, _signum: c_int, _val: sigval) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigrelse(_signum: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigset(_signum: c_int, _handler: sig_handler_t) -> sig_handler_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigsuspend(_mask: *const sigset_t) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigtimedwait(
|
||||
_mask: *const sigset_t,
|
||||
_info: *mut siginfo_t,
|
||||
_time: *const __ygg_timespec_t,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigwait(_mask: *const sigset_t, _signum: *mut c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sigwaitinfo(_mask: *const sigset_t, _info: *mut siginfo_t) -> c_int {
|
||||
todo!()
|
||||
// // NOTE handler might be NULL, so check that
|
||||
// let Ok(signal) = Signal::try_from(signum) else {
|
||||
// // Ignore
|
||||
// return __sig_terminate;
|
||||
// };
|
||||
// let handler_ptr = handler as usize;
|
||||
// let handler = (handler_ptr != 0).then_some(handler);
|
||||
|
||||
// signal::set_handler(signal, handler)
|
||||
}
|
||||
|
@ -1,8 +1,36 @@
|
||||
use core::ffi::{c_char, c_int};
|
||||
|
||||
// int grantpt(int);
|
||||
// char *mkdtemp(char *);
|
||||
// int mkstemp(char *);
|
||||
// int posix_openpt(int);
|
||||
// char *ptsname(int);
|
||||
// char *realpath(const char *restrict, char *restrict);
|
||||
// int unlockpt(int);
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn grantpt(_fd: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn mkdtemp(_template: *mut c_char) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn mkstemp(_template: *mut c_char) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn posix_openpt(_fd: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn ptsname(_fd: c_int) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn realpath(_path: *const c_char, _resolved: *mut c_char) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn unlockpt(_fd: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use core::{
|
||||
|
||||
use chrono::{DateTime, Datelike, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Timelike, Utc};
|
||||
|
||||
use super::{sys_time::__ygg_timespec_t, sys_types::time_t};
|
||||
use super::{sys_time::__ygg_timespec_t, sys_types::{clock_t, clockid_t, time_t}};
|
||||
|
||||
mod convert;
|
||||
mod string;
|
||||
@ -36,6 +36,15 @@ pub struct tm {
|
||||
|
||||
pub type __ygg_tm_t = tm;
|
||||
|
||||
pub const CLOCKS_PER_SEC: clock_t = 1000000;
|
||||
|
||||
pub const CLOCK_MONOTONIC: clockid_t = 1;
|
||||
pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2;
|
||||
pub const CLOCK_REALTIME: clockid_t = 3;
|
||||
pub const CLOCK_THREAD_CPUTIME_ID: clockid_t = 4;
|
||||
|
||||
pub const TIMER_ABSTIME: c_int = 1 << 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut daylight: c_int = 0;
|
||||
#[no_mangle]
|
||||
|
@ -25,7 +25,7 @@ unsafe extern "C" fn nanosleep(
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn time(_tp: *mut time_t) -> time_t {
|
||||
todo!()
|
||||
time_t(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -8,7 +8,8 @@
|
||||
maybe_uninit_slice,
|
||||
slice_internals,
|
||||
linkage,
|
||||
rustc_private
|
||||
rustc_private,
|
||||
naked_functions
|
||||
)]
|
||||
#![allow(internal_features)]
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
|
@ -1,7 +1,88 @@
|
||||
use core::{fmt, sync::atomic::AtomicUsize};
|
||||
|
||||
use crate::io::{managed::{stderr, FILE}, Write};
|
||||
|
||||
struct PanicPrinter {
|
||||
buffer: [u8; 1024],
|
||||
pos: usize,
|
||||
|
||||
print: Option<&'static mut FILE>
|
||||
}
|
||||
|
||||
impl fmt::Write for PanicPrinter {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for ch in s.bytes() {
|
||||
self.push(ch);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PanicPrinter {
|
||||
pub fn new() -> Self {
|
||||
let print = unsafe { stderr.as_mut() };
|
||||
|
||||
Self {
|
||||
buffer: [0; 1024],
|
||||
pos: 0,
|
||||
print,
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
let text = &self.buffer[..self.pos];
|
||||
if !text.is_empty() {
|
||||
// Print to debug trace
|
||||
unsafe { yggdrasil_rt::debug::trace_raw(text) };
|
||||
|
||||
// Print to stderr
|
||||
if let Some(print) = self.print.as_mut() {
|
||||
print.write_all(text).ok();
|
||||
print.write_all(b"\n").ok();
|
||||
}
|
||||
}
|
||||
|
||||
self.pos = 0;
|
||||
}
|
||||
|
||||
pub fn push(&mut self, ch: u8) {
|
||||
if self.pos >= self.buffer.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
if ch == b'\n' {
|
||||
self.flush();
|
||||
} else {
|
||||
self.buffer[self.pos] = ch;
|
||||
self.pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PANIC_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[cfg(any(not(test), rust_analyzer))]
|
||||
#[panic_handler]
|
||||
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
yggdrasil_rt::debug_trace!("PANIC {:?}", &pi);
|
||||
use core::{fmt::Write, sync::atomic::Ordering};
|
||||
|
||||
match PANIC_COUNT.fetch_add(1, Ordering::Relaxed) {
|
||||
0 => {
|
||||
let mut printer = PanicPrinter::new();
|
||||
|
||||
writeln!(printer, "!!! ygglibc panic !!!").ok();
|
||||
if let Some(location) = pi.location() {
|
||||
writeln!(printer, "{}:{}:", location.file(), location.line()).ok();
|
||||
}
|
||||
writeln!(printer, " {}", pi.message());
|
||||
|
||||
printer.flush();
|
||||
}
|
||||
1 => unsafe {
|
||||
yggdrasil_rt::debug_trace!("!!! ygglibc panicked while panicking !!!");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Kill myself
|
||||
super::process::abort();
|
||||
|
@ -196,6 +196,11 @@ pub fn build_initrd(
|
||||
|
||||
build_userspace(env, &mut install_extra, check)?;
|
||||
|
||||
install_extra.push((
|
||||
"toolchain-c/programs/lua-5.4.7/src/lua".into(),
|
||||
"lua".into(),
|
||||
));
|
||||
|
||||
build_rootfs(
|
||||
env,
|
||||
install_extra,
|
||||
|
Loading…
x
Reference in New Issue
Block a user