Git Product home page Git Product logo

steed's Introduction

Status

"It's dead, Jim".png

This project has been inactive since 2017-10-20.

If you are interested in hassle-free cross compilation from any OS to Linux I would suggest looking into the Linux/MUSL targets:

$ cargo new --bin hello && cd hello

$ rustup target add x86_64-unknown-linux-musl

$ cargo rustc --target x86_64-unknown-linux-musl -- -C linker=rust-lld

$ file target/x86_64-unknown-linux-musl/debug/hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

If you are interested in a Rust standard library free of C dependencies for Linux then I would suggest registering your interested in rust-lang/rfcs#2610

If you are interested in taking over the development of this project send me an e-mail (see my GH profile) and I'll transfer it and its dependencies to you.

-- @japaric, 2018-12-09


steed

[WIP] Rust's standard library, free of C dependencies, for Linux systems

It's very early days. Very little functionality has been ported over.

Goals

The ultimate goal is achieve truly hassle free cross compilation from any system (macOS, Windows, *BSD, etc.) to any Linux system, be it x86 or ARM hardware. That is:

$ cargo build --target aarch64-unknown-linux-steed

Should work without having to install a C toolchain or cross compiled C libraries, and without having to run the command inside a Docker container / VM.

By removing all the C dependencies, steed solves half of the problem. The other half will be solved by embedding lld, LLVM's multi-arch linker, into rustc.

The short term goal is to provide the exact same functionality and API as the std crate. Hopefully, by the time that's complete, PAL and std-aware Cargo will be around and we'll be able to plug a pal_steed crate into the normal std to get C free Rust programs.

Although, IMO, it would make more sense (*) and it would be more ergonomic to land chunks of steed in rust-lang/rust and add a new set of built-in target, e.g. aarch64-linux. That way, compiling C free Rust programs would be as simple as e.g. cargo build --target aarch64-linux.

(*) Because linking requires different linker arguments and programs are always statically linked.

Non-goals

  • Supporting other unix like systems, like the *BSD ones. Mainly because we have no (easy) way to test them inside Travis and also to reduce the amount of work required. After we are done with the C free port of std for Linux then we can start thinking about supporting other OSes.

Features

  • Zero C code. Zero C dependencies. Not even startup objects are required to link a steed binary. steed programs should still be able to interoperate with or link to C code though (This last part is currently untested).

  • Small, statically linked binaries:

// examples/hello.rs
use std::{io, process};
use std::io::Write;

fn main() {
    if io::stdout().write_all(b"Hello, world!\n").is_err() {
        process::exit(1)
    }
}
# xargo rustc --target x86_64-unknown-linux-steed --release --example hello -- -C lto
$ ./hello
Hello, world!

$ strip -s hello

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped, with debug_info

$ size hello
   text    data     bss     dec     hex filename
    173       0       0     173      ad hello

$ ls -l hello
-rwxr-xr-x 2 japaric japaric 4712 Apr 11 00:00 hello

Disclaimer The binary size will inevitably go up after we add missing startup/runtime features like stack overflow protection and unwinding.

Supported architectures

Turns out that writing architecture specific code is tricky! We were trying to provide "if it compiles, it works" level of support for every architecture that std supports but that stalled development as it's hard to get some features working on a bunch of different architectures.

So, we have adopted Rust's tier system to unstuck development. Our platform support is split in two tiers:

Tier 1

"If it compiles, it works" level of support. PRs won't land if CI tests don't pass on these platforms:

  • aarch64-unknown-linux-steed

  • arm-unknown-linux-steedeabi

  • armv7-unknown-linux-steedeabihf

  • i686-unknown-linux-steed

  • x86_64-unknown-linux-steed

Tier 2

"Best effort" level of support. Using some features that require architecture specific code, like threads, may panic at runtime if the work to support that feature has not been done yet (i.e. unimplemented!()). We don't block PRs if CI tests don't pass on these platforms:

  • mips-unknown-linux-steed
  • mipsel-unknown-linux-steed

  • powerpc-unknown-linux-steed

  • powerpc64-unknown-linux-steed

