I'm trying to compile the following code in a binary crate using the riscv32-imc toolchain and the default linker script (that is, I haven't added anything to link-arg yet):
But when I do the resulting elf file doesn't contain any .text section, it's just got some debugging bits in it. Looking at the intermediate .o file it's correctly generated the code, it just seems like the final link step is optimizing it out or otherwise dropping it.
Am I doing something obviously wrong? Subtly wrong?
What default linker script are you using? Can you give us a link to it?
What you're describing will happen if the linker script doesn't use the name "start" for the entry point, or doesn't contain an appropriate KEEP directive for it. If the linker script was not designed for embedded use (e.g. it targets RISC-V Linux), for example, it will be expecting _start and likely putting your entry point at the wrong address.
I'm using the default linker script from riscv32imc-unknown-none-elf, or at least believe I am because I'm not specifying any kind of override for it. But, you were right. The default linker script evidently specifies ENTRY(_start), and having:
#[no_mangle]
fn _start() -> ! {
does end up with the symbol in the final ELF. And now using a custom linker script with a custom ENTRY (and #[no_mangle]) on that symbol does work.
The part that confused to me is #![feature(start)] and #[start], which I thought was aliasing the fn I used it on to something that was declared ENTRY in the linker script but that appears to have been a wrong assumption. Thanks for pointing me the right direction!