Skip to content

Instantly share code, notes, and snippets.

@roblabla
Last active January 17, 2019 02:27
Show Gist options
  • Save roblabla/6a05eb53acf7b36809319a7877476a05 to your computer and use it in GitHub Desktop.
Save roblabla/6a05eb53acf7b36809319a7877476a05 to your computer and use it in GitHub Desktop.
// libuser syscalls:
/// Creates a thread in the current process.
pub fn create_thread(ip: fn() -> !, arg: usize, sp: *const u8, _priority: u32, _processor_id: u32) -> Result<Thread, KernelError> {
unsafe {
let (out_handle, ..) = syscall(nr::CreateThread, ip as usize, arg, sp as _, _priority as _, _processor_id as _, 0)?;
Ok(Thread(Handle::new(out_handle as _)))
}
}
// Function I'm writing:
fn test_threads() -> Terminal {
fn thread_b(c: usize) -> ! {
for _ in 0..10 {
println!("{}", c);
libuser::syscalls::sleep_thread(0);
}
}
libuser::syscalls::exit_thread()
}
#[naked]
fn function_wrapper() {
unsafe {
asm!("
push eax
call $0
" :: "i"(thread_b) :: "intel");
}
}
const THREAD_STACK_SIZE: usize = 0x2000;
let terminal = Arc::new(Mutex::new(terminal));
let stack = Box::new([0u8; THREAD_STACK_SIZE]);
let sp = (Box::into_raw(stack) as *const u8).wrapping_offset(THREAD_STACK_SIZE as isize);
let ip : fn() -> ! = unsafe {
// Safety: This is changing the return type from () to !. It's safe. It
// sucks though. This is, yet again, an instance of "naked functions are
// fucking horrible".
core::mem::transmute(function_wrapper) // THE BUG IS HERE
};
let thread_handle = libuser::syscalls::create_thread(ip, Arc::into_raw(terminal.clone()) as usize, sp, 0, 0)
.expect("svcCreateThread returned an error");
thread_handle.start()
.expect("svcStartThread returned an error");
// Wait for thread_b to terminate.
loop {
if let Ok(terminal) = Arc::try_unwrap(terminal) {
break terminal.into_inner()
}
libuser::syscalls::sleep_thread(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment