diff --git a/repos/base/src/lib/rust-targets/spec/arm/target.json b/repos/base/src/lib/rust-targets/spec/armv6/target.json similarity index 52% rename from repos/base/src/lib/rust-targets/spec/arm/target.json rename to repos/base/src/lib/rust-targets/spec/armv6/target.json index 513902106f..da57accd8b 100644 --- a/repos/base/src/lib/rust-targets/spec/arm/target.json +++ b/repos/base/src/lib/rust-targets/spec/armv6/target.json @@ -1,9 +1,11 @@ { - "llvm-target": "arm-pc-genode-elf", + "llvm-target": "armv6-pc-genode-gnueabi", "target-endian": "little", "target-pointer-width": "32", "arch": "arm", "os": "genode", "cpu": "generic", - "no_compiler_rt": true + "env": "armv6", + "no_compiler_rt": true, + "features": "+v6" } diff --git a/repos/base/src/lib/rust-targets/spec/armv7/target.json b/repos/base/src/lib/rust-targets/spec/armv7/target.json new file mode 100644 index 0000000000..2856218cdb --- /dev/null +++ b/repos/base/src/lib/rust-targets/spec/armv7/target.json @@ -0,0 +1,11 @@ +{ + "llvm-target": "armv7-pc-genode-gnueabi", + "target-endian": "little", + "target-pointer-width": "32", + "arch": "arm", + "os": "genode", + "cpu": "generic", + "env": "armv7", + "no_compiler_rt": true, + "features": "+v7" +} diff --git a/repos/base/src/lib/rust-targets/spec/riscv/target.json b/repos/base/src/lib/rust-targets/spec/riscv/target.json index fa852b542c..17446285e5 100644 --- a/repos/base/src/lib/rust-targets/spec/riscv/target.json +++ b/repos/base/src/lib/rust-targets/spec/riscv/target.json @@ -4,5 +4,6 @@ "target-endian": "little", "target-pointer-width": "64", "arch": "riscv", - "os": "genode" + "os": "genode", + "no_compiler_rt": true } diff --git a/repos/base/src/lib/rust-targets/spec/x86_32/target.json b/repos/base/src/lib/rust-targets/spec/x86_32/target.json index 4dfef36b7d..f363a670a8 100644 --- a/repos/base/src/lib/rust-targets/spec/x86_32/target.json +++ b/repos/base/src/lib/rust-targets/spec/x86_32/target.json @@ -3,5 +3,6 @@ "target-endian": "little", "target-pointer-width": "32", "arch": "x86", - "os": "genode" + "os": "genode", + "no_compiler_rt": true } diff --git a/repos/base/src/lib/rust-targets/spec/x86_64/target.json b/repos/base/src/lib/rust-targets/spec/x86_64/target.json index 1220c400a5..4b1a1d2c21 100644 --- a/repos/base/src/lib/rust-targets/spec/x86_64/target.json +++ b/repos/base/src/lib/rust-targets/spec/x86_64/target.json @@ -4,5 +4,6 @@ "target-endian": "little", "target-pointer-width": "64", "arch": "x86_64", - "os": "genode" + "os": "genode", + "no_compiler_rt": true } diff --git a/repos/base/src/test/rust/main.rs b/repos/base/src/test/rust/main.rs index efe8a6ec6d..1e70830ba7 100644 --- a/repos/base/src/test/rust/main.rs +++ b/repos/base/src/test/rust/main.rs @@ -1,18 +1,20 @@ #![no_std] -#![feature(lang_items,collections)] +#![feature(lang_items,collections,alloc)] extern crate collections; +extern crate alloc; extern crate libc; +use alloc::boxed::Box; extern "C"{ fn print_num(num: libc::c_int); } #[no_mangle] pub fn main() -> libc::c_int{ + let n = Box::new(42); unsafe { - print_num(42); + print_num(*n); } 0 } - #[lang="panic_fmt"] #[no_mangle] pub fn panic_fmt() -> ! { loop{} } diff --git a/repos/base/src/test/rust/target.mk b/repos/base/src/test/rust/target.mk index 224d9555c1..c2bbca052f 100644 --- a/repos/base/src/test/rust/target.mk +++ b/repos/base/src/test/rust/target.mk @@ -1,4 +1,4 @@ TARGET = rust-test SRC_RS = main.rs SRC_CC = printf.cc -LIBS = libcore-rust libcollections-rust base libc librustc_unicode-rust liballoc-rust liblibc-rust liballoc_system-rust +LIBS = libcore-rust libcollections-rust base librustc_unicode-rust liballoc-rust liblibc-rust liballoc_system-rust diff --git a/repos/libports/lib/import/import-libcore-rust.mk b/repos/libports/lib/import/import-libcore-rust.mk index 2c1ab35a9f..a70e75eba2 100644 --- a/repos/libports/lib/import/import-libcore-rust.mk +++ b/repos/libports/lib/import/import-libcore-rust.mk @@ -9,10 +9,17 @@ ifeq ($(filter-out $(SPECS),x86),) endif # 64bit endif # x86 -ifeq ($(filter-out $(SPECS),arm),) - CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/arm/target.json) +ifeq ($(filter-out $(SPECS),rpi),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/armv6/target.json) +else ifeq ($(filter-out $(SPECS),arm),) + CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/armv7/target.json) endif # ARM ifeq ($(filter-out $(SPECS),riscv),) CC_RUSTC_OPT += --target $(call select_from_repositories,$(TARGET_DIR)/riscv/target.json) endif # RISCV + +# +# Circular dependencies +# +LIBS += libunwind-rust builtins-rust diff --git a/repos/libports/lib/mk/builtins-rust.mk b/repos/libports/lib/mk/builtins-rust.mk new file mode 100644 index 0000000000..22c8472d18 --- /dev/null +++ b/repos/libports/lib/mk/builtins-rust.mk @@ -0,0 +1,4 @@ +LIBS = libcore-rust +SRC_RS += lib.rs + +vpath % $(REP_DIR)/src/lib/rust/builtins-rust diff --git a/repos/libports/lib/mk/liballoc_system-rust.mk b/repos/libports/lib/mk/liballoc_system-rust.mk index 0e77603606..52ddcbe411 100644 --- a/repos/libports/lib/mk/liballoc_system-rust.mk +++ b/repos/libports/lib/mk/liballoc_system-rust.mk @@ -1,4 +1,5 @@ LIBS = libcore-rust liblibc-rust CC_RUSTC_OPT += --allow unused_features -RLIB = liballoc_system -include $(REP_DIR)/lib/mk/rust.inc +RLIB = liballoc_genode +SRC_RS = lib.rs +vpath % $(REP_DIR)/src/lib/rust/$(RLIB) diff --git a/repos/libports/lib/mk/libcore-rust.mk b/repos/libports/lib/mk/libcore-rust.mk index 49114f9897..f99e8126b9 100644 --- a/repos/libports/lib/mk/libcore-rust.mk +++ b/repos/libports/lib/mk/libcore-rust.mk @@ -1,3 +1,8 @@ RLIB=libcore include $(REP_DIR)/lib/mk/rust.inc include $(REP_DIR)/lib/import/import-libcore-rust.mk + +# +# Prevent circular dependency +# +LIBS = diff --git a/repos/libports/lib/mk/liblibc-rust.mk b/repos/libports/lib/mk/liblibc-rust.mk index 51900b0bc2..21fa83eaf8 100644 --- a/repos/libports/lib/mk/liblibc-rust.mk +++ b/repos/libports/lib/mk/liblibc-rust.mk @@ -1,4 +1,4 @@ -LIBS = libcore-rust libc ldso-startup +LIBS = libcore-rust libc libc-stdlib ldso-startup RLIB = liblibc/src -CC_RUSTC_OPT += --cfg 'target_os = "netbsd"' +CC_RUSTC_OPT += --cfg 'target_os = "freebsd"' include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/librand-rust.mk b/repos/libports/lib/mk/librand-rust.mk new file mode 100644 index 0000000000..da5b801401 --- /dev/null +++ b/repos/libports/lib/mk/librand-rust.mk @@ -0,0 +1,3 @@ +LIBS = libcore-rust +RLIB = librand +include $(REP_DIR)/lib/mk/rust.inc diff --git a/repos/libports/lib/mk/libunwind-rust.mk b/repos/libports/lib/mk/libunwind-rust.mk new file mode 100644 index 0000000000..3a32d60c4c --- /dev/null +++ b/repos/libports/lib/mk/libunwind-rust.mk @@ -0,0 +1,3 @@ +SRC_RS = lib.rs +LIBS = libcore-rust +vpath % $(REP_DIR)/src/lib/rust/libunwind diff --git a/repos/libports/ports/rust.hash b/repos/libports/ports/rust.hash index 90724a6fbf..383bf61d98 100644 --- a/repos/libports/ports/rust.hash +++ b/repos/libports/ports/rust.hash @@ -1 +1 @@ -613098635ba8ed06c7f8723670e240982ad0f112 +98005b2246d288014ec9d3962e0ec2cd7c9446d0 diff --git a/repos/libports/ports/rust.port b/repos/libports/ports/rust.port index 1d688b9ddf..e59f6b9fb9 100644 --- a/repos/libports/ports/rust.port +++ b/repos/libports/ports/rust.port @@ -6,3 +6,5 @@ DOWNLOADS := rust.archive URL(rust) := http://static.rust-lang.org/dist/$(DATE)/rustc-$(VERSION)-src.tar.gz SHA(rust) := c75656f1238ce82e1cdede174d9cbc05f0b98ae2 DIR(rust) := src/lib/rust + +PATCHES := src/lib/rust/freebsd.patch diff --git a/repos/libports/src/lib/rust/builtins-rust/atomics.rs b/repos/libports/src/lib/rust/builtins-rust/atomics.rs new file mode 100644 index 0000000000..9b836cac08 --- /dev/null +++ b/repos/libports/src/lib/rust/builtins-rust/atomics.rs @@ -0,0 +1,46 @@ +#[cfg(target_env = "armv7")] +macro_rules! dmb { + () => {{ + asm!("dmb"); + }} +} + +#[cfg(target_env = "armv6")] +macro_rules! dmb { + () => {{ + asm!("MCR p15,0,r0,c7,c10,4"); + }} +} + +macro_rules! sync_val_compare_and_swap { + ($ptr:expr, $oldval:expr, $newval:expr) => {{ + unsafe { + dmb!(); + let tmp = *$ptr; + dmb!(); + if tmp == $oldval { + dmb!(); + *$ptr = $newval; + dmb!(); + } + tmp + } + }} +} + +#[no_mangle] +pub extern fn __sync_val_compare_and_swap_1(ptr: *mut u8,oldval: u8,newval: u8) -> u8 { + sync_val_compare_and_swap!(ptr,oldval,newval) +} +#[no_mangle] +pub extern fn __sync_val_compare_and_swap_2(ptr: *mut u16,oldval: u16,newval: u16) -> u16 { + sync_val_compare_and_swap!(ptr,oldval,newval) +} +#[no_mangle] +pub extern fn __sync_val_compare_and_swap_4(ptr: *mut u32,oldval: u32,newval: u32) -> u32 { + sync_val_compare_and_swap!(ptr,oldval,newval) +} +#[no_mangle] +pub extern fn __sync_val_compare_and_swap_8(ptr: *mut u64,oldval: u64,newval: u64) -> u64 { + sync_val_compare_and_swap!(ptr,oldval,newval) +} diff --git a/repos/libports/src/lib/rust/builtins-rust/lib.rs b/repos/libports/src/lib/rust/builtins-rust/lib.rs new file mode 100644 index 0000000000..a71ca5edfe --- /dev/null +++ b/repos/libports/src/lib/rust/builtins-rust/lib.rs @@ -0,0 +1,5 @@ +#![no_std] +#![feature(asm,cfg_target_feature)] + +#[cfg(target_arch = "arm")] +pub mod atomics; diff --git a/repos/libports/src/lib/rust/freebsd.patch b/repos/libports/src/lib/rust/freebsd.patch new file mode 100644 index 0000000000..8a725cd311 --- /dev/null +++ b/repos/libports/src/lib/rust/freebsd.patch @@ -0,0 +1,13 @@ +*** src/lib/rust/src/liblibc/src/unix/bsd/freebsdlike/freebsd/mod2.rs 2016-03-05 19:12:50.388857026 -0800 +--- src/lib/rust/src/liblibc/src/unix/bsd/freebsdlike/freebsd/mod.rs 2016-03-05 19:10:14.606459559 -0800 +*************** +*** 81,86 **** +--- 81,88 ---- + mod x86_64; + pub use self::x86_64::*; + } else { ++ mod x86; ++ pub use self::x86::*; + // ... + } + } diff --git a/repos/libports/src/lib/rust/liballoc_genode/lib.rs b/repos/libports/src/lib/rust/liballoc_genode/lib.rs new file mode 100644 index 0000000000..91ce115241 --- /dev/null +++ b/repos/libports/src/lib/rust/liballoc_genode/lib.rs @@ -0,0 +1,217 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "alloc_system"] +#![crate_type = "rlib"] +#![no_std] +#![allocator] +#![cfg_attr(not(stage0), deny(warnings))] +#![unstable(feature = "alloc_system", + reason = "this library is unlikely to be stabilized in its current \ + form or name", + issue = "27783")] +#![feature(allocator)] +#![feature(libc)] +#![feature(staged_api)] + +extern crate libc; + +// The minimum alignment guaranteed by the architecture. This value is used to +// add fast paths for low alignment values. In practice, the alignment is a +// constant at the call site and the branch will be optimized out. +//#[cfg(all(any(target_arch = "x86", +// target_arch = "arm", +// target_arch = "mips", +// target_arch = "powerpc", +// target_arch = "powerpc64", +// target_arch = "asmjs")))] +//const MIN_ALIGN: usize = 8; +//#[cfg(all(any(target_arch = "x86_64", +// target_arch = "aarch64")))] +//const MIN_ALIGN: usize = 16; + +#[no_mangle] +pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 { + unsafe { imp::allocate(size, align) } +} + +#[no_mangle] +pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) { + unsafe { imp::deallocate(ptr, old_size, align) } +} + +#[no_mangle] +pub extern "C" fn __rust_reallocate(ptr: *mut u8, + old_size: usize, + size: usize, + align: usize) + -> *mut u8 { + unsafe { imp::reallocate(ptr, old_size, size, align) } +} + +#[no_mangle] +pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8, + old_size: usize, + size: usize, + align: usize) + -> usize { + unsafe { imp::reallocate_inplace(ptr, old_size, size, align) } +} + +#[no_mangle] +pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize { + imp::usable_size(size, align) +} + +#[cfg(unix)] +mod imp { + //use core::cmp; + //use core::ptr; + use libc; + //use MIN_ALIGN; + + pub unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { + //if align <= MIN_ALIGN { + libc::malloc(size as libc::size_t) as *mut u8 + /*} else { + let mut out = ptr::null_mut(); + let ret = libc::posix_memalign(&mut out, align as libc::size_t, size as libc::size_t); + if ret != 0 { + ptr::null_mut() + } else { + out as *mut u8 + } + }*/ + } + + pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, _align: usize) -> *mut u8 { + // if align <= MIN_ALIGN { + libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8 + /*} else { + let new_ptr = allocate(size, align); + ptr::copy(ptr, new_ptr, cmp::min(size, old_size)); + deallocate(ptr, old_size, align); + new_ptr + }*/ + } + + pub unsafe fn reallocate_inplace(_ptr: *mut u8, + old_size: usize, + _size: usize, + _align: usize) + -> usize { + old_size + } + + pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) { + libc::free(ptr as *mut libc::c_void) + } + + pub fn usable_size(size: usize, _align: usize) -> usize { + size + } +} + +#[cfg(windows)] +#[allow(bad_style)] +mod imp { + use MIN_ALIGN; + + type LPVOID = *mut u8; + type HANDLE = LPVOID; + type SIZE_T = usize; + type DWORD = u32; + type BOOL = i32; + + extern "system" { + fn GetProcessHeap() -> HANDLE; + fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; + fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; + fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; + } + + #[repr(C)] + struct Header(*mut u8); + + const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010; + + unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { + &mut *(ptr as *mut Header).offset(-1) + } + + unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { + let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize); + *get_header(aligned) = Header(ptr); + aligned + } + + pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 { + if align <= MIN_ALIGN { + HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8 + } else { + let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8; + if ptr.is_null() { + return ptr; + } + align_ptr(ptr, align) + } + } + + pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 { + if align <= MIN_ALIGN { + HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8 + } else { + let header = get_header(ptr); + let new = HeapReAlloc(GetProcessHeap(), + 0, + header.0 as LPVOID, + (size + align) as SIZE_T) as *mut u8; + if new.is_null() { + return new; + } + align_ptr(new, align) + } + } + + pub unsafe fn reallocate_inplace(ptr: *mut u8, + old_size: usize, + size: usize, + align: usize) + -> usize { + if align <= MIN_ALIGN { + let new = HeapReAlloc(GetProcessHeap(), + HEAP_REALLOC_IN_PLACE_ONLY, + ptr as LPVOID, + size as SIZE_T) as *mut u8; + if new.is_null() { + old_size + } else { + size + } + } else { + old_size + } + } + + pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) { + if align <= MIN_ALIGN { + let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); + debug_assert!(err != 0); + } else { + let header = get_header(ptr); + let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); + debug_assert!(err != 0); + } + } + + pub fn usable_size(size: usize, _align: usize) -> usize { + size + } +} diff --git a/repos/libports/src/lib/rust/libunwind/lib.rs b/repos/libports/src/lib/rust/libunwind/lib.rs new file mode 100644 index 0000000000..7e13db9674 --- /dev/null +++ b/repos/libports/src/lib/rust/libunwind/lib.rs @@ -0,0 +1,57 @@ +#![no_std] +#[no_mangle] +pub extern fn rust_begin_unwind(_args: ::core::fmt::Arguments, _file: &str, _line: usize) -> ! +{ + loop {} +} + + +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone,Copy)] +pub enum _Unwind_Reason_Code +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8, +} + +#[allow(non_camel_case_types)] +#[derive(Clone,Copy)] +pub struct _Unwind_Context; + +#[allow(non_camel_case_types)] +pub type _Unwind_Action = u32; +static _UA_SEARCH_PHASE: _Unwind_Action = 1; + +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone,Copy)] +pub struct _Unwind_Exception +{ + exception_class: u64, + exception_cleanup: fn(_Unwind_Reason_Code,*const _Unwind_Exception), + private: [u64; 2], +} + +#[no_mangle] +pub extern fn rust_eh_personality( + _version: isize, _actions: _Unwind_Action, _exception_class: u64, + _exception_object: &_Unwind_Exception, _context: &_Unwind_Context + ) -> _Unwind_Reason_Code +{ + loop{} +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern fn _Unwind_Resume() +{ + loop{} +}