We eventually hope to move all targets into the tier 1 but we'll need help from people more familiar with the non-x86 architectures. If you'd like to help, feel free to contact us on IRC (#rust-steed @ irc.mozilla.org) or via the issue tracker, or directly tackle the architecture specific issues, issue tagged with e.g. A-powerpc, listed on the issue tracker.

Usage

To compile your library / application against steed, follow these steps:

DISCLAIMER steed has not achieved feature parity with std yet, so it's likely that your crate won't compile against steed. However, if your crate compiles against steed and then crashes or doesn't behave as expected at runtime, that's a bug and we would appreciate a bug report.

Using cross

To easiest way to use steed is to use the cross tool:

NOTE cross depends on Docker and only works on x86_64 Linux

# Always use the latest version
$ cargo install cross

# instead of this step, just go to the crate you want to build
$ cargo new --bin hello && cd $_

# Xargo magic to replace `std` with `steed`
# (if you want to run tests, fetch `Xargo.test.toml` instead of `Xargo.std.toml`)
$ curl -L https://raw.githubusercontent.com/japaric/steed/master/Xargo.std.toml > Xargo.toml
# NOTE `steed` uses its own set of targets; these have `steed` instead of `gnu`
# in their triples
$ cross run --target x86_64-unknown-linux-steed
Hello, world!

$ file target/x86_64-unknown-linux-steed/debug/hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),statically linked, not stripped, with debug_info

You can use cross to cross compile your crate to other architectures as well.

# continuation from the previous example
$ cross build --target aarch64-unknown-linux-steed

$ file target/aarch64-unknown-linux-steed/debug/hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped, with debug_info

cross can even transparently execute those cross compiled binaries using QEMU. QEMU doesn't need to be installed on the host system.

