Tried and failed to use unwinding crate: shall do it myself tomorrow.

This commit is contained in:
2025-03-05 03:24:26 +00:00
parent 014ec5310c
commit af995d1d76
8 changed files with 177 additions and 92 deletions
+7
View File
@@ -19,6 +19,13 @@ futures-util = { version = "0.3.31", default-features = false, features = [
"alloc", "alloc",
] } ] }
linked_list_allocator = { version = "0.10.5", features = ["use_spin"] } linked_list_allocator = { version = "0.10.5", features = ["use_spin"] }
# unwinding = { version = "0.2.5", default-features = false, features = [
# "unwinder",
# "fde-static",
# "personality",
# "panic",
# "hide-trace",
# ] }
[build-dependencies] [build-dependencies]
cc = "1.2.14" cc = "1.2.14"
+7 -2
View File
@@ -46,6 +46,12 @@ SECTIONS
*(.rodata .rodata.*) *(.rodata .rodata.*)
} :rodata } :rodata
/* Adds support for stack unwinding using the unwinding crate. */
. = ALIGN(8);
PROVIDE(__eh_frame = .);
.eh_frame : { KEEP (*(.eh_frame)) *(.eh_frame.*) }
/* Move to the next memory page for .data */ /* Move to the next memory page for .data */
. = ALIGN(CONSTANT(MAXPAGESIZE)); . = ALIGN(CONSTANT(MAXPAGESIZE));
@@ -62,9 +68,8 @@ SECTIONS
*(COMMON) *(COMMON)
} :data } :data
/* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ /* Discard .note.* and ~~.eh_frame*~~ since they may cause issues on some hosts. */
/DISCARD/ : { /DISCARD/ : {
*(.eh_frame*)
*(.note .note.*) *(.note .note.*)
} }
} }
+3 -3
View File
@@ -237,12 +237,12 @@ macro_rules! print {
} }
#[macro_export] #[macro_export]
macro_rules! printlnerr { macro_rules! eprintln {
() => ($crate::printerr!("\n")); () => ($crate::printerr!("\n"));
($($arg:tt)*) => ($crate::printerr!("{}\n", format_args!($($arg)*))); ($($arg:tt)*) => ($crate::eprint!("{}\n", format_args!($($arg)*)));
} }
#[macro_export] #[macro_export]
macro_rules! printerr { macro_rules! eprint {
($($arg:tt)*) => ($crate::prelude::_print_err(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::prelude::_print_err(format_args!($($arg)*)));
} }
+4 -3
View File
@@ -22,16 +22,17 @@ use limine::BaseRevision;
use x86_64::VirtAddr; use x86_64::VirtAddr;
pub mod arch; pub mod arch;
mod panic;
pub mod resources; pub mod resources;
#[allow(unused)] // We aren't using much of this right now. #[allow(unused)] // We aren't using much of this right now.
pub mod std; pub mod std;
pub mod util; pub mod util;
pub mod prelude { pub mod prelude {
pub use crate::std::io::{_print, _print_log, _serial_write};
pub use crate::{ pub use crate::{
print, print_log, printerr, println, println_log, printlnerr, eprint, eprintln, print, print_log, println, println_log, serial_print,
serial_print, serial_println, serial_println,
std::io::{_print, _print_err, _print_log, _serial_write},
}; };
} }
+75
View File
@@ -0,0 +1,75 @@
// //! Stack-unwinding code for the Kernel. This is a modified version of https://github.com/nbdd0121/unwinding/blob/trunk/src/panic_handler.rs
// //! which does not support environment variables for obvious reasons, however we
// //! may implement a cmdline similar to Linux in the near future.
// #![expect(
// clippy::empty_loop,
// reason = "We don't yet have working power management. This is OK for now."
// )]
// use crate::prelude::*;
// use alloc::boxed::Box;
// use core::any::Any;
// use core::cell::Cell;
// use core::ffi::c_void;
// use core::panic::{Location, PanicInfo};
// use unwinding::abi::*;
// use unwinding::panic::begin_panic;
// #[thread_local]
// static PANIC_COUNT: Cell<usize> = Cell::new(0);
// #[link(name = "c")]
// unsafe extern "C" {}
// fn stack_trace() {
// struct CallbackData {
// counter: usize,
// }
// extern "C" fn callback(
// unwind_ctx: &UnwindContext<'_>,
// arg: *mut c_void,
// ) -> UnwindReasonCode {
// let data = unsafe { &mut *(arg as *mut CallbackData) };
// data.counter += 1;
// eprintln!(
// "{:4}:{:#19x} - <unknown>",
// data.counter,
// _Unwind_GetIP(unwind_ctx)
// );
// UnwindReasonCode::NO_REASON
// }
// let mut data = CallbackData { counter: 0 };
// _Unwind_Backtrace(callback, &mut data as *mut _ as _);
// }
// fn do_panic(msg: Box<dyn Any + Send>) -> ! {
// if PANIC_COUNT.get() >= 1 {
// stack_trace();
// eprintln!("Thread panicked while processing panic. aborting.");
// loop {}
// }
// PANIC_COUNT.set(1);
// stack_trace();
// let code = begin_panic(Box::new(msg));
// eprintln!("Failed to initiate panic: error {}", code.0);
// loop {}
// }
// #[panic_handler]
// fn panic(info: &PanicInfo<'_>) -> ! {
// eprintln!("{}", info);
// struct NoPayload;
// do_panic(Box::new(NoPayload))
// }
// #[track_caller]
// #[expect(unused, reason = "May still be used in the future.")]
// pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
// eprintln!("Panicked at {}", Location::caller());
// do_panic(Box::new(msg))
// }
-84
View File
@@ -1,84 +0,0 @@
pub use crate::arch::x86_64::drivers::{
ascii::{_print, _print_err, _print_log},
serial::_serial_write,
};
pub mod stdin {
use crate::arch::x86_64::drivers::{
ascii::WRITER,
keyboard::{KeyStroke, get_keystroke_async, get_keystroke_optional},
};
use alloc::string::String;
/// Reads a line of input from standard input asynchronously, returning a
/// `String` containing the input line. Does not include the newline
/// character at the end of the line.
///
/// If the user presses the abort key (usually Ctrl+C), the returned string
/// will be empty.
///
/// This function is currently unimplemented.
pub async fn read_line() -> String {
let mut writer = WRITER.lock();
let mut buff = String::new();
loop {
match get_keystroke_async().await {
KeyStroke::Char(c) => match c {
'\n' => {
writer.write_glyph(c as u8);
return buff;
}
'\r' => {
writer.write_glyph(c as u8);
return buff;
}
'\x08' => {
if !buff.is_empty() {
buff.pop();
writer.backspace();
}
}
c => {
writer.write_glyph(c as u8);
buff.push(c)
}
},
KeyStroke::Enter => {
writer.write_glyph(b'\n');
return buff;
}
KeyStroke::Backspace => {
if !buff.is_empty() {
buff.pop();
writer.backspace();
}
}
_ => continue,
}
}
}
/// Reads a character from standard input and blocks the current task until
/// a character is available.
///
/// # Note
///
/// This function is not yet implemented.
pub async fn async_keystroke() -> KeyStroke {
get_keystroke_async().await
}
/// Attempt to read a character from standard input without blocking the
/// current task.
///
/// If no character is available, returns `None`.
///
/// # Note
///
/// This function is not yet implemented.
pub fn keystroke() -> Option<KeyStroke> {
get_keystroke_optional()
}
}
+6
View File
@@ -0,0 +1,6 @@
pub use crate::arch::x86_64::drivers::{
ascii::{_print, _print_err, _print_log},
serial::_serial_write,
};
pub mod stdin;
+75
View File
@@ -0,0 +1,75 @@
use crate::arch::x86_64::drivers::{
ascii::WRITER,
keyboard::{KeyStroke, get_keystroke_async, get_keystroke_optional},
};
use alloc::string::String;
/// Reads a line of input from standard input asynchronously, returning a
/// `String` containing the input line. Does not include the newline
/// character at the end of the line.
///
/// If the user presses the abort key (usually Ctrl+C), the returned string
/// will be empty.
pub async fn read_line() -> String {
let mut writer = WRITER.lock();
let mut buff = String::new();
loop {
match get_keystroke_async().await {
KeyStroke::Char(c) => match c {
'\n' => {
writer.write_glyph(c as u8);
return buff;
}
'\r' => {
writer.write_glyph(c as u8);
return buff;
}
'\x08' => {
if !buff.is_empty() {
buff.pop();
writer.backspace();
}
}
c => {
writer.write_glyph(c as u8);
buff.push(c)
}
},
KeyStroke::Enter => {
writer.write_glyph(b'\n');
return buff;
}
KeyStroke::Backspace => {
if !buff.is_empty() {
buff.pop();
writer.backspace();
}
}
_ => continue,
}
}
}
/// Reads a character from standard input and blocks the current task until
/// a character is available.
///
/// # Note
///
/// This function is not yet implemented.
pub async fn async_keystroke() -> KeyStroke {
get_keystroke_async().await
}
/// Attempt to read a character from standard input without blocking the
/// current task.
///
/// If no character is available, returns `None`.
///
/// # Note
///
/// This function is not yet implemented.
pub fn keystroke() -> Option<KeyStroke> {
get_keystroke_optional()
}