mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 06:26:47 +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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_armeb
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_armeb
|
||||
|
|
|
@ -150,6 +150,7 @@ symbols = (
|
|||
'arm_cp_write_ignore',
|
||||
'arm_current_el',
|
||||
'arm_dc_feature',
|
||||
'arm_debug_check_watchpoint',
|
||||
'arm_debug_excp_handler',
|
||||
'arm_debug_target_el',
|
||||
'arm_el_is_aa64',
|
||||
|
|
|
@ -144,6 +144,7 @@
|
|||
#define arm_cp_write_ignore arm_cp_write_ignore_m68k
|
||||
#define arm_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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_current_el arm_current_el_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_target_el arm_debug_target_el_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;
|
||||
#endif
|
||||
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)
|
||||
|
|
|
@ -411,6 +411,9 @@ void hw_breakpoint_update(ARMCPU *cpu, int n);
|
|||
*/
|
||||
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. */
|
||||
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)
|
||||
{
|
||||
/* 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->flags & BP_CPU) {
|
||||
cs->watchpoint_hit = NULL;
|
||||
if (check_watchpoints(cpu)) {
|
||||
bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
|
||||
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)) {
|
||||
env->exception.fsr = (1 << 9) | 0x22;
|
||||
} else {
|
||||
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));
|
||||
cs->watchpoint_hit = NULL;
|
||||
if (extended_addresses_enabled(env)) {
|
||||
env->exception.fsr = (1 << 9) | 0x22;
|
||||
} 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 {
|
||||
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_current_el arm_current_el_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_target_el arm_debug_target_el_x86_64
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_x86_64
|
||||
|
|
Loading…
Reference in a new issue