Open
Description
Here's a minimal reproducer for the issue described in the title.
.cargo/config.toml
:
[build]
target = "riscv32imc-unknown-none-elf"
[unstable]
build-std = ["core,panic_abort"]
memory.x
(exact contents unimportant, but provided for convenience):
MEMORY
{
IMEM : ORIGIN = 0x80000000, LENGTH = 1024K
DMEM : ORIGIN = 0x10000000, LENGTH = 256K
}
REGION_ALIAS("REGION_TEXT", IMEM);
REGION_ALIAS("REGION_RODATA", DMEM);
REGION_ALIAS("REGION_DATA", DMEM);
REGION_ALIAS("REGION_BSS", DMEM);
REGION_ALIAS("REGION_HEAP", DMEM);
REGION_ALIAS("REGION_STACK", DMEM);
build.rs
:
use std::env;
use std::fs;
use std::path::Path;
fn main() {
let out_dir = env::var("OUT_DIR").expect("No out dir");
let dest_path = Path::new(&out_dir).join("memory.x");
fs::write(dest_path, include_bytes!("memory.x")).expect("Could not write file");
if env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "riscv32" {
println!("cargo:rustc-link-arg=-Tmemory.x");
println!("cargo:rustc-link-arg=-Tlink.x");
}
println!("cargo:rustc-link-search={out_dir}");
println!("cargo:rerun-if-changed=memory.x");
println!("cargo:rerun-if-changed=build.rs");
}
src/main.rs
:
#![no_std]
#![no_main]
use riscv_rt::entry;
#[entry]
fn main() -> ! {
loop {}
}
#[panic_handler]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[unsafe(export_name = "ExceptionHandler")]
fn exception_handler(_: &riscv_rt::TrapFrame) -> ! {
loop {}
}
#[unsafe(export_name = "DefaultHandler")]
fn default_handler(_: &riscv_rt::TrapFrame) -> ! {
loop {}
}
Cargo.toml
:
[package]
name = "lto-bug-repro"
version = "0.1.0"
edition = "2021"
[profile.release]
lto = true # Commenting out this line should allow it to compile successfully
[dependencies]
riscv-rt = "0.13.0"
As is documented in riscv-rt
, ExceptionHandler
and DefaultHandler
are weak symbols, and I verified in the source code for the crate that they're marked with .weak
in global_asm!
(relevant src). What I don't understand is why enabling lto = true
causes the build to fail with the errors
error: DefaultHandler changed binding to STB_GLOBAL
error: symbol 'DefaultHandler' is already defined
error: ExceptionHandler changed binding to STB_GLOBAL
error: could not compile `lto-bug-repro` (bin "lto-bug-repro") due to 3 previous errors
I also have no idea how to track down what's causing this.