linux-user/aarch64: Split out signal_for_exception

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250830054128.448363-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2025-08-30 15:40:05 +10:00 committed by Peter Maydell
parent 424dc390ec
commit 71eba04575

View file

@ -27,11 +27,56 @@
#include "target/arm/syndrome.h"
#include "target/arm/cpu-features.h"
/* Use the exception syndrome to map a cpu exception to a signal. */
static void signal_for_exception(CPUARMState *env, vaddr addr)
{
uint32_t syn = env->exception.syndrome;
int si_code, si_signo;
switch (syn_get_ec(syn)) {
case EC_DATAABORT:
case EC_INSNABORT:
/* Both EC have the same format for FSC, or close enough. */
switch (extract32(syn, 0, 6)) {
case 0x04 ... 0x07: /* Translation fault, level {0-3} */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_MAPERR;
break;
case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_ACCERR;
break;
case 0x11: /* Synchronous Tag Check Fault */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_MTESERR;
break;
case 0x21: /* Alignment fault */
si_signo = TARGET_SIGBUS;
si_code = TARGET_BUS_ADRALN;
break;
default:
g_assert_not_reached();
}
break;
case EC_PCALIGNMENT:
si_signo = TARGET_SIGBUS;
si_code = TARGET_BUS_ADRALN;
break;
default:
g_assert_not_reached();
}
force_sig_fault(si_signo, si_code, addr);
}
/* AArch64 main loop */
void cpu_loop(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
int trapnr, ec, fsc, si_code, si_signo;
int trapnr;
abi_long ret;
for (;;) {
@ -67,42 +112,7 @@ void cpu_loop(CPUARMState *env)
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
ec = syn_get_ec(env->exception.syndrome);
switch (ec) {
case EC_DATAABORT:
case EC_INSNABORT:
/* Both EC have the same format for FSC, or close enough. */
fsc = extract32(env->exception.syndrome, 0, 6);
switch (fsc) {
case 0x04 ... 0x07: /* Translation fault, level {0-3} */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_MAPERR;
break;
case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_ACCERR;
break;
case 0x11: /* Synchronous Tag Check Fault */
si_signo = TARGET_SIGSEGV;
si_code = TARGET_SEGV_MTESERR;
break;
case 0x21: /* Alignment fault */
si_signo = TARGET_SIGBUS;
si_code = TARGET_BUS_ADRALN;
break;
default:
g_assert_not_reached();
}
break;
case EC_PCALIGNMENT:
si_signo = TARGET_SIGBUS;
si_code = TARGET_BUS_ADRALN;
break;
default:
g_assert_not_reached();
}
force_sig_fault(si_signo, si_code, env->exception.vaddress);
signal_for_exception(env, env->exception.vaddress);
break;
case EXCP_DEBUG:
case EXCP_BKPT: