8

The "ARM Architecture Procedure Calling Standard" (AAPCS/EABI) states (5.1.1) that

"The role of register r9 is platform specific."

but

"A virtual platform [...] may designate r9 as an additional callee-saved
 variable register, v6."

The question is: does the Linux kernel use r9 for some special purpose? Or is it used as a normal nonvolatile register?

Mircea
  • 1,841
  • 15
  • 18

3 Answers3

1

A simple way of finding out how the kernel uses it is to simply build a kernel (CROSS_COMPILE=... ARCH=arm make vmlinux), and then disassemble the whole thing,

${CROSS_COMPILE}objdump -d vmlinux.o | grep 'sb|r9'

to check (Using both r9 and sb names as it depends on your objdump what exactly is output).

If you ever find it used in prologue / epilogue code (in instructions like push {..., r9, ...}, stmfd sp!, {..., r9, ...} or their corresponding pop/ldmfd) then it's callee-saved. Otherwise, just another scratch reg. The result may depend on your toolchain, kernel config options, or ARM target.

That said, if you compile a Thumb-2 kernel, it will not be callee-saved. That's because Thumb-2 push/pop only operate on the lower reg set (and lr/pc in a complementary fashion, push lr paired with pop pc).

FrankH.
  • 17,675
  • 3
  • 44
  • 63
  • Thanks for the hint! I wouldn't do it for vmlinux since it includes the scheduler bits. But a `objdump -DS -M reg-names-std net/core/dev.o | grep push | grep r9` (non-arch code) shows quite some entries, so it's safe to assume that `r9` is a nonvolatile register. – Mircea Oct 26 '11 at 12:56
  • If you use "-S" in objdump it intersperses the code with source; for a Linux tree, that'll make the output _enormously long_ ... combined with "-D" it disassembles data sections as well (not just code like "-d"), making it even longer. Just "-d", on the other hand, is practical/useful on a Linux kernel. – FrankH. Oct 28 '11 at 14:16
  • I know. But I was doing it on _one_ object file :) – Mircea Oct 28 '11 at 15:14
  • Thumb2 information is wrong. Thumb1 (original on ARMv4 and ARMv5) have restriction on register use in Thumb mode. *Thumb2* (a nebulous concept) which is found on ARMv6 and later has a mixed 16/32bit instruction stream and can save/restore r9. Also, the question state AAPCS/EABI and this is for non-Thumb1 code. – artless noise Jun 17 '22 at 13:35
  • Also, the OPs use of this information is wrong. Just a hit of `r9` in `grep` is not sufficient. You need to see stack operations. A correct answer is determined by the compiler and libc; Linux itself can support either. On a system you could see both. Just because one binary has stack use of r9 does not mean that the program you build will not use it. The `objdump`/`grep` combination should be performed on output from your tools. – artless noise Jun 17 '22 at 13:39
0

TL;DR - It depends on the libc and compiler options. For most ARM Linux distribution, the answer is it is a callee saved register.

Only deeply embedded libcs and tools might use a static base.

The linux kernel itself does not use static base and r9 is free to use.

It is unclear whether the question is for user processes or for kernel developers.


The register sb stands for static base. It is a reference to static data (including program globals). For some systems, you might have multiple processes which share the same code, but need different static base. For instance, a network gateway might have a process for each port with the static base containing the state for that port.

As Linux with VM can remap the physical store to a demanded location, it is an alternative to static base. If you ran on an NOMMU system, such as a Cortex-M version of Linux, it is possible that it could use sb. This is not part of the actual OS and Linux's responsibility. It will just save/restore r9 on context switches. So the actual answer is that it depends on the libc.

It is possible to use GOT and other RAM thunks. But it might be most efficient with NOR flash or ROM in deeply embedded devices to use the static base. For something like a Raspberry Pi, Beagle bone, Android phone, etc. It will have an MMU and there is no need for the gymnastics of a static base.

You may use objdump -d my_code | grep -E '(sb|r9)' to determine STACK use of r9. Just a hit of r9 in grep is not sufficient. You need to see stack operations. On a system you could see both. Just because one binary has stack use of r9 does not mean that the program you build will not use it. The objdump/grep combination should be performed on output from your tools.

A correct answer is determined by the compiler and libc; Linux itself can support either. You should look at the libc documentation. In fact, gcc supports the sb use by using different options such as,

  • -mpic-register=
  • -mpic-data-is-text-relative
  • -msingle-pic-base

https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html


U-boot uses a static base for instance. It is quite possible for a static binary to use a static base and other program on the same system to have general purpose r9 use. Linux has some nomenclature about ABI use, but is mainly to do with system call mechanics and not register use.

For certain, the Linux kernel will not manage the sb/r9 register. It would need to be managed and set by the libc loader which would call map, sbrk, etc to set an initial sb before the processes main() runs or in the case of a static binary, by program startup code.

See: Static shared libraries for more technical details.

artless noise
  • 21,212
  • 6
  • 68
  • 105
0

I think the register definitions are stored in include/asm-arm/ptrace.h

Not sure 100% though...

Trevor Arjeski
  • 2,108
  • 1
  • 24
  • 40
  • Yes, they are there. I don't see anything special about it, but this is not a guarantee. Take PowerPC, for example: ptrace.h has the pt_regs with all GPRs in an array. BUT r2 is the `current()` task in process context :) – Mircea Oct 24 '11 at 21:08
  • 1
    Weird, I was reading an article about it and ARM seems to say that ptrace.h has all the register definitions. Sorry I couldn't be of any help, but http://infocenter.arm.com might be contain this info. It might also depend on which ARM processor you're using. – Trevor Arjeski Oct 24 '11 at 21:34