'cargo/rustc produces no_std ELF without compiled functions (riscv32i-unknown-none-elf)

Given this .cargo/config:

[build]
target = "riscv32i-unknown-none-elf"

and this main.rs:

#![no_std]
#![no_main]
use core::arch::global_asm;

global_asm!(".globl _start

.section \".text\"

_start:
    call      rust_main
");

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {

    }
}

#[no_mangle]
pub extern "C" fn rust_main() -> ! {
    loop {
        test();
    }
}

fn test() {
    unsafe {
        (0 as *mut u32).write(42);
    }
}

cargo build --release produces a binary where all rust functions are missing:

$ riscv64-unknown-elf-objdump -d ./target/riscv32i-unknown-none-elf/release/BINARY_NAME

./target/riscv32i-unknown-none-elf/release/BINARY_NAME:     file format elf32-littleriscv


Disassembly of section .text:

000110b4 <_start>:
   110b4:       00000097                auipc   ra,0x0
   110b8:       008080e7                jalr    8(ra) # 110bc <rust_main>

000110bc <rust_main>:
   110bc:       c0001073                unimp

However the linker appears to be "finding" rust_main, because if I change just the function name, the linking fails because the then undefined symbol.

Am I missing something, or is this a bug in the rust buildchain? Rust was installed with rustup, cargo version cargo 1.60.0-nightly (25fcb135d 2022-02-01).



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source