[PATCH 1a] utrace: tracehook for ia64 This patch does the initial tracehook conversion for ia64. Signed-off-by: Roland McGrath Signed-off-by: Anil S Keshavamurthy Signed-off-by: Bibo mao --- arch/ia64/ia32/ia32_entry.S | 2 + arch/ia64/ia32/sys_ia32.c | 23 ++----------- arch/ia64/kernel/ptrace.c | 39 ++++++---------------- arch/ia64/kernel/signal.c | 4 ++ include/asm-ia64/tracehook.h | 73 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 50 deletions(-) create include/asm-ia64/tracehook.h --- linux-2.6/arch/ia64/ia32/ia32_entry.S +++ linux-2.6/arch/ia64/ia32/ia32_entry.S @@ -199,7 +199,7 @@ ia32_syscall_table: data8 sys_setuid /* 16-bit version */ data8 sys_getuid /* 16-bit version */ data8 compat_sys_stime /* 25 */ - data8 sys32_ptrace + data8 compat_sys_ptrace data8 sys32_alarm data8 sys_ni_syscall data8 sys32_pause --- linux-2.6/arch/ia64/ia32/sys_ia32.c +++ linux-2.6/arch/ia64/ia32/sys_ia32.c @@ -1436,25 +1436,6 @@ sys32_waitpid (int pid, unsigned int *st return compat_sys_wait4(pid, stat_addr, options, NULL); } -static unsigned int -ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val) -{ - size_t copied; - unsigned int ret; - - copied = access_process_vm(child, addr, val, sizeof(*val), 0); - return (copied != sizeof(ret)) ? -EIO : 0; -} - -static unsigned int -ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val) -{ - - if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val)) - return -EIO; - return 0; -} - /* * The order in which registers are stored in the ptrace regs structure */ @@ -1752,6 +1733,7 @@ restore_ia32_fpxstate (struct task_struc return 0; } +#if 0 /* XXX */ asmlinkage long sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data) { @@ -1859,9 +1841,11 @@ sys32_ptrace (int request, pid_t pid, un compat_ptr(data)); break; +#if 0 /* XXX */ case PTRACE_GETEVENTMSG: ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data)); break; +#endif case PTRACE_SYSCALL: /* continue, stop after next syscall */ case PTRACE_CONT: /* restart after signal. */ @@ -1882,6 +1866,7 @@ sys32_ptrace (int request, pid_t pid, un unlock_kernel(); return ret; } +#endif typedef struct { unsigned int ss_sp; --- linux-2.6/arch/ia64/kernel/ptrace.c +++ linux-2.6/arch/ia64/kernel/ptrace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1598,28 +1599,6 @@ sys_ptrace (long request, pid_t pid, uns return ret; } - -static void -syscall_trace (void) -{ - /* - * The 0x80 provides a way for the tracing parent to - * distinguish between a syscall stop and SIGTRAP delivery. - */ - ptrace_notify(SIGTRAP - | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - - /* - * This isn't the same as continuing with a signal, but it - * will do for normal use. strace only continues with a - * signal if the stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - /* "asmlinkage" so the input arguments are preserved... */ asmlinkage void @@ -1627,9 +1606,8 @@ syscall_trace_enter (long arg0, long arg long arg4, long arg5, long arg6, long arg7, struct pt_regs regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE) - && (current->ptrace & PT_PTRACED)) - syscall_trace(); + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall(®s, 0); if (unlikely(current->audit_context)) { long syscall; @@ -1664,8 +1642,11 @@ syscall_trace_leave (long arg0, long arg audit_syscall_exit(success, result); } - if ((test_thread_flag(TIF_SYSCALL_TRACE) - || test_thread_flag(TIF_SINGLESTEP)) - && (current->ptrace & PT_PTRACED)) - syscall_trace(); + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall(®s, 1); + + if (test_thread_flag(TIF_SINGLESTEP)) { + force_sig(SIGTRAP, current); /* XXX */ + tracehook_report_syscall_step(®s); + } } --- linux-2.6/arch/ia64/kernel/signal.c +++ linux-2.6/arch/ia64/kernel/signal.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -429,6 +429,8 @@ handle_signal (unsigned long sig, struct sigaddset(¤t->blocked, sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + + tracehook_report_handle_signal(sig, ka, oldset, &scr->pt); return 1; } --- linux-2.6/include/asm-ia64/tracehook.h +++ linux-2.6/include/asm-ia64/tracehook.h @@ -0,0 +1,73 @@ +/* + * Copyright (C)2006 Intel Co + * Anil S Keshavamurthy + * and Bibo Mao adapted from i386. + * + * Tracing hooks, ia64 CPU support + */ + +#ifndef _ASM_TRACEHOOK_H +#define _ASM_TRACEHOOK_H 1 + +#include +#include + +/* + * See linux/tracehook.h for the descriptions of what these need to do. + */ + +#define ARCH_HAS_SINGLE_STEP (1) +#define ARCH_HAS_BLOCK_STEP (1) + +static inline void tracehook_enable_single_step(struct task_struct *tsk) +{ + struct pt_regs *pt = task_pt_regs(tsk); + ia64_psr(pt)->ss = 1; + set_tsk_thread_flag(tsk, TIF_SINGLESTEP); +} + +static inline void tracehook_disable_single_step(struct task_struct *tsk) +{ + struct pt_regs *pt = task_pt_regs(tsk); + ia64_psr(pt)->ss = 0; + if (ia64_psr(pt)->tb == 0) + clear_tsk_thread_flag(tsk, TIF_SINGLESTEP); +} + +static inline void tracehook_enable_block_step(struct task_struct *tsk) +{ + struct pt_regs *pt = task_pt_regs(tsk); + ia64_psr(pt)->tb = 1; + set_tsk_thread_flag(tsk, TIF_SINGLESTEP); +} + +static inline void tracehook_disable_block_step(struct task_struct *tsk) +{ + struct pt_regs *pt = task_pt_regs(tsk); + ia64_psr(pt)->tb = 0; + if (ia64_psr(pt)->ss == 0) + clear_tsk_thread_flag(tsk, TIF_SINGLESTEP); +} + +static inline void tracehook_enable_syscall_trace(struct task_struct *tsk) +{ + set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE); +} + +static inline void tracehook_disable_syscall_trace(struct task_struct *tsk) +{ + clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE); +} + +static inline int tracehook_single_step_enabled(struct task_struct *tsk) +{ + struct pt_regs *pt = task_pt_regs(tsk); + return ia64_psr(pt)->ss; +} + +static inline void tracehook_abort_syscall(struct pt_regs *regs) +{ + regs->r15 = -1L; +} + +#endif