Skip to content

Rust with [no_std] & CustomAllocator -> rust_oom either undefined in link stage or already defined in compile stage :/ #63348

Open
@2ndTaleStudio

Description

@2ndTaleStudio

Hi there,

i'm a bit new to rust and writing a library for embedded Raspberry Pi bare metal programming. I'm completely using #![no_std] in all of my crates. However, at a certain point functions of the alloc crate are needed. So I came accross the option to implement a custom GlobalAllocator as per the doc: (https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html).

However, when compiling this the crate also requires an alloc_error_handler present like so:

#![no_std]
#![feature(alloc_error_handler)]

#[global_allocator]
static ALLOCATOR: RusPiRoAllocator = RusPiRoAllocator;
[...] here comes the implementation of the allocator [...]
#[alloc_error_handler]
fn alloc_error_handler(_: Layout) -> ! {
    // TODO: how to handle memory allocation errors?
    loop { }
}

However, doing so compilation works fine, but using this crate in an actual binary to be build as a dependency lead to the linker error undefined reference to 'rust_oom'.

So well I just put this into the code as well:

#[alloc_error_handler]
fn alloc_error_handler(_: Layout) -> ! {
    // TODO: how to handle memory allocation errors?
    loop { }
}

#[no_mangle]
fn rust_oom() -> ! {
    // well, currently there is nothing we could do on out-of-memory other than halt the core
    loop { }
}

BUT, doing so the compiler complains that the function rust_oom has already being defined. So for whatever reason the compiler seem to optimize the rust_oom function away before linking. As a workaround I put the rust_oom function into a separate crate the allocator crate depends on. (you can find the whole code here: ruspiro-allocator.

With this workaround in place the building of the binary works fine as long as the ruspiro-allocator crate is a direct dependency of it. I would rather like to bundle other crates of mine into a new crate that makes it easier to consume and may need only one dependency in the binary to be created with some feature gates but not many...

So I created a crate, lets call it kernel-crate that represents the final binary to be build. This crate has a dependency to a library-crate which depends on allocator-crate.
In this scenario the linker will again complain that the reference to rust_oom is undefined. So somewhere down the route the function seem to be optimized away again...
But if kernel-crate directly depends on allocator-crate everything works fine....

I would appreciate if someone could shed a light on the issue and how to solve it properly.

Btw. I'm building for the target armv7-unknown-linux-gnueabihf, cross compiling from a windows host machine with cargo version:

cargo 1.38.0-nightly (677a180f4 2019-07-08)

Any hint would be much appreciated...
Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-allocatorsArea: Custom and system allocatorsA-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.O-bare-metalTarget: Rust without an operating systemT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions