struct task_struct;
-extern int ptrace_getregs(struct task_struct *child, __s64 __user *data);
-extern int ptrace_setregs(struct task_struct *child, __s64 __user *data);
+extern int ptrace_getregs(struct task_struct *child,
+ struct user_pt_regs __user *data);
+extern int ptrace_setregs(struct task_struct *child,
+ struct user_pt_regs __user *data);
extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data);
extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data);
#define DSP_CONTROL 77
#define ACX 78
-#ifndef __KERNEL__
/*
- * This struct defines the way the registers are stored on the stack during a
- * system call/exception. As usual the registers k0/k1 aren't being saved.
+ * This struct defines the registers as used by PTRACE_{GET,SET}REGS. The
+ * format is the same for both 32- and 64-bit processes. Registers for 32-bit
+ * processes are sign extended.
*/
+#ifdef __KERNEL__
+struct user_pt_regs {
+#else
struct pt_regs {
+#endif
/* Saved main processor registers. */
- unsigned long regs[32];
+ __u64 regs[32];
/* Saved special registers. */
- unsigned long cp0_status;
- unsigned long hi;
- unsigned long lo;
- unsigned long cp0_badvaddr;
- unsigned long cp0_cause;
- unsigned long cp0_epc;
+ __u64 lo;
+ __u64 hi;
+ __u64 cp0_epc;
+ __u64 cp0_badvaddr;
+ __u64 cp0_status;
+ __u64 cp0_cause;
} __attribute__ ((aligned (8)));
-#endif /* __KERNEL__ */
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
#define PTRACE_GETREGS 12
* 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)
+int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data)
{
struct pt_regs *regs;
int i;
regs = task_pt_regs(child);
for (i = 0; i < 32; i++)
- __put_user((long)regs->regs[i], data + i);
- __put_user((long)regs->lo, data + EF_LO - EF_R0);
- __put_user((long)regs->hi, data + EF_HI - EF_R0);
- __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
- __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
- __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
- __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+ __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]);
+ __put_user((long)regs->lo, (__s64 __user *)&data->lo);
+ __put_user((long)regs->hi, (__s64 __user *)&data->hi);
+ __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
+ __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr);
+ __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status);
+ __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause);
return 0;
}
* 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)
+int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data)
{
struct pt_regs *regs;
int i;
regs = task_pt_regs(child);
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);
+ __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]);
+ __get_user(regs->lo, (__s64 __user *)&data->lo);
+ __get_user(regs->hi, (__s64 __user *)&data->hi);
+ __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
/* badvaddr, status, and cause may not be written. */