On 11/09, Roland McGrath wrote:
>
> > Not sure I understand. You mean, if arch hook is not defined, we add
> > the default arch_fill_sigtrap_info (or whatever) which only sets si_signo?
>
> Right.  To be more precise, I think the arch hook should only set what's
> arch-specific and nonzero, so have generic code zero-fill and set si_signo.
> The arch hook just sets si_code et al, so that if there is no arch hook
> then the default one is empty.  The arch code will only ever define what it
> needs to add vs that default.

Oh... this adds more naming problems. And this way x86's send_sigtrap()
can't use this helper easily.

OK, please see below, but perhaps it is better to not introduce the
generic helper.

-------------------------------------------------------------------------------
> 1. specify arch hook, define default case

[PATCH 1/x] introduce user_single_step_siginfo()

perhaps user_single_step_siginfo() should go into ptrace.c ?

ARCH_HAS_USER_SINGLE_STEP_INFO doesn't match arch_has_single_step.

it should be ARCH_HAS_ARCH_USER_SINGLE_STEP_INFO, but this looks ugly.
I don't really care, up to you.

---

 include/linux/ptrace.h |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- TH/include/linux/ptrace.h~1_ARCH_DEFAULT_HOOK       2009-10-30 
00:46:06.000000000 +0100
+++ TH/include/linux/ptrace.h   2009-11-09 21:38:07.000000000 +0100
@@ -273,6 +273,25 @@ static inline void user_enable_block_ste
 }
 #endif /* arch_has_block_step */
 
+#ifdef ARCH_HAS_USER_SINGLE_STEP_INFO
+extern void arch_user_single_step_siginfo(struct task_struct *tsk,
+                               struct pt_regs *regs, siginfo_t *info);
+#else
+static inline void arch_user_single_step_siginfo(struct task_struct *tsk,
+                               struct pt_regs *regs, siginfo_t *info)
+{
+}
+#endif
+
+static inline void user_single_step_siginfo(struct task_struct *tsk,
+                               struct pt_regs *regs, siginfo_t *info)
+{
+       memset(info, 0, sizeof(*info));
+       info->si_signo = SIGTRAP;
+
+       arch_user_single_step_siginfo(tsk, regs, info);
+}
+
 #ifndef arch_ptrace_stop_needed
 /**
  * arch_ptrace_stop_needed - Decide whether arch_ptrace_stop() should be called
--------------------------------------------------------------------------------

OK?

> 2. define powerpc's arch hook

[PATCH 2/x] change powepc

---

 arch/powerpc/include/asm/ptrace.h |    2 ++
 arch/powerpc/kernel/traps.c       |    7 +++++++
 2 files changed, 9 insertions(+)

--- TH/arch/powerpc/include/asm/ptrace.h~2_POWERPC      2009-11-09 
21:32:17.000000000 +0100
+++ TH/arch/powerpc/include/asm/ptrace.h        2009-11-09 21:39:19.000000000 
+0100
@@ -140,6 +140,8 @@ extern void user_enable_single_step(stru
 extern void user_enable_block_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
+#define ARCH_HAS_USER_SINGLE_STEP_INFO
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
--- TH/arch/powerpc/kernel/traps.c~2_POWERPC    2009-11-09 21:32:17.000000000 
+0100
+++ TH/arch/powerpc/kernel/traps.c      2009-11-09 21:39:39.000000000 +0100
@@ -174,6 +174,13 @@ int die(const char *str, struct pt_regs 
        return 0;
 }
 
+void arch_user_single_step_siginfo(struct task_struct *tsk,
+                               struct pt_regs *regs, siginfo_t *info)
+{
+       info->si_code = TRAP_TRACE;
+       info->si_addr = (void __user *) regs->nip;
+}
+
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 {
        siginfo_t info;
-------------------------------------------------------------------------------

Correct?

> 3. change tracehook_report_syscall_exit to look at step flag

[PATCH 3/x] change tracehook_report_syscall_exit() to look at step flag

---

 include/linux/tracehook.h |    6 ++++++
 1 file changed, 6 insertions(+)

--- TH/include/linux/tracehook.h~3_TRACEHOOK    2009-11-09 21:00:38.000000000 
+0100
+++ TH/include/linux/tracehook.h        2009-11-09 21:42:16.000000000 +0100
@@ -134,6 +134,12 @@ static inline __must_check int tracehook
  */
 static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int 
step)
 {
+       if (step) {
+               siginfo_t info;
+               user_single_step_siginfo(current, regs, &info);
+               force_sig_info(SIGTRAP, &info, current);
+               return;
+       }
        ptrace_report_syscall(regs);
 }
 
-----------------------------------------------------------------------------
> 4. define x86's arch hook
> 5. change x86 tracehook_report_syscall_exit to match common pattern

This is clear.

What do you think?

Oleg.

Reply via email to