$ cross run --target aarch64-unknown-linux-steed -v
       Fresh hello v0.1.0 (file:///project)
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `/target/aarch64-unknown-linux-steed/debug/hello`
Hello, world!

NOTE cross test works as well but you have to use the other Xargo.toml

Using lld

If you are not running x86_64 Linux or don't want to install / use Docker. You can compile steed programs using xargo and lld.

# This is for Ubuntu, adjust as necessary
$ sudo apt-get install lld-4.0

# Xargo v0.3.4 or newer is required
$ cargo install xargo

# OMITTED: fetching Xargo.toml

# Fetch the target definition
$ curl -LO https://raw.githubusercontent.com/japaric/steed/master/docker/x86_64-unknown-linux-steed.json

$ xargo run --target x86_64-unknown-linux-steed
Hello, world!

Cross compilation works out of the box; there's no need to install a cross C toolchain:

# fetch another target definition
$ curl -LO https://raw.githubusercontent.com/japaric/steed/master/docker/aarch64-unknown-linux-steed.json

$ xargo build --target aarch64-unknown-linux-steed

$ file target/aarch64-unknown-linux-steed/debug/examples/hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped, with debug_info

To execute foreign binaries you can use QEMU:

# This is for Ubuntu, adjust as necessary
$ sudo apt-get install qemu-user

$ qemu-aarch64 target/aarch64-unknown-linux-steed/debug/examples/hello
Hello, world!

Using gcc

If you don't want to install lld, you can link steed programs using gcc, which you probably already have installed.

$ xargo rustc --target x86_64-unknown-linux-steed -- -C linker=gcc -Z linker-flavor=gcc

$ file target/x86_64-unknown-linux-steed/debug/hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=ac4fce139edd9741b818cd73123be6c934718f78, not stripped, with debug_info

Current functionality

Check the API docs, but to summarize the functionality that interfaces with the Linux kernel:

  • Standard I/O (stdin, stdout, stderr)

  • File I/O

  • Filesystem operations (std::fs)

  • std::net: TCP, UDP. lookup_host is missing.

  • Dynamic memory allocation (thanks to ralloc!)

  • std::time

  • Minimal thread support.

Yup, that's all! I did say it was very early days, didn't I?

Contributing

There's plenty of work to do (spoilers most of it is copy pasting code from the rust-lang/rust repo) and you can help! Check out the issue tracker. We have tagged the issues according to their difficulty from D-easy to D-hard. Each issue description has instructions on how to proceed but keep these general guidelines in mind:

  • We have an IRC channel on Mozilla network, #rust-steed, if you have any question!

  • We can't depend on the libc crate because that will make all our programs link to libc, libm, etc.

  • We still don't support the #[test] attribute so, if you add new functionality, please add a smoke test in the form of an example that exercises the new functionality to the examples directory and to the list in ci/script.sh.

  • Some functionality, like std::Path, is architecture independent. Re-implementing that functionality in steed is as simple as copy pasting std's code. When that happens, make sure to copy from a stable Rust release, e.g. 1.14.0, and to also add a comment indicates from which Rust version the code came from.

  • Try to mimic the layout of rust-lang/rust's src/libstd directory as much as possible. I expect that, except for the sys and linux modules, everything else will be very similar in layout and contents to the rust-lang/rust repo.

  • Keep all the code that directly interfaces with the Linux kernel in the private linux module.

  • Some code will involve constants / flags like EBADF or O_CLOEXEC. Get the values of those constants from the Linux kernel source code. Be careful with architecture dependent values! Look for O_CLOEXEC inside the linux module to see how those are handled.

# cargo install ripgrep
$ rg 'define[ \t]+\bO_CLOEXEC[ \t]+'
tools/perf/builtin-trace.c
51:# define O_CLOEXEC           02000000

include/uapi/asm-generic/fcntl.h
62:#define O_CLOEXEC    02000000        /* set close_on_exec */

arch/sparc/include/uapi/asm/fcntl.h
20:#define O_CLOEXEC    0x400000

arch/parisc/include/uapi/asm/fcntl.h
16:#define O_CLOEXEC    010000000 /* set close_on_exec */

arch/alpha/include/uapi/asm/fcntl.h
17:#define O_CLOEXEC    010000000 /* set close_on_exec */
  • Some code will require doing system calls. Instead of directly using the syscall! macro, create a wrapper function to add type checking. As for the signature of the wrapper function, base it on the signature used in the Linux kernel:
$ rg '\bSYSCALL_DEFINE.\(open,'
fs/open.c
1066:SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)

Would become:

// fs/open.c
#[inline(always)]
pub unsafe fn open(filename: *const c_char, flags: c_int, mode: umode_t) { .. }
  • Some of those signatures will involve type aliases like umode_t. Get those from the Linux kernel source as well and add the type aliases to the linux module.
$ rg 'typedef.+umode_t'
include/linux/types.h
18:typedef unsigned short               umode_t;
  • man 2 is your friend. Most system calls are documented in there. For example, man 2 write, documents the write system call.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

steed's People

Contributors

aleksander avatar anatol avatar fenrirwolf avatar homunkulus avatar japaric avatar tbu- avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

steed's Issues

add synchronization to stdin/stdout/stderr

The current implementation is not synchronized. This is OK for now because we don't have threads. Once we get threads the implementation will have to be updated. The code that uses synchronization is already there but we haven't switched to it yet.

This is blocked by TLS support. cc #30

add math functions (`sin`, `cos`, etc.)

There's a WIP C free implementation of these math functions in the m crate so let's use that. The tricky part is that the m crate exposes the functionality as traits but std must expose that functionality as inherent methods. So you'll have to do something like this (not tested):

use m::Float;

#[lang = "f32"]
impl {
    fn abs(self) -> Self {
        <f32 as Float>::abs(self)
    }
}

Xargo integration

We want to be able to build std programs against steed.

Xargo already supports building a custom std source (cf. XARGO_RUST_SRC) but it expects a very specific directory layout.

We may have to hack Xargo to achieve this.

