diff options
Diffstat (limited to 'arch/s390/kernel/ptrace.c')
-rw-r--r-- | arch/s390/kernel/ptrace.c | 100 |
1 files changed, 6 insertions, 94 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 7f4270163744..35827b9bd4d1 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -292,8 +292,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
292 | return 0; | 292 | return 0; |
293 | } | 293 | } |
294 | 294 | ||
295 | static int | 295 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
296 | do_ptrace_normal(struct task_struct *child, long request, long addr, long data) | ||
297 | { | 296 | { |
298 | ptrace_area parea; | 297 | ptrace_area parea; |
299 | int copied, ret; | 298 | int copied, ret; |
@@ -529,35 +528,19 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) | |||
529 | return 0; | 528 | return 0; |
530 | } | 529 | } |
531 | 530 | ||
532 | static int | 531 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
533 | do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) | 532 | compat_ulong_t caddr, compat_ulong_t cdata) |
534 | { | 533 | { |
535 | unsigned int tmp; /* 4 bytes !! */ | 534 | unsigned long addr = caddr; |
535 | unsigned long data = cdata; | ||
536 | ptrace_area_emu31 parea; | 536 | ptrace_area_emu31 parea; |
537 | int copied, ret; | 537 | int copied, ret; |
538 | 538 | ||
539 | switch (request) { | 539 | switch (request) { |
540 | case PTRACE_PEEKTEXT: | ||
541 | case PTRACE_PEEKDATA: | ||
542 | /* read word at location addr. */ | ||
543 | copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); | ||
544 | if (copied != sizeof(tmp)) | ||
545 | return -EIO; | ||
546 | return put_user(tmp, (unsigned int __force __user *) data); | ||
547 | |||
548 | case PTRACE_PEEKUSR: | 540 | case PTRACE_PEEKUSR: |
549 | /* read the word at location addr in the USER area. */ | 541 | /* read the word at location addr in the USER area. */ |
550 | return peek_user_emu31(child, addr, data); | 542 | return peek_user_emu31(child, addr, data); |
551 | 543 | ||
552 | case PTRACE_POKETEXT: | ||
553 | case PTRACE_POKEDATA: | ||
554 | /* write the word at location addr. */ | ||
555 | tmp = data; | ||
556 | copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1); | ||
557 | if (copied != sizeof(tmp)) | ||
558 | return -EIO; | ||
559 | return 0; | ||
560 | |||
561 | case PTRACE_POKEUSR: | 544 | case PTRACE_POKEUSR: |
562 | /* write the word at location addr in the USER area */ | 545 | /* write the word at location addr in the USER area */ |
563 | return poke_user_emu31(child, addr, data); | 546 | return poke_user_emu31(child, addr, data); |
@@ -587,82 +570,11 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) | |||
587 | copied += sizeof(unsigned int); | 570 | copied += sizeof(unsigned int); |
588 | } | 571 | } |
589 | return 0; | 572 | return 0; |
590 | case PTRACE_GETEVENTMSG: | ||
591 | return put_user((__u32) child->ptrace_message, | ||
592 | (unsigned int __force __user *) data); | ||
593 | case PTRACE_GETSIGINFO: | ||
594 | if (child->last_siginfo == NULL) | ||
595 | return -EINVAL; | ||
596 | return copy_siginfo_to_user32((compat_siginfo_t | ||
597 | __force __user *) data, | ||
598 | child->last_siginfo); | ||
599 | case PTRACE_SETSIGINFO: | ||
600 | if (child->last_siginfo == NULL) | ||
601 | return -EINVAL; | ||
602 | return copy_siginfo_from_user32(child->last_siginfo, | ||
603 | (compat_siginfo_t | ||
604 | __force __user *) data); | ||
605 | } | 573 | } |
606 | return ptrace_request(child, request, addr, data); | 574 | return compat_ptrace_request(child, request, addr, data); |
607 | } | 575 | } |
608 | #endif | 576 | #endif |
609 | 577 | ||
610 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||
611 | { | ||
612 | switch (request) { | ||
613 | case PTRACE_SYSCALL: | ||
614 | /* continue and stop at next (return from) syscall */ | ||
615 | case PTRACE_CONT: | ||
616 | /* restart after signal. */ | ||
617 | if (!valid_signal(data)) | ||
618 | return -EIO; | ||
619 | if (request == PTRACE_SYSCALL) | ||
620 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
621 | else | ||
622 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
623 | child->exit_code = data; | ||
624 | /* make sure the single step bit is not set. */ | ||
625 | user_disable_single_step(child); | ||
626 | wake_up_process(child); | ||
627 | return 0; | ||
628 | |||
629 | case PTRACE_KILL: | ||
630 | /* | ||
631 | * make the child exit. Best I can do is send it a sigkill. | ||
632 | * perhaps it should be put in the status that it wants to | ||
633 | * exit. | ||
634 | */ | ||
635 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
636 | return 0; | ||
637 | child->exit_code = SIGKILL; | ||
638 | /* make sure the single step bit is not set. */ | ||
639 | user_disable_single_step(child); | ||
640 | wake_up_process(child); | ||
641 | return 0; | ||
642 | |||
643 | case PTRACE_SINGLESTEP: | ||
644 | /* set the trap flag. */ | ||
645 | if (!valid_signal(data)) | ||
646 | return -EIO; | ||
647 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
648 | child->exit_code = data; | ||
649 | user_enable_single_step(child); | ||
650 | /* give it a chance to run. */ | ||
651 | wake_up_process(child); | ||
652 | return 0; | ||
653 | |||
654 | /* Do requests that differ for 31/64 bit */ | ||
655 | default: | ||
656 | #ifdef CONFIG_COMPAT | ||
657 | if (test_thread_flag(TIF_31BIT)) | ||
658 | return do_ptrace_emu31(child, request, addr, data); | ||
659 | #endif | ||
660 | return do_ptrace_normal(child, request, addr, data); | ||
661 | } | ||
662 | /* Not reached. */ | ||
663 | return -EIO; | ||
664 | } | ||
665 | |||
666 | asmlinkage void | 578 | asmlinkage void |
667 | syscall_trace(struct pt_regs *regs, int entryexit) | 579 | syscall_trace(struct pt_regs *regs, int entryexit) |
668 | { | 580 | { |