mirror of
https://github.com/Noratrieb/libuwuc.git
synced 2026-01-14 19:55:07 +01:00
more things
This commit is contained in:
parent
1baf8df4a8
commit
5673cf51db
18 changed files with 292 additions and 9 deletions
|
|
@ -1,2 +0,0 @@
|
||||||
[target.x86_64-unknown-linux-gnu]
|
|
||||||
rustflags = ["-Clink-arg=-nostartfiles", "-Clink-arg=-nostdlib"]
|
|
||||||
41
Cargo.lock
generated
41
Cargo.lock
generated
|
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
@ -13,6 +19,26 @@ name = "libuwuc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"linked_list_allocator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked_list_allocator"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||||
|
dependencies = [
|
||||||
|
"spinning_top",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -21,3 +47,18 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libuwuc",
|
"libuwuc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spinning_top"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
|
||||||
41
example-user/Cargo.lock
generated
41
example-user/Cargo.lock
generated
|
|
@ -2,6 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
@ -21,6 +27,26 @@ name = "libuwuc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"linked_list_allocator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked_list_allocator"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
|
||||||
|
dependencies = [
|
||||||
|
"spinning_top",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -29,3 +55,18 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libuwuc",
|
"libuwuc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spinning_top"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
|
||||||
3
hello.c
3
hello.c
|
|
@ -1,5 +1,6 @@
|
||||||
#include<stdio.h>
|
#include<stdio.h>
|
||||||
|
#include<sys/mman.h>
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
PROT_WRITE;
|
||||||
puts("Hello, world!");
|
puts("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
linked_list_allocator = "0.10.5"
|
||||||
|
|
|
||||||
117
libuwuc/src/alloc.rs
Normal file
117
libuwuc/src/alloc.rs
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
use core::{
|
||||||
|
alloc::{GlobalAlloc, Layout},
|
||||||
|
ffi::c_int,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
|
use linked_list_allocator::LockedHeap;
|
||||||
|
|
||||||
|
static ALLOCATOR: LockedHeap = LockedHeap::empty();
|
||||||
|
|
||||||
|
const UNINIT: usize = 0;
|
||||||
|
const INITIALIZING: usize = 1;
|
||||||
|
const INIT: usize = 2;
|
||||||
|
|
||||||
|
static INIT_STATE: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
fn init() {
|
||||||
|
let state =
|
||||||
|
INIT_STATE.compare_exchange(UNINIT, INITIALIZING, Ordering::Relaxed, Ordering::Acquire);
|
||||||
|
|
||||||
|
match state {
|
||||||
|
Ok(_) => unsafe {
|
||||||
|
const HEAP_SIZE: usize = 0x100000;
|
||||||
|
let map_anon = 0x20;
|
||||||
|
let prot_read = 1;
|
||||||
|
let prod_write = 2;
|
||||||
|
|
||||||
|
let start = mmap(
|
||||||
|
core::ptr::null(),
|
||||||
|
HEAP_SIZE,
|
||||||
|
prot_read | prod_write,
|
||||||
|
map_anon,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
ALLOCATOR.lock().init(start, HEAP_SIZE);
|
||||||
|
|
||||||
|
INIT_STATE.store(INIT, Ordering::Release);
|
||||||
|
},
|
||||||
|
Err(INITIALIZING) => {
|
||||||
|
while INIT_STATE.load(Ordering::Acquire) != INIT {
|
||||||
|
core::hint::spin_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(INIT) => {}
|
||||||
|
Err(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn malloc_zeroed(size: usize, align: usize) -> *mut u8 {
|
||||||
|
/*
|
||||||
|
|start |align |offset |RETURN VALUE
|
||||||
|
*/
|
||||||
|
|
||||||
|
init();
|
||||||
|
let (layout, offset) = Layout::array::<usize>(3)
|
||||||
|
.unwrap_unchecked()
|
||||||
|
.extend(Layout::from_size_align_unchecked(size, align))
|
||||||
|
.unwrap_unchecked();
|
||||||
|
|
||||||
|
let ptr = ALLOCATOR.alloc_zeroed(layout);
|
||||||
|
if ptr.is_null() {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
ptr.cast::<[usize; 2]>()
|
||||||
|
.write([layout.size(), layout.align()]);
|
||||||
|
|
||||||
|
let ret_ptr = ptr.add(offset);
|
||||||
|
ret_ptr.cast::<usize>().sub(1).write(offset);
|
||||||
|
|
||||||
|
ret_ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn free(ptr: *mut u8) {
|
||||||
|
init();
|
||||||
|
let offset = ptr.cast::<usize>().sub(1).read();
|
||||||
|
let start = ptr.sub(offset);
|
||||||
|
let [size, align] = start.cast::<[usize; 2]>().read();
|
||||||
|
let layout = Layout::from_size_align_unchecked(size, align);
|
||||||
|
ALLOCATOR.dealloc(start, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn mmap(
|
||||||
|
addr: *const u8,
|
||||||
|
size: usize,
|
||||||
|
prot: c_int,
|
||||||
|
flags: c_int,
|
||||||
|
fd: c_int,
|
||||||
|
offset: u64,
|
||||||
|
) -> *mut u8 {
|
||||||
|
#[cfg(miri)]
|
||||||
|
{
|
||||||
|
extern crate std;
|
||||||
|
return std::alloc::System.alloc_zeroed(Layout::from_size_align_unchecked(size, 4096));
|
||||||
|
}
|
||||||
|
crate::sys::syscall::syscall!(
|
||||||
|
crate::sys::syscall::SYS_MMAP,
|
||||||
|
addr,
|
||||||
|
size,
|
||||||
|
prot,
|
||||||
|
flags,
|
||||||
|
fd,
|
||||||
|
offset
|
||||||
|
) as *mut u8
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn malloc_free() {
|
||||||
|
unsafe {
|
||||||
|
let x = super::malloc_zeroed(10, 8);
|
||||||
|
x.cast::<usize>().write(10);
|
||||||
|
super::free(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -47,6 +47,7 @@ impl Iterator for EnvP {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
pub(crate) fn debug_env() {
|
pub(crate) fn debug_env() {
|
||||||
println!("start vars");
|
println!("start vars");
|
||||||
global::get().for_each(|s| {
|
global::get().for_each(|s| {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ macro_rules! println {
|
||||||
pub use println;
|
pub use println;
|
||||||
|
|
||||||
pub unsafe fn write_all(fd: i32, mut buf: &[u8]) -> Result<(), i64> {
|
pub unsafe fn write_all(fd: i32, mut buf: &[u8]) -> Result<(), i64> {
|
||||||
while buf.len() > 0 {
|
while !buf.is_empty() {
|
||||||
let result = syscall::syscall!(syscall::SYS_WRITE, fd, buf.as_ptr(), buf.len()) as i64;
|
let result = syscall::syscall!(syscall::SYS_WRITE, fd, buf.as_ptr(), buf.len()) as i64;
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
return Err(result);
|
return Err(result);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![warn(unreachable_pub)]
|
#![warn(unreachable_pub)]
|
||||||
|
|
||||||
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
pub mod mem;
|
pub mod alloc;
|
||||||
pub mod env;
|
pub mod env;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
|
pub mod mem;
|
||||||
pub mod start;
|
pub mod start;
|
||||||
mod stubs;
|
mod stubs;
|
||||||
mod sys;
|
mod sys;
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,12 @@ pub fn exit(code: u64) -> ! {
|
||||||
core::hint::unreachable_unchecked()
|
core::hint::unreachable_unchecked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn abort() -> ! {
|
||||||
|
// FIXME: we actually need to do signal shenanigans
|
||||||
|
unsafe {
|
||||||
|
crate::sys::syscall::syscall!(crate::sys::syscall::SYS_EXIT, 1);
|
||||||
|
crate::sys::helpers::trap!();
|
||||||
|
core::hint::unreachable_unchecked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,48 @@ macro_rules! syscall {
|
||||||
);
|
);
|
||||||
out
|
out
|
||||||
}};
|
}};
|
||||||
|
($number:expr, $arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr) => {{
|
||||||
|
let out: u64;
|
||||||
|
::core::arch::asm!(
|
||||||
|
"syscall",
|
||||||
|
in("rax") $number,
|
||||||
|
in("rdi") $arg1,
|
||||||
|
in("rsi") $arg2,
|
||||||
|
in("rdx") $arg3,
|
||||||
|
in("r10") $arg4,
|
||||||
|
lateout("rax") out,
|
||||||
|
);
|
||||||
|
out
|
||||||
|
}};
|
||||||
|
($number:expr, $arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr) => {{
|
||||||
|
let out: u64;
|
||||||
|
::core::arch::asm!(
|
||||||
|
"syscall",
|
||||||
|
in("rax") $number,
|
||||||
|
in("rdi") $arg1,
|
||||||
|
in("rsi") $arg2,
|
||||||
|
in("rdx") $arg3,
|
||||||
|
in("r10") $arg4,
|
||||||
|
in("r8") $arg5,
|
||||||
|
lateout("rax") out,
|
||||||
|
);
|
||||||
|
out
|
||||||
|
}};
|
||||||
|
($number:expr, $arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr, $arg6:expr) => {{
|
||||||
|
let out: u64;
|
||||||
|
::core::arch::asm!(
|
||||||
|
"syscall",
|
||||||
|
in("rax") $number,
|
||||||
|
in("rdi") $arg1,
|
||||||
|
in("rsi") $arg2,
|
||||||
|
in("rdx") $arg3,
|
||||||
|
in("r10") $arg4,
|
||||||
|
in("r8") $arg5,
|
||||||
|
in("r9") $arg6,
|
||||||
|
lateout("rax") out,
|
||||||
|
);
|
||||||
|
out
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use syscall;
|
pub use syscall;
|
||||||
|
|
@ -83,7 +83,7 @@ impl From<SharedThinCstr> for &CStr {
|
||||||
|
|
||||||
impl PartialEq for SharedThinCstr {
|
impl PartialEq for SharedThinCstr {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.into_iter().eq(other.into_iter())
|
self.into_iter().eq(*other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
rawc/build.rs
Normal file
4
rawc/build.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rustc-link-arg=-nostartfiles");
|
||||||
|
println!("cargo:rustc-link-arg=-nostdlib");
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
|
#![deny(clippy::no_mangle_with_rust_abi)]
|
||||||
|
|
||||||
|
mod rt;
|
||||||
mod stdio;
|
mod stdio;
|
||||||
|
mod stdlib;
|
||||||
mod string;
|
mod string;
|
||||||
|
|
||||||
// libcore seems to require this symbol, even though it's unused.
|
// libcore seems to require this symbol, even though it's unused.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
#[allow(clippy::no_mangle_with_rust_abi)]
|
||||||
fn rust_eh_personality() {
|
fn rust_eh_personality() {
|
||||||
unsafe {
|
unsafe {
|
||||||
libuwuc::trap!();
|
libuwuc::trap!();
|
||||||
|
|
|
||||||
7
rawc/src/rt.rs
Normal file
7
rawc/src/rt.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn __stack_chk_fail() -> ! {
|
||||||
|
unsafe {
|
||||||
|
let _ = libuwuc::io::write_all(libuwuc::io::STDERR, b"error: stack overflow");
|
||||||
|
libuwuc::start::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
14
rawc/src/stdlib.rs
Normal file
14
rawc/src/stdlib.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 {
|
||||||
|
libuwuc::alloc::malloc_zeroed(size, 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn free(ptr: *mut u8) {
|
||||||
|
libuwuc::alloc::free(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn exit(code: i32) -> ! {
|
||||||
|
libuwuc::start::exit(code as i64 as _)
|
||||||
|
}
|
||||||
|
|
@ -9,13 +9,13 @@ pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, size: usize) -> *
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe fn memcmp(s1: *const u8, s2: *const u8, size: usize) -> i32 {
|
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, size: usize) -> i32 {
|
||||||
libuwuc::mem::memcmp(s1, s2, size)
|
libuwuc::mem::memcmp(s1, s2, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe fn bcmp(s1: *const u8, s2: *const u8, size: usize) -> i32 {
|
pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, size: usize) -> i32 {
|
||||||
libuwuc::mem::memcmp(s1, s2, size)
|
libuwuc::mem::memcmp(s1, s2, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
test.sh
2
test.sh
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
cargo run --manifest-path example-user/Cargo.toml --target x86_64-unknown-linux-gnu
|
cargo run --manifest-path example-user/Cargo.toml
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue