Code Monkey home page Code Monkey logo

kernel's People

Contributors

bors[bot] avatar cagatay-y avatar colinfinck avatar daniel-k avatar dependabot[bot] avatar duanyu-yu avatar gitter-badger avatar jbreitbart avatar joannejchen avatar joboet avatar jounathaen avatar jschwe avatar jts22 avatar justicezyx avatar lucashaug avatar luojia65 avatar michaelrichards99 avatar mkroening avatar nathanwhyte avatar naveensrinivasan avatar realrichardparker avatar sarahspberrypi avatar sfbdragon avatar simonschoening avatar stlankes avatar striezel avatar stv0g avatar teymour-aldridge avatar thane98 avatar tlambertz 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

kernel's Issues

Scheduler does not wake sleeping threads when multiple cores are available

When using multiple CPU cores, the scheduler does not wake sleeping threads once their sleep duration is over. I guess this happens because of the core-local scheduling, where the main core does not check for threads to be woken on other cores. But I have not verified this.

Simple reproducer:

#[cfg(target_os = "hermit")]
extern crate hermit_sys;

use std::thread;
use std::time;

fn main() {
    let mut children = vec![];

    let threadnum = 5;
    for i in 0..threadnum {
        println!("SPAWNING THREAD {}", i);
        children.push(thread::spawn(move || {
            println!("this is thread number {}", i);
            thread::sleep(time::Duration::from_millis(2000));
            println!("---------------THREAD DONE!---------- {}", i);
        }));
    }
    println!("SPAWNED THREADS");

    for child in children {
        let _ = child.join();
    }
}

My test project includes a cargo project, makefile and the rusty-loader: rusty-test-sleep.tar.gz.
The binary is build and started with make run. This also sets the correct QEMU options to reproduce the bug.

Build failed

OS: Ubuntu 18.04.3 LTS

I install rust nightly and followed these instructions

git clone https://github.com/hermitcore/rusty-hermit.git
cd rusty-hermit
git submodule init
git submodule update
cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit

and the build failed with the message:

[hikari@atlantis rusty-hermit]$ cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit
warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
package:   /home/hlab/hikari/rusty-hermit/demo/Cargo.toml
workspace: /home/hlab/hikari/rusty-hermit/Cargo.toml
   Compiling rustc-std-workspace-core v1.99.0 (/home/hlab/hikari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/tools/rustc-std-workspace-core)
   Compiling unwind v0.0.0 (/home/hlab/hikari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libunwind)
   Compiling backtrace-sys v0.1.32
   Compiling hermit-sys v0.1.6 (/home/hlab/hikari/rusty-hermit/hermit-sys)
error: failed to run custom build command for `hermit-sys v0.1.6 (/home/hlab/hikari/rusty-hermit/hermit-sys)`

Caused by:
  process didn't exit successfully: `/home/hlab/hikari/rusty-hermit/target/debug/build/hermit-sys-e186b5ca70364884/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'Unable to build kernel: Os { code: 2, kind: NotFound, message: "No such file or directory" }', hermit-sys/build.rs:31:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

warning: build failed, waiting for other jobs to finish...
error: build failed

Did I miss anything?

`RxQueues`: Panicking does not work properly in debug

Panicking in RxQueues::get_next does not work properly in debug and instead causes a page fault:

[0][ERROR] Page Fault (#PF) Exception: ExceptionStackFrame {
    instruction_pointer: 0x500,
    code_segment: 0x8,
    cpu_flags: 0x1206,
    stack_pointer: 0x3a953790,
    stack_segment: 0x10,
}
[0][ERROR] virtual_address = 0x500, page fault error = The fault was caused by a page-level protection violation.
The access causing the fault was a read.
The access causing the fault originated when the processor was executing in supervisor mode.
The fault was not caused by reserved bit violation.
The fault was caused by an instruction fetch.
[0][ERROR] fs = 0x1, gs = 0x1

request : RISCV64 support

any planning for supporting RISCV64 arch ? RISCV64 multicore and manycore may become potential for multi-kernel feature

Delete Stale branches

There are two branches which are outdated: devel and loader. I think they can be removed.

Add syscalls to Rust libstd

Hi, there is no "issues section" on the hermitcore:rust repo, so I post here.
I am now trying to add some system calls on RustyHermit.
I created my_syscalls.rs on rust/src/libstd/sys/hermit/ and tried to import it from the libhermit-rs/tests/src/tests/mod.rs.

As I observed, I can't directly use it because the libstd/sys is private.
So do I need to create interfaces for my system calls and overwrite them on rust/src/libstd/sys/hermit/my_syscalls.rs?

Missing FSGS leeds to endless spinloop without any error message

https://github.com/hermitcore/libhermit-rs/blob/d6539f202a1938c143fa7b975071f6dbaed0092a/src/arch/x86_64/kernel/processor.rs#L785-L792

Missing fsgs support leads to an endless spin-loop without any error message. I'm not quite sure why no error message is printed, maybe the serial interface is not initialized at that point? (it's still very early).
If possible it would be great to enable the serial interface before this point, so that an error message can get sent out.
Additionally I would propose to change the loop so that it loops only for a couple of seconds and terminates the kernel afterwards e.g. by panicking.

SMP issue

add microvm support

Citation:

microvm is a machine type inspired by Firecracker and constructed after its machine model.
It's a minimalist machine type without PCI nor ACPI support, designed for short-lived guests. microvm also establishes a baseline for benchmarking and optimizing both QEMU and guest operating systems, since it is optimized for both boot time and footprint.

Conseqeuntly, it is a interesting platform for RustyHermit and should be supported

Retry naked functions

Naked functions have come a long way since #95.

There is rust-lang/rfcs#2972 and rust-lang/rust#79653 which help against misusing the feature. We have adapted it in eduOS successfully, making it possible to use const and sym operands in asm! blocks instead of having to resort to global symbols. We could also eliminate most, if not all, hard coded constants from assembly, making the code much easier to understand.

What do you think, @stlankes?

`ExceptionStackFrame` in interrupts contains gibberish

Since LLVM 12 (rust-lang/rust#84230) ExceptionStackFrame has to be taken by value. See rust-lang/rust#40180 (comment).

Current output of ud2:

[0][ERROR] Invalid Opcode (#UD) Exception: ExceptionStackFrame {
    instruction_pointer: 0xc35b30c483480b0f,
    code_segment: 0xee9d058af2894850,
    cpu_flags: 0x3d8d48f76348ffff,
    stack_pointer: 0x7e8ffffffcc,
    stack_segment: 0xccccccccccc35900,
}

Expected:

[0][ERROR] Invalid Opcode (#UD) Exception: ExceptionStackFrame {
    instruction_pointer: 0x501738,
    code_segment: 0x8,
    cpu_flags: 0x11206,
    stack_pointer: 0x373be30,
    stack_segment: 0x10,
}

Unwinding support

According to the discussion in hermit-os/uhyve#30 (comment) this might still be impossible or very difficult at least.

It would make it much easier to host multiple "applications" in the same unikernel without a panic crashing all of it.

Slow thread creation

Benchmarks show that the time for a thread creation is too high. As workaround we use currently in our demo a thread pool.

error: output of --print=file-names has changed in the compiler, cannot parse

I tried to rebuild rust by running
$./x.py install

However, I got an error,

error: output of --print=file-names has changed in the compiler, cannot parse
command was: /home/mincheol/rust/build/bootstrap/debug/rustc - --crate-name ___ --print=file-names -Zexternal-macro-backtrace '-Clink-args=-Wl,-rpath,$ORIGIN/../lib' -Wrust_2018_idioms -Wunused_lifetimes -Dwarnings -Zsave-analysis -Cprefer-dynamic --target x86_64-unknown-linux-gnu --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg

--- stdout
Here????

___
lib___.rlib
lib___.so
lib___.so
lib___.a
lib___.so
/home/mincheol/rust/build/x86_64-unknown-linux-gnu/stage1
debug_assertions
proc_macro
target_arch="x86_64"
target_endian="little"
target_env="gnu"
target_family="unix"
target_feature="fxsr"
target_feature="mmx"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="cas"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="64"
target_thread_local
target_vendor="unknown"
unix

command did not execute successfully: "/home/mincheol/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "-Zconfig-profile" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-j" "32" "--release" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/home/mincheol/rust/src/libtest/Cargo.toml" "--message-format" "json-render-diagnostics"
expected success, got: exit code: 101
failed to run: /home/mincheol/rust/build/bootstrap/debug/bootstrap install
Build completed unsuccessfully in 0:06:00

Intructions for local build

Hi!

I am trying to locally build RustyHermit.
Are there instructions for that?
I tried "make" but failed to build.

mincheol@mir3:~/libhermit-rs$ make
Build libhermit
Finished dev [optimized + debuginfo] target(s) in 0.02s
make arch=x86_64 release=0 -C tests
make[1]: Entering directory '/home/mincheol/libhermit-rs/tests'
Compiling nodrop v0.1.13
Compiling lazy_static v1.4.0
Compiling cfg-if v0.1.9
Compiling scopeguard v1.0.0
Compiling fnv v1.0.6
Compiling either v1.5.2
Compiling itoa v0.4.4
Compiling libc v0.2.62
Compiling byteorder v1.3.2
Compiling memoffset v0.5.1
error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: Could not compile cfg-if.
warning: build failed, waiting for other jobs to finish...
error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: aborting due to previous error

error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

For more information about this error, try rustc --explain E0463.
error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: Could not compile nodrop.
warning: build failed, waiting for other jobs to finish...
error: Could not compile either.
warning: build failed, waiting for other jobs to finish...
error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error[E0463]: can't find crate for core
|
= note: the x86_64-unknown-hermit target may not be installed

error: aborting due to previous error

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
For more information about this error, try rustc --explain E0463.
error: Could not compile libc.
warning: build failed, waiting for other jobs to finish...
error: Could not compile lazy_static.
warning: build failed, waiting for other jobs to finish...
error: Could not compile scopeguard.
warning: build failed, waiting for other jobs to finish...
error: Could not compile memoffset.
warning: build failed, waiting for other jobs to finish...
error[E0463]: can't find crate for std
|
= note: the x86_64-unknown-hermit target may not be installed

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error[E0463]: can't find crate for std
|
= note: the x86_64-unknown-hermit target may not be installed

error: Could not compile fnv.
warning: build failed, waiting for other jobs to finish...
error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: Could not compile itoa.
warning: build failed, waiting for other jobs to finish...
error[E0463]: can't find crate for std
|
= note: the x86_64-unknown-hermit target may not be installed

error: aborting due to previous error

For more information about this error, try rustc --explain E0463.
error: Could not compile byteorder.

To learn more, run the command again with --verbose.
Makefile:23: recipe for target 'default' failed
make[1]: *** [default] Error 101
make[1]: Leaving directory '/home/mincheol/libhermit-rs/tests'
Makefile:23: recipe for target 'default' failed
make: *** [default] Error 2

RFC: virtqueue interface

I have been considering how to rewrite the virtio-queue interface to make it more unified, safer and easier to understand. Since @mustermeiszer is working on this as well, I figured I'd post some notes here. Feedback very welcome.

Requirements:

  • Usability
    • virtio-fs needs to send/receive in the same transmission (packed queue)
    • virtio-fs wants to hand in multiple buffers, which get concatenated in a single descriptor chain. This way we can easily prepend a header to the data.
    • virtio-net needs to have a filled receive queue, since the device can initiate transmissions on it's own. Once a buffer is used, the same descriptor is inserted into the queue again.
    • virtio-net wants to also recycle transmit descriptors for speed. On initialization, it allocates all tx buffers, constructs descriptor chains for them. When we want to send we can now simply place the correct index into the ring.
  • Memory Safety
    • While a transfer is ongoing, the buffer should not be read/writable for the initiator
    • Check if given buffers are physical contiguous, if not split into multiple descriptors on page boundaries
    • mem::forget is safe, so we should consider what happens when destructors don't run

Proposal:

Use TransferTokens, which take ownership of the buffers which are to be transferred. On initialization it creates the descritor chain. Can be placed into a virtqueue, upon which it gets converted into a Transfer. Transfer only gives back ownership (or references) to the buffers, once the transfer is complete.

To accomodate the virtio-net usecase of recycling the buffer, we have two modes:

  1. consume the Transfer and return the buffers. This frees up the descriptor chain
  2. extract only a reference to the buffer, use it, later 'recycle' the transfer by re-inserting it into the queue.

Questions:

  • is the interface sufficient for virtio-net? afaik it should be, but I have not looked too deep yet.
  • do we need a 'fire and forget' functionality, where we are allowed to drop an ongoing transfer, which is then automatically freed once done? Currently both virtio-fs and virtio-net don't need it. We could default to warning + leaking.
  • doing it the way I propose below is slightly unsafe, since when a transfer is dropped with mem::forget, we do NOT free the descriptors associated with the transfer, so permanently exhaust some of them. They are limited by the virtqueue length, so doing this often would block all transfers. But I think this is okay in our case, since we can just be careful to not use mem::forget. The only other option I see is doing more housekeeping within the virtqueue itself. I feel this is too complex (and likely slower?), since we would have to keep track of all transfertokens in the virtqueue.
  • Is the interface prepare_transfer(send, recv) -> Result appropriate for a split queue?
  • the function argument types (Option<Box<[Box<[u8]>]>>) look a bit wild. We could use a newtype with .into() to make it look cleaner
  • should we use boxed arrays, or vectors for storing the buffers? (Box<[Box<[u8]>]> vs Vec<Vec<u8>> vs Vec<Box<[u8]>>). Both store an array with size on the heap, a vector has an additional capacity field. I feel that boxes are better since we can easily convert vec to box with .into_boxed_slice(), but not the other way around.
  • We could, if we wanted to be extra safe, unmap the pages the buffers are stored in while a transfer is happening. This way, userspace (or other kernel code) cannot write to buffers if it has kept 'illegal' references around. This could prevent an VM escape via a broken device. But since this is not guaranteed by the spec, it should not be a problem. I know virtio-fs safeguards against changing buffer contents by copying the headers before parsing them.

Interface

/// A prepared transfer, that can be inserted into a virtqueue
pub struct TransferToken<'a> {
    /// memory that is to be send. Multiple, virtual-contiguous u8 arrays
    send_bufs: Option<Box<[Box<[u8]>]>>,

    /// memory that is to be received into. Multiple, virtual-contiguous u8 arrays
    recv_bufs: Option<Box<[Box<[u8]>]>>,
    
    /// descriptor chain, that references send/recv bufs
    desc_chain: Rc<RefCell<VirtqDescriptorChain>>,

    /// virtq on which the transfer is being done
    virtq: &'a Virtq<'a>,
}

/// A single transfer inside a virtqueue
pub struct Transfer<'a> {
    /// virtq-index is not enough, since it wraps easily. Since transfers do not have to be handled in-order, this might be an issue so we use a large id.
    id: u64,
    
    /// Token that was converted to this transfer
    token: TransferToken<'a>,
}

impl<'a> TransferToken<'a> {
    /// Places the already prepared descriptor chain into the virtqueue, returns a Transfer
    ///
    /// Since Transfer's give back the token once they are completed, we can insert the same
    /// token with the same descriptor chain multiple times if we want
    pub fn send(self) -> Transfer<'a> {
        unimplemented!()
    }

    /// Returns mutable references to the send and receive buffers.
    pub fn buf_ref_mut(&mut self) -> (Option<&[&mut [u8]]>, Option<&[&mut [u8]]>) {
        unimplemented!()
    }
    
    /// Consumes the token, returning ownership of the buffers
    pub fn consume(self) -> (Option<Box<[Box<[u8]>]>>, Option<Box<[Box<[u8]>]>>) {
        unimplemented!()
    }
}

impl<'a> Drop for TransferToken<'a> {
    fn drop(&mut self) { 
        // Free descriptor chain in the virtq, so it can be reused by new transfers
        unimplemented!() 
    }
}

impl<'a> Transfer<'a> {
    /// Checks whether the transfer is completed yet. If it is, returns the TransferToken
    pub fn check(&self) -> Option<TransferToken> {
        // checks current ID against virtq's last received id.
        unimplemented!()
    }

    /// Waits until transfer is completed. Returns the TransferToken used.
    pub fn wait(&self) -> TransferToken {
        unimplemented!()
    }
}

impl<'a> Drop for Transfer<'a> {
    fn drop(&mut self) { 
        // If a transfer is dropped while it is ongoing, do NOT free the memory, leak it instead.
        // We could register it in the virtq, so it can be freed later.
        unimplemented!() 
    }
}

impl<'a> Virtq<'a> {
    /// Places send and recv buffers in a descriptor chain, returns a Transfer Token.
    /// Transfer is not placed in the queue yet.
    /// Specifying both send and receive is only possible in a packed queue, else Err
    /// For a split queue, send/recv have to match the queue mode, else Err
    ///
    /// Checks whether the buffers are physically contiguous, split into multiple descriptors if not
    pub fn prepare_transfer(send: Option<Box<[Box<[u8]>]>>, recv: Option<Box<[Box<[u8]>]>>) -> Result<TransferToken<'a>, ()> {
        unimplemented!()
    }

    /// Places send and recv buffers in a descriptor chain, returns a Transfer Token.
    /// Transfer is not placed in the queue yet,
    /// Specifying both send and receive is only possible in a packed queue, else Err
    /// For a split queue, send/recv have to match the queue mode, else Err
    ///
    /// Does NOT check whether the buffers are physically contiguous! Caller has to guarantee this!
    pub unsafe fn prepare_transfer_unchecked(send: Option<Box<[Box<[u8]>]>>, recv: Option<Box<[Box<[u8]>]>>) -> TransferToken<'a> {
        unimplemented!()
    }
}

Naming is completely chaotic

Now the names for this project include:

  • HermitCore-rs
  • RustyHermit
  • libhermit-rs

Same for the hypervisor:

  • uhyve
  • hermit-caves

This should be unified as long as it is still possible...

Add code coverage (LLVM source based coverage)

This is something I've wanted to do for some time, but I haven't had the time.
I'll use this issue to write down some of the issues that need to be solved.
If someone has the time to address this feel free to open a PR.

Source-based coverage support via LLVM landed in the rust compiler somewhat recently.
It can be enabled via the nightly RUSTFLAG -Zinstrument-coverage

Challenges specific to rusty-hermit:

RUSTC_WRAPPER

RUSTFLAGS apply to everything, including dependencies, build scripts and macros.
A RUSTC_WRAPPER program should be written that filters the RUSTFLAG -Zinstrument-coverage
flag and only applies it to relevant crates.
In particular crates such as core must be excluded, since profiler_builtins,
which is required for -Zinstrument_coverage relies on core.

It should be evaluated if we can include std, since we provide a hermit specific std
library, and coverage metrics for that would be useful as well.

Optimizations

Optimizations are detrimental to code coverage so they should be disabled, i.e.
by at least using the flags -Copt-level=0 -Clink-dead-code.
If possible we should again use the RUSTC_WRAPPER to control this, so that
crates without code coverage are optimized, while crates with code coverage are not.

Previous tests have shown that rusty-hermit may be lacking some (mathematical) functions, which
are never called. -Clink-dead-code might surface such problems.

Profiler_builtins

This can be solved independently from the previous issue via the following MWE:

In rusty-hermit add profiler_builtins to the build-std configuration .cargo/config.
Run cargo rustc -p rusty_demo -- -Zinstrument-coverage. This is a sort of poor mans
RUSTC_WRAPPER where the -Zinstrument-coverageflag is only passed to the rusty_demo crate.
Of course this means that the actual kernel is not instrumented, but i believe instrumenting
the userspace application first is easier.

This will probably result in a linker error where some __llvm_profile_* functions are missing.
The issue is that the llvm source code files for the profiler builtins are not shipped with the nightly
and the build script (see profiler_builtins ) in the rust compiler silently ignores the missing files and simply does nothing.

To test things out you can visit rust/src
and clone the linked version of the llvm-project.
You can then copy the compiler-rt folder into "$HOME/.rustup/toolchains/nightly-2020-12-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/llvm-project/".
Replace the version in the above string to whatever version you are using (could also be simply nightly) and make sure that rustup also installed the rustsrc component.
Opening an issue on rustup asking for a profiling component which installs the necessary files
could also be an option.

Now when building the application (with verbose option) you should get new linker errors, that mention
undefined symbols such as strlen, fopen etc. originating from the llvm profiler c files.

To solve that I'd take a look at hermit playground, but additional steps might be needed, since in the end we need the symbols in the kernel code too, if we want coverage there.

Ensure that the latest commit on master / devel branch works

In order to ensure that the master / devel branches are always in a working state I propose the following changes:

  1. Protect master and possibly devel (in rusty-hermit) and disallow direct pushes to these branches.

  2. These branches should only be changed via MRs or PRs and only if the pipeline succeeds. This should be enforced via github settings.

  3. Improve the pipeline in libhermit-rs so that the demo tests are actually executed. Currently the situation is such, that the pipeline in libhermit-rs often succeeds, since it only checks if the code builds, even though there are still errors, which become evident when the changes get integrated into the rusty-hermit repository. PR #40 should help with that.

  4. Change the pipeline so that it runs for pushes on every branch. If costs are an issue, then maybe the matrix could be reduced for pushes. This encourages working on feature branches and gives direct feedback to the developer, without the need to open a PR or push to master.

  5. Encourage the use of git rebase -i on branches before merging into master to keep the History clean and squash commits like minor changes to pass the format check together with the commit it originally belonged to.

Use of newlib's memcpy/memmove functions in the kernel is unstable.

When building the kernel with newlib, rlib.rs is not compiled. This usually provides implementation for memcpy, memmove and the like. Instead, the implementations provided by newlib are used.

This is an issue, since newlib is not build for the kernel target, but a user one. Newlib is allowed to use the floating point unit, and as such memmove uses SSE. Using SSE in the kernel-context is an obviously bad idea.

I can somewhat reliably reproduce a BorrowMutError in my filesystem benchmark code:

[0][!!!PANIC!!!] src/scheduler/mod.rs:326: already borrowed: BorrowMutError

I am not entirely sure what causes this, but have tracked it down to the SSE usage inside memmove. Maybe something like:

  • userspace thread accesses FPU for the first time, exception is thrown and fpu_switch() is called.
  • fpu_switch() borrows current owner, switches state to new owner
  • fpu_switch() does self.current_task.clone(), which under certain circumstances calls memmove.
    • memmove again uses the FPU, causing another call to fpu_switch(), and a double-borrow occurs -> panic()

Log:

I am running 6 threads on a single core. First [ ] column contains rdtsc value. Unfortunately, adding more logging makes the bug disappear.

[0x112aeaebc][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x112ce00e4][0][INFO] Switching FPU owner from task 6 to 7
[0x112eda4e4][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x1130a30c0][0][INFO] Switching FPU owner from task 7 to 5
[0x11329b468][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x11350c854][0][INFO] Switching FPU owner from task 5 to 4
[0x1137a506c][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x113a09900][0][INFO] Switching FPU owner from task 4 to 6
[0x113c9f9b8][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x113f05938][0][INFO] Switching FPU owner from task 6 to 3
[0x114196350][0][INFO] FPU Switch caused by PC 0x807b1b (userspace uses `fild    qword [rbp-0x8]`)
[0x1143b2428][0][INFO] Switching FPU owner from task 3 to 2
[0x114685c44][0][INFO] FPU Switch caused by PC 0x8aee0a (userspace uses `_calloc_r`, which uses `xorps xmm0, xmm0`)
[0x1148a0fc0][0][INFO] Switching FPU owner from task 2 to 7
[0x11538e0f4][0][INFO] FPU Switch caused by PC 0x8aee0a (userspace uses `_calloc_r`, which uses `xorps xmm0, xmm0`)
[0x11559bc94][0][INFO] Switching FPU owner from task 7 to 6
[0x1159dd6fc][0][INFO] FPU Switch caused by PC 0x8aee0a (userspace uses `_calloc_r`, which uses `xorps xmm0, xmm0`)
[0x115c01718][0][INFO] Switching FPU owner from task 6 to 2
[0x115e5f898][0][INFO] FPU Switch caused by PC 0x8b7b10 (kernel? in `memmove`, which does `movups xmm1, [rcx]`)
[0x116079b10][0][INFO] Switching FPU owner from task 2 to 5
[0][!!!PANIC!!!] src/scheduler/mod.rs:326: already borrowed: BorrowMutError

Solution

The use of newlibs optimized memcpy also had an unexpected performance penalty during my testing. We should stick to the implementations inside rlib.rs, even when building with newlib.

This can be done by simply removing the #[cfg(target_os = "hermit")] annotation from mod rlib;. Not entirely sure why that compiles rather then complaining about duplicate symbols though.

The resulting binary only contains the rlib version, which are non-optimized. This means userspace also gets the performance hit of not using SSE instructions in their copies. But this seems preferable to a race condition.

I can not think of a nice way to have both implementations with the current build system.

libhermit-rs fails to compile without feature "pci"

drivers/net contains imports / uses functions that depend on pci being enabled.

 error[E0433]: failed to resolve: use of undeclared crate or module `pci`
     --> src/drivers/net/mod.rs:149:30
      |
  149 |     let check_scheduler = match pci::get_network_driver() {
      |                                 ^^^ use of undeclared crate or module `pci`

I'm not really familiar with the network module, but if it depends on pci, it should be disabled if pci is not enabled. Alternatively we could remove the pci feature and simply unconditionally enable it.

Compiling fails with segfault

Compiling libhermit-rs currently fails with a segmentation fault. This behaviour was introduced with the nightly-2020-08-24. This is likely to be related to the following issue: rust-lang/rust#75922.
The comments there suggest that we will have to make changes on our end to the #[naked] functions.

Resolve the rusty-hermit name clash

Current Situation:

The naming of the repositories and the crates is contradictory.

Crate Name Repository Name Task
rusty-hermit https://github.com/hermitcore/libhermit-rs The Kernel itself
hermit-sys https://github.com/hermitcore/rusty-hermit FFI - What is actually imported in the applications. libhermit-rs is downloaded and linked in the magic build.rs script

Problems

Solution Attempts

These are the two solutions I came up with

Rename the Repository Attempt

  • Move the content of https://github.com/hermitcore/rusty-hermit to a differently named repository.
  • Update crates.io to the new location
  • Move this repository to the now free rusty-hermit url. This implies breakage

Rename this Crate Attempt

  • change the name of this crate to libhermit-rs
  • update the crate name in hermit-sys/hermit-loader/...

Build for loader fails on both Ubuntu & Windows

I first went for QEMU to run test programs, but I was not able to build the loader...

[hikari@atlantis loader]$ cargo xbuild --target x86_64-unknown-hermit-loader.json
    Updating crates.io index
   Compiling core v0.0.0 (/home/hlab/hikari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore)
   Compiling compiler_builtins v0.1.24
   Compiling rustc-std-workspace-core v1.99.0 (/home/hlab/hikari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/tools/rustc-std-workspace-core)
   Compiling alloc v0.0.0 (/tmp/xargo.0B51MgwlFncp)
    Finished release [optimized] target(s) in 24.39s
  Downloaded bitflags v1.0.4
  Downloaded x86 v0.20.0
  Downloaded raw-cpuid v6.1.0
  Downloaded cc v1.0.46
   Compiling semver-parser v0.7.0
   Compiling cc v1.0.46
   Compiling x86 v0.20.0
   Compiling bitflags v1.0.4
   Compiling rusty-loader v0.2.5 (/home/hlab/hikari/rusty-hermit/loader)
   Compiling multiboot v0.3.0
   Compiling semver v0.9.0
   Compiling rustc_version v0.2.3
error: failed to run custom build command for `rusty-loader v0.2.5 (/home/hlab/hikari/rusty-hermit/loader)`

Caused by:
  process didn't exit successfully: `/home/hlab/hikari/rusty-hermit/loader/target/debug/build/rusty-loader-c19c1aeae5788de3/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', build.rs:8:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

warning: build failed, waiting for other jobs to finish...
error: build failed

Same problem for Win10 and Ubuntu 18.04.

I also gave uhyve a try, but it hangs without giving any output...

[hikari@atlantis hello_world]$ sudo ~/.cargo/bin/uhyve target/x86_64-unknown-hermit/debug/hello_world
^C

(I had to run it as sudo since otherwise there will be a permission error)

Readme/tutorial does not work on macOS

The readme doesn't mention anywhere that the described steps are Linux-only.

I suspect this is the actual reason that

cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit

fails for me on macOS 10.15.2 (Catalina) with

running: "cc" "cc" "-O1" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-I" "src/libbacktrace" "-I" "/Users/moritz/code/rust-unikernel/target/x86_64-unknown-hermit/debug/build/backtrace-sys-40bab59e68f76f0a/out" "-fvisibility=hidden" "-DBACKTRACE_ELF_SIZE=64" "-DBACKTRACE_SUPPORTED=1" "-DBACKTRACE_USES_MALLOC=1" "-DBACKTRACE_SUPPORTS_THREADS=0" "-DBACKTRACE_SUPPORTS_DATA=0" "-DHAVE_DL_ITERATE_PHDR=1" "-D_GNU_SOURCE=1" "-D_LARGE_FILES=1" "-Dbacktrace_full=__rdos_backtrace_full" "-Dbacktrace_dwarf_add=__rdos_backtrace_dwarf_add" "-Dbacktrace_initialize=__rdos_backtrace_initialize" "-Dbacktrace_pcinfo=__rdos_backtrace_pcinfo" "-Dbacktrace_syminfo=__rdos_backtrace_syminfo" "-Dbacktrace_get_view=__rdos_backtrace_get_view" "-Dbacktrace_release_view=__rdos_backtrace_release_view" "-Dbacktrace_alloc=__rdos_backtrace_alloc" "-Dbacktrace_free=__rdos_backtrace_free" "-Dbacktrace_vector_finish=__rdos_backtrace_vector_finish" "-Dbacktrace_vector_grow=__rdos_backtrace_vector_grow" "-Dbacktrace_vector_release=__rdos_backtrace_vector_release" "-Dbacktrace_close=__rdos_backtrace_close" "-Dbacktrace_open=__rdos_backtrace_open" "-Dbacktrace_print=__rdos_backtrace_print" "-Dbacktrace_simple=__rdos_backtrace_simple" "-Dbacktrace_qsort=__rdos_backtrace_qsort" "-Dbacktrace_create_state=__rdos_backtrace_create_state" "-Dbacktrace_uncompress_zdebug=__rdos_backtrace_uncompress_zdebug" "-Dmacho_get_view=__rdos_macho_get_view" "-Dmacho_symbol_type_relevant=__rdos_macho_symbol_type_relevant" "-Dmacho_get_commands=__rdos_macho_get_commands" "-Dmacho_try_dsym=__rdos_macho_try_dsym" "-Dmacho_try_dwarf=__rdos_macho_try_dwarf" "-Dmacho_get_addr_range=__rdos_macho_get_addr_range" "-Dmacho_get_uuid=__rdos_macho_get_uuid" "-Dmacho_add=__rdos_macho_add" "-Dmacho_add_symtab=__rdos_macho_add_symtab" "-Dmacho_file_to_host_u64=__rdos_macho_file_to_host_u64" "-Dmacho_file_to_host_u32=__rdos_macho_file_to_host_u32" "-Dmacho_file_to_host_u16=__rdos_macho_file_to_host_u16" "-o" "/Users/moritz/code/rust-unikernel/target/x86_64-unknown-hermit/debug/build/backtrace-sys-40bab59e68f76f0a/out/src/libbacktrace/elf.o" "-c" "src/libbacktrace/elf.c"
cargo:warning=src/libbacktrace/elf.c:43:10: fatal error: 'link.h' file not found
cargo:warning=#include <link.h>
cargo:warning=         ^~~~~~~~
cargo:warning=1 error generated.
exit code: 1

If the above is expected on non-Linux platforms โ€“ see this issue in backtrace-sys โ€“ I suggest adding a note to the README.md that the instructions in there are Linux-only.

Or adding instructions how to install a toolchain that alleviates it for non-Linux platforms.

Error in installation

I am following the README steps to install the library but I couldn't. I installed the dependencies that are necessary. Also I added these packages:

sudo apt-get install binutils-hermit newlib-hermit pte-hermit-rs gcc-hermit libhermit-rs
apt-get install qemu-system-x86

And finally, I checked that I have installed the library that It gives error:
libmpfr-dev - multiple precision floating-point computation developers tools
libmpfr4 - multiple precision floating-point computation
libgmpv4-dev - Multiprecision arithmetic library developers tools (GCC 4.x compatible)
libmpfrc++-dev - multi-precision floating point number class for C++

Anyway, I receive this error:

carlosb@carlosb-UX530UX ~/Desktop/tools/libhermit-rs/build $ cmake ..
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- The Fortran compiler identification is unknown
/opt/hermit/libexec/gcc/x86_64-hermit/6.3.0/cc1: error while loading shared libraries: libmpfr.so.6: cannot open shared object file: No such file or directory
-- Check for working C compiler: /opt/hermit/bin/x86_64-hermit-gcc
-- Check for working C compiler: /opt/hermit/bin/x86_64-hermit-gcc -- broken
CMake Error at /home/carlosb/Desktop/tools/cmake-3.11.3-Linux-x86_64/share/cmake-3.11/Modules/CMakeTestCCompiler.cmake:52 (message):
  The C compiler

    "/opt/hermit/bin/x86_64-hermit-gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeTmp
    
    Run Build Command:"/usr/bin/make" "cmTC_9ee17/fast"
    /usr/bin/make -f CMakeFiles/cmTC_9ee17.dir/build.make CMakeFiles/cmTC_9ee17.dir/build
    make[1]: Entering directory '/home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeTmp'
    Building C object CMakeFiles/cmTC_9ee17.dir/testCCompiler.c.obj
    /opt/hermit/bin/x86_64-hermit-gcc -Wl,--gc-sections    -o CMakeFiles/cmTC_9ee17.dir/testCCompiler.c.obj   -c /home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeTmp/testCCompiler.c
    /opt/hermit/libexec/gcc/x86_64-hermit/6.3.0/cc1: error while loading shared libraries: libmpfr.so.6: cannot open shared object file: No such file or directory
    CMakeFiles/cmTC_9ee17.dir/build.make:65: recipe for target 'CMakeFiles/cmTC_9ee17.dir/testCCompiler.c.obj' failed
    make[1]: *** [CMakeFiles/cmTC_9ee17.dir/testCCompiler.c.obj] Error 1
    make[1]: Leaving directory '/home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeTmp'
    Makefile:126: recipe for target 'cmTC_9ee17/fast' failed
    make: *** [cmTC_9ee17/fast] Error 2
    

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  cmake/HermitCore.cmake:96 (enable_language)
  CMakeLists.txt:4 (include)


-- Configuring incomplete, errors occurred!
See also "/home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeOutput.log".
See also "/home/carlosb/Desktop/tools/libhermit-rs/build/CMakeFiles/CMakeError.log".

RUSTSEC-2021-0013: Soundness issues in `raw-cpuid`

Soundness issues in raw-cpuid

Details
Package raw-cpuid
Version 8.1.2
URL rustsec/advisory-db#614
Date 2021-01-20
Patched versions >=9.0.0

Undefined behavior in as_string() methods

VendorInfo::as_string(), SoCVendorBrand::as_string(),
and ExtendedFunctionInfo::processor_brand_string() construct byte slices
using std::slice::from_raw_parts(), with data coming from
#[repr(Rust)] structs. This is always undefined behavior.

See gz/rust-cpuid#40.

This flaw has been fixed in v9.0.0, by making the relevant structs
#[repr(C)].

native_cpuid::cpuid_count() is unsound

native_cpuid::cpuid_count() exposes the unsafe __cpuid_count() intrinsic
from core::arch::x86 or core::arch::x86_64 as a safe function, and uses
it internally, without checking the
safety requirement:

> The CPU the program is currently running on supports the function being
> called.

CPUID is available in most, but not all, x86/x86_64 environments. The crate
compiles only on these architectures, so others are unaffected.

This issue is mitigated by the fact that affected programs are expected
to crash deterministically every time.

See gz/rust-cpuid#41.

The flaw has been fixed in v9.0.0, by intentionally breaking compilation
when targetting SGX or 32-bit x86 without SSE. This covers all affected CPUs.

See advisory page for additional details.

detection of virtio devices within RustyHermit

It is possible to run RustyHermit within qemu. For instance, the following starts the test application within qemu:

qemu-system-x86_64 -display none -smp 1 -m 64M -serial stdio -kernel loader/target/x86_64-unknown-hermit-loader/debug/hermit-loader -initrd tests/target/x86_64-unknown-hermit/debug/rusty_tests -cpu qemu64,apic,fsgsbase,pku,rdtscp,xsave,fxsr

Hereby, hermit_loader is a basic loader to initialize the system.

In the C version is already a basic virtio support available. This code snippet detects a virtio device and can be used as template for RustyHermit. Consequently, we have to use qemu with virtio support and modify RustyHermit to detect such a device.

Missing arithmetic functions for f32 and f64

The following hello world program compiles and runs perfectly fine on linux (without hermit) with opt-level set to zero:

use rand::Rng;

fn main() {
    println!("Hello, world!");
	let mut rng = rand::thread_rng();
	let x = rng.gen::<f64>();
	let y: f64 = x.exp();
	let z: f64 = y.log(2.0);
	println!("e^10 = {}, log2(e^10) = {}", y, z);
}

When adding hermit-sys as a dependency and compiling for our custom target with opt-level = 0 (Update: when using a random number linking fails regardless of opt-level):

$ cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit
    Updating crates.io index
   Compiling test_exp v0.1.0 (/home/jonathan/Dev/test_exp)
error: linking with `rust-lld` failed: exit code: 1
  |
  = note: .... (redacted)
  = note: rust-lld: error: undefined symbol: log
          >>> referenced by f64.rs:403 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:403)
          >>>               /home/jonathan/Dev/test_exp/target/x86_64-unknown-hermit/debug/deps/test_exp-85e78a36219e34e3.22gg921bj828b09i.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::ln::_$u7b$$u7b$closure$u7d$$u7d$::h8d76086132c6a7c6)
          
          rust-lld: error: undefined symbol: exp
          >>> referenced by f64.rs:363 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:363)
          >>>               /home/jonathan/Dev/test_exp/target/x86_64-unknown-hermit/debug/deps/test_exp-85e78a36219e34e3.42usio8klobzguuk.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::exp::h6af4cf026acce374)
          

