1 /* 2 * linux/arch/arm/kernel/ptrace.c 3 * 4 * By Ross Biro 1/23/92 5 * edited by Linus Torvalds 6 * ARM modifications Copyright (C) 2000 Russell King 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 #include <linux/config.h> 13 #include <linux/kernel.h> 14 #include <linux/sched.h> 15 #include <linux/mm.h> 16 #include <linux/smp.h> 17 #include <linux/smp_lock.h> 18 #include <linux/ptrace.h> 19 #include <linux/user.h> 20 #include <linux/security.h> 21 #include <linux/init.h> 22 #include <linux/signal.h> 23 24 #include <asm/uaccess.h> 25 #include <asm/pgtable.h> 26 #include <asm/system.h> 27 #include <asm/traps.h> 28 29 #include "ptrace.h" 30 31 #define REG_PC 15 32 #define REG_PSR 16 33 /* 34 * does not yet catch signals sent when the child dies. 35 * in exit.c or in signal.c. 36 */ 37 38 #if 0 39 /* 40 * Breakpoint SWI instruction: SWI &9F0001 41 */ 42 #define BREAKINST_ARM 0xef9f0001 43 #define BREAKINST_THUMB 0xdf00 /* fill this in later */ 44 #else 45 /* 46 * New breakpoints - use an undefined instruction. The ARM architecture 47 * reference manual guarantees that the following instruction space 48 * will produce an undefined instruction exception on all CPUs: 49 * 50 * ARM: xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx 51 * Thumb: 1101 1110 xxxx xxxx 52 */ 53 #define BREAKINST_ARM 0xe7f001f0 54 #define BREAKINST_THUMB 0xde01 55 #endif 56 57 /* 58 * this routine will get a word off of the processes privileged stack. 59 * the offset is how far from the base addr as stored in the THREAD. 60 * this routine assumes that all the privileged stacks are in our 61 * data space. 62 */ 63 static inline long get_user_reg(struct task_struct *task, int offset) 64 { 65 return task_pt_regs(task)->uregs[offset]; 66 } 67 68 /* 69 * this routine will put a word on the processes privileged stack. 70 * the offset is how far from the base addr as stored in the THREAD. 71 * this routine assumes that all the privileged stacks are in our 72 * data space. 73 */ 74 static inline int 75 put_user_reg(struct task_struct *task, int offset, long data) 76 { 77 struct pt_regs newregs, *regs = task_pt_regs(task); 78 int ret = -EINVAL; 79 80 newregs = *regs; 81 newregs.uregs[offset] = data; 82 83 if (valid_user_regs(&newregs)) { 84 regs->uregs[offset] = data; 85 ret = 0; 86 } 87 88 return ret; 89 } 90 91 static inline int 92 read_u32(struct task_struct *task, unsigned long addr, u32 *res) 93 { 94 int ret; 95 96 ret = access_process_vm(task, addr, res, sizeof(*res), 0); 97 98 return ret == sizeof(*res) ? 0 : -EIO; 99 } 100 101 static inline int 102 read_instr(struct task_struct *task, unsigned long addr, u32 *res) 103 { 104 int ret; 105 106 if (addr & 1) { 107 u16 val; 108 ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0); 109 ret = ret == sizeof(val) ? 0 : -EIO; 110 *res = val; 111 } else { 112 u32 val; 113 ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0); 114 ret = ret == sizeof(val) ? 0 : -EIO; 115 *res = val; 116 } 117 return ret; 118 } 119 120 /* 121 * Get value of register `rn' (in the instruction) 122 */ 123 static unsigned long 124 ptrace_getrn(struct task_struct *child, unsigned long insn) 125 { 126 unsigned int reg = (insn >> 16) & 15; 127 unsigned long val; 128 129 val = get_user_reg(child, reg); 130 if (reg == 15) 131 val = pc_pointer(val + 8); 132 133 return val; 134 } 135 136 /* 137 * Get value of operand 2 (in an ALU instruction) 138 */ 139 static unsigned long 140 ptrace_getaluop2(struct task_struct *child, unsigned long insn) 141 { 142 unsigned long val; 143 int shift; 144 int type; 145 146 if (insn & 1 << 25) { 147 val = insn & 255; 148 shift = (insn >> 8) & 15; 149 type = 3; 150 } else { 151 val = get_user_reg (child, insn & 15); 152 153 if (insn & (1 << 4)) 154 shift = (int)get_user_reg (child, (insn >> 8) & 15); 155 else 156 shift = (insn >> 7) & 31; 157 158 type = (insn >> 5) & 3; 159 } 160 161 switch (type) { 162 case 0: val <<= shift; break; 163 case 1: val >>= shift; break; 164 case 2: 165 val = (((signed long)val) >> shift); 166 break; 167 case 3: 168 val = (val >> shift) | (val << (32 - shift)); 169 break; 170 } 171 return val; 172 } 173 174 /* 175 * Get value of operand 2 (in a LDR instruction) 176 */ 177 static unsigned long 178 ptrace_getldrop2(struct task_struct *child, unsigned long insn) 179 { 180 unsigned long val; 181 int shift; 182 int type; 183 184 val = get_user_reg(child, insn & 15); 185 shift = (insn >> 7) & 31; 186 type = (insn >> 5) & 3; 187 188 switch (type) { 189 case 0: val <<= shift; break; 190 case 1: val >>= shift; break; 191 case 2: 192 val = (((signed long)val) >> shift); 193 break; 194 case 3: 195 val = (val >> shift) | (val << (32 - shift)); 196 break; 197 } 198 return val; 199 } 200 201 #define OP_MASK 0x01e00000 202 #define OP_AND 0x00000000 203 #define OP_EOR 0x00200000 204 #define OP_SUB 0x00400000 205 #define OP_RSB 0x00600000 206 #define OP_ADD 0x00800000 207 #define OP_ADC 0x00a00000 208 #define OP_SBC 0x00c00000 209 #define OP_RSC 0x00e00000 210 #define OP_ORR 0x01800000 211 #define OP_MOV 0x01a00000 212 #define OP_BIC 0x01c00000 213 #define OP_MVN 0x01e00000 214 215 static unsigned long 216 get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn) 217 { 218 u32 alt = 0; 219 220 switch (insn & 0x0e000000) { 221 case 0x00000000: 222 case 0x02000000: { 223 /* 224 * data processing 225 */ 226 long aluop1, aluop2, ccbit; 227 228 if ((insn & 0x0fffffd0) == 0x012fff10) { 229 /* 230 * bx or blx 231 */ 232 alt = get_user_reg(child, insn & 15); 233 break; 234 } 235 236 237 if ((insn & 0xf000) != 0xf000) 238 break; 239 240 aluop1 = ptrace_getrn(child, insn); 241 aluop2 = ptrace_getaluop2(child, insn); 242 ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0; 243 244 switch (insn & OP_MASK) { 245 case OP_AND: alt = aluop1 & aluop2; break; 246 case OP_EOR: alt = aluop1 ^ aluop2; break; 247 case OP_SUB: alt = aluop1 - aluop2; break; 248 case OP_RSB: alt = aluop2 - aluop1; break; 249 case OP_ADD: alt = aluop1 + aluop2; break; 250 case OP_ADC: alt = aluop1 + aluop2 + ccbit; break; 251 case OP_SBC: alt = aluop1 - aluop2 + ccbit; break; 252 case OP_RSC: alt = aluop2 - aluop1 + ccbit; break; 253 case OP_ORR: alt = aluop1 | aluop2; break; 254 case OP_MOV: alt = aluop2; break; 255 case OP_BIC: alt = aluop1 & ~aluop2; break; 256 case OP_MVN: alt = ~aluop2; break; 257 } 258 break; 259 } 260 261 case 0x04000000: 262 case 0x06000000: 263 /* 264 * ldr 265 */ 266 if ((insn & 0x0010f000) == 0x0010f000) { 267 unsigned long base; 268 269 base = ptrace_getrn(child, insn); 270 if (insn & 1 << 24) { 271 long aluop2; 272 273 if (insn & 0x02000000) 274 aluop2 = ptrace_getldrop2(child, insn); 275 else 276 aluop2 = insn & 0xfff; 277 278 if (insn & 1 << 23) 279 base += aluop2; 280 else 281 base -= aluop2; 282 } 283 if (read_u32(child, base, &alt) == 0) 284 alt = pc_pointer(alt); 285 } 286 break; 287 288 case 0x08000000: 289 /* 290 * ldm 291 */ 292 if ((insn & 0x00108000) == 0x00108000) { 293 unsigned long base; 294 unsigned int nr_regs; 295 296 if (insn & (1 << 23)) { 297 nr_regs = hweight16(insn & 65535) << 2; 298 299 if (!(insn & (1 << 24))) 300 nr_regs -= 4; 301 } else { 302 if (insn & (1 << 24)) 303 nr_regs = -4; 304 else 305 nr_regs = 0; 306 } 307 308 base = ptrace_getrn(child, insn); 309 310 if (read_u32(child, base + nr_regs, &alt) == 0) 311 alt = pc_pointer(alt); 312 break; 313 } 314 break; 315 316 case 0x0a000000: { 317 /* 318 * bl or b 319 */ 320 signed long displ; 321 /* It's a branch/branch link: instead of trying to 322 * figure out whether the branch will be taken or not, 323 * we'll put a breakpoint at both locations. This is 324 * simpler, more reliable, and probably not a whole lot 325 * slower than the alternative approach of emulating the 326 * branch. 327 */ 328 displ = (insn & 0x00ffffff) << 8; 329 displ = (displ >> 6) + 8; 330 if (displ != 0 && displ != 4) 331 alt = pc + displ; 332 } 333 break; 334 } 335 336 return alt; 337 } 338 339 static int 340 swap_insn(struct task_struct *task, unsigned long addr, 341 void *old_insn, void *new_insn, int size) 342 { 343 int ret; 344 345 ret = access_process_vm(task, addr, old_insn, size, 0); 346 if (ret == size) 347 ret = access_process_vm(task, addr, new_insn, size, 1); 348 return ret; 349 } 350 351 static void 352 add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr) 353 { 354 int nr = dbg->nsaved; 355 356 if (nr < 2) { 357 u32 new_insn = BREAKINST_ARM; 358 int res; 359 360 res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4); 361 362 if (res == 4) { 363 dbg->bp[nr].address = addr; 364 dbg->nsaved += 1; 365 } 366 } else 367 printk(KERN_ERR "ptrace: too many breakpoints\n"); 368 } 369 370 /* 371 * Clear one breakpoint in the user program. We copy what the hardware 372 * does and use bit 0 of the address to indicate whether this is a Thumb 373 * breakpoint or an ARM breakpoint. 374 */ 375 static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) 376 { 377 unsigned long addr = bp->address; 378 union debug_insn old_insn; 379 int ret; 380 381 if (addr & 1) { 382 ret = swap_insn(task, addr & ~1, &old_insn.thumb, 383 &bp->insn.thumb, 2); 384 385 if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) 386 printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " 387 "0x%08lx (0x%04x)\n", task->comm, task->pid, 388 addr, old_insn.thumb); 389 } else { 390 ret = swap_insn(task, addr & ~3, &old_insn.arm, 391 &bp->insn.arm, 4); 392 393 if (ret != 4 || old_insn.arm != BREAKINST_ARM) 394 printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " 395 "0x%08lx (0x%08x)\n", task->comm, task->pid, 396 addr, old_insn.arm); 397 } 398 } 399 400 void ptrace_set_bpt(struct task_struct *child) 401 { 402 struct pt_regs *regs; 403 unsigned long pc; 404 u32 insn; 405 int res; 406 407 regs = task_pt_regs(child); 408 pc = instruction_pointer(regs); 409 410 if (thumb_mode(regs)) { 411 printk(KERN_WARNING "ptrace: can't handle thumb mode\n"); 412 return; 413 } 414 415 res = read_instr(child, pc, &insn); 416 if (!res) { 417 struct debug_info *dbg = &child->thread.debug; 418 unsigned long alt; 419 420 dbg->nsaved = 0; 421 422 alt = get_branch_address(child, pc, insn); 423 if (alt) 424 add_breakpoint(child, dbg, alt); 425 426 /* 427 * Note that we ignore the result of setting the above 428 * breakpoint since it may fail. When it does, this is 429 * not so much an error, but a forewarning that we may 430 * be receiving a prefetch abort shortly. 431 * 432 * If we don't set this breakpoint here, then we can 433 * lose control of the thread during single stepping. 434 */ 435 if (!alt || predicate(insn) != PREDICATE_ALWAYS) 436 add_breakpoint(child, dbg, pc + 4); 437 } 438 } 439 440 /* 441 * Ensure no single-step breakpoint is pending. Returns non-zero 442 * value if child was being single-stepped. 443 */ 444 void ptrace_cancel_bpt(struct task_struct *child) 445 { 446 int i, nsaved = child->thread.debug.nsaved; 447 448 child->thread.debug.nsaved = 0; 449 450 if (nsaved > 2) { 451 printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); 452 nsaved = 2; 453 } 454 455 for (i = 0; i < nsaved; i++) 456 clear_breakpoint(child, &child->thread.debug.bp[i]); 457 } 458 459 /* 460 * Called by kernel/ptrace.c when detaching.. 461 * 462 * Make sure the single step bit is not set. 463 */ 464 void ptrace_disable(struct task_struct *child) 465 { 466 child->ptrace &= ~PT_SINGLESTEP; 467 ptrace_cancel_bpt(child); 468 } 469 470 /* 471 * Handle hitting a breakpoint. 472 */ 473 void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) 474 { 475 siginfo_t info; 476 477 ptrace_cancel_bpt(tsk); 478 479 info.si_signo = SIGTRAP; 480 info.si_errno = 0; 481 info.si_code = TRAP_BRKPT; 482 info.si_addr = (void __user *)instruction_pointer(regs); 483 484 force_sig_info(SIGTRAP, &info, tsk); 485 } 486 487 static int break_trap(struct pt_regs *regs, unsigned int instr) 488 { 489 ptrace_break(current, regs); 490 return 0; 491 } 492 493 static struct undef_hook arm_break_hook = { 494 .instr_mask = 0x0fffffff, 495 .instr_val = 0x07f001f0, 496 .cpsr_mask = PSR_T_BIT, 497 .cpsr_val = 0, 498 .fn = break_trap, 499 }; 500 501 static struct undef_hook thumb_break_hook = { 502 .instr_mask = 0xffff, 503 .instr_val = 0xde01, 504 .cpsr_mask = PSR_T_BIT, 505 .cpsr_val = PSR_T_BIT, 506 .fn = break_trap, 507 }; 508 509 static int __init ptrace_break_init(void) 510 { 511 register_undef_hook(&arm_break_hook); 512 register_undef_hook(&thumb_break_hook); 513 return 0; 514 } 515 516 core_initcall(ptrace_break_init); 517 518 /* 519 * Read the word at offset "off" into the "struct user". We 520 * actually access the pt_regs stored on the kernel stack. 521 */ 522 static int ptrace_read_user(struct task_struct *tsk, unsigned long off, 523 unsigned long __user *ret) 524 { 525 unsigned long tmp; 526 527 if (off & 3 || off >= sizeof(struct user)) 528 return -EIO; 529 530 tmp = 0; 531 if (off < sizeof(struct pt_regs)) 532 tmp = get_user_reg(tsk, off >> 2); 533 534 return put_user(tmp, ret); 535 } 536 537 /* 538 * Write the word at offset "off" into "struct user". We 539 * actually access the pt_regs stored on the kernel stack. 540 */ 541 static int ptrace_write_user(struct task_struct *tsk, unsigned long off, 542 unsigned long val) 543 { 544 if (off & 3 || off >= sizeof(struct user)) 545 return -EIO; 546 547 if (off >= sizeof(struct pt_regs)) 548 return 0; 549 550 return put_user_reg(tsk, off >> 2, val); 551 } 552 553 /* 554 * Get all user integer registers. 555 */ 556 static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) 557 { 558 struct pt_regs *regs = task_pt_regs(tsk); 559 560 return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; 561 } 562 563 /* 564 * Set all user integer registers. 565 */ 566 static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) 567 { 568 struct pt_regs newregs; 569 int ret; 570 571 ret = -EFAULT; 572 if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { 573 struct pt_regs *regs = task_pt_regs(tsk); 574 575 ret = -EINVAL; 576 if (valid_user_regs(&newregs)) { 577 *regs = newregs; 578 ret = 0; 579 } 580 } 581 582 return ret; 583 } 584 585 /* 586 * Get the child FPU state. 587 */ 588 static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp) 589 { 590 return copy_to_user(ufp, &task_thread_info(tsk)->fpstate, 591 sizeof(struct user_fp)) ? -EFAULT : 0; 592 } 593 594 /* 595 * Set the child FPU state. 596 */ 597 static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) 598 { 599 struct thread_info *thread = task_thread_info(tsk); 600 thread->used_cp[1] = thread->used_cp[2] = 1; 601 return copy_from_user(&thread->fpstate, ufp, 602 sizeof(struct user_fp)) ? -EFAULT : 0; 603 } 604 605 #ifdef CONFIG_IWMMXT 606 607 /* 608 * Get the child iWMMXt state. 609 */ 610 static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) 611 { 612 struct thread_info *thread = task_thread_info(tsk); 613 614 if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) 615 return -ENODATA; 616 iwmmxt_task_disable(thread); /* force it to ram */ 617 return copy_to_user(ufp, &thread->fpstate.iwmmxt, IWMMXT_SIZE) 618 ? -EFAULT : 0; 619 } 620 621 /* 622 * Set the child iWMMXt state. 623 */ 624 static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) 625 { 626 struct thread_info *thread = task_thread_info(tsk); 627 628 if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) 629 return -EACCES; 630 iwmmxt_task_release(thread); /* force a reload */ 631 return copy_from_user(&thread->fpstate.iwmmxt, ufp, IWMMXT_SIZE) 632 ? -EFAULT : 0; 633 } 634 635 #endif 636 637 #ifdef CONFIG_CRUNCH 638 /* 639 * Get the child Crunch state. 640 */ 641 static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp) 642 { 643 struct thread_info *thread = task_thread_info(tsk); 644 645 crunch_task_disable(thread); /* force it to ram */ 646 return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE) 647 ? -EFAULT : 0; 648 } 649 650 /* 651 * Set the child Crunch state. 652 */ 653 static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) 654 { 655 struct thread_info *thread = task_thread_info(tsk); 656 657 crunch_task_release(thread); /* force a reload */ 658 return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE) 659 ? -EFAULT : 0; 660 } 661 #endif 662 663 long arch_ptrace(struct task_struct *child, long request, long addr, long data) 664 { 665 unsigned long tmp; 666 int ret; 667 668 switch (request) { 669 /* 670 * read word at location "addr" in the child process. 671 */ 672 case PTRACE_PEEKTEXT: 673 case PTRACE_PEEKDATA: 674 ret = access_process_vm(child, addr, &tmp, 675 sizeof(unsigned long), 0); 676 if (ret == sizeof(unsigned long)) 677 ret = put_user(tmp, (unsigned long __user *) data); 678 else 679 ret = -EIO; 680 break; 681 682 case PTRACE_PEEKUSR: 683 ret = ptrace_read_user(child, addr, (unsigned long __user *)data); 684 break; 685 686 /* 687 * write the word at location addr. 688 */ 689 case PTRACE_POKETEXT: 690 case PTRACE_POKEDATA: 691 ret = access_process_vm(child, addr, &data, 692 sizeof(unsigned long), 1); 693 if (ret == sizeof(unsigned long)) 694 ret = 0; 695 else 696 ret = -EIO; 697 break; 698 699 case PTRACE_POKEUSR: 700 ret = ptrace_write_user(child, addr, data); 701 break; 702 703 /* 704 * continue/restart and stop at next (return from) syscall 705 */ 706 case PTRACE_SYSCALL: 707 case PTRACE_CONT: 708 ret = -EIO; 709 if (!valid_signal(data)) 710 break; 711 if (request == PTRACE_SYSCALL) 712 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 713 else 714 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 715 child->exit_code = data; 716 /* make sure single-step breakpoint is gone. */ 717 child->ptrace &= ~PT_SINGLESTEP; 718 ptrace_cancel_bpt(child); 719 wake_up_process(child); 720 ret = 0; 721 break; 722 723 /* 724 * make the child exit. Best I can do is send it a sigkill. 725 * perhaps it should be put in the status that it wants to 726 * exit. 727 */ 728 case PTRACE_KILL: 729 /* make sure single-step breakpoint is gone. */ 730 child->ptrace &= ~PT_SINGLESTEP; 731 ptrace_cancel_bpt(child); 732 if (child->exit_state != EXIT_ZOMBIE) { 733 child->exit_code = SIGKILL; 734 wake_up_process(child); 735 } 736 ret = 0; 737 break; 738 739 /* 740 * execute single instruction. 741 */ 742 case PTRACE_SINGLESTEP: 743 ret = -EIO; 744 if (!valid_signal(data)) 745 break; 746 child->ptrace |= PT_SINGLESTEP; 747 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 748 child->exit_code = data; 749 /* give it a chance to run. */ 750 wake_up_process(child); 751 ret = 0; 752 break; 753 754 case PTRACE_DETACH: 755 ret = ptrace_detach(child, data); 756 break; 757 758 case PTRACE_GETREGS: 759 ret = ptrace_getregs(child, (void __user *)data); 760 break; 761 762 case PTRACE_SETREGS: 763 ret = ptrace_setregs(child, (void __user *)data); 764 break; 765 766 case PTRACE_GETFPREGS: 767 ret = ptrace_getfpregs(child, (void __user *)data); 768 break; 769 770 case PTRACE_SETFPREGS: 771 ret = ptrace_setfpregs(child, (void __user *)data); 772 break; 773 774 #ifdef CONFIG_IWMMXT 775 case PTRACE_GETWMMXREGS: 776 ret = ptrace_getwmmxregs(child, (void __user *)data); 777 break; 778 779 case PTRACE_SETWMMXREGS: 780 ret = ptrace_setwmmxregs(child, (void __user *)data); 781 break; 782 #endif 783 784 case PTRACE_GET_THREAD_AREA: 785 ret = put_user(task_thread_info(child)->tp_value, 786 (unsigned long __user *) data); 787 break; 788 789 case PTRACE_SET_SYSCALL: 790 ret = 0; 791 child->ptrace_message = data; 792 break; 793 794 #ifdef CONFIG_CRUNCH 795 case PTRACE_GETCRUNCHREGS: 796 ret = ptrace_getcrunchregs(child, (void __user *)data); 797 break; 798 799 case PTRACE_SETCRUNCHREGS: 800 ret = ptrace_setcrunchregs(child, (void __user *)data); 801 break; 802 #endif 803 804 default: 805 ret = ptrace_request(child, request, addr, data); 806 break; 807 } 808 809 return ret; 810 } 811 812 asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) 813 { 814 unsigned long ip; 815 816 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 817 return scno; 818 if (!(current->ptrace & PT_PTRACED)) 819 return scno; 820 821 /* 822 * Save IP. IP is used to denote syscall entry/exit: 823 * IP = 0 -> entry, = 1 -> exit 824 */ 825 ip = regs->ARM_ip; 826 regs->ARM_ip = why; 827 828 current->ptrace_message = scno; 829 830 /* the 0x80 provides a way for the tracing parent to distinguish 831 between a syscall stop and SIGTRAP delivery */ 832 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 833 ? 0x80 : 0)); 834 /* 835 * this isn't the same as continuing with a signal, but it will do 836 * for normal use. strace only continues with a signal if the 837 * stopping signal is not SIGTRAP. -brl 838 */ 839 if (current->exit_code) { 840 send_sig(current->exit_code, current, 1); 841 current->exit_code = 0; 842 } 843 regs->ARM_ip = ip; 844 845 return current->ptrace_message; 846 } 847