diff --git a/Cargo.lock b/Cargo.lock index 035268ce4d3bf1eb3acd247dd723cd3917235c54..24e95adbbf64f692eb0734859233a011fcae6f29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,6 +199,7 @@ dependencies = [ "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)", "fcntl 0.1.0", "platform 0.1.0", + "string 0.1.0", "unistd 0.1.0", ] @@ -364,6 +365,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "string" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.0", + "platform 0.1.0", +] + [[package]] name = "strsim" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index ac7c7f864d4ec51156557669c8176fab3cca95bb..15ad2717e7ad6b06ba0bd9b545a9660554920bd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = ["crt0"] compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins.git", default-features = false, features = ["mem"] } platform = { path = "platform" } fcntl = { path = "fcntl" } +string = { path = "string" } unistd = { path = "unistd" } [profile.dev] diff --git a/crt0/src/lib.rs b/crt0/src/lib.rs index 47ff4842987bccb4da0c6a6efe12dfcb08de59ac..c16d2d7449f25d4230e7e5b7b6c1429ccbdade06 100644 --- a/crt0/src/lib.rs +++ b/crt0/src/lib.rs @@ -17,18 +17,37 @@ pub unsafe extern "C" fn _start() { : : : - : "intel" + : "intel", "volatile" ); } +#[repr(C)] +pub struct Stack { + argc: isize, + argv0: *const u8, +} + +impl Stack { + fn argc(&self) -> isize { + self.argc + } + + fn argv(&self) -> *const *const u8 { + &self.argv0 as *const *const u8 + } +} + #[inline(never)] #[no_mangle] -pub unsafe extern "C" fn _start_rust(sp: usize) -> ! { +pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! { extern "C" { - fn main(argc: c_int, argv: *const *const c_char) -> c_int; + fn main(argc: isize, argv: *const *const u8) -> c_int; } - platform::exit(main(0, 0 as *const *const c_char)); + let argc = sp.argc(); + let argv = sp.argv(); + + platform::exit(main(argc, argv)); } #[lang = "panic_fmt"] diff --git a/include/stddef.h b/include/stddef.h new file mode 100644 index 0000000000000000000000000000000000000000..fa0bc7daf528f082aab9958c1054fa0f716e9a03 --- /dev/null +++ b/include/stddef.h @@ -0,0 +1,12 @@ +#ifndef _STDDEF_H +#define _STDDEF_H + +#define NULL 0 + +typedef signed long long ptrdiff_t; + +typedef unsigned char wchar_t; + +typedef unsigned long long size_t; + +#endif /* _STDDEF_H */ diff --git a/include/sys/types.h b/include/sys/types.h index 3a65d4d00ddd88743e03f6bbbc211fa00944b141..6f770aa64c19aa215a00a8c898ad6a1d66a68c45 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -10,7 +10,6 @@ typedef long off_t; typedef int pid_t; -typedef unsigned long size_t; typedef long ssize_t; typedef int useconds_t; diff --git a/src/lib.rs b/src/lib.rs index d49813d1e7e121f51b42fbe4f7a301c446696906..5eda04b6e8575b338f54a25dc0be0055718c5722 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,11 +5,9 @@ extern crate compiler_builtins; extern crate platform; extern crate fcntl; +extern crate string; extern crate unistd; -pub use fcntl::*; -pub use unistd::*; - use core::fmt; struct PanicWriter; diff --git a/string/Cargo.toml b/string/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2e110e97a9a59a304a24ddeb6bbfe6dac7946792 --- /dev/null +++ b/string/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "string" +version = "0.1.0" +authors = ["Jeremy Soller <jackpot51@gmail.com>"] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../cbindgen" } + +[dependencies] +platform = { path = "../platform" } diff --git a/string/build.rs b/string/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..1aca9f78199a6c6a06eab01a8d6a5d8369b81ef5 --- /dev/null +++ b/string/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/string.h"); +} diff --git a/string/cbindgen.toml b/string/cbindgen.toml new file mode 100644 index 0000000000000000000000000000000000000000..b7762a3faa288497fd2c964fbdbdb65954f68db3 --- /dev/null +++ b/string/cbindgen.toml @@ -0,0 +1,6 @@ +sys_includes = ["stddef.h"] +include_guard = "_STRING_H" +language = "C" + +[enum] +prefix_with_name = true diff --git a/string/src/lib.rs b/string/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..12b4ea3dbc03a320fc7be349ad1ea6fe76055f50 --- /dev/null +++ b/string/src/lib.rs @@ -0,0 +1,28 @@ +//! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html + +#![no_std] + +extern crate platform; + +use platform::types::*; + +#[no_mangle] +pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t { + let mut size = 0; + + loop { + if *s.offset(size) == 0 { + break; + } + size += 1; + } + + size as size_t +} + +/* +#[no_mangle] +pub extern "C" fn func(args) -> c_int { + unimplemented!(); +} +*/ diff --git a/tests/.gitignore b/tests/.gitignore index 0348d78de95bbda30622e9b2852fc236b42ca4fa..5c6fa79146ac30c76feaebe8d249a270c4c997b5 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,3 +1,4 @@ +/args /create /create.out /write diff --git a/tests/Makefile b/tests/Makefile index 1f638014e5e6d860398be7f516029203c501e304..dfbab932985d83e9033aae60f732b75e1492c412 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,14 +1,15 @@ BINS=\ + args \ create \ write all: $(BINS) clean: - rm -f $(BINS) + rm -f $(BINS) *.out run: $(BINS) - for bin in $(BINS); do echo "\\033[1m$${bin}\\033[0m"; ./$${bin}; done + for bin in $(BINS); do echo "\\033[1m$${bin}\\033[0m"; ./$${bin} test args; done %: %.c gcc -nostdinc -nostdlib -I ../include -I ../target/include ../target/debug/libcrt0.a $< ../target/debug/libc.a -o $@ diff --git a/tests/args.c b/tests/args.c new file mode 100644 index 0000000000000000000000000000000000000000..70686673e49c8d11e76c799c23df7e4eb41807ba --- /dev/null +++ b/tests/args.c @@ -0,0 +1,11 @@ +#include <string.h> +#include <unistd.h> + +int main(int argc, char **argv) { + int i; + for(i = 0; i < argc; i++) { + write(STDOUT_FILENO, argv[i], strlen(argv[i])); + write(STDOUT_FILENO, " ", 1); + } + write(STDOUT_FILENO, "\n", 1); +} diff --git a/unistd/cbindgen.toml b/unistd/cbindgen.toml index 259e4fadf236a580c35a4e995ae39e362322c873..cf1de270d4e51c0643f3858b8327402b09fcdd1e 100644 --- a/unistd/cbindgen.toml +++ b/unistd/cbindgen.toml @@ -1,4 +1,4 @@ -sys_includes = ["stdint.h", "sys/types.h"] +sys_includes = ["stddef.h", "stdint.h", "sys/types.h"] include_guard = "_UNISTD_H" language = "C" diff --git a/unistd/src/lib.rs b/unistd/src/lib.rs index de23c114485ae6f07c777d300f0b3d157012a6cb..66905beae6564fe1b05b95b962c00fa201242396 100644 --- a/unistd/src/lib.rs +++ b/unistd/src/lib.rs @@ -6,8 +6,6 @@ extern crate platform; pub use platform::types::*; -pub const NULL: c_int = 0; - pub const R_OK: c_int = 1; pub const W_OK: c_int = 2; pub const X_OK: c_int = 4; @@ -101,20 +99,20 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) { unimplemented!(); } -#[no_mangle] -pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { - unimplemented!(); -} - -#[no_mangle] -pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { - unimplemented!(); -} - -#[no_mangle] -pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { - unimplemented!(); -} +// #[no_mangle] +// pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { +// unimplemented!(); +// } +// +// #[no_mangle] +// pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { +// unimplemented!(); +// } +// +// #[no_mangle] +// pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int { +// unimplemented!(); +// } #[no_mangle] pub extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {