Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4cc5894 authored by Andreas Schwab's avatar Andreas Schwab Committed by Paul Mackerras
Browse files

[POWERPC] Add compat handler for PTRACE_GETSIGINFO



Current versions of gdb require a working implementation of
PTRACE_GETSIGINFO for proper watchpoint support.  Since struct siginfo
contains pointers it must be converted when passed to a 32-bit debugger.

Signed-off-by: default avatarAndreas Schwab <schwab@suse.de>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 585468e5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -135,4 +135,6 @@ struct ucontext32 {
	struct mcontext32	uc_mcontext;
};

extern int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s);

#endif  /* _PPC64_PPC32_H */
+27 −0
Original line number Diff line number Diff line
@@ -29,12 +29,15 @@
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/compat.h>
#include <linux/elf.h>

#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>

#include "ppc32.h"

/*
 * does not yet catch signals sent when the child dies.
 * in exit.c or in signal.c.
@@ -64,6 +67,27 @@ static long compat_ptrace_old(struct task_struct *child, long request,
	return -EPERM;
}

static int compat_ptrace_getsiginfo(struct task_struct *child, compat_siginfo_t __user *data)
{
	siginfo_t lastinfo;
	int error = -ESRCH;

	read_lock(&tasklist_lock);
	if (likely(child->sighand != NULL)) {
		error = -EINVAL;
		spin_lock_irq(&child->sighand->siglock);
		if (likely(child->last_siginfo != NULL)) {
			lastinfo = *child->last_siginfo;
			error = 0;
		}
		spin_unlock_irq(&child->sighand->siglock);
	}
	read_unlock(&tasklist_lock);
	if (!error)
		return copy_siginfo_to_user32(data, &lastinfo);
	return error;
}

long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
			compat_ulong_t caddr, compat_ulong_t cdata)
{
@@ -282,6 +306,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
			0, PT_REGS_COUNT * sizeof(compat_long_t),
			compat_ptr(data));

	case PTRACE_GETSIGINFO:
		return compat_ptrace_getsiginfo(child, compat_ptr(data));

	case PTRACE_GETFPREGS:
	case PTRACE_SETFPREGS:
	case PTRACE_GETVRREGS: