0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/mm.h>
0009 #include <linux/sched.h>
0010 #include <linux/errno.h>
0011 #define __FRAME_OFFSETS
0012 #include <asm/ptrace.h>
0013 #include <linux/uaccess.h>
0014 #include <registers.h>
0015 #include <asm/ptrace-abi.h>
0016
0017
0018
0019
0020
0021 #define FLAG_MASK 0x44dd5UL
0022
0023 static const int reg_offsets[] =
0024 {
0025 [R8 >> 3] = HOST_R8,
0026 [R9 >> 3] = HOST_R9,
0027 [R10 >> 3] = HOST_R10,
0028 [R11 >> 3] = HOST_R11,
0029 [R12 >> 3] = HOST_R12,
0030 [R13 >> 3] = HOST_R13,
0031 [R14 >> 3] = HOST_R14,
0032 [R15 >> 3] = HOST_R15,
0033 [RIP >> 3] = HOST_IP,
0034 [RSP >> 3] = HOST_SP,
0035 [RAX >> 3] = HOST_AX,
0036 [RBX >> 3] = HOST_BX,
0037 [RCX >> 3] = HOST_CX,
0038 [RDX >> 3] = HOST_DX,
0039 [RSI >> 3] = HOST_SI,
0040 [RDI >> 3] = HOST_DI,
0041 [RBP >> 3] = HOST_BP,
0042 [CS >> 3] = HOST_CS,
0043 [SS >> 3] = HOST_SS,
0044 [FS_BASE >> 3] = HOST_FS_BASE,
0045 [GS_BASE >> 3] = HOST_GS_BASE,
0046 [DS >> 3] = HOST_DS,
0047 [ES >> 3] = HOST_ES,
0048 [FS >> 3] = HOST_FS,
0049 [GS >> 3] = HOST_GS,
0050 [EFLAGS >> 3] = HOST_EFLAGS,
0051 [ORIG_RAX >> 3] = HOST_ORIG_AX,
0052 };
0053
0054 int putreg(struct task_struct *child, int regno, unsigned long value)
0055 {
0056 switch (regno) {
0057 case R8:
0058 case R9:
0059 case R10:
0060 case R11:
0061 case R12:
0062 case R13:
0063 case R14:
0064 case R15:
0065 case RIP:
0066 case RSP:
0067 case RAX:
0068 case RBX:
0069 case RCX:
0070 case RDX:
0071 case RSI:
0072 case RDI:
0073 case RBP:
0074 break;
0075
0076 case ORIG_RAX:
0077
0078 UPT_SYSCALL_NR(&child->thread.regs.regs) = value;
0079 break;
0080
0081 case FS:
0082 case GS:
0083 case DS:
0084 case ES:
0085 case SS:
0086 case CS:
0087 if (value && (value & 3) != 3)
0088 return -EIO;
0089 value &= 0xffff;
0090 break;
0091
0092 case FS_BASE:
0093 case GS_BASE:
0094 if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
0095 return -EIO;
0096 break;
0097
0098 case EFLAGS:
0099 value &= FLAG_MASK;
0100 child->thread.regs.regs.gp[HOST_EFLAGS] |= value;
0101 return 0;
0102
0103 default:
0104 panic("Bad register in putreg(): %d\n", regno);
0105 }
0106
0107 child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value;
0108 return 0;
0109 }
0110
0111 int poke_user(struct task_struct *child, long addr, long data)
0112 {
0113 if ((addr & 3) || addr < 0)
0114 return -EIO;
0115
0116 if (addr < MAX_REG_OFFSET)
0117 return putreg(child, addr, data);
0118 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
0119 (addr <= offsetof(struct user, u_debugreg[7]))) {
0120 addr -= offsetof(struct user, u_debugreg[0]);
0121 addr = addr >> 3;
0122 if ((addr == 4) || (addr == 5))
0123 return -EIO;
0124 child->thread.arch.debugregs[addr] = data;
0125 return 0;
0126 }
0127 return -EIO;
0128 }
0129
0130 unsigned long getreg(struct task_struct *child, int regno)
0131 {
0132 unsigned long mask = ~0UL;
0133
0134 switch (regno) {
0135 case R8:
0136 case R9:
0137 case R10:
0138 case R11:
0139 case R12:
0140 case R13:
0141 case R14:
0142 case R15:
0143 case RIP:
0144 case RSP:
0145 case RAX:
0146 case RBX:
0147 case RCX:
0148 case RDX:
0149 case RSI:
0150 case RDI:
0151 case RBP:
0152 case ORIG_RAX:
0153 case EFLAGS:
0154 case FS_BASE:
0155 case GS_BASE:
0156 break;
0157 case FS:
0158 case GS:
0159 case DS:
0160 case ES:
0161 case SS:
0162 case CS:
0163 mask = 0xffff;
0164 break;
0165 default:
0166 panic("Bad register in getreg: %d\n", regno);
0167 }
0168 return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]];
0169 }
0170
0171 int peek_user(struct task_struct *child, long addr, long data)
0172 {
0173
0174 unsigned long tmp;
0175
0176 if ((addr & 3) || addr < 0)
0177 return -EIO;
0178
0179 tmp = 0;
0180 if (addr < MAX_REG_OFFSET)
0181 tmp = getreg(child, addr);
0182 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
0183 (addr <= offsetof(struct user, u_debugreg[7]))) {
0184 addr -= offsetof(struct user, u_debugreg[0]);
0185 addr = addr >> 2;
0186 tmp = child->thread.arch.debugregs[addr];
0187 }
0188 return put_user(tmp, (unsigned long *) data);
0189 }
0190
0191
0192 int is_syscall(unsigned long addr)
0193 {
0194 unsigned short instr;
0195 int n;
0196
0197 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
0198 if (n) {
0199
0200
0201
0202
0203
0204
0205 n = access_process_vm(current, addr, &instr, sizeof(instr),
0206 FOLL_FORCE);
0207 if (n != sizeof(instr)) {
0208 printk("is_syscall : failed to read instruction from "
0209 "0x%lx\n", addr);
0210 return 1;
0211 }
0212 }
0213
0214 return instr == 0x050f;
0215 }
0216
0217 static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
0218 {
0219 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
0220 struct user_i387_struct fpregs;
0221
0222 err = save_i387_registers(userspace_pid[cpu],
0223 (unsigned long *) &fpregs);
0224 if (err)
0225 return err;
0226
0227 n = copy_to_user(buf, &fpregs, sizeof(fpregs));
0228 if (n > 0)
0229 return -EFAULT;
0230
0231 return n;
0232 }
0233
0234 static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
0235 {
0236 int n, cpu = ((struct thread_info *) child->stack)->cpu;
0237 struct user_i387_struct fpregs;
0238
0239 n = copy_from_user(&fpregs, buf, sizeof(fpregs));
0240 if (n > 0)
0241 return -EFAULT;
0242
0243 return restore_i387_registers(userspace_pid[cpu],
0244 (unsigned long *) &fpregs);
0245 }
0246
0247 long subarch_ptrace(struct task_struct *child, long request,
0248 unsigned long addr, unsigned long data)
0249 {
0250 int ret = -EIO;
0251 void __user *datap = (void __user *) data;
0252
0253 switch (request) {
0254 case PTRACE_GETFPREGS:
0255 ret = get_fpregs(datap, child);
0256 break;
0257 case PTRACE_SETFPREGS:
0258 ret = set_fpregs(datap, child);
0259 break;
0260 case PTRACE_ARCH_PRCTL:
0261
0262 ret = arch_prctl(child, data, (void __user *) addr);
0263 break;
0264 }
0265
0266 return ret;
0267 }