Closed
Description
tl;dr: confusion about float ABI in rust-generated RV64 object files
To do a little testing with Rust on Kendryte K210 (RV64GC) without having to write a full BSP, I'm trying to link the output of rust into an existing bare-metal project,
With the following source:
#![no_std]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
#[allow(non_camel_case_types)]
type size_t = usize;
extern {
fn callback_to_c(input: *const u8, input_length: size_t, val: f32);
}
#[no_mangle]
pub extern fn rust_main() {
let x: f32 = 3.0;
let test = "string";
unsafe {
callback_to_c(test.as_ptr(), test.len(), x);
}
}
However, it looks like the output (see flags
is marked as soft-float ABI):
$ rustc +nightly --version
rustc 1.35.0-nightly (2975a3c4b 2019-04-15)
$ rustc +nightly --target riscv64gc-unknown-none-elf --crate-type staticlib --release src/lib.rs
$ readelf -a liblib.a |head -n 20
File: liblib.a(lib.lib.3a1fbbbh-cgu.0.rcgu.o)
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 296 (bytes into file)
---> Flags: 0x1, RVC, soft-float ABI <----
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
This causes the following error during link:
/opt/kendryte-toolchain/lib/gcc/riscv64-unknown-elf/8.2.0/../../../../riscv64-unknown-elf/bin/ld: /home/user/maixgo/rust-test/target/riscv64gc-unknown-none-elf/release/librust_test.a(rust_test-235c1d6ff76f1afc.rust_test.412mpu3z-cgu.0.rcgu.o):
can't link hard-float modules with soft-float modules
The expected value for flags
would be, in this specific case:
Flags: 0x3, RVC, single-float ABI
To be honest I don't know if this is expected or not! For gcc it seems to have to do with the -mabi
flag—I'm not sure what ABI we'd be expecting Rust to generate here:
$ riscv64-unknown-elf-gcc -mabi=lp64d -march=rv64gc test.c -c -o test.o && readelf -h test.o|grep Flags
Flags: 0x5, RVC, double-float ABI
$ riscv64-unknown-elf-gcc -mabi=lp64f -march=rv64gc test.c -c -o test.o && readelf -h test.o|grep Flags
Flags: 0x3, RVC, single-float ABI
$ riscv64-unknown-elf-gcc -mabi=lp64 -march=rv64gc test.c -c -o test.o && readelf -h test.o|grep Flags
Flags: 0x1, RVC, soft-float ABI