Could ARMv4T support be added?

Currently, LLD doesn’t support ARMv4T. The oldest ARM supported is ARMv5T. Because of this, when building a program for the GameBoy Advance the GNU Binutils linker is required.

Would it be possible for LLD to support to be expanded in this area?

It is in fact possible to link GBA programs using lld. What is not possible is mixing ARM and Thumb code. So what I’ve done is only use ARM code (because that’s what runs at startup). The linker will produce a warning, but as long as you’re not mixing the two states you can ignore it.

I hope that helps!

EDIT: I just see I’m rate late with this reply. Well, I hope it helps someone!

Unfortunately, “write the entire program using ARM code” is not a practical solution. There’s a very real code size penalty, and thus also a performance penalty, in doing this.

⚙ D139888 [lld][ARM] support absolute thunks for Armv4T Thumb and interworking will add the support.

1 Like

Excellent! I’ll follow that PR as it goes.

That PR landed :slight_smile:

Let me know if you hit upon any issues. I did find a bug where there’s a slight chance you might get an out of range error (for which I’ll put up a patch soon), but with the GBA memory constraints and the way that memory is laid out, I think you’d have to put in some work to recreate the conditions for that to trigger.

I also recently patched up compiler-rt for it to generate a runtime environment for v4t. The best way to build that is to use my local version of the LLVM embedded toolchain for Arm, which includes building for v4T (I’ll also try to upstream that): GitHub - stuij/LLVM-embedded-toolchain-for-Arm: A project dedicated to build LLVM toolchain for 32-bit Arm embedded targets.

That will also build you a complete C/C++ LLVM toolchain for Armv4T:

I’ve now also put up a patch review to do the same for position independent code:

Relatedly, I just pushed a fix (747fc27) for v4/v5/v6 where a b.w would be generated (not supported for these arches) if a range extension is needed and the distance between thunk section and target is smaller than b.w (the bug I referred to in my previous comment). So this would affect jumps spanning more than 32MB. Seeing the lack of a bug report, I guess this doesn’t happen very often.

For me the way I’d end up testing it is when Rust eventually upgrades their shipped version of LLVM to be whatever version of LLVM your patch ends up in. I don’t actually use C/C++ myself.