rustc编译RISC-V32IM二进制后llvm-objdump无指令输出问题
Rust编译RISC-V无指令输出问题解决方案
问题原因
- 代码被优化消除:开启
-O优化后,由于#![no_main]声明没有标准库入口,编译器发现main函数未被任何代码引用,连带mult函数也因仅被main调用而被整体优化移除,最终生成的ELF文件中无有效可执行指令。 - 链接器行为导致符号丢弃:裸机
no_std环境下,默认链接器会丢弃未被标记为“需要保留”或未作为入口的符号,即使汇编文件存在指令,链接后也不会保留到最终二进制中。
解决方法
1. 标记函数强制保留
给main和mult添加#[used]属性,告知编译器即使未被引用也要保留这些函数:
#![no_std] #![no_main] use core::panic::PanicInfo; #[panic_handler] fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } #[used] fn mult(a: u32, b: u32) -> u32 { a * b } #[no_mangle] #[used] fn main() -> u32 { mult(3, 4) }
2. 指定链接器入口符号
编译时通过-C link-arg参数告诉链接器将main作为入口点,确保其不会被丢弃:
rustc --target riscv32i-unknown-none-elf -Ctarget-feature=+m -O -C link-arg=-e main simple.rs
3. 验证反汇编结果
重新编译后执行反汇编命令,即可看到预期的指令:
llvm-objdump -d simple
补充说明
- 使用
--emit asm时,编译器仅生成汇编代码,不执行链接阶段的优化,因此汇编文件会保留所有函数代码,但链接成ELF时,未被引用或标记的符号会被链接器丢弃。 - RISC-V GNU Toolchain编译C程序时,默认将
main作为入口点,链接器会自动保留该符号,因此不会出现代码被优化移除的情况。
内容的提问来源于stack exchange,提问作者Tony I.
相关产品推荐
相关产品推荐

