aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-x86_64/ptrace.c')
-rw-r--r--arch/um/sys-x86_64/ptrace.c101
1 files changed, 39 insertions, 62 deletions
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index b9032992a997..a3cfeed17af4 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
@@ -12,17 +13,10 @@
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13#include <asm/elf.h> 14#include <asm/elf.h>
14 15
15/* XXX x86_64 */ 16/*
16unsigned long not_ss; 17 * determines which flags the user has access to.
17unsigned long not_ds; 18 * 1 = access 0 = no access
18unsigned long not_es; 19 */
19
20#define SC_SS(r) (not_ss)
21#define SC_DS(r) (not_ds)
22#define SC_ES(r) (not_es)
23
24/* determines which flags the user has access to. */
25/* 1 = access 0 = no access */
26#define FLAG_MASK 0x44dd5UL 20#define FLAG_MASK 0x44dd5UL
27 21
28int putreg(struct task_struct *child, int regno, unsigned long value) 22int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -66,20 +60,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
66 60
67int poke_user(struct task_struct *child, long addr, long data) 61int poke_user(struct task_struct *child, long addr, long data)
68{ 62{
69 if ((addr & 3) || addr < 0) 63 if ((addr & 3) || addr < 0)
70 return -EIO; 64 return -EIO;
71 65
72 if (addr < MAX_REG_OFFSET) 66 if (addr < MAX_REG_OFFSET)
73 return putreg(child, addr, data); 67 return putreg(child, addr, data);
74 else if((addr >= offsetof(struct user, u_debugreg[0])) && 68 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
75 (addr <= offsetof(struct user, u_debugreg[7]))){ 69 (addr <= offsetof(struct user, u_debugreg[7]))){
76 addr -= offsetof(struct user, u_debugreg[0]); 70 addr -= offsetof(struct user, u_debugreg[0]);
77 addr = addr >> 2; 71 addr = addr >> 2;
78 if((addr == 4) || (addr == 5)) return -EIO; 72 if ((addr == 4) || (addr == 5))
79 child->thread.arch.debugregs[addr] = data; 73 return -EIO;
80 return 0; 74 child->thread.arch.debugregs[addr] = data;
81 } 75 return 0;
82 return -EIO; 76 }
77 return -EIO;
83} 78}
84 79
85unsigned long getreg(struct task_struct *child, int regno) 80unsigned long getreg(struct task_struct *child, int regno)
@@ -107,29 +102,22 @@ unsigned long getreg(struct task_struct *child, int regno)
107int peek_user(struct task_struct *child, long addr, long data) 102int peek_user(struct task_struct *child, long addr, long data)
108{ 103{
109 /* read the word at location addr in the USER area. */ 104 /* read the word at location addr in the USER area. */
110 unsigned long tmp; 105 unsigned long tmp;
111
112 if ((addr & 3) || addr < 0)
113 return -EIO;
114
115 tmp = 0; /* Default return condition */
116 if(addr < MAX_REG_OFFSET){
117 tmp = getreg(child, addr);
118 }
119 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
120 (addr <= offsetof(struct user, u_debugreg[7]))){
121 addr -= offsetof(struct user, u_debugreg[0]);
122 addr = addr >> 2;
123 tmp = child->thread.arch.debugregs[addr];
124 }
125 return put_user(tmp, (unsigned long *) data);
126}
127 106
128void arch_switch(void) 107 if ((addr & 3) || addr < 0)
129{ 108 return -EIO;
130/* XXX 109
131 printk("arch_switch\n"); 110 tmp = 0; /* Default return condition */
132*/ 111 if (addr < MAX_REG_OFFSET){
112 tmp = getreg(child, addr);
113 }
114 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
115 (addr <= offsetof(struct user, u_debugreg[7]))){
116 addr -= offsetof(struct user, u_debugreg[0]);
117 addr = addr >> 2;
118 tmp = child->thread.arch.debugregs[addr];
119 }
120 return put_user(tmp, (unsigned long *) data);
133} 121}
134 122
135/* XXX Mostly copied from sys-i386 */ 123/* XXX Mostly copied from sys-i386 */
@@ -139,21 +127,21 @@ int is_syscall(unsigned long addr)
139 int n; 127 int n;
140 128
141 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 129 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
142 if(n){ 130 if (n){
143 /* access_process_vm() grants access to vsyscall and stub, 131 /* access_process_vm() grants access to vsyscall and stub,
144 * while copy_from_user doesn't. Maybe access_process_vm is 132 * while copy_from_user doesn't. Maybe access_process_vm is
145 * slow, but that doesn't matter, since it will be called only 133 * slow, but that doesn't matter, since it will be called only
146 * in case of singlestepping, if copy_from_user failed. 134 * in case of singlestepping, if copy_from_user failed.
147 */ 135 */
148 n = access_process_vm(current, addr, &instr, sizeof(instr), 0); 136 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
149 if(n != sizeof(instr)) { 137 if (n != sizeof(instr)) {
150 printk("is_syscall : failed to read instruction from " 138 printk("is_syscall : failed to read instruction from "
151 "0x%lx\n", addr); 139 "0x%lx\n", addr);
152 return(1); 140 return 1;
153 } 141 }
154 } 142 }
155 /* sysenter */ 143 /* sysenter */
156 return(instr == 0x050f); 144 return instr == 0x050f;
157} 145}
158 146
159int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) 147int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
@@ -204,14 +192,3 @@ long subarch_ptrace(struct task_struct *child, long request, long addr,
204 192
205 return ret; 193 return ret;
206} 194}
207
208/*
209 * Overrides for Emacs so that we follow Linus's tabbing style.
210 * Emacs will notice this stuff at the end of the file and automatically
211 * adjust the settings for this buffer only. This must remain at the end
212 * of the file.
213 * ---------------------------------------------------------------------------
214 * Local variables:
215 * c-file-style: "linux"
216 * End:
217 */