Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARM. Access user R13 and R14 from Supervisor mode

How do I access the user R13 and R14 which are saved when supervisor mode is entered? I am using an ARM7TDMI.

I.E. I do not want to access supervisor R14 which now contains the return address to user mode, instead want the value of user mode's link register. This is part of a debugger I am writing.

Are there special aliases for these registers?

Thanks

like image 736
Tarski Avatar asked Nov 27 '08 21:11

Tarski


2 Answers

I'll describe the answer for your specific question but the same approach applies to other modes as well.

You'll need to change the processor mode by changing the mode bits in the CPSR to system mode. This will give you access to user mode's SP/LR (R13 & R14). Remember that system mode is privileged, but its R13 and R14 are the same as user mode's R13 and R14.

Once you're in system mode, read R13 and R14 and put them where you want. Then just switch the mode bits back to your previous mode (I believe that was supervisor mode in your example) and you're good to go.

Note that we did not switch from supervisor to user mode. If you switched from supervisor to user, you couldn't get back to supervisor mode. (Otherwise there would be no protection from user code escalating privilege). That's why we used system mode -- system mode is privileged, but the registers are the same as user mode.

You can switch between any of the privileged modes at will by manipulating the mode bits in the CPSR. I think they're the lower 5 bits? I'm on the road & don't have the info at my fingertips. Otherwise I would have provided you with the assembly code for what I've described above. Actually, if you want to put some hair on your chest, take what I've given you above, implement it, test it, and post it back here. :-D

(One thing I should add for the "general case" (yours is very specific) -- you can examine the SPSR to see "where you came from" -- and use that to determine which mode you need to switch to.)

By the way, I just did this recently for one of my customers.... small world, I guess.

like image 187
Dan Avatar answered Nov 17 '22 00:11

Dan


I've discovered a better way: -

When doing a STM, if r15 isn't one of the operands then ^ gives access to user-mode registers. However, autoincrementing doesn't seem to work within the instruction, and a nop is required afterwards if you want to access the register bank.

Something like

stmfd r13, {r13-r14}^ ;store r13 and r14 usermode
nop
sub r13, r13, #8      ;update stack pointer
like image 43
Tarski Avatar answered Nov 17 '22 00:11

Tarski