From f5ef0af883990135e2f26ed5fa559b5ca7781109 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 3 Mar 2018 16:54:58 -0700 Subject: [PATCH] Implement malloc/free with ralloc --- .gitmodules | 3 +++ Cargo.lock | 37 +++++++++++++++++++++++++ Cargo.toml | 1 + ralloc | 1 + src/lib.rs | 15 +++++++++++ stdio/cbindgen.toml | 2 +- stdlib/Cargo.toml | 12 +++++++++ stdlib/build.rs | 11 ++++++++ stdlib/cbindgen.toml | 6 +++++ stdlib/src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++ tests/.gitignore | 1 + tests/Makefile | 1 + tests/alloc.c | 10 +++++++ 13 files changed, 163 insertions(+), 1 deletion(-) create mode 160000 ralloc create mode 100644 stdlib/Cargo.toml create mode 100644 stdlib/build.rs create mode 100644 stdlib/cbindgen.toml create mode 100644 stdlib/src/lib.rs create mode 100644 tests/alloc.c diff --git a/.gitmodules b/.gitmodules index 271673cd4e..6d57d168a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "cbindgen"] path = cbindgen url = https://github.com/redox-os/cbindgen.git +[submodule "ralloc"] + path = ralloc + url = https://github.com/redox-os/ralloc.git diff --git a/Cargo.lock b/Cargo.lock index d64703e038..7a33582447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,6 +169,21 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ralloc" +version = "1.0.0" +dependencies = [ + "ralloc_shim 0.1.1", + "unborrow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ralloc_shim" +version = "0.1.1" +dependencies = [ + "sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.2" @@ -200,6 +215,7 @@ dependencies = [ "fcntl 0.1.0", "platform 0.1.0", "stdio 0.1.0", + "stdlib 0.1.0", "string 0.1.0", "unistd 0.1.0", ] @@ -289,6 +305,11 @@ dependencies = [ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sc" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.27" @@ -374,6 +395,15 @@ dependencies = [ "platform 0.1.0", ] +[[package]] +name = "stdlib" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.0", + "platform 0.1.0", + "ralloc 1.0.0", +] + [[package]] name = "string" version = "0.1.0" @@ -454,6 +484,11 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unborrow" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.4" @@ -542,6 +577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-ap-serialize 40.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43d227b1b3de1ec6d3fb48e10799d08c073c57e45f536766e1d897d46b737e0b" "checksum rustc-ap-syntax 40.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b6e525fc674e8a75eaed08a90a6df7adfa73a66135056577722185dd7ca0771" "checksum rustc-ap-syntax_pos 40.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e157f53ad5c4a6cf9ae5b5be15325dd2eeca190c03ab9873cc1460788767e5e9" +"checksum sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ebbb026ba4a707c25caec2db5ef59ad8b41f7ad77cad06257e06229c891f376" "checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" "checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" "checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" @@ -560,6 +596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" +"checksum unborrow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e92e959f029e4f8ee25d70d15ab58d2b46f98a17bc238b9265ff0c26f6f3d67f" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/Cargo.toml b/Cargo.toml index 34453157f3..40f0723002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-built platform = { path = "platform" } fcntl = { path = "fcntl" } stdio = { path = "stdio" } +stdlib = { path = "stdlib" } string = { path = "string" } unistd = { path = "unistd" } diff --git a/ralloc b/ralloc new file mode 160000 index 0000000000..b521bac287 --- /dev/null +++ b/ralloc @@ -0,0 +1 @@ +Subproject commit b521bac28702de86c7c4eef9641ec83c6ac38224 diff --git a/src/lib.rs b/src/lib.rs index cdbf7bc9a0..a72ecd8e8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ extern crate platform; extern crate fcntl; extern crate stdio; +extern crate stdlib; extern crate string; extern crate unistd; @@ -20,6 +21,10 @@ impl fmt::Write for PanicWriter { } } +#[lang = "eh_personality"] +#[no_mangle] +pub extern "C" fn rust_eh_personality() {} + #[lang = "panic_fmt"] #[no_mangle] pub extern "C" fn rust_begin_unwind(fmt: fmt::Arguments, file: &str, line: u32) -> ! { @@ -29,3 +34,13 @@ pub extern "C" fn rust_begin_unwind(fmt: fmt::Arguments, file: &str, line: u32) platform::exit(1); } + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn _Unwind_Resume() -> ! { + use fmt::Write; + + let _ = PanicWriter.write_str("_Unwind_Resume\n"); + + platform::exit(1); +} diff --git a/stdio/cbindgen.toml b/stdio/cbindgen.toml index 41dd92770e..e2c98aae1d 100644 --- a/stdio/cbindgen.toml +++ b/stdio/cbindgen.toml @@ -1,5 +1,5 @@ sys_includes = ["stdarg.h", "stddef.h"] -include_guard = "_stdio_H" +include_guard = "_STDIO_H" trailer = "#include " language = "C" diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml new file mode 100644 index 0000000000..7becd734a3 --- /dev/null +++ b/stdlib/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "stdlib" +version = "0.1.0" +authors = ["Jeremy Soller "] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../cbindgen" } + +[dependencies] +platform = { path = "../platform" } +ralloc = { path = "../ralloc", default-features = false } diff --git a/stdlib/build.rs b/stdlib/build.rs new file mode 100644 index 0000000000..0a0b7570c2 --- /dev/null +++ b/stdlib/build.rs @@ -0,0 +1,11 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + fs::create_dir_all("../target/include").expect("failed to create include directory"); + cbindgen::generate(crate_dir) + .expect("failed to generate bindings") + .write_to_file("../target/include/stdlib.h"); +} diff --git a/stdlib/cbindgen.toml b/stdlib/cbindgen.toml new file mode 100644 index 0000000000..c4d72d172a --- /dev/null +++ b/stdlib/cbindgen.toml @@ -0,0 +1,6 @@ +sys_includes = ["stddef.h"] +include_guard = "_STDLIB_H" +language = "C" + +[enum] +prefix_with_name = true diff --git a/stdlib/src/lib.rs b/stdlib/src/lib.rs new file mode 100644 index 0000000000..ee61d9577d --- /dev/null +++ b/stdlib/src/lib.rs @@ -0,0 +1,64 @@ +//! stdlib implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/stdlib.h.html + +#![no_std] +#![feature(global_allocator)] + +extern crate platform; +extern crate ralloc; + +use platform::types::*; + +#[global_allocator] +static ALLOCATOR: ralloc::Allocator = ralloc::Allocator; + +pub const EXIT_FAILURE: c_int = 1; +pub const EXIT_SUCCESS: c_int = 0; + +static mut ATEXIT_FUNCS: [usize; 32] = [0; 32]; + +#[no_mangle] +pub unsafe extern "C" fn atexit(func: extern "C" fn()) -> c_int { + for i in 0..ATEXIT_FUNCS.len() { + if ATEXIT_FUNCS[i] == 0 { + ATEXIT_FUNCS[i] = func as usize; + return 0; + } + } + + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn exit(status: c_int) { + use core::mem; + + for i in (0..ATEXIT_FUNCS.len()).rev() { + if ATEXIT_FUNCS[i] != 0 { + let func = mem::transmute::(ATEXIT_FUNCS[i]); + (func)(); + } + } + + platform::exit(status); +} + +#[no_mangle] +pub unsafe extern "C" fn free(ptr: *mut c_void) { + let ptr = (ptr as *mut u8).offset(-8); + let size = *(ptr as *mut u64); + ralloc::free(ptr, size as usize); +} + +#[no_mangle] +pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void { + let ptr = ralloc::alloc(size + 8, 8); + *(ptr as *mut u64) = size as u64; + ptr.offset(8) as *mut c_void +} + +/* +#[no_mangle] +pub extern "C" fn func(args) -> c_int { + unimplemented!(); +} +*/ diff --git a/tests/.gitignore b/tests/.gitignore index 5c6fa79146..7cf5819daf 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,3 +1,4 @@ +/alloc /args /create /create.out diff --git a/tests/Makefile b/tests/Makefile index dfbab93298..2a191bb5c6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,5 @@ BINS=\ + alloc \ args \ create \ write diff --git a/tests/alloc.c b/tests/alloc.c new file mode 100644 index 0000000000..a082385f2b --- /dev/null +++ b/tests/alloc.c @@ -0,0 +1,10 @@ +#include + +int main(int argc, char **argv) { + char * ptr = (char *)malloc(256); + int i; + for(i = 0; i < 256; i++) { + ptr[i] = (char)i; + } + free(ptr); +}