On an ARMv7-A processor, I am looking for a simple way to determine the current mode of the processor (User, Supervisor, IRQ, etc) from any mode. This will allow me to dynamically decide whether to perform certain actions, such as making a supervisor call or performing an action directly.
At first glance, this seemed simple. The CPSR
contains the (M
) mode bits, which determine the processor mode.
Section B1.3.3 (Program Status Registers), on page 1150 of the revision C.b of the ARMv7-A Architecture Reference Manual, states:
This field can be written only at PL1 or higher. Its value can be read in any mode, but ARM deprecates software executing at PL0 making any use of its value, or attempting to change it.
So, use of the the CPSR.M
bits is deprecated in user mode, but should work.
However, moving on to actually reading the CPSR using MRS
(which is the only way I know of). Section B9.3.8 (MRS) on page 1988 of the ARM states:
An MRS that is executed in User mode and accesses the CPSR returns an UNKNOWN value for the CPSR.{E, A, I, F, M} fields.
Since these fields are unknown, there does not seem to be a way of reading the mode bits from user mode. Is there some alternate way to read the CPSR from user mode, or some alternate way to determine which mode code is executing?
I could likely instrument the undefined instruction exception, and attempt an instruction illegal in user mode, but I am hoping that there is a better way.