aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/ptrace32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/ptrace32.c')
-rw-r--r--arch/mips/kernel/ptrace32.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 5c45a5880226..c28cdddd4c21 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -35,6 +35,12 @@
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#include <asm/bootinfo.h> 36#include <asm/bootinfo.h>
37 37
38int ptrace_getregs (struct task_struct *child, __s64 __user *data);
39int ptrace_setregs (struct task_struct *child, __s64 __user *data);
40
41int ptrace_getfpregs (struct task_struct *child, __u32 __user *data);
42int ptrace_setfpregs (struct task_struct *child, __u32 __user *data);
43
38/* 44/*
39 * Tracing a 32-bit process with a 64-bit strace and vice versa will not 45 * Tracing a 32-bit process with a 64-bit strace and vice versa will not
40 * work. I don't know how to fix this. 46 * work. I don't know how to fix this.
@@ -99,6 +105,35 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
99 break; 105 break;
100 } 106 }
101 107
108 /*
109 * Read 4 bytes of the other process' storage
110 * data is a pointer specifying where the user wants the
111 * 4 bytes copied into
112 * addr is a pointer in the user's storage that contains an 8 byte
113 * address in the other process of the 4 bytes that is to be read
114 * (this is run in a 32-bit process looking at a 64-bit process)
115 * when I and D space are separate, these will need to be fixed.
116 */
117 case PTRACE_PEEKTEXT_3264:
118 case PTRACE_PEEKDATA_3264: {
119 u32 tmp;
120 int copied;
121 u32 __user * addrOthers;
122
123 ret = -EIO;
124
125 /* Get the addr in the other process that we want to read */
126 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
127 break;
128
129 copied = access_process_vm(child, (u64)addrOthers, &tmp,
130 sizeof(tmp), 0);
131 if (copied != sizeof(tmp))
132 break;
133 ret = put_user(tmp, (u32 __user *) (unsigned long) data);
134 break;
135 }
136
102 /* Read the word at location addr in the USER area. */ 137 /* Read the word at location addr in the USER area. */
103 case PTRACE_PEEKUSR: { 138 case PTRACE_PEEKUSR: {
104 struct pt_regs *regs; 139 struct pt_regs *regs;
@@ -202,6 +237,31 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
202 ret = -EIO; 237 ret = -EIO;
203 break; 238 break;
204 239
240 /*
241 * Write 4 bytes into the other process' storage
242 * data is the 4 bytes that the user wants written
243 * addr is a pointer in the user's storage that contains an
244 * 8 byte address in the other process where the 4 bytes
245 * that is to be written
246 * (this is run in a 32-bit process looking at a 64-bit process)
247 * when I and D space are separate, these will need to be fixed.
248 */
249 case PTRACE_POKETEXT_3264:
250 case PTRACE_POKEDATA_3264: {
251 u32 __user * addrOthers;
252
253 /* Get the addr in the other process that we want to write into */
254 ret = -EIO;
255 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
256 break;
257 ret = 0;
258 if (access_process_vm(child, (u64)addrOthers, &data,
259 sizeof(data), 1) == sizeof(data))
260 break;
261 ret = -EIO;
262 break;
263 }
264
205 case PTRACE_POKEUSR: { 265 case PTRACE_POKEUSR: {
206 struct pt_regs *regs; 266 struct pt_regs *regs;
207 ret = 0; 267 ret = 0;
@@ -276,6 +336,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
276 break; 336 break;
277 } 337 }
278 338
339 case PTRACE_GETREGS:
340 ret = ptrace_getregs (child, (__u64 __user *) (__u64) data);
341 break;
342
343 case PTRACE_SETREGS:
344 ret = ptrace_setregs (child, (__u64 __user *) (__u64) data);
345 break;
346
347 case PTRACE_GETFPREGS:
348 ret = ptrace_getfpregs (child, (__u32 __user *) (__u64) data);
349 break;
350
351 case PTRACE_SETFPREGS:
352 ret = ptrace_setfpregs (child, (__u32 __user *) (__u64) data);
353 break;
354
279 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 355 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
280 case PTRACE_CONT: { /* restart after signal. */ 356 case PTRACE_CONT: { /* restart after signal. */
281 ret = -EIO; 357 ret = -EIO;
@@ -320,6 +396,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
320 (unsigned int __user *) (unsigned long) data); 396 (unsigned int __user *) (unsigned long) data);
321 break; 397 break;
322 398
399 case PTRACE_GET_THREAD_AREA_3264:
400 ret = put_user(child->thread_info->tp_value,
401 (unsigned long __user *) (unsigned long) data);
402 break;
403
323 default: 404 default:
324 ret = ptrace_request(child, request, addr, data); 405 ret = ptrace_request(child, request, addr, data);
325 break; 406 break;