66 lines
1.3 KiB
ArmAsm
66 lines
1.3 KiB
ArmAsm
|
|
||
|
.globl _check_context_loop
|
||
|
.globl _remaining_invocations
|
||
|
.globl _origstate
|
||
|
.globl _newstate
|
||
|
|
||
|
#define JUNK 0xCC0FFEE0
|
||
|
|
||
|
#define COPY(dest, offset) \
|
||
|
mov $dest, %ebp ; \
|
||
|
mov 4*offset(%esp), %ebx ; \
|
||
|
mov %ebx, 4*offset(%ebp) ;
|
||
|
|
||
|
/* Copy the result of a pusha to dest. */
|
||
|
#define COPYA(dest) \
|
||
|
COPY(dest, 0); COPY(dest, 1); COPY(dest, 2); COPY(dest, 3); \
|
||
|
COPY(dest, 4); COPY(dest, 5); COPY(dest, 6); COPY(dest, 7);
|
||
|
|
||
|
.text
|
||
|
/* void check_context_loop() */
|
||
|
_check_context_loop:
|
||
|
/* Save original context so we can restore it. */
|
||
|
pusha
|
||
|
|
||
|
/* Put some junk in the registers.
|
||
|
* We want to junk the state, and junk it differently per reg,
|
||
|
* so it's likelier corruption is actually detected. We can't
|
||
|
* touch %esp but we can verify that it doesn't change from its
|
||
|
* current value.
|
||
|
*/
|
||
|
mov $JUNK+1, %eax
|
||
|
mov $JUNK+2, %ebx
|
||
|
mov $JUNK+3, %ecx
|
||
|
mov $JUNK+4, %edx
|
||
|
mov $JUNK+5, %ebp
|
||
|
mov $JUNK+6, %esi
|
||
|
mov $JUNK+7, %edi
|
||
|
|
||
|
/* Save the junked state so we can compare it. */
|
||
|
pusha
|
||
|
cont:
|
||
|
/* Check if we're done. */
|
||
|
cmpl $0, (_remaining_invocations)
|
||
|
jz done
|
||
|
|
||
|
/* We're not done. */
|
||
|
|
||
|
/* Restart loop. */
|
||
|
jmp cont
|
||
|
|
||
|
done:
|
||
|
/* Save the junked, but should be unmodified state
|
||
|
* so we can copy it.
|
||
|
*/
|
||
|
pusha
|
||
|
COPYA(_newstate);
|
||
|
popa
|
||
|
|
||
|
/* copy and restore junked state */
|
||
|
COPYA(_origstate);
|
||
|
popa
|
||
|
|
||
|
/* restore original state and return */
|
||
|
popa
|
||
|
ret
|