diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/kernel/ptrace.c | 56 |
1 files changed, 1 insertions, 55 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 54b7ea551559..e82fe296c2c0 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -698,52 +698,6 @@ thread_matches (struct task_struct *thread, unsigned long addr) | |||
698 | } | 698 | } |
699 | 699 | ||
700 | /* | 700 | /* |
701 | * GDB apparently wants to be able to read the register-backing store | ||
702 | * of any thread when attached to a given process. If we are peeking | ||
703 | * or poking an address that happens to reside in the kernel-backing | ||
704 | * store of another thread, we need to attach to that thread, because | ||
705 | * otherwise we end up accessing stale data. | ||
706 | * | ||
707 | * task_list_lock must be read-locked before calling this routine! | ||
708 | */ | ||
709 | static struct task_struct * | ||
710 | find_thread_for_addr (struct task_struct *child, unsigned long addr) | ||
711 | { | ||
712 | struct task_struct *p; | ||
713 | struct mm_struct *mm; | ||
714 | struct list_head *this, *next; | ||
715 | int mm_users; | ||
716 | |||
717 | if (!(mm = get_task_mm(child))) | ||
718 | return child; | ||
719 | |||
720 | /* -1 because of our get_task_mm(): */ | ||
721 | mm_users = atomic_read(&mm->mm_users) - 1; | ||
722 | if (mm_users <= 1) | ||
723 | goto out; /* not multi-threaded */ | ||
724 | |||
725 | /* | ||
726 | * Traverse the current process' children list. Every task that | ||
727 | * one attaches to becomes a child. And it is only attached children | ||
728 | * of the debugger that are of interest (ptrace_check_attach checks | ||
729 | * for this). | ||
730 | */ | ||
731 | list_for_each_safe(this, next, ¤t->children) { | ||
732 | p = list_entry(this, struct task_struct, sibling); | ||
733 | if (p->tgid != child->tgid) | ||
734 | continue; | ||
735 | if (thread_matches(p, addr)) { | ||
736 | child = p; | ||
737 | goto out; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | out: | ||
742 | mmput(mm); | ||
743 | return child; | ||
744 | } | ||
745 | |||
746 | /* | ||
747 | * Write f32-f127 back to task->thread.fph if it has been modified. | 701 | * Write f32-f127 back to task->thread.fph if it has been modified. |
748 | */ | 702 | */ |
749 | inline void | 703 | inline void |
@@ -1520,7 +1474,6 @@ asmlinkage long | |||
1520 | sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | 1474 | sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) |
1521 | { | 1475 | { |
1522 | struct pt_regs *pt; | 1476 | struct pt_regs *pt; |
1523 | unsigned long peek_or_poke; | ||
1524 | struct task_struct *child; | 1477 | struct task_struct *child; |
1525 | struct switch_stack *sw; | 1478 | struct switch_stack *sw; |
1526 | long ret; | 1479 | long ret; |
@@ -1532,19 +1485,12 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | |||
1532 | goto out; | 1485 | goto out; |
1533 | } | 1486 | } |
1534 | 1487 | ||
1535 | peek_or_poke = (request == PTRACE_PEEKTEXT | ||
1536 | || request == PTRACE_PEEKDATA | ||
1537 | || request == PTRACE_POKETEXT | ||
1538 | || request == PTRACE_POKEDATA); | ||
1539 | ret = -ESRCH; | 1488 | ret = -ESRCH; |
1540 | read_lock(&tasklist_lock); | 1489 | read_lock(&tasklist_lock); |
1541 | { | 1490 | { |
1542 | child = find_task_by_pid(pid); | 1491 | child = find_task_by_pid(pid); |
1543 | if (child) { | 1492 | if (child) |
1544 | if (peek_or_poke) | ||
1545 | child = find_thread_for_addr(child, addr); | ||
1546 | get_task_struct(child); | 1493 | get_task_struct(child); |
1547 | } | ||
1548 | } | 1494 | } |
1549 | read_unlock(&tasklist_lock); | 1495 | read_unlock(&tasklist_lock); |
1550 | if (!child) | 1496 | if (!child) |