re-implement fs::File

The current implementation is minimal and only meant to sanity check the syscall interface.

Let's copy paste the actual implementation from rust-lang/rust

We'll probably want to get io::Error done first though. So ...

blocked by #6

How to test on real hardware?

I have PowerPC (IBM G3) and ARMv7 (Allwinner R18) with cross installed and steed's dependencies built. I removed the docker bits that I don't need and passed in the targets. On both, I received this:

edwinamsler@chip-01:~/Documents/Code/steed$ TARGET=armv7-unknown-linux-gnueabihf bash ci/script.sh 
+ main
+ examples=(_llseek create format format hello instant open preadwrite stderr system-time vec zero)
+ local examples
+ for example in '${examples[@]}'
+ cross run --target armv7-unknown-linux-gnueabihf --example _llseek
   Compiling unborrow v0.3.1
   Compiling sc v0.1.3 (https://github.com/japaric/syscall.rs#ee704d7f)
   Compiling sc v0.1.3
   Compiling ralloc_shim v0.1.1 (https://github.com/japaric/ralloc?branch=sc#837933b6)
   Compiling compiler_builtins v0.1.0 (https://github.com/rust-lang-nursery/compiler-builtins#764557f0)
   Compiling ralloc v1.0.0 (https://github.com/japaric/ralloc?branch=sc#837933b6)
   Compiling std v0.1.0 (file:///home/edwinamsler/Documents/Code/steed)
error: language item required, but not found: `eh_personality`

error: aborting due to previous error

error: Could not compile `std`.

As a Canadian, I can provide plenty of "Eh" personality, but I don't know how to hand it over to Steed :D

Use custom targets

Given that we are forced to use panic = abort, which currently has to be specified in Cargo.toml, until we implement unwinding (#12) and that some crates may require modifications to be compiled against steed (e.g. use syscalls instead of the libc crate, or not use last_os_error), I propose that we create and ship with this repo custom targets that make it easier to deal with those two requirements.

In a nutshell, we would create custom targets named e.g. x86_64-linux that look very similar to their built-in counterparts, e.g. x86_64-unknown-linux-gnu, except for:

  • Setting panic-strategy to abort

  • Setting env to steed so people can use cfg(target_env = "steed") to make their crates compatible with steed

  • And moving the linker flags that currently reside in .cargo/config into the pre-link-args fields so people don't have to carry that file around to compile against steed.

The main downside is that to call cargo build --target x86_64-linux you would need to have the target specification file around. But I think that can be fixed by teaching cross how to support custom targets and by providing images that contain the target specification file and set RUST_TARGET_PATH as appropriate such that cross build --target x86_64-linux just works.

Thoughts on this?

powerpc64le broken

Apparently #65 broke this target.

$ cross run --target powerpc64le-unknown-linux-steed --example zero
Invalid data memory access: 0xffffffffffff8300
NIP 00000000100000ec   LR 0000000010000204 CTR 0000000000000000 XER 0000000000000000 CPU#0
MSR 9000000102806001 HID0 0000000000000000  HF 9000000002806001 iidx 6 didx 6
TB 00009545 40996312833228
GPR00 0000000010000204 00000040008008c0 0000000000000000 0000000000000001
GPR04 0000004000800a08 ffffffffffff80b0 ffffffffffff8300 0000000000000000
GPR08 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR12 0000000010000190 0000000000000000 0000000000000000 0000000000000000
GPR16 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR20 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR24 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR28 0000000000000000 0000000000000000 0000000000000000 00000040008008c0
CR 00000000  [ -  -  -  -  -  -  -  -  ]             RES ffffffffffffffff
FPR00 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR04 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR08 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR12 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR16 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR20 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR24 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPR28 0000000000000000 0000000000000000 0000000000000000 0000000000000000
FPSCR 0000000000000000

I have seen this QEMU crash before in other projects but was spurius. However, in this case the crash always happens.

implement std::sync

  • std::sync::Once #63
  • ???

My original intention was to depend on the parking_lot but that crate depends on std (Duration, actually) and uses C functions (pthread stuff). So we'll have to vendor that crate and also this is ...

blocked by #13 because of the pthread stuff. Although, I think this is not 100% true because it seems that some parts of parking_lot can be ported by only implementing the FUTEX syscall.

Discussion: Provide a libc module similar to the original one

Most implementations (e.g. in src/sys/linux/fs.rs) just require changing the original std code by replacing libc with something like linux or errno. I suggest that we build most of the abstractions (those that are possible to do) in a separate module called libc in the root namespace, so that we can use the original std code with less modifications (should make updating easier).

What do you think?

re-implement io::Error

The current implementation is minimal.

Copy paste rust-lang/rust's implementation.

This is also going to require creating "definitions" like const EBADF: c_int = 9 so
we can map error codes to io::error::Kinds. You can get those values from the
Linux kernel source:

# cargo install ripgrep
$ rg 'define[ \t]+\bEBADF[ \t]+'
include/uapi/asm-generic/errno-base.h
12:#define      EBADF            9      /* Bad file number */

Support normal `fn main()`

This should work:

extern crate steed;

fn main() {
    println!("Hello, world!);
}

In theory, we only have to implement the start lang item then fn main() will just work. At the very least this going to require implementing env::args support (because of start's signature) so ...

Blocked by #7

can't find crate for core_rand

I get this error:

$ export RUST_TARGET_PATH=$(pwd)
$ xargo build --target=mips-unknown-linux-steed --release
   Compiling core v0.0.0 (file:///Users/vadzim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore)
   Compiling alloc v0.0.0 (file:///Users/vadzim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/liballoc)
   Compiling std_unicode v0.0.0 (file:///Users/vadzim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libstd_unicode)
   Compiling collections v0.0.0 (file:///Users/vadzim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcollections)
    Finished release [optimized] target(s) in 16.49 secs
    Updating git repository `https://github.com/japaric/steed`
    Updating git repository `https://github.com/rust-lang-nursery/compiler-builtins`
    Updating git repository `https://github.com/redox-os/ralloc`
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling unborrow v0.3.1
   Compiling gcc v0.3.43
   Compiling rustc-cfg v0.3.0
   Compiling sc v0.1.5
   Compiling ralloc_shim v0.1.1 (https://github.com/redox-os/ralloc#35fd0db9)
   Compiling ralloc v1.0.0 (https://github.com/redox-os/ralloc#35fd0db9)
   Compiling compiler_builtins v0.1.0 (https://github.com/rust-lang-nursery/compiler-builtins#0d0f22a9)
   Compiling std v0.1.0 (https://github.com/japaric/steed#861a0457)
error[E0463]: can't find crate for `core_rand`
  --> /Users/vadzim/.cargo/git/checkouts/steed-63ab0a422b3ba8a3/861a045/src/lib.rs:61:1
   |
61 | extern crate rand as core_rand;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

error: Could not compile `std`.

To learn more, run the command again with --verbose.

Generate syscalls ?

Awesome project!

Golang took the same approach, partly for the same reasons. I believe that some of the Golang work / ideas could be reused here.

What they do is to generate simple functions that do nothing but calling syscall() with the right syscall number and arguments (example). Then these functions are used in the standard library.

Generation is done by the mksyscall.pl script. It takes an input file like this one, and generates this.

Syscall number constants are also generated by a script.

Document the boostrapping strategy

I think documenting the boostrapping strategy will help contributors a lot in understanding how to solve some chicken-and-egg problems.

Is it a requirement that no C code is allowed at all, even now? Or is that just the eventual goal? Is it a requirement that no external assembler (gas or clang-ml) be required? I personally would rather steed depend on an external assembler rather than using (the unstable) asm!.

IMO it makes a lot of sense to bootstrap things by reusing parts of the entry point code from Go and/or Android (which is partially in assembly language) and/or MUSL, and then incrementally go back and replace the legacy C/assembly code with Rust code. In particular, I think it would be OK to temporarily depend on MUSL's pthreads C code in order to boostrap other things, but I'm not sure if this fits in with your strategy.

implement env::args

This is going to require messing with the stack in _start (the entry point). Whatever invokes the program, passes the program arguments through the stack and only _start can access them.

SPARC support

SPARC kinda works:

$ cross run --target sparc64-unknown-linux-gnu --example zero; echo $?
0

$ cross run --target sparc64-unknown-linux-gnu --example one; echo $?
1

# Should return 0
$ cross run --target sparc64-unknown-linux-gnu --example hello
Hello, world!
1

Except when it goes very wrong

$ cross run --target sparc64-unknown-linux-gnu --example panic; echo $?
panicked at '101

I'm not quite sure what's wrong: the system calls, the startup code or rustc's codegen.

What's the strategy for copying files

Do we want them as a whole, and just provide the interfaces they call (like the sys module in the standard library)? Would be easier to update in this case.

Or do we want to modify them? This would likely lead to less boilerplate. :)

On a side note: Is there an IRC channel?

implement std::thread

Update 2017-04-15

Basic support has landed for the following platforms:

  • aarch64
  • arm
  • mips
  • powerpc
  • powerpc64
  • sparc64
  • x86
  • x86_64

Original text

This is going to require re-implementing a subset of libpthreads in Rust. So, probably will require quite a bit of work.

We can base our implementation on MUSL's.

Linker errors

When building

  • the open and vec examples for armv7-unknown-linux-gnueabihf
  • the vec example for i686-unknown-linux-gnu and x86_64-unknown-linux-gnu

in release mode. Note that LTO is enabled. This is the linker error:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/xargo/HOST/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/target/x86_64-unknown-linux-gnu/release/examples/vec-f6b3b7cebebee883.0.o" "-o" "/target/x86_64-unknown-linux-gnu/release/examples/vec-f6b3b7cebebee883" "-Wl,--gc-sections" "-Wl,-O1" "-nodefaultlibs" "-L" "/target/x86_64-unknown-linux-gnu/release/deps" "-L" "/target/release/deps" "-L" "/xargo/HOST/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/tmp/rustc.KuuDEWQSJZ1f/libcompiler_builtins-11b9715dd721de11.rlib" "-Wl,--build-id=none" "-nostartfiles" "-static"
  = note: /usr/bin/ld: /target/x86_64-unknown-linux-gnu/release/examples/vec-f6b3b7cebebee883: hidden symbol `core::panicking::panic::h55044ef132086b67' isn't defined
          /usr/bin/ld: final link failed: Bad value
          collect2: ld returned 1 exit status


error: aborting due to previous error

It's also the case that these targets are using gcc-4.6.2 (because of the cross
environment) to link the executables so that may be the problem.

It should be noted that cross users haven't reported any trouble linking Rust
programs using that old gcc version until now.

Let's:

  • check if the problem goes away by making the panic_fmt lang item public.

  • check if this is a regression by using an older nightly. There was a relevant
    change in how rustc emits symbols (it's now more strict about what's public,
    etc.) in the last month so that could contribute to the problem.

  • check if installing gcc-4.7 in the cross environment solves the problem. If it
    does, then let's send a PR to japaric/cross.

unwinding support

AFAIK, there is no pure Rust implementation of unwinding out there so this is going to be a lot of work to support all the architectures.

Implement a Rust analog to `getauxval(3)`

ring uses getauxval(AT_HWCAP) and getauxval(AT_HWCAP2) on ARM & AAarch64 (and maybe all platforms eventually) to determine which hardware instructions are available: NEON, ARMv8 crypto instructions, etc. When targetting non-Android ARM/AAarch64 Linux using steed, we need a way to get the same information, ideally using a Rust API instead of a C API.

See http://articles.manugarg.com/aboutelfauxiliaryvectors and http://man7.org/linux/man-pages/man3/getauxval.3.html and the Android implementation:
https://android.googlesource.com/platform/bionic/+/master/libc/bionic/getauxval.cpp
https://android.googlesource.com/platform/bionic/+/master/libc/bionic/libc_init_common.cpp#77

compiling *ring*

i.e. what needs to be done to be able to compile ring against steed?

  • std::sync::Once. #63
  • getauxval. #48
  • ???

Other operating systems?

Right now this project is only targeting for Linux support. What about Windows, FreeBSD or macOs?

Implement Rust getrandom syscall wrapper

ring calls libc's syscall(2) from C code to invoke the getrandom syscall. In order to port ring to steed, we need a wrapper around the syscall that we can call from Rust (ideally) or C (less-than-ideally).

implement std::command

It's OK to start with just implementing the "builder" API part of Command and stubbing (i.e. sprinkling unimplemented! in) the spawn parts of it.

Then we'll have to use syscalls to implement the spawn part.

Both are going to involve mainly copy pasting code. The first part more than the latter though.

Allow offline compilation

I don't know what needs to be done to make that work, but I'd like to be able to compile without being connected to the internet.

$ cross run --target i686-unknown-linux-steed --example hashmap --no-default-features --features naive_ralloc
    Updating git repository `https://github.com/redox-os/ralloc`
warning: spurious network error (2 tries remaining): [12/-1] Failed to resolve address for github.com: Name or service not known
warning: spurious network error (1 tries remaining): [12/-1] Failed to resolve address for github.com: Name or service not known
error: failed to load source for a dependency on `ralloc`

Caused by:
  Unable to update https://github.com/redox-os/ralloc

Caused by:
  failed to fetch into /home/<user>/.cargo/git/db/ralloc-797ee1a3f928155b

To learn more, run the command again with --verbose.
error: couldn't generate Cargo.lock
caused by: `"cargo" "generate-lockfile" "--manifest-path" "/path/to/steed/Cargo.toml"` failed with exit code: Some(101)
note: run with `RUST_BACKTRACE=1` for a backtrace

Linking with lld

Let's try to link the examples in this repository using lld instead of the gcc linker in the cross environment. Just to find out how many targets are usable with lld. I expect that x86, ARM and MIPS will work.

errno constants are wrong on some architectures

Some constants, like EBADFD, have different values on different architectures:

$ rg 'define[ \t]*EBADFD'
include/uapi/asm-generic/errno.h
59:#define      EBADFD          77      /* File descriptor in bad state */

arch/sparc/include/uapi/asm/errno.h
68:#define      EBADFD          93      /* File descriptor in bad state */

arch/parisc/include/uapi/asm/errno.h
54:#define      EBADFD          168     /* File descriptor in bad state */

arch/mips/include/uapi/asm/errno.h
55:#define EBADFD               81      /* File descriptor in bad state */

arch/alpha/include/uapi/asm/errno.h
94:#define      EBADFD          114     /* File descriptor in bad state */

The implementation has to handle this using cfgs.

The architectures that usually use different values are SPARC and MIPS, which we are not currently considered supported platforms due to other bugs, so this is not a pressing issue. However, we'll have to fix this before listing those two architectures as supported.

cc @tbu-

minimal `test` crate

  • term
    • collections::HashMap
    • env
    • io::BufReader
    • fs::metadata
  • getopts
    • ???
  • test
    • ???

Let's make sure the test crate can be compiled against steed then we'll be able to use #[test] with steed.

It's OK to heavily modify the source as long as the main functionality remains. It's OK to drop parallelism and stub the catch_unwind calls (let panic!s kill the test runner)

implement std::collections

I think most of would be simply re-exporting the stuff from the collections crate (modulo collections::HashMap which is covered by #4)

Fate of `last_os_error`

Since we don't have a C-style errno variable, what should we return from io::Error::last_os_error. Currently, it just panics.

Other options include: Introducing a C-style errno variable, or returning 0 (apparantly Redox does that, #43 (comment)).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.