* RFC: Revise n32 ptrace interface
@ 2005-09-22 18:26 Daniel Jacobowitz
2005-09-28 22:11 ` [PATCH] Revise MIPS64 " Daniel Jacobowitz
2005-09-30 0:05 ` RFC: Revise n32 " Ralf Baechle
0 siblings, 2 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2005-09-22 18:26 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
Currently n32 uses the n64 ptrace interface. This means that it expects
both of its arguments to be "long long" rather than "long", PTRACE_PEEKTEXT
transfers eight bytes, et cetera. All of which has combined to cause no end
of trouble for GDB.
Here's an alternative interface that I've just started testing. n32 uses
the o32 ptrace interface instead, which transfers 32-bit quantities, as we'd
expect from a system with 32-bit longs. There are only a couple of catches:
1. We need to get at the 64-bit registers. I considered a number of
different approaches for this and decided to just implement a 64-bit
PTRACE_GETREGS instead of messing with PTRACE_PEEKUSR. It's much simpler
this way. I didn't add one for the DSP registers; that can be handled
separately when someone's working on debug support for them...
2. While I'm fixing this interface, an n32 program ought to be able to
debug an n64 program. This copies the clever trick that ppc64 uses,
i.e. passing the 64-bit address via reference. Less efficient but hugely
simpler.
3. PTRACE_{GET,SET}SIGINFO. I didn't even go there. N32 kernel and glibc
don't even agree about the layout of struct siginfo at the moment. This
should be investigated, but it's a problem for another day.
Any thoughts on the ABI change? Just for N32 of course; for o32/n64 this
strictly adds new mechanisms.
NOTE: this patch is just for comments, I don't want it to go in as is. There
ought to be a 32-bit GETREGS while I'm here, and I haven't written GDB
support for the _3264 operations yet, so I haven't tested it much. I'll be
back to work on this some more in a couple of days.
Index: linux/arch/mips/kernel/ptrace32.c
===================================================================
--- linux.orig/arch/mips/kernel/ptrace32.c 2005-09-21 14:48:02.000000000 -0400
+++ linux/arch/mips/kernel/ptrace32.c 2005-09-22 14:14:06.000000000 -0400
@@ -35,6 +35,12 @@
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+int ptrace_getregs64 (struct task_struct *child, __u64 __user *data);
+int ptrace_setregs64 (struct task_struct *child, __u64 __user *data);
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
+
/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
@@ -99,6 +105,35 @@ asmlinkage int sys32_ptrace(int request,
break;
}
+ /*
+ * Read 4 bytes of the other process' storage
+ * data is a pointer specifying where the user wants the
+ * 4 bytes copied into
+ * addr is a pointer in the user's storage that contains an 8 byte
+ * address in the other process of the 4 bytes that is to be read
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_PEEKTEXT_3264:
+ case PTRACE_PEEKDATA_3264: {
+ u32 tmp;
+ int copied;
+ u32 __user * addrOthers;
+
+ ret = -EIO;
+
+ /* Get the addr in the other process that we want to read */
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+
+ copied = access_process_vm(child, (u64)addrOthers, &tmp,
+ sizeof(tmp), 0);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (u32 __user *) (unsigned long) data);
+ break;
+ }
+
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
@@ -202,6 +237,31 @@ asmlinkage int sys32_ptrace(int request,
ret = -EIO;
break;
+ /*
+ * Write 4 bytes into the other process' storage
+ * data is the 4 bytes that the user wants written
+ * addr is a pointer in the user's storage that contains an
+ * 8 byte address in the other process where the 4 bytes
+ * that is to be written
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_POKETEXT_3264:
+ case PTRACE_POKEDATA_3264: {
+ u32 __user * addrOthers;
+
+ /* Get the addr in the other process that we want to write into */
+ ret = -EIO;
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+ ret = 0;
+ if (access_process_vm(child, (u64)addrOthers, &data,
+ sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
+ }
+
case PTRACE_POKEUSR: {
struct pt_regs *regs;
ret = 0;
@@ -276,6 +336,22 @@ asmlinkage int sys32_ptrace(int request,
break;
}
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GETREGS64:
+ ret = ptrace_getregs64 (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETREGS64:
+ ret = ptrace_setregs64 (child, (__u64 __user *) (__u64) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -320,6 +396,11 @@ asmlinkage int sys32_ptrace(int request,
(unsigned int __user *) (unsigned long) data);
break;
+ case PTRACE_GET_THREAD_AREA_3264:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) (unsigned long) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
Index: linux/include/asm-mips/ptrace.h
===================================================================
--- linux.orig/include/asm-mips/ptrace.h 2005-09-21 14:48:02.000000000 -0400
+++ linux/include/asm-mips/ptrace.h 2005-09-22 13:03:20.000000000 -0400
@@ -50,8 +50,8 @@ struct pt_regs {
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
/* #define PTRACE_GETREGS 12 */
/* #define PTRACE_SETREGS 13 */
-/* #define PTRACE_GETFPREGS 14 */
-/* #define PTRACE_SETFPREGS 15 */
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
/* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */
@@ -60,6 +60,17 @@ struct pt_regs {
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_SET_THREAD_AREA 26
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
+/* Calls to fetch 64bit registers from an o32 or n32 program. */
+#define PTRACE_GETREGS64 0xd0
+#define PTRACE_SETREGS64 0xd1
+
#ifdef __KERNEL__
#include <linux/linkage.h>
Index: linux/arch/mips/kernel/scall64-n32.S
===================================================================
--- linux.orig/arch/mips/kernel/scall64-n32.S 2005-09-21 09:34:45.000000000 -0400
+++ linux/arch/mips/kernel/scall64-n32.S 2005-09-22 14:04:19.000000000 -0400
@@ -216,7 +216,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_getrusage
PTR sys32_sysinfo
PTR compat_sys_times
- PTR sys_ptrace
+ PTR sys32_ptrace
PTR sys_getuid /* 6100 */
PTR sys_syslog
PTR sys_getgid
Index: linux/arch/mips/kernel/ptrace.c
===================================================================
--- linux.orig/arch/mips/kernel/ptrace.c 2005-09-22 14:11:07.000000000 -0400
+++ linux/arch/mips/kernel/ptrace.c 2005-09-22 14:11:12.000000000 -0400
@@ -38,6 +38,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+#include <asm/reg.h>
/*
* Called by kernel/ptrace.c when detaching..
@@ -49,6 +50,110 @@ void ptrace_disable(struct task_struct *
/* Nothing to do.. */
}
+#ifdef CONFIG_64BIT
+int ptrace_getregs64 (struct task_struct *child, __u64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, EF_SIZE))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __put_user (regs->regs[i], data + EF_R0 + i);
+ __put_user (regs->lo, data + EF_LO);
+ __put_user (regs->hi, data + EF_HI);
+ __put_user (regs->cp0_epc, data + EF_CP0_EPC);
+ __put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR);
+ __put_user (regs->cp0_status, data + EF_CP0_STATUS);
+ __put_user (regs->cp0_cause, data + EF_CP0_CAUSE);
+
+ return 0;
+}
+
+int ptrace_setregs64 (struct task_struct *child, __u64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, EF_SIZE))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __get_user (regs->regs[i], data + EF_R0 + i);
+ __get_user (regs->lo, data + EF_LO);
+ __get_user (regs->hi, data + EF_HI);
+ __get_user (regs->cp0_epc, data + EF_CP0_EPC);
+
+ /* badvaddr, status, and cause may not be written. */
+
+ return 0;
+}
+#endif
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
+{
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user (fregs[i], i + (__u64 __user *) data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user ((__u64) -1, i + (__u64 __user *) data);
+ }
+
+ if (cpu_has_fpu) {
+ unsigned int flags, tmp;
+
+ __put_user (child->thread.fpu.hard.fcr31, data + 64);
+
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ __put_user (tmp, data + 65);
+ } else {
+ __put_user (child->thread.fpu.soft.fcr31, data + 64);
+ __put_user ((__u32) 0, data + 65);
+ }
+
+ return 0;
+}
+
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
+{
+ fpureg_t *fregs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+ return -EIO;
+
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user (fregs[i], i + (__u64 __user *) data);
+
+ if (cpu_has_fpu)
+ __get_user (child->thread.fpu.hard.fcr31, data + 64);
+ else
+ __get_user (child->thread.fpu.soft.fcr31, data + 64);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -300,6 +405,24 @@ asmlinkage int sys_ptrace(long request,
break;
}
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) data);
+ break;
+
+#ifdef CONFIG_64BIT
+ case PTRACE_GETREGS64:
+ ret = ptrace_getregs64 (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_SETREGS64:
+ ret = ptrace_setregs64 (child, (__u64 __user *) data);
+ break;
+#endif
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH] Revise MIPS64 ptrace interface
2005-09-22 18:26 RFC: Revise n32 ptrace interface Daniel Jacobowitz
@ 2005-09-28 22:11 ` Daniel Jacobowitz
2005-09-30 0:13 ` Ralf Baechle
2005-09-30 0:05 ` RFC: Revise n32 " Ralf Baechle
1 sibling, 1 reply; 6+ messages in thread
From: Daniel Jacobowitz @ 2005-09-28 22:11 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
Change the N32 debugging ABI to something more sane, and add support
for o32 and n32 debuggers to trace n64 programs.
Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
---
I've now tested everything except the actual _3264 operations, which
were copied from PPC anyway and I have reasonable faith in. So here's
a final patch. If this seems reasonable to everyone, I'd like for it
to be merged, and then I can submit the glibc and gdb bits.
The patch itself is below. If you want to test it, at
http://return.false.org/~drow/mips/ you can find:
gdb-2005-09-28-HEAD-MIPS64-DEBUG.tar.gz
glibc-2005-09-28-HEAD-MIPS64-NPTL.tar.gz
linux-2005-09-28-sentosa-n32-ptrace.tar.gz
These are patches against linux-mips.org HEAD, glibc HEAD, and gdb HEAD
(all last week) that allow n32 and n64 debugging. For n64 debugging
you'll need to remove .debug_frame/.eh_frame first since I haven't
looked at those bits of GDB / GCC yet.
Index: linux/arch/mips/kernel/ptrace32.c
===================================================================
--- linux.orig/arch/mips/kernel/ptrace32.c 2005-09-21 14:48:02.000000000 -0400
+++ linux/arch/mips/kernel/ptrace32.c 2005-09-28 15:18:29.000000000 -0400
@@ -35,6 +35,12 @@
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+int ptrace_getregs (struct task_struct *child, __s64 __user *data);
+int ptrace_setregs (struct task_struct *child, __s64 __user *data);
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
+
/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
@@ -99,6 +105,35 @@ asmlinkage int sys32_ptrace(int request,
break;
}
+ /*
+ * Read 4 bytes of the other process' storage
+ * data is a pointer specifying where the user wants the
+ * 4 bytes copied into
+ * addr is a pointer in the user's storage that contains an 8 byte
+ * address in the other process of the 4 bytes that is to be read
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_PEEKTEXT_3264:
+ case PTRACE_PEEKDATA_3264: {
+ u32 tmp;
+ int copied;
+ u32 __user * addrOthers;
+
+ ret = -EIO;
+
+ /* Get the addr in the other process that we want to read */
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+
+ copied = access_process_vm(child, (u64)addrOthers, &tmp,
+ sizeof(tmp), 0);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (u32 __user *) (unsigned long) data);
+ break;
+ }
+
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
struct pt_regs *regs;
@@ -202,6 +237,31 @@ asmlinkage int sys32_ptrace(int request,
ret = -EIO;
break;
+ /*
+ * Write 4 bytes into the other process' storage
+ * data is the 4 bytes that the user wants written
+ * addr is a pointer in the user's storage that contains an
+ * 8 byte address in the other process where the 4 bytes
+ * that is to be written
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_POKETEXT_3264:
+ case PTRACE_POKEDATA_3264: {
+ u32 __user * addrOthers;
+
+ /* Get the addr in the other process that we want to write into */
+ ret = -EIO;
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+ ret = 0;
+ if (access_process_vm(child, (u64)addrOthers, &data,
+ sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
+ }
+
case PTRACE_POKEUSR: {
struct pt_regs *regs;
ret = 0;
@@ -276,6 +336,22 @@ asmlinkage int sys32_ptrace(int request,
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
@@ -320,6 +396,11 @@ asmlinkage int sys32_ptrace(int request,
(unsigned int __user *) (unsigned long) data);
break;
+ case PTRACE_GET_THREAD_AREA_3264:
+ ret = put_user(child->thread_info->tp_value,
+ (unsigned long __user *) (unsigned long) data);
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
Index: linux/include/asm-mips/ptrace.h
===================================================================
--- linux.orig/include/asm-mips/ptrace.h 2005-09-21 14:48:02.000000000 -0400
+++ linux/include/asm-mips/ptrace.h 2005-09-28 15:15:14.000000000 -0400
@@ -48,10 +48,10 @@ struct pt_regs {
};
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-/* #define PTRACE_GETREGS 12 */
-/* #define PTRACE_SETREGS 13 */
-/* #define PTRACE_GETFPREGS 14 */
-/* #define PTRACE_SETFPREGS 15 */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
/* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */
@@ -60,6 +60,13 @@ struct pt_regs {
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_SET_THREAD_AREA 26
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
#ifdef __KERNEL__
#include <linux/linkage.h>
Index: linux/arch/mips/kernel/scall64-n32.S
===================================================================
--- linux.orig/arch/mips/kernel/scall64-n32.S 2005-09-21 09:34:45.000000000 -0400
+++ linux/arch/mips/kernel/scall64-n32.S 2005-09-22 14:04:19.000000000 -0400
@@ -216,7 +216,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_getrusage
PTR sys32_sysinfo
PTR compat_sys_times
- PTR sys_ptrace
+ PTR sys32_ptrace
PTR sys_getuid /* 6100 */
PTR sys_syslog
PTR sys_getgid
Index: linux/arch/mips/kernel/ptrace.c
===================================================================
--- linux.orig/arch/mips/kernel/ptrace.c 2005-09-22 14:11:07.000000000 -0400
+++ linux/arch/mips/kernel/ptrace.c 2005-09-28 15:17:23.000000000 -0400
@@ -38,6 +38,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/bootinfo.h>
+#include <asm/reg.h>
/*
* Called by kernel/ptrace.c when detaching..
@@ -49,6 +50,118 @@ void ptrace_disable(struct task_struct *
/* Nothing to do.. */
}
+/*
+ * Read a general register set. We always use the 64-bit format, even
+ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+ * Registers are sign extended to fill the available space.
+ */
+int ptrace_getregs (struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __put_user (regs->regs[i], data + i);
+ __put_user (regs->lo, data + EF_LO - EF_R0);
+ __put_user (regs->hi, data + EF_HI - EF_R0);
+ __put_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+ __put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
+ __put_user (regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
+ __put_user (regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+
+ return 0;
+}
+
+/*
+ * Write a general register set. As for PTRACE_GETREGS, we always use
+ * the 64-bit format. On a 32-bit kernel only the lower order half
+ * (according to endianness) will be used.
+ */
+int ptrace_setregs (struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 38 * 8))
+ return -EIO;
+
+ regs = (struct pt_regs *) ((unsigned long) child->thread_info +
+ THREAD_SIZE - 32 - sizeof(struct pt_regs));
+
+ for (i = 0; i < 32; i++)
+ __get_user (regs->regs[i], data + i);
+ __get_user (regs->lo, data + EF_LO - EF_R0);
+ __get_user (regs->hi, data + EF_HI - EF_R0);
+ __get_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+
+ /* badvaddr, status, and cause may not be written. */
+
+ return 0;
+}
+
+int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
+{
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user (fregs[i], i + (__u64 __user *) data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user ((__u64) -1, i + (__u64 __user *) data);
+ }
+
+ if (cpu_has_fpu) {
+ unsigned int flags, tmp;
+
+ __put_user (child->thread.fpu.hard.fcr31, data + 64);
+
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ __put_user (tmp, data + 65);
+ } else {
+ __put_user (child->thread.fpu.soft.fcr31, data + 64);
+ __put_user ((__u32) 0, data + 65);
+ }
+
+ return 0;
+}
+
+int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
+{
+ fpureg_t *fregs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+ return -EIO;
+
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user (fregs[i], i + (__u64 __user *) data);
+
+ if (cpu_has_fpu)
+ __get_user (child->thread.fpu.hard.fcr31, data + 64);
+ else
+ __get_user (child->thread.fpu.soft.fcr31, data + 64);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -300,6 +413,22 @@ asmlinkage int sys_ptrace(long request,
break;
}
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs (child, (__u64 __user *) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs (child, (__u32 __user *) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs (child, (__u32 __user *) data);
+ break;
+
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] Revise MIPS64 ptrace interface
2005-09-28 22:11 ` [PATCH] Revise MIPS64 " Daniel Jacobowitz
@ 2005-09-30 0:13 ` Ralf Baechle
0 siblings, 0 replies; 6+ messages in thread
From: Ralf Baechle @ 2005-09-30 0:13 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: linux-mips
On Wed, Sep 28, 2005 at 06:11:15PM -0400, Daniel Jacobowitz wrote:
> Change the N32 debugging ABI to something more sane, and add support
> for o32 and n32 debuggers to trace n64 programs.
>
> Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
> ---
>
> I've now tested everything except the actual _3264 operations, which
> were copied from PPC anyway and I have reasonable faith in. So here's
> a final patch. If this seems reasonable to everyone, I'd like for it
> to be merged, and then I can submit the glibc and gdb bits.
I haven't heared any objections and I guess for an interface like ptrace
such a somewhat trigger happy change is still ok, so I've applied your
patch.
Ralf
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: Revise n32 ptrace interface
2005-09-22 18:26 RFC: Revise n32 ptrace interface Daniel Jacobowitz
2005-09-28 22:11 ` [PATCH] Revise MIPS64 " Daniel Jacobowitz
@ 2005-09-30 0:05 ` Ralf Baechle
2005-09-30 19:46 ` Dominic Sweetman
1 sibling, 1 reply; 6+ messages in thread
From: Ralf Baechle @ 2005-09-30 0:05 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: linux-mips
On Thu, Sep 22, 2005 at 02:26:01PM -0400, Daniel Jacobowitz wrote:
> 1. We need to get at the 64-bit registers. I considered a number of
> different approaches for this and decided to just implement a 64-bit
> PTRACE_GETREGS instead of messing with PTRACE_PEEKUSR. It's much simpler
> this way. I didn't add one for the DSP registers; that can be handled
> separately when someone's working on debug support for them...
I quite deliberately did omit DSP support from 64-bit ptrace(2); there
is currently no MIPS64 processor with DSP support that I know of.
Ralf
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: Revise n32 ptrace interface
2005-09-30 0:05 ` RFC: Revise n32 " Ralf Baechle
@ 2005-09-30 19:46 ` Dominic Sweetman
2005-09-30 20:34 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Dominic Sweetman @ 2005-09-30 19:46 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Daniel Jacobowitz, linux-mips
Ralf Baechle (ralf@linux-mips.org) writes:
> I quite deliberately did omit DSP support from 64-bit ptrace(2); there
> is currently no MIPS64 processor with DSP support that I know of.
This is true so far.
But assuming that 64-bit processing becomes increasingly interesting
(which seems certain) and that some kind of DSP support with extra
registers remains attractive (which seems fairly likely)... well, I'd
have said that any 64-bit MIPS CPU configured from now on is quite
likely to have extra DSP registers.
So while "you aren't going to need it" for a while, anyone thinking of
doing a non-compatible change to ptrace might want to reserve some
space for these registers.
--
Dominic
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: Revise n32 ptrace interface
2005-09-30 19:46 ` Dominic Sweetman
@ 2005-09-30 20:34 ` Daniel Jacobowitz
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2005-09-30 20:34 UTC (permalink / raw)
To: Dominic Sweetman; +Cc: Ralf Baechle, linux-mips
On Fri, Sep 30, 2005 at 08:46:55PM +0100, Dominic Sweetman wrote:
>
> Ralf Baechle (ralf@linux-mips.org) writes:
>
> > I quite deliberately did omit DSP support from 64-bit ptrace(2); there
> > is currently no MIPS64 processor with DSP support that I know of.
>
> This is true so far.
>
> But assuming that 64-bit processing becomes increasingly interesting
> (which seems certain) and that some kind of DSP support with extra
> registers remains attractive (which seems fairly likely)... well, I'd
> have said that any 64-bit MIPS CPU configured from now on is quite
> likely to have extra DSP registers.
>
> So while "you aren't going to need it" for a while, anyone thinking of
> doing a non-compatible change to ptrace might want to reserve some
> space for these registers.
In the future they should be added using PTRACE_GETDSPREGS, or
something similar. No one's designed that yet, so the first person to
need it gets to do it right.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-09-30 20:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-22 18:26 RFC: Revise n32 ptrace interface Daniel Jacobowitz
2005-09-28 22:11 ` [PATCH] Revise MIPS64 " Daniel Jacobowitz
2005-09-30 0:13 ` Ralf Baechle
2005-09-30 0:05 ` RFC: Revise n32 " Ralf Baechle
2005-09-30 19:46 ` Dominic Sweetman
2005-09-30 20:34 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox