Last active
January 17, 2019 02:27
-
-
Save roblabla/6a05eb53acf7b36809319a7877476a05 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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