How to get process-saved registers in Linux (ARM architecture)
I’m writing a program to parse all tasks running on linux, starting with the init_task of each task, I read its task_struct structure, which allows me to get its PID, state, Oncpu…
But I also need to find the registers saved by that task, specifically registers R0 to R10, IP, SP, FP, and PC
Also in task_struct I found a pointer to a structure called cpu_context that saves register R4 to the PC
So the problem is that I don’t know how to get registers R0 to R3
I tried to manually parse the stack of the task, but I didn’t find any relevant values
So here’s my question:
– Where in the stack (or elsewhere in memory) holds registers for tasks that are not running?
– Can I trust the value of register R4 to the PC found in structure cpu_context?
I’m using a development board containing an ARM Cortex A9 MPCore processor (2 cores), linked to the host PC via JTAG link
The board runs Linux Kernel 2.6.35.7+ (of course, this kernel is compiled for the ARM architecture).
ON THE HOST, I USE OPENOCD AND GDB FOR DEBUGGING.
Thanks
Solution
It depends on which set of registers you are interested in.
If you’re interested in user-mode state, check out how ptrace
is implemented. With a quick look at the source code, task_pt_regs
is where you should look. Obviously, they are located near the top of the kernel stack of the task (for example, see vector_swi
; It has a stmia sp near it, starting with {r0 - r12},
followed by storage for sp
and lr
.
If you are interested in kernel-mode state, it is __switch_to
saved to the task->cpu_context
(TI_CPU_SAVE
is the offset of struct thread_info
cpu_context
)。 As another answer already points out, it doesn’t save r0-r3 because it doesn’t have to; The callers of switch_to
assume that they will be destroyed by __switch_to
, so their values do not matter.