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