svc: print values, trace interrupt

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-02-20 00:00:01 +00:00
parent 2b93b18646
commit 7c2a9c0e9c
4 changed files with 137 additions and 6 deletions

View File

@@ -11302,9 +11302,11 @@ output:
3
....
==== ARM exception handling
==== svc
Setup a handler for `svc`, do an `svc`, and observe that the handler got called and returned from C and assembly:
This is the most basic example of exception handling we have.
We a handler for `svc`, do an `svc`, and observe that the handler got called and returned from C and assembly:
....
./run --arch aarch64 --baremetal arch/aarch64/svc
@@ -11316,14 +11318,100 @@ Sources:
* link:baremetal/arch/aarch64/svc_asm.S[]
* link:baremetal/arch/aarch64/svc.c[]
Output for the C one:
Sample output for the C one:
....
daif 0x3c0
spsel 0x1
vbar_el1 0x0
vbar_el1 0x40000800
lkmc_vector_trap_handler
exc_type 0x11
exc_type is LKMC_VECTOR_SYNC_SPX
ESR 0x56000000
SP 0x4200bba8
ELR 0x40002470
SPSR 0x600003c5
x0 0x0
x1 0x1
x2 0x14
x3 0x14
x4 0x40008390
x5 0xfffffff8
x6 0x4200ba28
x7 0x0
x8 0x0
x9 0x13
x10 0x0
x11 0x0
x12 0x0
x13 0x0
x14 0x0
x15 0x0
x16 0x0
x17 0x0
x18 0x0
x19 0x0
x20 0x0
x21 0x0
x22 0x0
x23 0x0
x24 0x0
x25 0x0
x26 0x0
x27 0x0
x28 0x0
x29 0x4200bba8
x30 0x4000246c
....
Both QEMU and gem5 are able to trace interrupts in addition to instructions, and it is instructive to enable both and have a look at the traces:
....
./run \
--arch aarch64 \
--baremetal arch/aarch64/svc_asm
-- -d in_asm,int \
;
....
contains:
....
----------------
IN:
0x40002060: d4000001 svc #0
Taking exception 2 [SVC]
...from EL1 to EL1
...with ESR 0x15/0x56000000
...with ELR 0x40002064
...to EL1 PC 0x40000a00 PSTATE 0x3c5
----------------
IN:
0x40000a00: 14000225 b #0x40001294
....
and:
....
./run \
--arch aarch64 \
--baremetal arch/aarch64/svc_asm \
--trace ExecAll,Faults \
--trace-stdout \
;
....
contains:
....
4000: system.cpu A0 T0 : @main+8 : svc #0x0 : IntAlu : flags=(IsSerializeAfter|IsNonSpeculative|IsSyscall)
4000: Supervisor Call: Invoking Fault (AArch64 target EL):Supervisor Call cpsr:0x3c5 PC:0x80000808 elr:0x8000080c newVec: 0x80001200
4500: system.cpu A0 T0 : @vector_table+512 : b <_curr_el_spx_sync> : IntAlu : flags=(IsControl|IsDirectControl|IsUncondControl)
....
So we see in both cases that the `svc` is done, then an exception happens, and then we just continue running from the exception handler address.
The vector table format is described on <<armarm8>> Table D1-7 "Vector offsets from vector table base address".
A good representation of the format of the vector table can also be found at <<programmers-guide-for-armv8-a>> Table 10-2 "Vector table offsets from vector table base address".

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#svc */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
@@ -7,7 +9,46 @@
int myvar = 0;
void lkmc_vector_trap_handler(LkmcVectorExceptionFrame *exception) {
puts("trap handler");
puts("lkmc_vector_trap_handler");
printf("exc_type 0x%" PRIx64 "\n", exception->exc_type);
if (exception->exc_type == LKMC_VECTOR_SYNC_SPX) {
puts("exc_type is LKMC_VECTOR_SYNC_SPX");
}
printf("ESR 0x%" PRIx64 "\n", exception->exc_esr);
printf("SP 0x%" PRIx64 "\n", exception->exc_sp);
printf("ELR 0x%" PRIx64 "\n", exception->exc_elr);
printf("SPSR 0x%" PRIx64 "\n", exception->exc_spsr);
printf("x0 0x%" PRIx64 "\n", exception->x0);
printf("x1 0x%" PRIx64 "\n", exception->x1);
printf("x2 0x%" PRIx64 "\n", exception->x2);
printf("x3 0x%" PRIx64 "\n", exception->x3);
printf("x4 0x%" PRIx64 "\n", exception->x4);
printf("x5 0x%" PRIx64 "\n", exception->x5);
printf("x6 0x%" PRIx64 "\n", exception->x6);
printf("x7 0x%" PRIx64 "\n", exception->x7);
printf("x8 0x%" PRIx64 "\n", exception->x8);
printf("x9 0x%" PRIx64 "\n", exception->x9);
printf("x10 0x%" PRIx64 "\n", exception->x10);
printf("x11 0x%" PRIx64 "\n", exception->x11);
printf("x12 0x%" PRIx64 "\n", exception->x12);
printf("x13 0x%" PRIx64 "\n", exception->x13);
printf("x14 0x%" PRIx64 "\n", exception->x14);
printf("x15 0x%" PRIx64 "\n", exception->x15);
printf("x16 0x%" PRIx64 "\n", exception->x16);
printf("x17 0x%" PRIx64 "\n", exception->x17);
printf("x18 0x%" PRIx64 "\n", exception->x18);
printf("x19 0x%" PRIx64 "\n", exception->x19);
printf("x20 0x%" PRIx64 "\n", exception->x20);
printf("x21 0x%" PRIx64 "\n", exception->x21);
printf("x22 0x%" PRIx64 "\n", exception->x22);
printf("x23 0x%" PRIx64 "\n", exception->x23);
printf("x24 0x%" PRIx64 "\n", exception->x24);
printf("x25 0x%" PRIx64 "\n", exception->x25);
printf("x26 0x%" PRIx64 "\n", exception->x26);
printf("x27 0x%" PRIx64 "\n", exception->x27);
printf("x28 0x%" PRIx64 "\n", exception->x28);
printf("x29 0x%" PRIx64 "\n", exception->x29);
printf("x30 0x%" PRIx64 "\n", exception->x30);
myvar = 1;
}

View File

@@ -1,3 +1,5 @@
/* https://github.com/cirosantilli/linux-kernel-module-cheat#svc */
#include <lkmc.h>
.global main

2
lkmc.h
View File

@@ -80,7 +80,7 @@ void lkmc_assert_fail();
stp x21, x0, [sp, -16]!; \
mrs x21, elr_el1; \
stp xzr, x21, [sp, -16]!; \
mov x21, (exc_type); \
mov x21, exc_type; \
mrs x22, esr_el1; \
stp x21, x22, [sp, -16]!