Skip to content

Redox Cross Compilation #38401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Dec 23, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
341d2d1
Add redox target
jackpot51 Dec 13, 2016
c7aa284
Fix typo
jackpot51 Dec 13, 2016
a621d12
Fix issue with setting cfg(unix)
jackpot51 Dec 13, 2016
d2707aa
Use panic abort by default
jackpot51 Dec 13, 2016
ece703a
Add Redox make config
jackpot51 Dec 13, 2016
f86e014
Use alloc_system as default allocation crate
jackpot51 Dec 14, 2016
3e7543a
WIP: Cross-compilation for Redox target
jackpot51 Dec 15, 2016
773a0a2
Add start functions, switch allocation crate to ralloc
jackpot51 Dec 15, 2016
07e313d
Add openlibm to redox
jackpot51 Dec 15, 2016
6d7c2ec
Revert libstd/Cargo.toml to master
jackpot51 Dec 15, 2016
57bc1a9
Add arm syscalls
jackpot51 Dec 20, 2016
86f85c1
Move start functions into libstd/rt
jackpot51 Dec 20, 2016
01157e6
Link openlibm only in libstd
jackpot51 Dec 20, 2016
e55596f
Move rt into sys::rt, fix tidy
jackpot51 Dec 20, 2016
65eecf8
Readd statvfs
jackpot51 Dec 20, 2016
fd4bc88
Fix building without backtrace
jackpot51 Dec 21, 2016
7697c72
Static link openlibm
jackpot51 Dec 21, 2016
2ca1f0b
Switch back to alloc_system
jackpot51 Dec 21, 2016
bf50acb
Fix tidy
jackpot51 Dec 21, 2016
e909e43
Update liblibc, go back to lazy linking openlibm
jackpot51 Dec 21, 2016
92c8e0f
Merge branch 'redox_cross' of https://github.com/redox-os/rust into r…
jackpot51 Dec 21, 2016
7d3ae87
Add RawFd traits for net
jackpot51 Dec 22, 2016
e7b006d
In order to successfully build, go back to ralloc
jackpot51 Dec 22, 2016
1eb6c44
Remove start functions, use newlib instead of openlibm + ralloc
jackpot51 Dec 22, 2016
2ddd117
Revert rt.rs
jackpot51 Dec 22, 2016
474eb62
Do not build emutls on Redox
jackpot51 Dec 23, 2016
c59bb49
Correct target_family mess
jackpot51 Dec 23, 2016
4dcb867
Convert fam to Symbol
jackpot51 Dec 23, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WIP: Cross-compilation for Redox target
  • Loading branch information
jackpot51 committed Dec 15, 2016
commit 3e7543a16ec6450b8fe0c3d50bc341b5f143cc54
3 changes: 2 additions & 1 deletion src/liballoc_jemalloc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ fn main() {
// targets, which means we have to build the alloc_jemalloc crate
// for targets like emscripten, even if we don't use it.
if target.contains("rumprun") || target.contains("bitrig") || target.contains("openbsd") ||
target.contains("msvc") || target.contains("emscripten") || target.contains("fuchsia") {
target.contains("msvc") || target.contains("emscripten") || target.contains("fuchsia") ||
target.contains("redox") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not support jemalloc, so we will build with the dummy.

println!("cargo:rustc-cfg=dummy_jemalloc");
return;
}
Expand Down
45 changes: 44 additions & 1 deletion src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
issue = "27783")]
#![feature(allocator)]
#![feature(staged_api)]
#![cfg_attr(target_os = "redox", feature(libc))]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that ralloc is used as the default allocator in librust_back. What we have done here is to ensure that liballoc_system builds, as it is a required dependency of libstd. We never link to it, however.

#![cfg_attr(unix, feature(libc))]

// The minimum alignment guaranteed by the architecture. This value is used to
Expand Down Expand Up @@ -71,7 +72,49 @@ pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
imp::usable_size(size, align)
}

