japaric/f3

unsupported relocation on symbol

wezm opened this issue · 7 comments

wezm commented

Hi Jorge,

First up thanks for all the great embedded rust work you've done. I've been working though the process to create a crate f0 akin to this one but for Cortex-M0 generated by svd2rust. When compiling I get:

LLVM ERROR: unsupported relocation on symbol

It's triggered by default_handler_entry_point, specifically the branch instruction. It appears I'm encountering Bug 30279. The fix was added to LLVM in r280651. I expect that this will take a while to trickle down to rustc.

I'm a bit out of my depth at this point. From what I understand I need locate the _default_exception_handler_impl symbol closer to _default_exception_handler_impl. Is there any linker script magic that can be done that might work around the issue?

First up thanks for all the great embedded rust work you've done.

❤️

I've been working though the process to create a crate f0 akin to this one but for Cortex-M0 generated by svd2rust

Awesome!

LLVM ERROR: unsupported relocation on symbol

Interesting. Just to confirm, are you using the built-in thumbv6m-none-eabi target? Or are you supplying your own target using a .json file. If the later, make sure you are setting relocation-model to static.

It's triggered by default_handler_entry_point, specifically the branch instruction.

The assembly in that function is using the b instruction. The Cortex-M4 (F3) and the Cortex-M0 (F0) have different architectures. The Cortex-M4 can jump in the range (−16 MB to +16 MB) using the B
instruction whereas the Cortex-M0 can only jump in the range (−2KB to +2KB) using the same instruction. So, you could try the bl instruction in your f0 crate, with that instruction it's possible to jump in the (-16MB to +16MB) range just like the Cortex-M4 does.

Is there any linker script magic that can be done that might work around the issue?

Yes. This should work, I think:

     /* Entry point: reset handler */
     _reset = .;
     KEEP(*(.text._reset));
+    KEEP(*(.text._default_exception_handler));
+    KEEP(*(.text._default_exception_handler_impl));

     *(.text.*);
     *(.rodata.*);

That should put the impl symbol right next to the _default_exception_handler symbol.

I expect that this will take a while to trickle down to rustc.

I expect we'll do a LLVM up (from 3.9 to 4.0) in November. If not, you could request backporting the patch if you confirm that it indeed solves the problem you are seeing.

wezm commented

Just to confirm, are you using the built-in thumbv6m-none-eabi target? Or are you supplying your own target using a .json file. If the later, make sure you are setting relocation-model to static.

I did see a mention that the thumbv6 target was supposed to be built in now but when I ran rustc --print target-list I didn't see it so I stuck with a custom one. That one does have relocation-model set to static. I updated my nightly compiler yesterday when I ran into this issue and I note that the thumb targets are now listed.

So, you could try the bl instruction in your f0 crate

Using the long branch does seem to fix it (it compiles now). The error still happened when using b with _default_exception_handler_impl and _default_exception_handler added to the linker script. So I think I'll just stick with bl and do some more testing.

Thank you so much for your help.

Using the long branch does seem to fix it (it compiles now).

Awesome!

The error still happened when using b with _default_exception_handler_impl and _default_exception_handler added to the linker script.

Weird. Are the symbols one next to the other when you look at the disassemble (objdump -Cd)? Oh, wait I guess there's nothing to disassemble if this hits an LLVM error -- not even a foo.o is generated.

Yeah, I guess this needs to be fixed in LLVM proper. Or rather we need to update our LLVM fork.

Thank you so much for your help.

You are welcome!

I've fallen over the same issue, working on support for the Freescale Kinetis KE06Z.

I expect we'll do a LLVM up (from 3.9 to 4.0) in November.

Hahaha ha ... (me being naive)


@thejpster Could you open an issue in the rust-lang/rust repo with a small repro file. Seems like the patch @wezm linked shouldn't be too hard to backport. Then I can take it from there.

I'll take a look later.

For now, I just replaced my b with a bl in my hardfault handler code and it's OK.