rust-embedded / cortex-m-rt

Minimal startup / runtime for Cortex-M microcontrollers
https://rust-embedded.github.io/cortex-m-rt/
Apache License 2.0
358 stars 85 forks source link

"error: cortex-m-rt appears more than once in the dependency graph" #275

Closed bugadani closed 4 years ago

bugadani commented 4 years ago

I've been reading some of the emitted ASM of my application, and I've found that "error: cortex-m-rt appears more than once in the dependency graph" is present in the generated binary (-O3) and is referenced 126 times (63 loads I think) in my assembly. What's up with that, if the error is only there for compile-time?

adamgreig commented 4 years ago

That's odd, the string is the export name of an empty static variable so shouldn't end up in the actual binary output. Is it appearing in the output ELF file or the output raw binary (i.e. cargo objcopy --release -- -O binary test.bin)? What section is it in?

bugadani commented 4 years ago

It seems it isn't present in the binary that objcopy gives me, which is weird because the assembly listing contains a lot of this:

    movw    r2, :lower16:"error: cortex-m-rt appears more than once in the dependency graph"
    mov r0, r1
    movt    r2, :upper16:"error: cortex-m-rt appears more than once in the dependency graph"
    movs    r1, #1
adamgreig commented 4 years ago

I think what's going on might be that because that variable is static and zero-sized, the next static variable is assigned to the same address, and when the disassembler tries to work out what symbol name to display, it picks the wrong one. How are you generating the assembly listing?

bugadani commented 4 years ago

I'm using cargo rustc --release -- --emit asm

adamgreig commented 4 years ago

How about if using cargo objdump --release -- -D? (or arm-none-eabi-objdump).

bugadani commented 4 years ago

It looks like you are right about the symbol being assigned to something else, I see a lot of jumps to the symbol plus a random offset. Sounds odd, but it looks like a harmless quirk.

Although, in the disassembly by objdump, the symbol is listed in different context than when using emit asm... But I guess that's also some tool quirk.

adamgreig commented 4 years ago

Probably the solution is to move to the Cargo.toml links key instead of this "linker hack". The links key didn't exist when the linker hack was added, but it's been in Cargo for a while now so we can probably swap to it and remove the linker hack.

adamgreig commented 4 years ago

Unfortunately this doesn't look like something we can fix any time soon; eventually we can remove __ONCE__ after a few versions exist with the links key, but not before then. It doesn't look like it affects the generated binary written to a device at least.

One workaround for development purposes might be to add a small static to your firmware that ends up mapped to the ONCE address but isn't otherwise used, so that your other references to actual statics still disassemble correctly.

Since there's not much else to do now I'll close this issue; please re-open if further discussion is needed though. Thank you for reporting it!

bugadani commented 4 years ago

It doesn't look like it affects the generated binary written to a device at least.

Fortunately, this does seem the case. Thank you for investigating.