x86: rename the struct pt_regs members for 32/64-bit consistency
[firefly-linux-kernel-4.4.55.git] / arch / x86 / ia32 / ptrace32.c
1 /*
2  * 32bit ptrace for x86-64.
3  *
4  * Copyright 2001,2002 Andi Kleen, SuSE Labs.
5  * Some parts copied from arch/i386/kernel/ptrace.c. See that file for earlier
6  * copyright.
7  *
8  * This allows to access 64bit processes too; but there is no way to
9  * see the extended register contents.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/stddef.h>
14 #include <linux/sched.h>
15 #include <linux/syscalls.h>
16 #include <linux/unistd.h>
17 #include <linux/mm.h>
18 #include <linux/err.h>
19 #include <linux/ptrace.h>
20 #include <asm/ptrace.h>
21 #include <asm/compat.h>
22 #include <asm/uaccess.h>
23 #include <asm/user32.h>
24 #include <asm/user.h>
25 #include <asm/errno.h>
26 #include <asm/debugreg.h>
27 #include <asm/i387.h>
28 #include <asm/fpu32.h>
29 #include <asm/ia32.h>
30
31 /*
32  * Determines which flags the user has access to [1 = access, 0 = no access].
33  * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
34  * Also masks reserved bits (31-22, 15, 5, 3, 1).
35  */
36 #define FLAG_MASK 0x54dd5UL
37
38 #define R32(l,q)                                                        \
39         case offsetof(struct user32, regs.l):                           \
40                 stack[offsetof(struct pt_regs, q) / 8] = val; break
41
42 static int putreg32(struct task_struct *child, unsigned regno, u32 val)
43 {
44         __u64 *stack = (__u64 *)task_pt_regs(child);
45
46         switch (regno) {
47         case offsetof(struct user32, regs.fs):
48                 if (val && (val & 3) != 3)
49                         return -EIO;
50                 child->thread.fsindex = val & 0xffff;
51                 break;
52         case offsetof(struct user32, regs.gs):
53                 if (val && (val & 3) != 3)
54                         return -EIO;
55                 child->thread.gsindex = val & 0xffff;
56                 break;
57         case offsetof(struct user32, regs.ds):
58                 if (val && (val & 3) != 3)
59                         return -EIO;
60                 child->thread.ds = val & 0xffff;
61                 break;
62         case offsetof(struct user32, regs.es):
63                 child->thread.es = val & 0xffff;
64                 break;
65         case offsetof(struct user32, regs.ss):
66                 if ((val & 3) != 3)
67                         return -EIO;
68                 stack[offsetof(struct pt_regs, ss)/8] = val & 0xffff;
69                 break;
70         case offsetof(struct user32, regs.cs):
71                 if ((val & 3) != 3)
72                         return -EIO;
73                 stack[offsetof(struct pt_regs, cs)/8] = val & 0xffff;
74                 break;
75
76         R32(ebx, bx);
77         R32(ecx, cx);
78         R32(edx, dx);
79         R32(edi, di);
80         R32(esi, si);
81         R32(ebp, bp);
82         R32(eax, ax);
83         R32(orig_eax, orig_ax);
84         R32(eip, ip);
85         R32(esp, sp);
86
87         case offsetof(struct user32, regs.eflags): {
88                 __u64 *flags = &stack[offsetof(struct pt_regs, flags)/8];
89
90                 val &= FLAG_MASK;
91                 /*
92                  * If the user value contains TF, mark that
93                  * it was not "us" (the debugger) that set it.
94                  * If not, make sure it stays set if we had.
95                  */
96                 if (val & X86_EFLAGS_TF)
97                         clear_tsk_thread_flag(child, TIF_FORCED_TF);
98                 else if (test_tsk_thread_flag(child, TIF_FORCED_TF))
99                         val |= X86_EFLAGS_TF;
100                 *flags = val | (*flags & ~FLAG_MASK);
101                 break;
102         }
103
104         case offsetof(struct user32, u_debugreg[0]) ...
105                 offsetof(struct user32, u_debugreg[7]):
106                 regno -= offsetof(struct user32, u_debugreg[0]);
107                 return ptrace_set_debugreg(child, regno / 4, val);
108
109         default:
110                 if (regno > sizeof(struct user32) || (regno & 3))
111                         return -EIO;
112
113                 /*
114                  * Other dummy fields in the virtual user structure
115                  * are ignored
116                  */
117                 break;
118         }
119         return 0;
120 }
121
122 #undef R32
123
124 #define R32(l,q)                                                        \
125         case offsetof(struct user32, regs.l):                           \
126                 *val = stack[offsetof(struct pt_regs, q)/8]; break
127
128 static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
129 {
130         __u64 *stack = (__u64 *)task_pt_regs(child);
131
132         switch (regno) {
133         case offsetof(struct user32, regs.fs):
134                 *val = child->thread.fsindex;
135                 break;
136         case offsetof(struct user32, regs.gs):
137                 *val = child->thread.gsindex;
138                 break;
139         case offsetof(struct user32, regs.ds):
140                 *val = child->thread.ds;
141                 break;
142         case offsetof(struct user32, regs.es):
143                 *val = child->thread.es;
144                 break;
145
146         R32(cs, cs);
147         R32(ss, ss);
148         R32(ebx, bx);
149         R32(ecx, cx);
150         R32(edx, dx);
151         R32(edi, di);
152         R32(esi, si);
153         R32(ebp, bp);
154         R32(eax, ax);
155         R32(orig_eax, orig_ax);
156         R32(eip, ip);
157         R32(esp, sp);
158
159         case offsetof(struct user32, regs.eflags):
160                 /*
161                  * If the debugger set TF, hide it from the readout.
162                  */
163                 *val = stack[offsetof(struct pt_regs, flags)/8];
164                 if (test_tsk_thread_flag(child, TIF_FORCED_TF))
165                         *val &= ~X86_EFLAGS_TF;
166                 break;
167
168         case offsetof(struct user32, u_debugreg[0]) ...
169                 offsetof(struct user32, u_debugreg[7]):
170                 regno -= offsetof(struct user32, u_debugreg[0]);
171                 *val = ptrace_get_debugreg(child, regno / 4);
172                 break;
173
174         default:
175                 if (regno > sizeof(struct user32) || (regno & 3))
176                         return -EIO;
177
178                 /*
179                  * Other dummy fields in the virtual user structure
180                  * are ignored
181                  */
182                 *val = 0;
183                 break;
184         }
185         return 0;
186 }
187
188 #undef R32
189
190 static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
191 {
192         siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t));
193         compat_siginfo_t __user *si32 = compat_ptr(data);
194         siginfo_t ssi;
195         int ret;
196
197         if (request == PTRACE_SETSIGINFO) {
198                 memset(&ssi, 0, sizeof(siginfo_t));
199                 ret = copy_siginfo_from_user32(&ssi, si32);
200                 if (ret)
201                         return ret;
202                 if (copy_to_user(si, &ssi, sizeof(siginfo_t)))
203                         return -EFAULT;
204         }
205         ret = sys_ptrace(request, pid, addr, (unsigned long)si);
206         if (ret)
207                 return ret;
208         if (request == PTRACE_GETSIGINFO) {
209                 if (copy_from_user(&ssi, si, sizeof(siginfo_t)))
210                         return -EFAULT;
211                 ret = copy_siginfo_to_user32(si32, &ssi);
212         }
213         return ret;
214 }
215
216 asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
217 {
218         struct task_struct *child;
219         struct pt_regs *childregs;
220         void __user *datap = compat_ptr(data);
221         int ret;
222         __u32 val;
223
224         switch (request) {
225         case PTRACE_TRACEME:
226         case PTRACE_ATTACH:
227         case PTRACE_KILL:
228         case PTRACE_CONT:
229         case PTRACE_SINGLESTEP:
230         case PTRACE_SINGLEBLOCK:
231         case PTRACE_DETACH:
232         case PTRACE_SYSCALL:
233         case PTRACE_OLDSETOPTIONS:
234         case PTRACE_SETOPTIONS:
235         case PTRACE_SET_THREAD_AREA:
236         case PTRACE_GET_THREAD_AREA:
237                 return sys_ptrace(request, pid, addr, data);
238
239         default:
240                 return -EINVAL;
241
242         case PTRACE_PEEKTEXT:
243         case PTRACE_PEEKDATA:
244         case PTRACE_POKEDATA:
245         case PTRACE_POKETEXT:
246         case PTRACE_POKEUSR:
247         case PTRACE_PEEKUSR:
248         case PTRACE_GETREGS:
249         case PTRACE_SETREGS:
250         case PTRACE_SETFPREGS:
251         case PTRACE_GETFPREGS:
252         case PTRACE_SETFPXREGS:
253         case PTRACE_GETFPXREGS:
254         case PTRACE_GETEVENTMSG:
255                 break;
256
257         case PTRACE_SETSIGINFO:
258         case PTRACE_GETSIGINFO:
259                 return ptrace32_siginfo(request, pid, addr, data);
260         }
261
262         child = ptrace_get_task_struct(pid);
263         if (IS_ERR(child))
264                 return PTR_ERR(child);
265
266         ret = ptrace_check_attach(child, request == PTRACE_KILL);
267         if (ret < 0)
268                 goto out;
269
270         childregs = task_pt_regs(child);
271
272         switch (request) {
273         case PTRACE_PEEKDATA:
274         case PTRACE_PEEKTEXT:
275                 ret = 0;
276                 if (access_process_vm(child, addr, &val, sizeof(u32), 0) !=
277                     sizeof(u32))
278                         ret = -EIO;
279                 else
280                         ret = put_user(val, (unsigned int __user *)datap);
281                 break;
282
283         case PTRACE_POKEDATA:
284         case PTRACE_POKETEXT:
285                 ret = 0;
286                 if (access_process_vm(child, addr, &data, sizeof(u32), 1) !=
287                     sizeof(u32))
288                         ret = -EIO;
289                 break;
290
291         case PTRACE_PEEKUSR:
292                 ret = getreg32(child, addr, &val);
293                 if (ret == 0)
294                         ret = put_user(val, (__u32 __user *)datap);
295                 break;
296
297         case PTRACE_POKEUSR:
298                 ret = putreg32(child, addr, data);
299                 break;
300
301         case PTRACE_GETREGS: { /* Get all gp regs from the child. */
302                 int i;
303
304                 if (!access_ok(VERIFY_WRITE, datap, 16*4)) {
305                         ret = -EIO;
306                         break;
307                 }
308                 ret = 0;
309                 for (i = 0; i <= 16*4; i += sizeof(__u32)) {
310                         getreg32(child, i, &val);
311                         ret |= __put_user(val, (u32 __user *)datap);
312                         datap += sizeof(u32);
313                 }
314                 break;
315         }
316
317         case PTRACE_SETREGS: { /* Set all gp regs in the child. */
318                 unsigned long tmp;
319                 int i;
320
321                 if (!access_ok(VERIFY_READ, datap, 16*4)) {
322                         ret = -EIO;
323                         break;
324                 }
325                 ret = 0;
326                 for (i = 0; i <= 16*4; i += sizeof(u32)) {
327                         ret |= __get_user(tmp, (u32 __user *)datap);
328                         putreg32(child, i, tmp);
329                         datap += sizeof(u32);
330                 }
331                 break;
332         }
333
334         case PTRACE_GETFPREGS:
335                 ret = -EIO;
336                 if (!access_ok(VERIFY_READ, compat_ptr(data),
337                                sizeof(struct user_i387_struct)))
338                         break;
339                 save_i387_ia32(child, datap, childregs, 1);
340                 ret = 0;
341                         break;
342
343         case PTRACE_SETFPREGS:
344                 ret = -EIO;
345                 if (!access_ok(VERIFY_WRITE, datap,
346                                sizeof(struct user_i387_struct)))
347                         break;
348                 ret = 0;
349                 /* don't check EFAULT to be bug-to-bug compatible to i386 */
350                 restore_i387_ia32(child, datap, 1);
351                 break;
352
353         case PTRACE_GETFPXREGS: {
354                 struct user32_fxsr_struct __user *u = datap;
355
356                 init_fpu(child);
357                 ret = -EIO;
358                 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
359                         break;
360                         ret = -EFAULT;
361                 if (__copy_to_user(u, &child->thread.i387.fxsave, sizeof(*u)))
362                         break;
363                 ret = __put_user(childregs->cs, &u->fcs);
364                 ret |= __put_user(child->thread.ds, &u->fos);
365                 break;
366         }
367         case PTRACE_SETFPXREGS: {
368                 struct user32_fxsr_struct __user *u = datap;
369
370                 unlazy_fpu(child);
371                 ret = -EIO;
372                 if (!access_ok(VERIFY_READ, u, sizeof(*u)))
373                         break;
374                 /*
375                  * no checking to be bug-to-bug compatible with i386.
376                  * but silence warning
377                  */
378                 if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
379                         ;
380                 set_stopped_child_used_math(child);
381                 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
382                 ret = 0;
383                 break;
384         }
385
386         case PTRACE_GETEVENTMSG:
387                 ret = put_user(child->ptrace_message,
388                                (unsigned int __user *)compat_ptr(data));
389                 break;
390
391         default:
392                 BUG();
393         }
394
395  out:
396         put_task_struct(child);
397         return ret;
398 }