diff options
Diffstat (limited to 'arch/mips/kernel/ptrace32.c')
-rw-r--r-- | arch/mips/kernel/ptrace32.c | 81 |
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 | ||
38 | int ptrace_getregs (struct task_struct *child, __s64 __user *data); | ||
39 | int ptrace_setregs (struct task_struct *child, __s64 __user *data); | ||
40 | |||
41 | int ptrace_getfpregs (struct task_struct *child, __u32 __user *data); | ||
42 | int 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; |