mirror of
https://github.com/Noratrieb/libuwuc.git
synced 2026-01-14 11:45:05 +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.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
|
@ -13,6 +19,26 @@ name = "libuwuc"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"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]]
|
||||
|
|
@ -21,3 +47,18 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"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.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
|
@ -21,6 +27,26 @@ name = "libuwuc"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"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]]
|
||||
|
|
@ -29,3 +55,18 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"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<sys/mman.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
PROT_WRITE;
|
||||
puts("Hello, world!");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
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() {
|
||||
println!("start vars");
|
||||
global::get().for_each(|s| {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ macro_rules! println {
|
|||
pub use println;
|
||||
|
||||
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;
|
||||
if result < 0 {
|
||||
return Err(result);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
#![no_std]
|
||||
#![warn(unreachable_pub)]
|
||||
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate std;
|
||||
|
||||
pub mod mem;
|
||||
pub mod alloc;
|
||||
pub mod env;
|
||||
pub mod io;
|
||||
pub mod mem;
|
||||
pub mod start;
|
||||
mod stubs;
|
||||
mod sys;
|
||||
|
|
|
|||
|
|
@ -27,3 +27,12 @@ pub fn exit(code: u64) -> ! {
|
|||
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
|
||||
}};
|
||||
($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;
|
||||
|
|
@ -83,7 +83,7 @@ impl From<SharedThinCstr> for &CStr {
|
|||
|
||||
impl PartialEq for SharedThinCstr {
|
||||
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]
|
||||
#![feature(panic_info_message)]
|
||||
#![deny(clippy::no_mangle_with_rust_abi)]
|
||||
|
||||
mod rt;
|
||||
mod stdio;
|
||||
mod stdlib;
|
||||
mod string;
|
||||
|
||||
// libcore seems to require this symbol, even though it's unused.
|
||||
#[no_mangle]
|
||||
#[allow(clippy::no_mangle_with_rust_abi)]
|
||||
fn rust_eh_personality() {
|
||||
unsafe {
|
||||
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]
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#[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)
|
||||
}
|
||||
|
||||
|
|
|
|||
2
test.sh
2
test.sh
|
|
@ -1,3 +1,3 @@
|
|||
#!/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