All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] linux-user/arm: Deliver SIGTRAP for UDF patterns used as breakpoints
@ 2020-11-17 15:56 Peter Maydell
  2020-11-19 18:27 ` Richard Henderson
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Maydell @ 2020-11-17 15:56 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Laurent Vivier

The Linux kernel doesn't use the official bkpt insn for breakpoints;
instead it uses three instructions in the guaranteed-to-UNDEF space,
and generates SIGTRAP for these rather than the SIGILL that most
UNDEF insns generate:

https://elixir.bootlin.com/linux/v5.9.8/source/arch/arm/kernel/ptrace.c#L197

Make QEMU treat these insns specially too.  The main benefit of this
is that if you're running a debugger on a guest program that runs
into a GCC __builtin_trap() or LLVM "trap because execution should
never reach here" then you'll get the expected signal rather than a
SIGILL.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
This is not a "fix" for LP:1904210, but it does bring QEMU's
behaviour into line with that of the real kernel on that binary.

---
 linux-user/arm/cpu_loop.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 13629ee1f6a..3d272b56ef0 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -205,6 +205,24 @@ do_kernel_trap(CPUARMState *env)
     return 0;
 }
 
+static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb)
+{
+    /*
+     * Return true if this insn is one of the three magic UDF insns
+     * which the kernel treats as breakpoint insns.
+     */
+    if (!is_thumb) {
+        return (opcode & 0x0fffffff) == 0x07f001f0;
+    } else {
+        /*
+         * Note that we get the two halves of the 32-bit T32 insn
+         * in the opposite order to the value the kernel uses in
+         * its undef_hook struct.
+         */
+        return ((opcode & 0xffff) == 0xde01) || (opcode == 0xa000f7f0);
+    }
+}
+
 void cpu_loop(CPUARMState *env)
 {
     CPUState *cs = env_cpu(env);
@@ -234,6 +252,16 @@ void cpu_loop(CPUARMState *env)
                 /* FIXME - what to do if get_user() fails? */
                 get_user_code_u32(opcode, env->regs[15], env);
 
+                /*
+                 * The Linux kernel treats some UDF patterns specially
+                 * to use as breakpoints (instead of the architectural
+                 * bkpt insn). These should trigger a SIGTRAP rather
+                 * than SIGILL.
+                 */
+                if (insn_is_linux_bkpt(opcode, env->thumb)) {
+                    goto excp_debug;
+                }
+
                 rc = EmulateAll(opcode, &ts->fpa, env);
                 if (rc == 0) { /* illegal instruction */
                     info.si_signo = TARGET_SIGILL;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] linux-user/arm: Deliver SIGTRAP for UDF patterns used as breakpoints
  2020-11-17 15:56 [PATCH] linux-user/arm: Deliver SIGTRAP for UDF patterns used as breakpoints Peter Maydell
@ 2020-11-19 18:27 ` Richard Henderson
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Henderson @ 2020-11-19 18:27 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Laurent Vivier

On 11/17/20 7:56 AM, Peter Maydell wrote:
> The Linux kernel doesn't use the official bkpt insn for breakpoints;
> instead it uses three instructions in the guaranteed-to-UNDEF space,
> and generates SIGTRAP for these rather than the SIGILL that most
> UNDEF insns generate:
> 
> https://elixir.bootlin.com/linux/v5.9.8/source/arch/arm/kernel/ptrace.c#L197
> 
> Make QEMU treat these insns specially too.  The main benefit of this
> is that if you're running a debugger on a guest program that runs
> into a GCC __builtin_trap() or LLVM "trap because execution should
> never reach here" then you'll get the expected signal rather than a
> SIGILL.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> This is not a "fix" for LP:1904210, but it does bring QEMU's
> behaviour into line with that of the real kernel on that binary.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-11-19 18:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17 15:56 [PATCH] linux-user/arm: Deliver SIGTRAP for UDF patterns used as breakpoints Peter Maydell
2020-11-19 18:27 ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.