error: aborting due to previous error

error: could not compile `test_exp`.

As far as I can tell the standard library uses compiler intrinsics for exp and log, so maybe they are missing for our target and opt-level 0.

This error might be relevant, since this also leads to rusty-demo failing to compile when using the RUSTFLAGS -Clink-dead-code -Copt-level=0 flags, since the rand crate links to these two functions. This in turn might be relevant, since these flags are important if you want to have accurate code coverage. Update: Since the functions seem to be missing completely, I think this is actually very relevant.

Edit: Okay, there seem to be a lot more functions which don't work without optimizations:

  • fn sys_free_tx_buffer(handle: usize) seems to not be defined rust-lld: error: undefined symbol: sys_free_tx_buffer (this depends on opt-level)
  • Basically all functions in f64 and f32 seem to be affected.
List of linker errors for rusty-demo with -Clink-dead-code ``` rust-lld: error: undefined symbol: floorf >>> referenced by f32.rs:50 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:50) >>> std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::floor::h62d47b5d8a582595) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      rust-lld: error: undefined symbol: ceilf
      >>> referenced by f32.rs:68 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:68)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::ceil::h00f93d25febac2db) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: roundf
      >>> referenced by f32.rs:87 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:87)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::round::h24a1e278e0329ebc) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: truncf
      >>> referenced by f32.rs:107 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:107)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::trunc::h2abe80f3c1c20c2a) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fmaf
      >>> referenced by f32.rs:225 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:225)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::mul_add::haaf051250328cce1) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fmodf
      >>> referenced by f32.rs:250 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:250)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::div_euclid::h96ca000e50e1e265) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      >>> referenced by f32.rs:283 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:283)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::rem_euclid::hbec624b64e0faf2d) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      >>> referenced by arith.rs:561 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/arith.rs:561)
      >>>               core-eb986db391052d85.core.ebjdxfud-cgu.0.rcgu.o:(_$LT$f32$u20$as$u20$core..ops..arith..Rem$GT$::rem::h6d51506b84acdfc8) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libcore-eb986db391052d85.rlib
      >>> referenced by arith.rs:893 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/arith.rs:893)
      >>>               core-eb986db391052d85.core.ebjdxfud-cgu.0.rcgu.o:(_$LT$f32$u20$as$u20$core..ops..arith..RemAssign$GT$::rem_assign::h1a0dbe719120058c) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libcore-eb986db391052d85.rlib
      
      rust-lld: error: undefined symbol: powf
      >>> referenced by f32.rs:320 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:320)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::powf::ha50bc59de6abfeb8) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: expf
      >>> referenced by f32.rs:363 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:363)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::exp::hc00c1895e2a4aca7) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: exp2f
      >>> referenced by f32.rs:382 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:382)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::exp2::h9c92dcbdff3d25b6) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: logf
      >>> referenced by f32.rs:403 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:403)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::ln::h888103fb654b5cca) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log2f
      >>> referenced by f32.rs:448 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:448)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::log2::hd8151d77c6896626) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log10f
      >>> referenced by f32.rs:467 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:467)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::log10::h0086ced65d4989c7) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fdimf
      >>> referenced by f32.rs:501 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:501)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::abs_sub::he21b4754f5bd256c) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: cbrtf
      >>> referenced by f32.rs:520 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:520)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::cbrt::h29a20003137a9dbe) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: hypotf
      >>> referenced by f32.rs:541 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:541)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::hypot::h943dbd5050f1c48c) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: sinf
      >>> referenced by f32.rs:559 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:559)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::sin::h05e3473b4effecde) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: cosf
      >>> referenced by f32.rs:577 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:577)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::cos::he59365039bea615b) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: tanf
      >>> referenced by f32.rs:594 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:594)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::tan::h04d3a7b15b8317b0) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: asinf
      >>> referenced by f32.rs:615 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:615)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::asin::hf7329a8001a5bd60) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: acosf
      >>> referenced by f32.rs:636 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:636)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::acos::hc602671081059e94) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: atanf
      >>> referenced by f32.rs:656 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:656)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::atan::hce624ebbfc5c9880) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: atan2f
      >>> referenced by f32.rs:689 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:689)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::atan2::h951605bebe9f831f) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: expm1f
      >>> referenced by f32.rs:730 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:730)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::exp_m1::hc66c6d33cc262902) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log1pf
      >>> referenced by f32.rs:750 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:750)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::ln_1p::h46910cceafd1f719) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: sinhf
      >>> referenced by f32.rs:772 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:772)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::sinh::hcfab056465788741) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: coshf
      >>> referenced by f32.rs:794 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:794)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::cosh::h04e515503dc3c5c4) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: tanhf
      >>> referenced by f32.rs:816 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f32.rs:816)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f32::_$LT$impl$u20$f32$GT$::tanh::hba45e97c2750a290) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: ceil
      >>> referenced by f64.rs:68 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:68)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::ceil::hcdfc631a678bfb3a) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: round
      >>> referenced by f64.rs:87 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:87)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::round::h9fd7c0c3115eaadd) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: trunc
      >>> referenced by f64.rs:107 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:107)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::trunc::hfe2308f04e36738b) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fma
      >>> referenced by f64.rs:225 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:225)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::mul_add::h4aae479dacf38aab) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fmod
      >>> referenced by f64.rs:250 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:250)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::div_euclid::h9228886410dae87e) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      >>> referenced by f64.rs:283 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:283)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::rem_euclid::hbf512fea4717341b) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      >>> referenced by arith.rs:561 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/arith.rs:561)
      >>>               core-eb986db391052d85.core.ebjdxfud-cgu.0.rcgu.o:(_$LT$f64$u20$as$u20$core..ops..arith..Rem$GT$::rem::h85c67b5dea271dba) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libcore-eb986db391052d85.rlib
      >>> referenced by arith.rs:893 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/arith.rs:893)
      >>>               core-eb986db391052d85.core.ebjdxfud-cgu.0.rcgu.o:(_$LT$f64$u20$as$u20$core..ops..arith..RemAssign$GT$::rem_assign::h5e9d0a7f11b26ae5) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libcore-eb986db391052d85.rlib
      
      rust-lld: error: undefined symbol: pow
      >>> referenced by f64.rs:320 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:320)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::powf::hbd837cb66a570ee4) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: exp
      >>> referenced by f64.rs:363 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:363)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::exp::hb21df079edbceed3) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: exp2
      >>> referenced by f64.rs:382 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:382)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::exp2::hfd1dbcfd627fa046) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log
      >>> referenced by f64.rs:403 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:403)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::ln::_$u7b$$u7b$closure$u7d$$u7d$::h4b2a29d71b83580f) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log2
      >>> referenced by f64.rs:449 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:449)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::log2::_$u7b$$u7b$closure$u7d$$u7d$::hf7f9aebab3c316bd) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log10
      >>> referenced by f64.rs:469 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:469)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::log10::_$u7b$$u7b$closure$u7d$$u7d$::h2d2d212a080dc0e3) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: fdim
      >>> referenced by f64.rs:503 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:503)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::abs_sub::h63fd60b4fd69f1d4) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: cbrt
      >>> referenced by f64.rs:522 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:522)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::cbrt::hef2a833242487fed) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: hypot
      >>> referenced by f64.rs:543 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:543)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::hypot::ha92b21079ae6fbda) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: sin
      >>> referenced by f64.rs:561 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:561)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::sin::hfb06ce40743f8bfe) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: cos
      >>> referenced by f64.rs:579 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:579)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::cos::hcddc6e96d808e5ea) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: tan
      >>> referenced by f64.rs:596 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:596)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::tan::hc72b96c5870564d1) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: asin
      >>> referenced by f64.rs:617 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:617)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::asin::h30d98dd3a05a7226) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: acos
      >>> referenced by f64.rs:638 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:638)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::acos::h956b5807150d1d67) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: atan
      >>> referenced by f64.rs:658 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:658)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::atan::h82b6f9831c4a8895) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: atan2
      >>> referenced by f64.rs:691 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:691)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::atan2::ha4f963a162d9d648) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: expm1
      >>> referenced by f64.rs:732 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:732)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::exp_m1::he58bc5d3a68f1ac8) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: log1p
      >>> referenced by f64.rs:752 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:752)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::ln_1p::h4e70e8f5bebc7cd3) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: sinh
      >>> referenced by f64.rs:774 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:774)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::sinh::h736265c508213ec8) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: cosh
      >>> referenced by f64.rs:796 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:796)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::cosh::he9c4bb2c3c098ce8) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
      
      rust-lld: error: undefined symbol: tanh
      >>> referenced by f64.rs:818 (/home/jonathan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/f64.rs:818)
      >>>               std-56f46232d5762505.std.70pvzhfu-cgu.0.rcgu.o:(std::f64::_$LT$impl$u20$f64$GT$::tanh::h05719a4e8a6484fb) in archive /home/jonathan/Dev/rusty-hermit/target/x86_64-unknown-hermit/debug/deps/libstd-56f46232d5762505.rlib
</details>          

hermit in uhyve can't read processor frequency

On my system using uhyve hermit fails to read the cpu-frequency with detect_from_cpuid and detect_from_cpid_tsc_info.

The first issue is that detect_from_cpuid can return a frequency of 0, which is Some, but not a valid value. This is fixed by #29.
The second issue I encountered is that detect_from_cpid_tsc_info fails with a panic, due to a division by zero here: https://github.com/gz/rust-cpuid/blob/b64cef2bbfd577b2d3e1c65b8ca76456730efa65/src/lib.rs#L3769
Is this something that should be fixed upstream or should we catch the panic on our side (I'm new to rust but I assume that's possible)?

The next method detect_from_hypervisor works fine for me.

Libhermit's use of `halt` and the `panic_handler`

When panicing, RustyHermit loops arch::processor::halt() infinitely. Uhyve treats hlt instructions by shutting down the vm with exit code 0. (hermit-os/uhyve#7)

Related Issue: hermit-os/uhyve#11

RustyHermit should not use arch::processor::halt when running in a VM but use the proper shutdown command.

  • It should probably keep using a hlt loop when running on real hardware so that the error message can be observed on e.g. the monitor.
  • It could write to the shutdown port, so that uhyve shuts down before the hlt-loop. I don't know how real Hardware handles out instructions to a non-existing port.

File mode passed to uhyve is given in hex instead of octal.

The mode in the open hypercall is passed in hex, but it should be passed as octal. This results in strange permissions of files which are created by uhyve.

https://github.com/hermitcore/libhermit-rs/blob/44eaa9f693566413884f505552f74f2e25863e78/src/syscalls/interfaces/mod.rs#L58-L69

Example: 1991 = 0x777 is passed but it should be 511 = 0o777 instead. The flags field is passed correctly.

@tlambertz pointed out that this has to be fixed in the stdlib

Spinlock is Unsound

RustyHermits Spinlock<T> implementation is unsound, since it always implements Sync + Send, no mater what T implements. This behavior was introduced in cf4e955.

Contrary to the commit message, I think this behavior is unsound, since it allows the following to compile:

pub static GLOBAL_WHICH_IS_SEND_AND_SYNC: Option<Spinlock<Rc<u64>>> = None;

This is just an example, but there are ways to construct a non-oneliner of this without the Option<>. Now consider the following:

  • Thread A unlocks the Spinlock, calls Rc.clone(), locks Spinlock again
  • Thread B does the same
  • now both Threads have a reference to 'the same' Rc, which is explicitly neither Send nor Sync (https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-Send), so should not be able to exist across threads. Using it will now lead to race conditions.

Reverting the mentioned commit introduces several issues:

53 | static PCI_DRIVERS: SpinlockIrqSave<Vec<PciDriver>> = SpinlockIrqSave::new(Vec::new());                                                                                                                                       
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `alloc::rc::Rc<core::cell::RefCell<arch::x86_64::kernel::virtio_net::VirtioNetDriver>>` cannot be sent between threads safely         

19 | static PHYSICAL_FREE_LIST: SpinlockIrqSave<FreeList> = SpinlockIrqSave::new(FreeList::new());                                                                                                                                 
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `alloc::rc::Rc<core::cell::RefCell<collections::doublylinkedlist::Node<mm::freelist::FreeListEntry>>>` cannot be sent between th

14 | static KERNEL_FREE_LIST: SpinlockIrqSave<FreeList> = SpinlockIrqSave::new(FreeList::new());
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `alloc::rc::Rc<core::cell::RefCell<collections::doublylinkedlist::Node<mm::freelist::FreeListEntry>>>` cannot be sent between thre

I am currently not sure how to best resolve this issue. Maybe tag the affected structs with unsafe impl Send for FreeList {}. Though that might be dangerous aswell, since it essential is just a DoublyLinkedList which can generate Rc clones. As far as I can see, there are no races currently possible. But that is only because the methods that could race are not used 'by accident', and not because the compiler prohibits this.
KERNEL_FREE_LIST.lock().list.push(entry); is used, so why not KERNEL_FREE_LIST.lock().list.head();, which returns Option<Rc<RefCell<Node<T>>>>

My current workaround is manually marking the structs I protect with a spinlock as Send, so I get the appropriate compiler guarantees without having to fix this issue. I initially constructed something similar to the example above and was wondering why it compiled.

Improve randomness syscalls

The RDRAND code used in generate_random_number32/64 does not contain a workaround for the AMD glitch. You can take a look at the getrandom code for reference.

Also it would be nice if instead of generate_random_number32/64 you will expose a Linux-like interface, i.e. a syscall which will work on buffers.

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.