Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/trap.c
Show First 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | if (far > VM_MAXUSER_ADDRESS) { | ||||
bp_harden = PCPU_GET(bp_harden); | bp_harden = PCPU_GET(bp_harden); | ||||
if (bp_harden != NULL) | if (bp_harden != NULL) | ||||
bp_harden(); | bp_harden(); | ||||
} | } | ||||
break; | break; | ||||
case EXCP_UNKNOWN: | case EXCP_UNKNOWN: | ||||
case EXCP_DATA_ABORT_L: | case EXCP_DATA_ABORT_L: | ||||
case EXCP_DATA_ABORT: | case EXCP_DATA_ABORT: | ||||
case EXCP_WATCHPT_EL0: | |||||
far = READ_SPECIALREG(far_el1); | far = READ_SPECIALREG(far_el1); | ||||
break; | break; | ||||
} | } | ||||
intr_enable(); | intr_enable(); | ||||
CTR4(KTR_TRAP, | CTR4(KTR_TRAP, | ||||
"do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, esr, | "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, esr, | ||||
frame->tf_elr, frame); | frame->tf_elr, frame); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | #endif | ||||
case EXCP_PC_ALIGN: | case EXCP_PC_ALIGN: | ||||
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr, | call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr, | ||||
exception); | exception); | ||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
case EXCP_BRKPT_EL0: | case EXCP_BRKPT_EL0: | ||||
case EXCP_BRK: | case EXCP_BRK: | ||||
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr, | call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr, | ||||
exception); | |||||
userret(td, frame); | |||||
break; | |||||
case EXCP_WATCHPT_EL0: | |||||
call_trapsignal(td, SIGTRAP, TRAP_TRACE, (void *)far, | |||||
mgorny_gentoo.org: I'm not sure here and I can't figure out the abstractions in Linux code but on Linux I'm… | |||||
Done Inline ActionsHmm. Returning the watched address in si_addr does seem more useful. I don't think there is any other simple way to determine which watchpoint triggered the exception, so we can probably switch over to this. My only reservation is that FreeBSD/amd64 does not appear to behave this way, and it returns the trapping instruction address in si_addr. mhorne: Hmm. Returning the watched address in `si_addr` does seem more useful. I don't think there is… | |||||
Not Done Inline ActionsIndeed it doesn't. We are working around that by checking DR7 directly. mgorny_gentoo.org: Indeed it doesn't. We are working around that by checking DR7 directly. | |||||
exception); | exception); | ||||
userret(td, frame); | userret(td, frame); | ||||
break; | break; | ||||
case EXCP_MSR: | case EXCP_MSR: | ||||
/* | /* | ||||
* The CPU can raise EXCP_MSR when userspace executes an mrs | * The CPU can raise EXCP_MSR when userspace executes an mrs | ||||
* instruction to access a special register userspace doesn't | * instruction to access a special register userspace doesn't | ||||
* have access to. | * have access to. | ||||
▲ Show 20 Lines • Show All 59 Lines • Show Last 20 Lines |
I'm not sure here and I can't figure out the abstractions in Linux code but on Linux I'm getting a SIGTRAP with si_addr pointing to the watched memory rather than the instruction, and LLDB uses that to identify which watchpoint was hit. Do you have any suggestion if I can determine that any other way?