Linking Rust with C: undefined reference to '__aeabi' functions
Asked Answered
N

1

6

I'm working on a project using Rust on an embedded device, where I'm trying to write functions in Rust that can be called from C. I compile the project without the standard library, more or less following this tutorial: Embedded Rust Right Now!

My Rust code compiles just fine to .o files, but I'm having troubles when trying to link the C and Rust object files together using arm-none-eabi-ld. I get several errors similar to these:

rustfunc.o: In function `func':
rustfunc.0.rs:(.text.hash+0x18): undefined reference to `__aeabi_memclr8'
...
/rust/src/libcore/slice.rs:1446: undefined reference to `__aeabi_memcpy'
/rust/src/libcore/fmt/num.rs:196: undefined reference to `__aeabi_memclr4'

What puzzles me the most is that even though I'm just linking object files together, the errors reference both my Rust code, and code from libcore.

Does anybody have an idea what these errors mean and why the linker cannot resolve these issues? Thanks!

Ngo answered 18/7, 2015 at 18:13 Comment(6)
Looks like a missmatch in the ABIs. I'd check if they are compatible or need wrappers. The symbols sems to be some libgcc special versions of memclr (which is a special variant of memset) and memcpyPronunciation
As a newbie to this, could you point me in the direction to look for checking this?Ngo
That depends on the OS and CPU and compiler settings. For ARM, current PCS is AAPCS and the ABI specs (free download), but gcc allows for some others, too. That is valid for C and some other languages, but no idea about Rust.Pronunciation
I'm working on this issue now. Did you solve it? I think we need to see a bit more of your code - cargo.toml, makefile, etc. My theory is that the arm-none-eabi tools work slightly differently than thumbv7. There are asm versions of these routines (builtins for llvm) out there.Ludie
No, didn't solve it. The code is here: github.com/halseth/embedded_rust The architecture I use is ARM Cortex-M0, which is thumbv6m I believe.Ngo
To add to that. That code repo is just used to build the Rust code, into object files. I end up with sha256.o, but the problem arises when I try to link this into my C-project. Cannot provide the whole Makefile for that link process unfortunately, as it has some proprietary code, but can provide snippets if I know what to look for.Ngo
L
8

The problem is that LLVM, which your rustc (and possibly your cc) is built on, references compiler builtins or sometimes intrinsics, which are small helper routines that the compiler assumes will have been optimised for the target platform.

Usually they come with the compiler, so you'll see a lot of commentary out on the 'Net saying "why don't you link with libgcc.a". This seems unhelpful for bare-metal projects, and in fact won't work, because LLVM calls slightly different builtins than gcc.

You can provide implementations for these routines, and a true bare metal OS should probably spend about five minutes contemplating it. You can write them in assembly or Rust:

// Use this at your peril
#[no_mangle]
pub unsafe extern fn __aeabi_memclr4(s: *mut u8, n: usize) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *s.offset(i as isize) = 0u8;
        i += 1;
    }
    return s;
} 

After you've finished dreaming, you set about compiling llvm's compiler-rt (equivalent to libgcc.a) for your target and you link that.

Until rustc and multirust increase their support for installing extra targets for cross-compilation, you have to download the Rust source and try to build the cross-compiler and libs (including compiler-rt) yourself.

Currently arm-none-eabi is not a supported target, and building is rough for a list of reasons, including that arm-none-eabi-gcc won't link an executable, which Rust's jemalloc insists on. My workaround is to harvest the source files from compiler-rt and build and link them individually.

Ludie answered 15/12, 2015 at 11:38 Comment(3)
I'm gonna mark this as the accepted answer since it explains why I ran into problems. Definitely let me know if you come up with a complete solution! Thanks.Ngo
It's not going well, but I am a rust/llvm/os novice.Ludie
Thanks to @Shepmaster for some quality edits, and raising the bar.Ludie

© 2022 - 2024 — McMap. All rights reserved.