mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-10 11:47:35 +00:00
target-arm: Implement checking of fired watchpoint
ARM stops before access to a location covered by watchpoint. Also, QEMU watchpoint fire is not necessarily an architectural watchpoint match. Unfortunately, that is hardly possible to ignore a fired watchpoint in debug exception handler. So move watchpoint check from debug exception handler to the dedicated watchpoint checking callback. Backports commit 3826121d9298cde1d29ead05910e1f40125ee9b0 from qemu
This commit is contained in:
parent
6a3038db7c
commit
dfb78118ff
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_aarch64
|
#define arm_cp_write_ignore arm_cp_write_ignore_aarch64
|
||||||
#define arm_current_el arm_current_el_aarch64
|
#define arm_current_el arm_current_el_aarch64
|
||||||
#define arm_dc_feature arm_dc_feature_aarch64
|
#define arm_dc_feature arm_dc_feature_aarch64
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_aarch64
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_aarch64
|
#define arm_debug_excp_handler arm_debug_excp_handler_aarch64
|
||||||
#define arm_debug_target_el arm_debug_target_el_aarch64
|
#define arm_debug_target_el arm_debug_target_el_aarch64
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_aarch64
|
#define arm_el_is_aa64 arm_el_is_aa64_aarch64
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_aarch64eb
|
#define arm_cp_write_ignore arm_cp_write_ignore_aarch64eb
|
||||||
#define arm_current_el arm_current_el_aarch64eb
|
#define arm_current_el arm_current_el_aarch64eb
|
||||||
#define arm_dc_feature arm_dc_feature_aarch64eb
|
#define arm_dc_feature arm_dc_feature_aarch64eb
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_aarch64eb
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_aarch64eb
|
#define arm_debug_excp_handler arm_debug_excp_handler_aarch64eb
|
||||||
#define arm_debug_target_el arm_debug_target_el_aarch64eb
|
#define arm_debug_target_el arm_debug_target_el_aarch64eb
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_aarch64eb
|
#define arm_el_is_aa64 arm_el_is_aa64_aarch64eb
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_arm
|
#define arm_cp_write_ignore arm_cp_write_ignore_arm
|
||||||
#define arm_current_el arm_current_el_arm
|
#define arm_current_el arm_current_el_arm
|
||||||
#define arm_dc_feature arm_dc_feature_arm
|
#define arm_dc_feature arm_dc_feature_arm
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_arm
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_arm
|
#define arm_debug_excp_handler arm_debug_excp_handler_arm
|
||||||
#define arm_debug_target_el arm_debug_target_el_arm
|
#define arm_debug_target_el arm_debug_target_el_arm
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_arm
|
#define arm_el_is_aa64 arm_el_is_aa64_arm
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_armeb
|
#define arm_cp_write_ignore arm_cp_write_ignore_armeb
|
||||||
#define arm_current_el arm_current_el_armeb
|
#define arm_current_el arm_current_el_armeb
|
||||||
#define arm_dc_feature arm_dc_feature_armeb
|
#define arm_dc_feature arm_dc_feature_armeb
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_armeb
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_armeb
|
#define arm_debug_excp_handler arm_debug_excp_handler_armeb
|
||||||
#define arm_debug_target_el arm_debug_target_el_armeb
|
#define arm_debug_target_el arm_debug_target_el_armeb
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_armeb
|
#define arm_el_is_aa64 arm_el_is_aa64_armeb
|
||||||
|
|
|
@ -150,6 +150,7 @@ symbols = (
|
||||||
'arm_cp_write_ignore',
|
'arm_cp_write_ignore',
|
||||||
'arm_current_el',
|
'arm_current_el',
|
||||||
'arm_dc_feature',
|
'arm_dc_feature',
|
||||||
|
'arm_debug_check_watchpoint',
|
||||||
'arm_debug_excp_handler',
|
'arm_debug_excp_handler',
|
||||||
'arm_debug_target_el',
|
'arm_debug_target_el',
|
||||||
'arm_el_is_aa64',
|
'arm_el_is_aa64',
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_m68k
|
#define arm_cp_write_ignore arm_cp_write_ignore_m68k
|
||||||
#define arm_current_el arm_current_el_m68k
|
#define arm_current_el arm_current_el_m68k
|
||||||
#define arm_dc_feature arm_dc_feature_m68k
|
#define arm_dc_feature arm_dc_feature_m68k
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_m68k
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_m68k
|
#define arm_debug_excp_handler arm_debug_excp_handler_m68k
|
||||||
#define arm_debug_target_el arm_debug_target_el_m68k
|
#define arm_debug_target_el arm_debug_target_el_m68k
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_m68k
|
#define arm_el_is_aa64 arm_el_is_aa64_m68k
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_mips
|
#define arm_cp_write_ignore arm_cp_write_ignore_mips
|
||||||
#define arm_current_el arm_current_el_mips
|
#define arm_current_el arm_current_el_mips
|
||||||
#define arm_dc_feature arm_dc_feature_mips
|
#define arm_dc_feature arm_dc_feature_mips
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_mips
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_mips
|
#define arm_debug_excp_handler arm_debug_excp_handler_mips
|
||||||
#define arm_debug_target_el arm_debug_target_el_mips
|
#define arm_debug_target_el arm_debug_target_el_mips
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_mips
|
#define arm_el_is_aa64 arm_el_is_aa64_mips
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_mips64
|
#define arm_cp_write_ignore arm_cp_write_ignore_mips64
|
||||||
#define arm_current_el arm_current_el_mips64
|
#define arm_current_el arm_current_el_mips64
|
||||||
#define arm_dc_feature arm_dc_feature_mips64
|
#define arm_dc_feature arm_dc_feature_mips64
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_mips64
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_mips64
|
#define arm_debug_excp_handler arm_debug_excp_handler_mips64
|
||||||
#define arm_debug_target_el arm_debug_target_el_mips64
|
#define arm_debug_target_el arm_debug_target_el_mips64
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_mips64
|
#define arm_el_is_aa64 arm_el_is_aa64_mips64
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_mips64el
|
#define arm_cp_write_ignore arm_cp_write_ignore_mips64el
|
||||||
#define arm_current_el arm_current_el_mips64el
|
#define arm_current_el arm_current_el_mips64el
|
||||||
#define arm_dc_feature arm_dc_feature_mips64el
|
#define arm_dc_feature arm_dc_feature_mips64el
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_mips64el
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_mips64el
|
#define arm_debug_excp_handler arm_debug_excp_handler_mips64el
|
||||||
#define arm_debug_target_el arm_debug_target_el_mips64el
|
#define arm_debug_target_el arm_debug_target_el_mips64el
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_mips64el
|
#define arm_el_is_aa64 arm_el_is_aa64_mips64el
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_mipsel
|
#define arm_cp_write_ignore arm_cp_write_ignore_mipsel
|
||||||
#define arm_current_el arm_current_el_mipsel
|
#define arm_current_el arm_current_el_mipsel
|
||||||
#define arm_dc_feature arm_dc_feature_mipsel
|
#define arm_dc_feature arm_dc_feature_mipsel
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_mipsel
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_mipsel
|
#define arm_debug_excp_handler arm_debug_excp_handler_mipsel
|
||||||
#define arm_debug_target_el arm_debug_target_el_mipsel
|
#define arm_debug_target_el arm_debug_target_el_mipsel
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_mipsel
|
#define arm_el_is_aa64 arm_el_is_aa64_mipsel
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_powerpc
|
#define arm_cp_write_ignore arm_cp_write_ignore_powerpc
|
||||||
#define arm_current_el arm_current_el_powerpc
|
#define arm_current_el arm_current_el_powerpc
|
||||||
#define arm_dc_feature arm_dc_feature_powerpc
|
#define arm_dc_feature arm_dc_feature_powerpc
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_powerpc
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_powerpc
|
#define arm_debug_excp_handler arm_debug_excp_handler_powerpc
|
||||||
#define arm_debug_target_el arm_debug_target_el_powerpc
|
#define arm_debug_target_el arm_debug_target_el_powerpc
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_powerpc
|
#define arm_el_is_aa64 arm_el_is_aa64_powerpc
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_sparc
|
#define arm_cp_write_ignore arm_cp_write_ignore_sparc
|
||||||
#define arm_current_el arm_current_el_sparc
|
#define arm_current_el arm_current_el_sparc
|
||||||
#define arm_dc_feature arm_dc_feature_sparc
|
#define arm_dc_feature arm_dc_feature_sparc
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_sparc
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_sparc
|
#define arm_debug_excp_handler arm_debug_excp_handler_sparc
|
||||||
#define arm_debug_target_el arm_debug_target_el_sparc
|
#define arm_debug_target_el arm_debug_target_el_sparc
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_sparc
|
#define arm_el_is_aa64 arm_el_is_aa64_sparc
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_sparc64
|
#define arm_cp_write_ignore arm_cp_write_ignore_sparc64
|
||||||
#define arm_current_el arm_current_el_sparc64
|
#define arm_current_el arm_current_el_sparc64
|
||||||
#define arm_dc_feature arm_dc_feature_sparc64
|
#define arm_dc_feature arm_dc_feature_sparc64
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_sparc64
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_sparc64
|
#define arm_debug_excp_handler arm_debug_excp_handler_sparc64
|
||||||
#define arm_debug_target_el arm_debug_target_el_sparc64
|
#define arm_debug_target_el arm_debug_target_el_sparc64
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_sparc64
|
#define arm_el_is_aa64 arm_el_is_aa64_sparc64
|
||||||
|
|
|
@ -1343,6 +1343,7 @@ static void arm_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *data
|
||||||
//cc->virtio_is_big_endian = arm_cpu_is_big_endian;
|
//cc->virtio_is_big_endian = arm_cpu_is_big_endian;
|
||||||
#endif
|
#endif
|
||||||
cc->debug_excp_handler = arm_debug_excp_handler;
|
cc->debug_excp_handler = arm_debug_excp_handler;
|
||||||
|
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_register(struct uc_struct *uc, const ARMCPUInfo *info)
|
static void cpu_register(struct uc_struct *uc, const ARMCPUInfo *info)
|
||||||
|
|
|
@ -411,6 +411,9 @@ void hw_breakpoint_update(ARMCPU *cpu, int n);
|
||||||
*/
|
*/
|
||||||
void hw_breakpoint_update_all(ARMCPU *cpu);
|
void hw_breakpoint_update_all(ARMCPU *cpu);
|
||||||
|
|
||||||
|
/* Callback function for checking if a watchpoint should trigger. */
|
||||||
|
bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
|
||||||
|
|
||||||
/* Callback function for when a watchpoint or breakpoint triggers. */
|
/* Callback function for when a watchpoint or breakpoint triggers. */
|
||||||
void arm_debug_excp_handler(CPUState *cs);
|
void arm_debug_excp_handler(CPUState *cs);
|
||||||
|
|
||||||
|
|
|
@ -973,6 +973,16 @@ void HELPER(check_breakpoints)(CPUARMState *env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
|
||||||
|
{
|
||||||
|
/* Called by core code when a CPU watchpoint fires; need to check if this
|
||||||
|
* is also an architectural watchpoint match.
|
||||||
|
*/
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs->uc, cs);
|
||||||
|
|
||||||
|
return check_watchpoints(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
void arm_debug_excp_handler(CPUState *cs)
|
void arm_debug_excp_handler(CPUState *cs)
|
||||||
{
|
{
|
||||||
/* Called by core code when a watchpoint or breakpoint fires;
|
/* Called by core code when a watchpoint or breakpoint fires;
|
||||||
|
@ -984,23 +994,19 @@ void arm_debug_excp_handler(CPUState *cs)
|
||||||
|
|
||||||
if (wp_hit) {
|
if (wp_hit) {
|
||||||
if (wp_hit->flags & BP_CPU) {
|
if (wp_hit->flags & BP_CPU) {
|
||||||
cs->watchpoint_hit = NULL;
|
bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
|
||||||
if (check_watchpoints(cpu)) {
|
bool same_el = arm_debug_target_el(env) == arm_current_el(env);
|
||||||
bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
|
|
||||||
bool same_el = arm_debug_target_el(env) == arm_current_el(env);
|
|
||||||
|
|
||||||
if (extended_addresses_enabled(env)) {
|
cs->watchpoint_hit = NULL;
|
||||||
env->exception.fsr = (1 << 9) | 0x22;
|
if (extended_addresses_enabled(env)) {
|
||||||
} else {
|
env->exception.fsr = (1 << 9) | 0x22;
|
||||||
env->exception.fsr = 0x2;
|
|
||||||
}
|
|
||||||
env->exception.vaddress = wp_hit->hitaddr;
|
|
||||||
raise_exception(env, EXCP_DATA_ABORT,
|
|
||||||
syn_watchpoint(same_el, 0, wnr),
|
|
||||||
arm_debug_target_el(env));
|
|
||||||
} else {
|
} else {
|
||||||
cpu_resume_from_signal(cs, NULL);
|
env->exception.fsr = 0x2;
|
||||||
}
|
}
|
||||||
|
env->exception.vaddress = wp_hit->hitaddr;
|
||||||
|
raise_exception(env, EXCP_DATA_ABORT,
|
||||||
|
syn_watchpoint(same_el, 0, wnr),
|
||||||
|
arm_debug_target_el(env));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
|
uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
#define arm_cp_write_ignore arm_cp_write_ignore_x86_64
|
#define arm_cp_write_ignore arm_cp_write_ignore_x86_64
|
||||||
#define arm_current_el arm_current_el_x86_64
|
#define arm_current_el arm_current_el_x86_64
|
||||||
#define arm_dc_feature arm_dc_feature_x86_64
|
#define arm_dc_feature arm_dc_feature_x86_64
|
||||||
|
#define arm_debug_check_watchpoint arm_debug_check_watchpoint_x86_64
|
||||||
#define arm_debug_excp_handler arm_debug_excp_handler_x86_64
|
#define arm_debug_excp_handler arm_debug_excp_handler_x86_64
|
||||||
#define arm_debug_target_el arm_debug_target_el_x86_64
|
#define arm_debug_target_el arm_debug_target_el_x86_64
|
||||||
#define arm_el_is_aa64 arm_el_is_aa64_x86_64
|
#define arm_el_is_aa64 arm_el_is_aa64_x86_64
|
||||||
|
|
Loading…
Reference in a new issue