diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index 725c0b40d89..3ba06fcb0f6 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" core = { path = "./sysroot_src/src/libcore" } compiler_builtins = "0.1" alloc = { path = "./sysroot_src/src/liballoc" } +std = { path = "./sysroot_src/src/libstd" } alloc_system = { path = "./alloc_system" } diff --git a/example/mini_core.rs b/example/mini_core.rs index 0ddd3ade401..66314ab3e5d 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -338,6 +338,7 @@ pub mod libc { #[link(name = "c")] extern "C" { pub fn puts(s: *const u8); + pub fn printf(format: *const i8, ...) -> i32; pub fn malloc(size: usize) -> *mut u8; pub fn free(ptr: *mut u8); pub fn memcpy(dst: *mut u8, src: *const u8, size: usize); diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 1254d917189..871aebddee9 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -121,6 +121,8 @@ fn main() { //return; unsafe { + printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8); + let hello: &[u8] = b"Hello\0" as &[u8; 6]; let ptr: *const u8 = hello as *const [u8] as *const u8; puts(ptr); diff --git a/example/std_example.rs b/example/std_example.rs new file mode 100644 index 00000000000..dceb68bcdf4 --- /dev/null +++ b/example/std_example.rs @@ -0,0 +1,9 @@ +use std::io::Write; + +fn main() { + let _ = ::std::iter::repeat('a' as u8).take(10).collect::>(); + let stderr = ::std::io::stderr(); + let mut stderr = stderr.lock(); + + writeln!(stderr, "some {} text", "").unwrap(); +} diff --git a/patches/0011-Workaround-for-libstd-crash.patch b/patches/0011-Workaround-for-libstd-crash.patch new file mode 100644 index 00000000000..46712718dec --- /dev/null +++ b/patches/0011-Workaround-for-libstd-crash.patch @@ -0,0 +1,25 @@ +From 2bc2ef06e118c6fba0626c0e9bf24fed873405b2 Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Sat, 29 Dec 2018 12:37:34 +0100 +Subject: [PATCH] Workaround for libstd crash + +I think this is related to the use of TLS inside those functions +--- + src/libstd/rt.rs | 2 +- + 1 file changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs +index 5ddb66b..6a0d0b5 100644 +--- a/src/libstd/rt.rs ++++ b/src/libstd/rt.rs +@@ -51,7 +51,7 @@ fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + ::panic::RefUnwindSafe), + #[cfg(not(feature = "backtrace"))] + let exit_code = panic::catch_unwind(move || main()); + +- sys_common::cleanup(); ++ //sys_common::cleanup(); + exit_code.unwrap_or(101) as isize + } + } +-- +2.17.2 (Apple Git-113) diff --git a/src/abi.rs b/src/abi.rs index 70e94db93ae..aa85349b9b8 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -191,12 +191,13 @@ pub fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::FnS pub fn get_function_name_and_sig<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, inst: Instance<'tcx>, + support_vararg: bool ) -> (String, Signature) { assert!(!inst.substs.needs_infer() && !inst.substs.has_param_types()); let fn_ty = inst.ty(tcx); let fn_sig = ty_fn_sig(tcx, fn_ty); - if fn_sig.variadic { - unimpl!("Variadic functions are not yet supported"); + if fn_sig.variadic && !support_vararg { + unimpl!("Variadic function definitions are not yet supported"); } let sig = clif_sig_from_fn_sig(tcx, fn_sig); (tcx.symbol_name(inst).as_str().to_string(), sig) @@ -208,7 +209,7 @@ pub fn import_function<'a, 'tcx: 'a>( module: &mut Module, inst: Instance<'tcx>, ) -> FuncId { - let (name, sig) = get_function_name_and_sig(tcx, inst); + let (name, sig) = get_function_name_and_sig(tcx, inst, true); module .declare_function(&name, Linkage::Import, &sig) .unwrap() @@ -659,6 +660,23 @@ pub fn codegen_call_inner<'a, 'tcx: 'a>( fx.bcx.ins().call(func_ref, &call_args) }; + // FIXME find a cleaner way to support varargs + if fn_sig.variadic { + if fn_sig.abi != Abi::C { + unimpl!("Variadic call for non-C abi {:?}", fn_sig.abi); + } + let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); + let abi_params = call_args.into_iter().map(|arg| { + let ty = fx.bcx.func.dfg.value_type(arg); + if !ty.is_int() { + // FIXME set %al to upperbound on float args once floats are supported + unimpl!("Non int ty {:?} for variadic call", ty); + } + AbiParam::new(ty) + }).collect::>(); + fx.bcx.func.dfg.signatures[sig_ref].params = abi_params; + } + match output_pass_mode { PassMode::NoPass => {} PassMode::ByVal(_) => { diff --git a/src/base.rs b/src/base.rs index 94598c65672..d2f31de71d1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -65,7 +65,7 @@ fn trans_fn<'a, 'clif, 'tcx: 'a, B: Backend + 'static>( let mir = tcx.instance_mir(instance.def); // Step 2. Declare function - let (name, sig) = get_function_name_and_sig(tcx, instance); + let (name, sig) = get_function_name_and_sig(tcx, instance, false); let func_id = cx.module .declare_function(&name, linkage, &sig) .unwrap(); diff --git a/src/main_shim.rs b/src/main_shim.rs index 446089fc9a1..20d79291296 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -53,8 +53,7 @@ fn create_entry_fn<'a, 'tcx: 'a>( let instance = Instance::mono(tcx, rust_main_def_id); - let (main_name, main_sig) = get_function_name_and_sig(tcx, instance); - + let (main_name, main_sig) = get_function_name_and_sig(tcx, instance, false); let main_func_id = m .declare_function(&main_name, Linkage::Import, &main_sig) .unwrap(); diff --git a/test.sh b/test.sh index 8cc4b0ff817..8cc5b2d186e 100755 --- a/test.sh +++ b/test.sh @@ -24,11 +24,16 @@ echo "[BUILD+RUN] alloc_example" $RUSTC --sysroot ./build_sysroot/sysroot example/alloc_example.rs --crate-type bin ./target/out/alloc_example +echo "[BUILD+RUN] std_example" +$RUSTC --sysroot ./build_sysroot/sysroot example/std_example.rs --crate-type bin +./target/out/std_example + echo "[BUILD] mod_bench" $RUSTC --sysroot ./build_sysroot/sysroot example/mod_bench.rs --crate-type bin -echo "[BUILD] sysroot in release mode" -./build_sysroot/build_sysroot.sh --release +# FIXME linker gives multiple definitions error on Linux +#echo "[BUILD] sysroot in release mode" +#./build_sysroot/build_sysroot.sh --release COMPILE_MOD_BENCH_INLINE="$RUSTC --sysroot ./build_sysroot/sysroot example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline" COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o target/out/mod_bench_llvm_0 -Cpanic=abort"