diff options
author | Mike Frysinger <vapier.adi@gmail.com> | 2008-10-09 03:17:36 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-10-09 03:17:36 -0400 |
commit | dabaad5b90dec6909c984d95330f6f41c325f9a8 (patch) | |
tree | f0f8e8c4a33d8f2b629e600cfa4a5b6a37d874d2 | |
parent | dd4354fa51f6379fb3ac98ba9377ca5895f50497 (diff) |
Blackfin arch: fix bug -- PTRACE_PEEKDATA does not seem to work which breaks umoven() in strace
Don't add arbitrary offset when peeking at data
Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index bf1a51d8e608..9ce80d05e2c9 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
47 | #include <asm/fixed_code.h> | 47 | #include <asm/fixed_code.h> |
48 | 48 | ||
49 | #define MAX_SHARED_LIBS 3 | ||
50 | #define TEXT_OFFSET 0 | 49 | #define TEXT_OFFSET 0 |
51 | /* | 50 | /* |
52 | * does not yet catch signals sent when the child dies. | 51 | * does not yet catch signals sent when the child dies. |
@@ -192,14 +191,12 @@ void ptrace_disable(struct task_struct *child) | |||
192 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 191 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
193 | { | 192 | { |
194 | int ret; | 193 | int ret; |
195 | int add = 0; | ||
196 | unsigned long __user *datap = (unsigned long __user *)data; | 194 | unsigned long __user *datap = (unsigned long __user *)data; |
197 | 195 | ||
198 | switch (request) { | 196 | switch (request) { |
199 | /* when I and D space are separate, these will need to be fixed. */ | 197 | /* when I and D space are separate, these will need to be fixed. */ |
200 | case PTRACE_PEEKDATA: | 198 | case PTRACE_PEEKDATA: |
201 | pr_debug("ptrace: PEEKDATA\n"); | 199 | pr_debug("ptrace: PEEKDATA\n"); |
202 | add = MAX_SHARED_LIBS * 4; /* space between text and data */ | ||
203 | /* fall through */ | 200 | /* fall through */ |
204 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | 201 | case PTRACE_PEEKTEXT: /* read word at location addr. */ |
205 | { | 202 | { |
@@ -207,39 +204,38 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
207 | int copied; | 204 | int copied; |
208 | 205 | ||
209 | ret = -EIO; | 206 | ret = -EIO; |
210 | pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add, | 207 | pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data)); |
211 | sizeof(data)); | 208 | if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) |
212 | if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0) | ||
213 | break; | 209 | break; |
214 | pr_debug("ptrace: user address is valid\n"); | 210 | pr_debug("ptrace: user address is valid\n"); |
215 | 211 | ||
216 | #if L1_CODE_LENGTH != 0 | 212 | #if L1_CODE_LENGTH != 0 |
217 | if (addr + add >= L1_CODE_START | 213 | if (addr >= L1_CODE_START |
218 | && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { | 214 | && addr + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { |
219 | safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); | 215 | safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); |
220 | copied = sizeof(tmp); | 216 | copied = sizeof(tmp); |
221 | } else | 217 | } else |
222 | #endif | 218 | #endif |
223 | #if L1_DATA_A_LENGTH != 0 | 219 | #if L1_DATA_A_LENGTH != 0 |
224 | if (addr + add >= L1_DATA_A_START | 220 | if (addr >= L1_DATA_A_START |
225 | && addr + add + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | 221 | && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { |
226 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | 222 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
227 | copied = sizeof(tmp); | 223 | copied = sizeof(tmp); |
228 | } else | 224 | } else |
229 | #endif | 225 | #endif |
230 | #if L1_DATA_B_LENGTH != 0 | 226 | #if L1_DATA_B_LENGTH != 0 |
231 | if (addr + add >= L1_DATA_B_START | 227 | if (addr >= L1_DATA_B_START |
232 | && addr + add + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | 228 | && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { |
233 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | 229 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
234 | copied = sizeof(tmp); | 230 | copied = sizeof(tmp); |
235 | } else | 231 | } else |
236 | #endif | 232 | #endif |
237 | if (addr + add >= FIXED_CODE_START | 233 | if (addr >= FIXED_CODE_START |
238 | && addr + add + sizeof(tmp) <= FIXED_CODE_END) { | 234 | && addr + sizeof(tmp) <= FIXED_CODE_END) { |
239 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | 235 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
240 | copied = sizeof(tmp); | 236 | copied = sizeof(tmp); |
241 | } else | 237 | } else |
242 | copied = access_process_vm(child, addr + add, &tmp, | 238 | copied = access_process_vm(child, addr, &tmp, |
243 | sizeof(tmp), 0); | 239 | sizeof(tmp), 0); |
244 | pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); | 240 | pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); |
245 | if (copied != sizeof(tmp)) | 241 | if (copied != sizeof(tmp)) |
@@ -291,39 +287,39 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
291 | int copied; | 287 | int copied; |
292 | 288 | ||
293 | ret = -EIO; | 289 | ret = -EIO; |
294 | pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n", | 290 | pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n", |
295 | addr, add, sizeof(data), data); | 291 | addr, sizeof(data), data); |
296 | if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0) | 292 | if (is_user_addr_valid(child, addr, sizeof(data)) < 0) |
297 | break; | 293 | break; |
298 | pr_debug("ptrace: user address is valid\n"); | 294 | pr_debug("ptrace: user address is valid\n"); |
299 | 295 | ||
300 | #if L1_CODE_LENGTH != 0 | 296 | #if L1_CODE_LENGTH != 0 |
301 | if (addr + add >= L1_CODE_START | 297 | if (addr >= L1_CODE_START |
302 | && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { | 298 | && addr + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { |
303 | safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); | 299 | safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); |
304 | copied = sizeof(data); | 300 | copied = sizeof(data); |
305 | } else | 301 | } else |
306 | #endif | 302 | #endif |
307 | #if L1_DATA_A_LENGTH != 0 | 303 | #if L1_DATA_A_LENGTH != 0 |
308 | if (addr + add >= L1_DATA_A_START | 304 | if (addr >= L1_DATA_A_START |
309 | && addr + add + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | 305 | && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { |
310 | memcpy((void *)(addr + add), &data, sizeof(data)); | 306 | memcpy((void *)(addr), &data, sizeof(data)); |
311 | copied = sizeof(data); | 307 | copied = sizeof(data); |
312 | } else | 308 | } else |
313 | #endif | 309 | #endif |
314 | #if L1_DATA_B_LENGTH != 0 | 310 | #if L1_DATA_B_LENGTH != 0 |
315 | if (addr + add >= L1_DATA_B_START | 311 | if (addr >= L1_DATA_B_START |
316 | && addr + add + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | 312 | && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { |
317 | memcpy((void *)(addr + add), &data, sizeof(data)); | 313 | memcpy((void *)(addr), &data, sizeof(data)); |
318 | copied = sizeof(data); | 314 | copied = sizeof(data); |
319 | } else | 315 | } else |
320 | #endif | 316 | #endif |
321 | if (addr + add >= FIXED_CODE_START | 317 | if (addr >= FIXED_CODE_START |
322 | && addr + add + sizeof(data) <= FIXED_CODE_END) { | 318 | && addr + sizeof(data) <= FIXED_CODE_END) { |
323 | memcpy((void *)(addr + add), &data, sizeof(data)); | 319 | memcpy((void *)(addr), &data, sizeof(data)); |
324 | copied = sizeof(data); | 320 | copied = sizeof(data); |
325 | } else | 321 | } else |
326 | copied = access_process_vm(child, addr + add, &data, | 322 | copied = access_process_vm(child, addr, &data, |
327 | sizeof(data), 1); | 323 | sizeof(data), 1); |
328 | pr_debug("ptrace: copied size %d\n", copied); | 324 | pr_debug("ptrace: copied size %d\n", copied); |
329 | if (copied != sizeof(data)) | 325 | if (copied != sizeof(data)) |