more things

This commit is contained in:
nora 2023-09-30 12:00:05 +02:00
parent 1baf8df4a8
commit 5673cf51db
18 changed files with 292 additions and 9 deletions

View file

@ -1,2 +0,0 @@
[target.x86_64-unknown-linux-gnu]
rustflags = ["-Clink-arg=-nostartfiles", "-Clink-arg=-nostdlib"]

41
Cargo.lock generated
View file

@ -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",
]

View file

@ -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",
]

View file

@ -1,5 +1,6 @@
#include<stdio.h>
#include<sys/mman.h>
int main(int argc, char *argv[]) {
PROT_WRITE;
puts("Hello, world!");
}

View file

@ -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
View 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);
}
}
}

View file

@ -47,6 +47,7 @@ impl Iterator for EnvP {
}
}
#[allow(unused)]
pub(crate) fn debug_env() {
println!("start vars");
global::get().for_each(|s| {

View file

@ -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);

View file

@ -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;

View file

@ -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()
}
}

View file

@ -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;

View file

@ -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
View file

@ -0,0 +1,4 @@
fn main() {
println!("cargo:rustc-link-arg=-nostartfiles");
println!("cargo:rustc-link-arg=-nostdlib");
}

View file

@ -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
View 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
View 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 _)
}

View file

@ -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)
}

View file

@ -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