aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68knommu/kernel/ptrace.c')
-rw-r--r--arch/m68knommu/kernel/ptrace.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 6fe7c38cd556..6709fb707335 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -112,9 +112,12 @@ void ptrace_disable(struct task_struct *child)
112 user_disable_single_step(child); 112 user_disable_single_step(child);
113} 113}
114 114
115long arch_ptrace(struct task_struct *child, long request, long addr, long data) 115long arch_ptrace(struct task_struct *child, long request,
116 unsigned long addr, unsigned long data)
116{ 117{
117 int ret; 118 int ret;
119 int regno = addr >> 2;
120 unsigned long __user *datap = (unsigned long __user *) data;
118 121
119 switch (request) { 122 switch (request) {
120 /* read the word at location addr in the USER area. */ 123 /* read the word at location addr in the USER area. */
@@ -122,53 +125,48 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
122 unsigned long tmp; 125 unsigned long tmp;
123 126
124 ret = -EIO; 127 ret = -EIO;
125 if ((addr & 3) || addr < 0 || 128 if ((addr & 3) || addr > sizeof(struct user) - 3)
126 addr > sizeof(struct user) - 3)
127 break; 129 break;
128 130
129 tmp = 0; /* Default return condition */ 131 tmp = 0; /* Default return condition */
130 addr = addr >> 2; /* temporary hack. */
131 ret = -EIO; 132 ret = -EIO;
132 if (addr < 19) { 133 if (regno < 19) {
133 tmp = get_reg(child, addr); 134 tmp = get_reg(child, regno);
134 if (addr == PT_SR) 135 if (regno == PT_SR)
135 tmp >>= 16; 136 tmp >>= 16;
136 } else if (addr >= 21 && addr < 49) { 137 } else if (regno >= 21 && regno < 49) {
137 tmp = child->thread.fp[addr - 21]; 138 tmp = child->thread.fp[regno - 21];
138 } else if (addr == 49) { 139 } else if (regno == 49) {
139 tmp = child->mm->start_code; 140 tmp = child->mm->start_code;
140 } else if (addr == 50) { 141 } else if (regno == 50) {
141 tmp = child->mm->start_data; 142 tmp = child->mm->start_data;
142 } else if (addr == 51) { 143 } else if (regno == 51) {
143 tmp = child->mm->end_code; 144 tmp = child->mm->end_code;
144 } else 145 } else
145 break; 146 break;
146 ret = put_user(tmp,(unsigned long *) data); 147 ret = put_user(tmp, datap);
147 break; 148 break;
148 } 149 }
149 150
150 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 151 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
151 ret = -EIO; 152 ret = -EIO;
152 if ((addr & 3) || addr < 0 || 153 if ((addr & 3) || addr > sizeof(struct user) - 3)
153 addr > sizeof(struct user) - 3)
154 break; 154 break;
155 155
156 addr = addr >> 2; /* temporary hack. */ 156 if (regno == PT_SR) {
157
158 if (addr == PT_SR) {
159 data &= SR_MASK; 157 data &= SR_MASK;
160 data <<= 16; 158 data <<= 16;
161 data |= get_reg(child, PT_SR) & ~(SR_MASK << 16); 159 data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
162 } 160 }
163 if (addr < 19) { 161 if (regno < 19) {
164 if (put_reg(child, addr, data)) 162 if (put_reg(child, regno, data))
165 break; 163 break;
166 ret = 0; 164 ret = 0;
167 break; 165 break;
168 } 166 }
169 if (addr >= 21 && addr < 48) 167 if (regno >= 21 && regno < 48)
170 { 168 {
171 child->thread.fp[addr - 21] = data; 169 child->thread.fp[regno - 21] = data;
172 ret = 0; 170 ret = 0;
173 } 171 }
174 break; 172 break;
@@ -180,11 +178,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
180 tmp = get_reg(child, i); 178 tmp = get_reg(child, i);
181 if (i == PT_SR) 179 if (i == PT_SR)
182 tmp >>= 16; 180 tmp >>= 16;
183 if (put_user(tmp, (unsigned long *) data)) { 181 if (put_user(tmp, datap)) {
184 ret = -EFAULT; 182 ret = -EFAULT;
185 break; 183 break;
186 } 184 }
187 data += sizeof(long); 185 datap++;
188 } 186 }
189 ret = 0; 187 ret = 0;
190 break; 188 break;
@@ -194,7 +192,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
194 int i; 192 int i;
195 unsigned long tmp; 193 unsigned long tmp;
196 for (i = 0; i < 19; i++) { 194 for (i = 0; i < 19; i++) {
197 if (get_user(tmp, (unsigned long *) data)) { 195 if (get_user(tmp, datap)) {
198 ret = -EFAULT; 196 ret = -EFAULT;
199 break; 197 break;
200 } 198 }
@@ -204,7 +202,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
204 tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16); 202 tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
205 } 203 }
206 put_reg(child, i, tmp); 204 put_reg(child, i, tmp);
207 data += sizeof(long); 205 datap++;
208 } 206 }
209 ret = 0; 207 ret = 0;
210 break; 208 break;
@@ -213,7 +211,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
213#ifdef PTRACE_GETFPREGS 211#ifdef PTRACE_GETFPREGS
214 case PTRACE_GETFPREGS: { /* Get the child FPU state. */ 212 case PTRACE_GETFPREGS: { /* Get the child FPU state. */
215 ret = 0; 213 ret = 0;
216 if (copy_to_user((void *)data, &child->thread.fp, 214 if (copy_to_user(datap, &child->thread.fp,
217 sizeof(struct user_m68kfp_struct))) 215 sizeof(struct user_m68kfp_struct)))
218 ret = -EFAULT; 216 ret = -EFAULT;
219 break; 217 break;
@@ -223,7 +221,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
223#ifdef PTRACE_SETFPREGS 221#ifdef PTRACE_SETFPREGS
224 case PTRACE_SETFPREGS: { /* Set the child FPU state. */ 222 case PTRACE_SETFPREGS: { /* Set the child FPU state. */
225 ret = 0; 223 ret = 0;
226 if (copy_from_user(&child->thread.fp, (void *)data, 224 if (copy_from_user(&child->thread.fp, datap,
227 sizeof(struct user_m68kfp_struct))) 225 sizeof(struct user_m68kfp_struct)))
228 ret = -EFAULT; 226 ret = -EFAULT;
229 break; 227 break;
@@ -231,8 +229,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
231#endif 229#endif
232 230
233 case PTRACE_GET_THREAD_AREA: 231 case PTRACE_GET_THREAD_AREA:
234 ret = put_user(task_thread_info(child)->tp_value, 232 ret = put_user(task_thread_info(child)->tp_value, datap);
235 (unsigned long __user *)data);
236 break; 233 break;
237 234
238 default: 235 default: