Smp (#23)
* Fire up multiple processors * Use IPIs to wake up secondary processors * Much better exception information * Modifications to show more information on fault * WIP: Use real libstd * Add TLS (not complete) * Add random function, export getpid, cleanup * Do not spin APs until new context * Update rust * Update rust * Use rd/wrfsbase * Implement TLS * Implement compiler builtins and update rust * Update rust * Back to Redox libstd * Update rust
This commit is contained in:
parent
25dc44b348
commit
149b0297a4
54 changed files with 1121 additions and 380 deletions
18
libstd_real/Cargo.toml
Normal file
18
libstd_real/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "redox_std"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
|
||||
[lib]
|
||||
name = "std"
|
||||
path = "../rust/src/libstd/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
alloc_system = { path = "alloc_system" }
|
||||
compiler_builtins = { path = "compiler_builtins" }
|
||||
panic_unwind = { path = "panic_unwind" }
|
||||
libc = { path = "libc" }
|
||||
unwind = { path = "unwind" }
|
||||
|
||||
[replace]
|
||||
"libc:0.2.17" = { git = "https://github.com/redox-os/liblibc.git", branch = "new_kernel" }
|
12
libstd_real/alloc_system/Cargo.toml
Normal file
12
libstd_real/alloc_system/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "alloc_system"
|
||||
version = "0.0.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
|
||||
[dependencies.ralloc]
|
||||
path = "../../ralloc/"
|
||||
default-features = false
|
||||
features = ["allocator"]
|
||||
|
||||
[replace]
|
||||
"libc:0.2.17" = { git = "https://github.com/redox-os/liblibc.git", branch = "new_kernel" }
|
6
libstd_real/alloc_system/src/lib.rs
Normal file
6
libstd_real/alloc_system/src/lib.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
#![allocator]
|
||||
#![feature(allocator)]
|
||||
#![no_std]
|
||||
|
||||
#[allocator]
|
||||
extern crate ralloc;
|
4
libstd_real/compiler_builtins/Cargo.toml
Normal file
4
libstd_real/compiler_builtins/Cargo.toml
Normal file
|
@ -0,0 +1,4 @@
|
|||
[package]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
72
libstd_real/compiler_builtins/src/lib.rs
Normal file
72
libstd_real/compiler_builtins/src/lib.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
#![no_std]
|
||||
|
||||
/// Memcpy
|
||||
///
|
||||
/// Copy N bytes of memory from one location to another.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
|
||||
n: usize) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
/// Memmove
|
||||
///
|
||||
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
|
||||
n: usize) -> *mut u8 {
|
||||
if src < dest as *const u8 {
|
||||
let mut i = n;
|
||||
while i != 0 {
|
||||
i -= 1;
|
||||
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||
}
|
||||
} else {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*((dest as usize + i) as *mut u8) = *((src as usize + i) as *const u8);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
/// Memset
|
||||
///
|
||||
/// Fill a block of memory with a specified value.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*((dest as usize + i) as *mut u8) = c as u8;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
/// Memcmp
|
||||
///
|
||||
/// Compare two blocks of memory.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
|
||||
let mut i = 0;
|
||||
|
||||
while i < n {
|
||||
let a = *((s1 as usize + i) as *const u8);
|
||||
let b = *((s2 as usize + i) as *const u8);
|
||||
if a != b {
|
||||
return a as i32 - b as i32
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
7
libstd_real/libc/Cargo.toml
Normal file
7
libstd_real/libc/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "libc"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
syscall = { path = "../../syscall/" }
|
19
libstd_real/libc/src/funcs.rs
Normal file
19
libstd_real/libc/src/funcs.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use super::{c_char, size_t};
|
||||
|
||||
pub unsafe extern fn strlen(ptr: *const c_char) -> size_t {
|
||||
let mut i: size_t = 0;
|
||||
while *ptr.offset(i as isize) != 0 {
|
||||
i += 1;
|
||||
}
|
||||
i
|
||||
}
|
||||
|
||||
pub unsafe extern fn random() -> u64 {
|
||||
let rand;
|
||||
asm!("rdrand rax"
|
||||
: "={rax}"(rand)
|
||||
:
|
||||
:
|
||||
: "intel", "volatile");
|
||||
rand
|
||||
}
|
18
libstd_real/libc/src/lib.rs
Normal file
18
libstd_real/libc/src/lib.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
#![no_std]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![feature(asm)]
|
||||
#![feature(naked_functions)]
|
||||
|
||||
pub use types::*;
|
||||
pub use funcs::*;
|
||||
pub use start::*;
|
||||
pub use syscall::*;
|
||||
|
||||
/// Basic types (not usually system specific)
|
||||
mod types;
|
||||
/// Basic functions (not system specific)
|
||||
mod funcs;
|
||||
/// Start function and call in to libstd
|
||||
mod start;
|
||||
/// Conversion for syscall library (specific to Redox)
|
||||
mod syscall;
|
40
libstd_real/libc/src/start.rs
Normal file
40
libstd_real/libc/src/start.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use super::exit;
|
||||
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub unsafe fn _start() {
|
||||
asm!("push esp
|
||||
call _start_stack
|
||||
pop esp"
|
||||
:
|
||||
:
|
||||
: "memory"
|
||||
: "intel", "volatile");
|
||||
let _ = exit(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub unsafe fn _start() {
|
||||
asm!("mov rdi, rsp
|
||||
and rsp, 0xFFFFFFFFFFFFFFF0
|
||||
call _start_stack"
|
||||
:
|
||||
:
|
||||
: "memory"
|
||||
: "intel", "volatile");
|
||||
let _ = exit(0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn _start_stack(stack: *const usize){
|
||||
extern "C" {
|
||||
fn main(argc: usize, argv: *const *const u8) -> usize;
|
||||
}
|
||||
|
||||
let argc = *stack as usize;
|
||||
let argv = stack.offset(1) as *const *const u8;
|
||||
let _ = exit(main(argc, argv));
|
||||
}
|
87
libstd_real/libc/src/syscall.rs
Normal file
87
libstd_real/libc/src/syscall.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
/// Convert syscall types to libc types
|
||||
extern crate syscall;
|
||||
|
||||
use super::{c_int, sa_family_t};
|
||||
|
||||
use self::syscall::data::{Stat, TimeSpec};
|
||||
|
||||
pub use self::syscall::error::*;
|
||||
pub use self::syscall::flag::*;
|
||||
pub use self::syscall::{
|
||||
clock_gettime, clone, execve as exec, exit, futex, getpid, kill, nanosleep, setgid, setuid, waitpid,
|
||||
chdir, getcwd, open, mkdir, rmdir, unlink, dup, pipe2,
|
||||
read, write, fpath, fstat, fsync, ftruncate, lseek, close
|
||||
};
|
||||
|
||||
//TODO: Thread local
|
||||
pub static mut errno: c_int = 0;
|
||||
|
||||
pub type stat = Stat;
|
||||
pub type timespec = TimeSpec;
|
||||
|
||||
pub const AF_INET: sa_family_t = 1;
|
||||
pub const AF_INET6: sa_family_t = 2;
|
||||
|
||||
pub const STDIN_FILENO: usize = 0;
|
||||
pub const STDOUT_FILENO: usize = 1;
|
||||
pub const STDERR_FILENO: usize = 2;
|
||||
|
||||
fn cvt(result: syscall::Result<usize>) -> c_int {
|
||||
match result {
|
||||
Ok(res) => res as c_int,
|
||||
Err(err) => {
|
||||
unsafe { errno = err.errno };
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ralloc shims {
|
||||
/// Cooperatively gives up a timeslice to the OS scheduler.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sched_yield() -> c_int {
|
||||
cvt(syscall::sched_yield())
|
||||
}
|
||||
|
||||
/// Increment data segment of this process by some, _n_, return a pointer to the new data segment
|
||||
/// start.
|
||||
///
|
||||
/// This uses the system call BRK as backend.
|
||||
///
|
||||
/// This is unsafe for multiple reasons. Most importantly, it can create an inconsistent state,
|
||||
/// because it is not atomic. Thus, it can be used to create Undefined Behavior.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sbrk(n: isize) -> *mut u8 {
|
||||
let orig_seg_end = match unsafe { syscall::brk(0) } {
|
||||
Ok(end) => end,
|
||||
Err(_) => return !0 as *mut u8
|
||||
};
|
||||
|
||||
if n == 0 {
|
||||
return orig_seg_end as *mut u8;
|
||||
}
|
||||
|
||||
let expected_end = match orig_seg_end.checked_add(n as usize) {
|
||||
Some(end) => end,
|
||||
None => return !0 as *mut u8
|
||||
};
|
||||
|
||||
let new_seg_end = match unsafe { syscall::brk(expected_end) } {
|
||||
Ok(end) => end,
|
||||
Err(_) => return !0 as *mut u8
|
||||
};
|
||||
|
||||
if new_seg_end != expected_end {
|
||||
// Reset the break.
|
||||
let _ = unsafe { syscall::brk(orig_seg_end) };
|
||||
|
||||
!0 as *mut u8
|
||||
} else {
|
||||
orig_seg_end as *mut u8
|
||||
}
|
||||
}
|
||||
// } ralloc shims
|
||||
|
||||
pub unsafe fn fcntl(_fd: usize, _cmd: c_int, _arg: c_int) -> c_int {
|
||||
cvt(Err(Error::new(ENOSYS)))
|
||||
}
|
96
libstd_real/libc/src/types.rs
Normal file
96
libstd_real/libc/src/types.rs
Normal file
|
@ -0,0 +1,96 @@
|
|||
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
|
||||
// more optimization opportunities around it recognizing things like
|
||||
// malloc/free.
|
||||
#[repr(u8)]
|
||||
pub enum c_void {
|
||||
// Two dummy variants so the #[repr] attribute can be used.
|
||||
#[doc(hidden)]
|
||||
__variant1,
|
||||
#[doc(hidden)]
|
||||
__variant2,
|
||||
}
|
||||
|
||||
pub type int8_t = i8;
|
||||
pub type int16_t = i16;
|
||||
pub type int32_t = i32;
|
||||
pub type int64_t = i64;
|
||||
pub type uint8_t = u8;
|
||||
pub type uint16_t = u16;
|
||||
pub type uint32_t = u32;
|
||||
pub type uint64_t = u64;
|
||||
|
||||
pub type c_schar = i8;
|
||||
pub type c_uchar = u8;
|
||||
pub type c_short = i16;
|
||||
pub type c_ushort = u16;
|
||||
pub type c_float = f32;
|
||||
pub type c_double = f64;
|
||||
|
||||
pub type intmax_t = i64;
|
||||
pub type uintmax_t = u64;
|
||||
|
||||
pub type c_char = i8;
|
||||
pub type c_int = i32;
|
||||
pub type c_uint = u32;
|
||||
pub type c_long = i64;
|
||||
pub type c_ulong = u64;
|
||||
pub type c_longlong = i64;
|
||||
pub type c_ulonglong = u64;
|
||||
|
||||
pub type off_t = usize;
|
||||
pub type size_t = usize;
|
||||
pub type ptrdiff_t = isize;
|
||||
pub type intptr_t = isize;
|
||||
pub type uintptr_t = usize;
|
||||
pub type ssize_t = isize;
|
||||
|
||||
pub type mode_t = u16;
|
||||
pub type time_t = i64;
|
||||
pub type pid_t = usize;
|
||||
pub type gid_t = usize;
|
||||
pub type uid_t = usize;
|
||||
|
||||
pub type in_addr_t = u32;
|
||||
pub type in_port_t = u16;
|
||||
|
||||
pub type socklen_t = u32;
|
||||
pub type sa_family_t = u16;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: in_addr_t,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
__align: [u32; 0],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub sa_data: [::c_char; 14],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in {
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: ::in_port_t,
|
||||
pub sin_addr: ::in_addr,
|
||||
pub sin_zero: [u8; 8],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in6 {
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: in_port_t,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_addr: ::in6_addr,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
7
libstd_real/panic_unwind/Cargo.toml
Normal file
7
libstd_real/panic_unwind/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "panic_unwind"
|
||||
version = "0.0.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
syscall = { path = "../../syscall/" }
|
27
libstd_real/panic_unwind/src/lib.rs
Normal file
27
libstd_real/panic_unwind/src/lib.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
#![no_std]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(panic_runtime)]
|
||||
#![panic_runtime]
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), data: *mut u8,
|
||||
_data_ptr: *mut usize, _vtable_ptr: *mut usize) -> u32 {
|
||||
f(data);
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 {
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
pub extern fn eh_personality() {}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
/// Required to handle panics
|
||||
pub unsafe extern "C" fn _Unwind_Resume() -> ! {
|
||||
core::intrinsics::abort();
|
||||
}
|
4
libstd_real/unwind/Cargo.toml
Normal file
4
libstd_real/unwind/Cargo.toml
Normal file
|
@ -0,0 +1,4 @@
|
|||
[package]
|
||||
name = "unwind"
|
||||
version = "0.0.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
1
libstd_real/unwind/src/lib.rs
Normal file
1
libstd_real/unwind/src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
#![no_std]
|
Loading…
Add table
Add a link
Reference in a new issue