Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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