1 /* 2 * Copyright 2003 PathScale, Inc. 3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 4 * 5 * Licensed under the GPL 6 */ 7 8 #include <linux/mm.h> 9 #include <linux/sched.h> 10 #include <linux/errno.h> 11 #define __FRAME_OFFSETS 12 #include <asm/ptrace.h> 13 #include <linux/uaccess.h> 14 #include <asm/ptrace-abi.h> 15 16 /* 17 * determines which flags the user has access to. 18 * 1 = access 0 = no access 19 */ 20 #define FLAG_MASK 0x44dd5UL 21 22 static const int reg_offsets[] = 23 { 24 [R8 >> 3] = HOST_R8, 25 [R9 >> 3] = HOST_R9, 26 [R10 >> 3] = HOST_R10, 27 [R11 >> 3] = HOST_R11, 28 [R12 >> 3] = HOST_R12, 29 [R13 >> 3] = HOST_R13, 30 [R14 >> 3] = HOST_R14, 31 [R15 >> 3] = HOST_R15, 32 [RIP >> 3] = HOST_IP, 33 [RSP >> 3] = HOST_SP, 34 [RAX >> 3] = HOST_AX, 35 [RBX >> 3] = HOST_BX, 36 [RCX >> 3] = HOST_CX, 37 [RDX >> 3] = HOST_DX, 38 [RSI >> 3] = HOST_SI, 39 [RDI >> 3] = HOST_DI, 40 [RBP >> 3] = HOST_BP, 41 [CS >> 3] = HOST_CS, 42 [SS >> 3] = HOST_SS, 43 [FS_BASE >> 3] = HOST_FS_BASE, 44 [GS_BASE >> 3] = HOST_GS_BASE, 45 [DS >> 3] = HOST_DS, 46 [ES >> 3] = HOST_ES, 47 [FS >> 3] = HOST_FS, 48 [GS >> 3] = HOST_GS, 49 [EFLAGS >> 3] = HOST_EFLAGS, 50 [ORIG_RAX >> 3] = HOST_ORIG_AX, 51 }; 52 53 int putreg(struct task_struct *child, int regno, unsigned long value) 54 { 55 #ifdef TIF_IA32 56 /* 57 * Some code in the 64bit emulation may not be 64bit clean. 58 * Don't take any chances. 59 */ 60 if (test_tsk_thread_flag(child, TIF_IA32)) 61 value &= 0xffffffff; 62 #endif 63 switch (regno) { 64 case R8: 65 case R9: 66 case R10: 67 case R11: 68 case R12: 69 case R13: 70 case R14: 71 case R15: 72 case RIP: 73 case RSP: 74 case RAX: 75 case RBX: 76 case RCX: 77 case RDX: 78 case RSI: 79 case RDI: 80 case RBP: 81 break; 82 83 case ORIG_RAX: 84 /* Update the syscall number. */ 85 UPT_SYSCALL_NR(&child->thread.regs.regs) = value; 86 break; 87 88 case FS: 89 case GS: 90 case DS: 91 case ES: 92 case SS: 93 case CS: 94 if (value && (value & 3) != 3) 95 return -EIO; 96 value &= 0xffff; 97 break; 98 99 case FS_BASE: 100 case GS_BASE: 101 if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) 102 return -EIO; 103 break; 104 105 case EFLAGS: 106 value &= FLAG_MASK; 107 child->thread.regs.regs.gp[HOST_EFLAGS] |= value; 108 return 0; 109 110 default: 111 panic("Bad register in putreg(): %d\n", regno); 112 } 113 114 child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; 115 return 0; 116 } 117 118 int poke_user(struct task_struct *child, long addr, long data) 119 { 120 if ((addr & 3) || addr < 0) 121 return -EIO; 122 123 if (addr < MAX_REG_OFFSET) 124 return putreg(child, addr, data); 125 else if ((addr >= offsetof(struct user, u_debugreg[0])) && 126 (addr <= offsetof(struct user, u_debugreg[7]))) { 127 addr -= offsetof(struct user, u_debugreg[0]); 128 addr = addr >> 3; 129 if ((addr == 4) || (addr == 5)) 130 return -EIO; 131 child->thread.arch.debugregs[addr] = data; 132 return 0; 133 } 134 return -EIO; 135 } 136 137 unsigned long getreg(struct task_struct *child, int regno) 138 { 139 unsigned long mask = ~0UL; 140 #ifdef TIF_IA32 141 if (test_tsk_thread_flag(child, TIF_IA32)) 142 mask = 0xffffffff; 143 #endif 144 switch (regno) { 145 case R8: 146 case R9: 147 case R10: 148 case R11: 149 case R12: 150 case R13: 151 case R14: 152 case R15: 153 case RIP: 154 case RSP: 155 case RAX: 156 case RBX: 157 case RCX: 158 case RDX: 159 case RSI: 160 case RDI: 161 case RBP: 162 case ORIG_RAX: 163 case EFLAGS: 164 case FS_BASE: 165 case GS_BASE: 166 break; 167 case FS: 168 case GS: 169 case DS: 170 case ES: 171 case SS: 172 case CS: 173 mask = 0xffff; 174 break; 175 default: 176 panic("Bad register in getreg: %d\n", regno); 177 } 178 return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; 179 } 180 181 int peek_user(struct task_struct *child, long addr, long data) 182 { 183 /* read the word at location addr in the USER area. */ 184 unsigned long tmp; 185 186 if ((addr & 3) || addr < 0) 187 return -EIO; 188 189 tmp = 0; /* Default return condition */ 190 if (addr < MAX_REG_OFFSET) 191 tmp = getreg(child, addr); 192 else if ((addr >= offsetof(struct user, u_debugreg[0])) && 193 (addr <= offsetof(struct user, u_debugreg[7]))) { 194 addr -= offsetof(struct user, u_debugreg[0]); 195 addr = addr >> 2; 196 tmp = child->thread.arch.debugregs[addr]; 197 } 198 return put_user(tmp, (unsigned long *) data); 199 } 200 201 /* XXX Mostly copied from sys-i386 */ 202 int is_syscall(unsigned long addr) 203 { 204 unsigned short instr; 205 int n; 206 207 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 208 if (n) { 209 /* 210 * access_process_vm() grants access to vsyscall and stub, 211 * while copy_from_user doesn't. Maybe access_process_vm is 212 * slow, but that doesn't matter, since it will be called only 213 * in case of singlestepping, if copy_from_user failed. 214 */ 215 n = access_process_vm(current, addr, &instr, sizeof(instr), 216 FOLL_FORCE); 217 if (n != sizeof(instr)) { 218 printk("is_syscall : failed to read instruction from " 219 "0x%lx\n", addr); 220 return 1; 221 } 222 } 223 /* sysenter */ 224 return instr == 0x050f; 225 } 226 227 static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) 228 { 229 int err, n, cpu = ((struct thread_info *) child->stack)->cpu; 230 struct user_i387_struct fpregs; 231 232 err = save_i387_registers(userspace_pid[cpu], 233 (unsigned long *) &fpregs); 234 if (err) 235 return err; 236 237 n = copy_to_user(buf, &fpregs, sizeof(fpregs)); 238 if (n > 0) 239 return -EFAULT; 240 241 return n; 242 } 243 244 static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) 245 { 246 int n, cpu = ((struct thread_info *) child->stack)->cpu; 247 struct user_i387_struct fpregs; 248 249 n = copy_from_user(&fpregs, buf, sizeof(fpregs)); 250 if (n > 0) 251 return -EFAULT; 252 253 return restore_i387_registers(userspace_pid[cpu], 254 (unsigned long *) &fpregs); 255 } 256 257 long subarch_ptrace(struct task_struct *child, long request, 258 unsigned long addr, unsigned long data) 259 { 260 int ret = -EIO; 261 void __user *datap = (void __user *) data; 262 263 switch (request) { 264 case PTRACE_GETFPREGS: /* Get the child FPU state. */ 265 ret = get_fpregs(datap, child); 266 break; 267 case PTRACE_SETFPREGS: /* Set the child FPU state. */ 268 ret = set_fpregs(datap, child); 269 break; 270 case PTRACE_ARCH_PRCTL: 271 /* XXX Calls ptrace on the host - needs some SMP thinking */ 272 ret = arch_prctl(child, data, (void __user *) addr); 273 break; 274 } 275 276 return ret; 277 } 278