ARM Static Base Register

Hi all,

I’m trying to see if I can use a global static base register instead of PC-relative addressing. I see that I can easily reserve R9 in the ARM Subtarget, but this doesn’t let me use it. I found a TODO in ARMAsmPrinter.cpp that refers to this:

// TODO: We currently only support either reserving the register, or treating
// it as another callee-saved register, but not as SB or a TLS pointer

Has anyone tried to do this before? Any pointers or suggestions? I figured I would check with the list before diving into implementation.


Hi Stephen,

We have a set of downstream patches that probably do what you want, and I am planning on sending them upstream once I am done with ARMv8.2-A.

Our patches implement what we refer to as ROPI and RWPI (read-only and read-write position independence). ROPI causes all read-only data to be addressed PC-relative, and RWPI causes all read-write data to be accessed R9-relative. These are orthogonal, so can be used individually or together. If one of them is not used, then that data will be accessed by absolute address (as per the existing static relocation model).

The ARM backend patch for this is quite small and self-contained, ~120 lines. This works for most cases, but if any global variables are initialised to the address of another global, will cause a silent miscompilation. For example:

int a;

int *b = &a;

We have a larger patch (~350 lines) in clang which solves this by emitting dynamic initialisers for variables like b, using the existing C++ dynamic initialiser mechanism. It could also be solved by emitting a relocation for b, and expecting a dynamic loader to fix up all values like this before the program starts executing. We went with the former to avoid the need to include a dynamic loader for very small embedded systems, and because our customers have existing code that they do not want to have to modify too much (this feature has also been in ARM Compiler 5 for a long time).

Does this sound like it would work for your use case?


Hi Oliver,

Thanks so much for the response. I’m glad to hear it’s feasible!

Your use-case has significant overlap with mine, although I’m looking to use R9-relative addressing for all global references instead of just for RW data. I’m looking to make all global data and other functions arbitrarily relocateable at load-time, and need a PLT/GOT-like structure at R9 to indirect references. I’d love to look at your patches and see how you implemented RWPI though (especially the backend changes). Would you be willing to post preliminary patches or something? While I’m not sure I can use your patches directly, I’m sure they would put me on the right track.