#[cfg(unix)]
#[cfg(target_os = "redox")]
mod imp {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so we have a stub for potentially using a libc allocator, we implement alloc_system similarly to how the unix implementation works. If desired, these two imp blocks could be combined.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're the one defining the abi of the system allocator, so this is largely up to you. If you follow unix's malloc/free conventions then I'd recommend unifying with the above block for Unix. That handles bits and pieces such as alignment for more-aligned types (e.g. simd types).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will probably change this to be different from Unix so that it defines externs that ralloc will fulfill.

extern crate libc;

use core::cmp;
use core::ptr;
use MIN_ALIGN;

pub unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
libc::malloc(size as libc::size_t) as *mut u8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memalign is not used like in the unix implementation, perhaps this is a problem

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I this is one case where I think you'll want to align with the implementation above. This really ends up just needing an allocator interface which supports alignment as an argument, and that's what memalign is targeted at.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, thanks

}

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);
if !new_ptr.is_null() {
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(any(unix))]
mod imp {
extern crate libc;

Expand Down
3 changes: 3 additions & 0 deletions src/libstd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ compiler_builtins = { path = "../libcompiler_builtins" }
std_unicode = { path = "../libstd_unicode" }
unwind = { path = "../libunwind" }

[replace]
"core:0.0.0" = { path = "../libcore" }

[build-dependencies]
build_helper = { path = "../build_helper" }
gcc = "0.3.27"
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {
let target = env::var("TARGET").expect("TARGET was not set");
let host = env::var("HOST").expect("HOST was not set");
if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") &&
!target.contains("emscripten") && !target.contains("fuchsia") {
!target.contains("emscripten") && !target.contains("fuchsia") && !target.contains("redox") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We disable the build of libbacktrace, as it will not currently compile for Redox

build_libbacktrace(&host, &target);
}

Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@
#![feature(unwind_attributes)]
#![feature(vec_push_all)]
#![feature(zero_one)]
#![cfg_attr(target_os = "redox", feature(naked_functions))]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hygiene error! In order to generate executables, we have to have a naked _start function at the libstd root.

#![cfg_attr(test, feature(update_panic_count))]

// Explicitly import the prelude. The compiler uses this same unstable attribute
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/redox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

#![allow(dead_code, missing_docs, bad_style)]

pub extern crate syscall;

use io::{self, ErrorKind};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have moved the syscall crate in-tree to the syscall module.


pub mod args;
Expand All @@ -33,7 +31,9 @@ pub mod process;
pub mod rand;
pub mod rwlock;
pub mod stack_overflow;
pub mod start;
pub mod stdio;
pub mod syscall;
pub mod thread;
pub mod thread_local;
pub mod time;
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/sys/redox/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ use vec::{IntoIter, Vec};

use self::dns::{Dns, DnsQuery};

pub extern crate libc as netc;
pub use self::tcp::{TcpStream, TcpListener};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer use the libc crate for netc definitions. They are now inside the netc module.

pub use self::udp::UdpSocket;

pub mod netc;

mod dns;
mod tcp;
mod udp;
Expand Down
47 changes: 47 additions & 0 deletions src/libstd/sys/redox/net/netc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pub type in_addr_t = u32;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the definitions from libc that are relevant in std::net

pub type in_port_t = u16;

pub type socklen_t = u32;
pub type sa_family_t = u16;

pub const AF_INET: sa_family_t = 1;
pub const AF_INET6: sa_family_t = 2;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct in_addr {
pub s_addr: in_addr_t,
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct in6_addr {
pub s6_addr: [u8; 16],
__align: [u32; 0],
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sockaddr {
pub sa_family: sa_family_t,
pub sa_data: [u8; 14],
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sockaddr_in {
pub sin_family: sa_family_t,
pub sin_port: in_port_t,
pub sin_addr: in_addr,
pub sin_zero: [u8; 8],
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct sockaddr_in6 {
pub sin6_family: sa_family_t,
pub sin6_port: in_port_t,
pub sin6_flowinfo: u32,
pub sin6_addr: in6_addr,
pub sin6_scope_id: u32,
}
25 changes: 21 additions & 4 deletions src/libstd/sys/redox/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
// except according to those terms.

use io;
use libc;
use rand::Rng;

pub struct OsRng;
// FIXME: Use rand:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to specify a simple OsRng algorithm until the rand: process is started. If you have more questions, please ask them here. In the future, rand: will be in the kernel to allow the init process to execute. (Rust currently uses OsRng in every process for the HashState)

pub struct OsRng {
state: [u64; 2]
}

impl OsRng {
/// Create a new `OsRng`.
pub fn new() -> io::Result<OsRng> {
Ok(OsRng)
Ok(OsRng {
state: [0xBADF00D1, 0xDEADBEEF]
})
}
}

Expand All @@ -26,7 +30,20 @@ impl Rng for OsRng {
self.next_u64() as u32
}
fn next_u64(&mut self) -> u64 {
unsafe { libc::random() }
// Store the first and second part.
let mut x = self.state[0];
let y = self.state[1];

// Put the second part into the first slot.
self.state[0] = y;
// Twist the first slot.
x ^= x << 23;
// Update the second slot.
self.state[1] = x ^ y ^ (x >> 17) ^ (y >> 26);

// Generate the final integer.
self.state[1].wrapping_add(y)

}
fn fill_bytes(&mut self, buf: &mut [u8]) {
for chunk in buf.chunks_mut(8) {
Expand Down
43 changes: 43 additions & 0 deletions src/libstd/sys/redox/start.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use sys::syscall::exit;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hygiene error! In order to generate executables, we have to have a naked _start function at the libstd root.

This code would typically be done in crt0 in libc. Since we are avoiding the linkage to a libc, we define it here. Due to the way #[no_mangle] works, the linker will fail if these functions are not exported all the way to the crate root.


#[allow(private_no_mangle_fns)]
#[no_mangle]
#[naked]
#[cfg(target_arch = "x86")]
pub unsafe fn _start() {
asm!("push esp
call _start_stack
pop esp"
:
:
: "memory"
: "intel", "volatile");
let _ = exit(0);
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
#[naked]
#[cfg(target_arch = "x86_64")]
pub unsafe fn _start() {
asm!("mov rdi, rsp
and rsp, 0xFFFFFFFFFFFFFFF0
call _start_stack"
:
:
: "memory"
: "intel", "volatile");
let _ = exit(0);
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
pub unsafe extern "C" fn _start_stack(stack: *const usize){
extern "C" {
fn main(argc: usize, argv: *const *const u8) -> usize;
}

let argc = *stack as usize;
let argv = stack.offset(1) as *const *const u8;
let _ = exit(main(argc, argv));
}
Loading