]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
linux-user/hppa: Detect glibc ABORT_INSTRUCTION and EXCP_BREAK handler
authorHelge Deller <deller@gmx.de>
Thu, 27 Oct 2022 06:58:37 +0000 (08:58 +0200)
committerLaurent Vivier <laurent@vivier.eu>
Wed, 2 Nov 2022 16:14:02 +0000 (17:14 +0100)
The glibc on the hppa platform uses the "iitlbp %r0,(%sr0, %r0)"
assembler instruction as ABORT_INSTRUCTION.
If this (in userspace context) illegal assembler statement is found,
dump the registers and report the failure to userspace the same way as
the Linux kernel on physical hardware.

For other illegal instructions report TARGET_ILL_ILLOPC instead of
TARGET_ILL_ILLOPN as si_code.

Additionally add the missing EXCP_BREAK exception handler which occurs
when the "break x,y" assembler instruction is executed and report
EXCP_ASSIST traps.

Signed-off-by: Helge Deller <deller@gmx.de>
Message-Id: <Y1osHVsylkuZNUnY@p100>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
linux-user/hppa/cpu_loop.c

index 1ef3b461911cc294f6ad562b34242997fd9451ff..8ab13351060260f51e312c18ecc42437c94ff563 100644 (file)
@@ -147,15 +147,20 @@ void cpu_loop(CPUHPPAState *env)
             force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f);
             break;
         case EXCP_ILL:
-            EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
-            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
+            EXCP_DUMP(env, "qemu: EXCP_ILL exception %#x\n", trapnr);
+            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f);
             break;
         case EXCP_PRIV_OPR:
-            EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
-            force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f);
+            /* check for glibc ABORT_INSTRUCTION "iitlbp %r0,(%sr0, %r0)" */
+            EXCP_DUMP(env, "qemu: EXCP_PRIV_OPR exception %#x\n", trapnr);
+            if (env->cr[CR_IIR] == 0x04000000) {
+                   force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f);
+            } else {
+                   force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f);
+            }
             break;
         case EXCP_PRIV_REG:
-            EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
+            EXCP_DUMP(env, "qemu: EXCP_PRIV_REG exception %#x\n", trapnr);
             force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f);
             break;
         case EXCP_OVERFLOW:
@@ -167,6 +172,10 @@ void cpu_loop(CPUHPPAState *env)
         case EXCP_ASSIST:
             force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f);
             break;
+        case EXCP_BREAK:
+            EXCP_DUMP(env, "qemu: EXCP_BREAK exception %#x\n", trapnr);
+            force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f & ~3);
+            break;
         case EXCP_DEBUG:
             force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f);
             break;