]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/ptrace-getsiginfo
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / ptrace-getsiginfo
1 From: Andreas Schwab <schwab@suse.de>
2 Subject: Add compat handler for PTRACE_GETSIGINFO
3
4 Current versions of gdb require a working implementation of
5 PTRACE_GETSIGINFO for proper watchpoint support. Since struct siginfo
6 contains pointers it must be converted when passed to a 32-bit debugger.
7
8 Signed-off-by: Andreas Schwab <schwab@suse.de>
9 ---
10 arch/powerpc/kernel/ppc32.h | 2 ++
11 arch/powerpc/kernel/ptrace32.c | 27 +++++++++++++++++++++++++++
12 2 files changed, 29 insertions(+)
13
14 --- a/arch/powerpc/kernel/ppc32.h
15 +++ b/arch/powerpc/kernel/ppc32.h
16 @@ -136,4 +136,6 @@ struct ucontext32 {
17 struct mcontext32 uc_mcontext;
18 };
19
20 +extern int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s);
21 +
22 #endif /* _PPC64_PPC32_H */
23 --- a/arch/powerpc/kernel/ptrace32.c
24 +++ b/arch/powerpc/kernel/ptrace32.c
25 @@ -29,12 +29,15 @@
26 #include <linux/security.h>
27 #include <linux/signal.h>
28 #include <linux/compat.h>
29 +#include <linux/elf.h>
30
31 #include <asm/uaccess.h>
32 #include <asm/page.h>
33 #include <asm/pgtable.h>
34 #include <asm/system.h>
35
36 +#include "ppc32.h"
37 +
38 /*
39 * does not yet catch signals sent when the child dies.
40 * in exit.c or in signal.c.
41 @@ -69,6 +72,27 @@ static long compat_ptrace_old(struct tas
42 #define FPRHALF(i) (((i) - PT_FPR0) & 1)
43 #define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) + FPRHALF(i)
44
45 +static int compat_ptrace_getsiginfo(struct task_struct *child, compat_siginfo_t __user *data)
46 +{
47 + siginfo_t lastinfo;
48 + int error = -ESRCH;
49 +
50 + read_lock(&tasklist_lock);
51 + if (likely(child->sighand != NULL)) {
52 + error = -EINVAL;
53 + spin_lock_irq(&child->sighand->siglock);
54 + if (likely(child->last_siginfo != NULL)) {
55 + lastinfo = *child->last_siginfo;
56 + error = 0;
57 + }
58 + spin_unlock_irq(&child->sighand->siglock);
59 + }
60 + read_unlock(&tasklist_lock);
61 + if (!error)
62 + return copy_siginfo_to_user32(data, &lastinfo);
63 + return error;
64 +}
65 +
66 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
67 compat_ulong_t caddr, compat_ulong_t cdata)
68 {
69 @@ -290,6 +314,9 @@ long compat_arch_ptrace(struct task_stru
70 0, PT_REGS_COUNT * sizeof(compat_long_t),
71 compat_ptr(data));
72
73 + case PTRACE_GETSIGINFO:
74 + return compat_ptrace_getsiginfo(child, compat_ptr(data));
75 +
76 case PTRACE_GETFPREGS:
77 case PTRACE_SETFPREGS:
78 case PTRACE_GETVRREGS: