Loading arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ config X86 select HAVE_FTRACE select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER select HAVE_ARCH_TRACEHOOK select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS Loading arch/x86/kernel/ptrace.c +6 −28 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/errno.h> #include <linux/ptrace.h> #include <linux/regset.h> #include <linux/tracehook.h> #include <linux/user.h> #include <linux/elf.h> #include <linux/security.h> Loading Loading @@ -1469,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) force_sig_info(SIGTRAP, &info, tsk); } static void syscall_trace(struct pt_regs *regs) { if (!(current->ptrace & PT_PTRACED)) return; #if 0 printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n", current->comm, regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0), current_thread_info()->flags, current->ptrace); #endif 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; } } #ifdef CONFIG_X86_32 # define IS_IA32 1 Loading Loading @@ -1526,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; if (ret || test_thread_flag(TIF_SYSCALL_TRACE)) syscall_trace(regs); if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) && tracehook_report_syscall_entry(regs)) ret = -1L; if (unlikely(current->audit_context)) { if (IS_IA32) Loading @@ -1553,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); if (test_thread_flag(TIF_SYSCALL_TRACE)) syscall_trace(regs); tracehook_report_syscall_exit(regs, 0); /* * If TIF_SYSCALL_EMU is set, we only get here because of Loading @@ -1569,6 +1547,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) * system call instruction. */ if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) send_sigtrap(current, regs, 0); } arch/x86/kernel/signal_32.c +9 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/errno.h> #include <linux/sched.h> #include <linux/wait.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/smp.h> #include <linux/mm.h> Loading Loading @@ -559,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); Loading @@ -569,6 +568,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); return 0; } Loading Loading @@ -662,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } clear_thread_flag(TIF_IRET); } arch/x86/kernel/signal_64.c +14 −35 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/errno.h> #include <linux/wait.h> #include <linux/ptrace.h> #include <linux/tracehook.h> #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/personality.h> Loading @@ -26,6 +27,7 @@ #include <asm/proto.h> #include <asm/ia32_unistd.h> #include <asm/mce.h> #include <asm/syscall.h> #include <asm/syscalls.h> #include "sigframe.h" Loading Loading @@ -355,35 +357,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return -EFAULT; } /* * Return -1L or the syscall number that @regs is executing. */ static long current_syscall(struct pt_regs *regs) { /* * We always sign-extend a -1 value being set here, * so this is always either -1L or a syscall number. */ return regs->orig_ax; } /* * Return a value that is -EFOO if the system call in @regs->orig_ax * returned an error. This only works for @regs from @current. */ static long current_syscall_ret(struct pt_regs *regs) { #ifdef CONFIG_IA32_EMULATION if (test_thread_flag(TIF_IA32)) /* * Sign-extend the value so (int)-EFOO becomes (long)-EFOO * and will match correctly in comparisons. */ return (int) regs->ax; #endif return regs->ax; } /* * OK, we're invoking a handler */ Loading @@ -395,9 +368,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, int ret; /* Are we from a system call? */ if (current_syscall(regs) >= 0) { if (syscall_get_nr(current, regs) >= 0) { /* If so, check system call restarting.. */ switch (current_syscall_ret(regs)) { switch (syscall_get_error(current, regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ax = -EINTR; Loading Loading @@ -454,8 +427,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -463,6 +434,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; Loading Loading @@ -519,9 +493,9 @@ static void do_signal(struct pt_regs *regs) } /* Did we come from a system call? */ if (current_syscall(regs) >= 0) { if (syscall_get_nr(current, regs) >= 0) { /* Restart the system call - no handlers present */ switch (current_syscall_ret(regs)) { switch (syscall_get_error(current, regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: Loading Loading @@ -559,6 +533,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused, /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) Loading include/asm-x86/ptrace.h +5 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs) return regs->bp; } static inline unsigned long user_stack_pointer(struct pt_regs *regs) { return regs->sp; } /* * These are defined as per linux/ptrace.h, which see. */ Loading Loading
arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ config X86 select HAVE_FTRACE select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER select HAVE_ARCH_TRACEHOOK select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS Loading
arch/x86/kernel/ptrace.c +6 −28 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/errno.h> #include <linux/ptrace.h> #include <linux/regset.h> #include <linux/tracehook.h> #include <linux/user.h> #include <linux/elf.h> #include <linux/security.h> Loading Loading @@ -1469,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) force_sig_info(SIGTRAP, &info, tsk); } static void syscall_trace(struct pt_regs *regs) { if (!(current->ptrace & PT_PTRACED)) return; #if 0 printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n", current->comm, regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0), current_thread_info()->flags, current->ptrace); #endif 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; } } #ifdef CONFIG_X86_32 # define IS_IA32 1 Loading Loading @@ -1526,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) ret = -1L; if (ret || test_thread_flag(TIF_SYSCALL_TRACE)) syscall_trace(regs); if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) && tracehook_report_syscall_entry(regs)) ret = -1L; if (unlikely(current->audit_context)) { if (IS_IA32) Loading @@ -1553,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); if (test_thread_flag(TIF_SYSCALL_TRACE)) syscall_trace(regs); tracehook_report_syscall_exit(regs, 0); /* * If TIF_SYSCALL_EMU is set, we only get here because of Loading @@ -1569,6 +1547,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) * system call instruction. */ if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) send_sigtrap(current, regs, 0); }
arch/x86/kernel/signal_32.c +9 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/errno.h> #include <linux/sched.h> #include <linux/wait.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/smp.h> #include <linux/mm.h> Loading Loading @@ -559,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); Loading @@ -569,6 +568,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); return 0; } Loading Loading @@ -662,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } clear_thread_flag(TIF_IRET); }
arch/x86/kernel/signal_64.c +14 −35 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ #include <linux/errno.h> #include <linux/wait.h> #include <linux/ptrace.h> #include <linux/tracehook.h> #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/personality.h> Loading @@ -26,6 +27,7 @@ #include <asm/proto.h> #include <asm/ia32_unistd.h> #include <asm/mce.h> #include <asm/syscall.h> #include <asm/syscalls.h> #include "sigframe.h" Loading Loading @@ -355,35 +357,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return -EFAULT; } /* * Return -1L or the syscall number that @regs is executing. */ static long current_syscall(struct pt_regs *regs) { /* * We always sign-extend a -1 value being set here, * so this is always either -1L or a syscall number. */ return regs->orig_ax; } /* * Return a value that is -EFOO if the system call in @regs->orig_ax * returned an error. This only works for @regs from @current. */ static long current_syscall_ret(struct pt_regs *regs) { #ifdef CONFIG_IA32_EMULATION if (test_thread_flag(TIF_IA32)) /* * Sign-extend the value so (int)-EFOO becomes (long)-EFOO * and will match correctly in comparisons. */ return (int) regs->ax; #endif return regs->ax; } /* * OK, we're invoking a handler */ Loading @@ -395,9 +368,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, int ret; /* Are we from a system call? */ if (current_syscall(regs) >= 0) { if (syscall_get_nr(current, regs) >= 0) { /* If so, check system call restarting.. */ switch (current_syscall_ret(regs)) { switch (syscall_get_error(current, regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ax = -EINTR; Loading Loading @@ -454,8 +427,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * handler too. */ regs->flags &= ~X86_EFLAGS_TF; if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); Loading @@ -463,6 +434,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); tracehook_signal_handler(sig, info, ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; Loading Loading @@ -519,9 +493,9 @@ static void do_signal(struct pt_regs *regs) } /* Did we come from a system call? */ if (current_syscall(regs) >= 0) { if (syscall_get_nr(current, regs) >= 0) { /* Restart the system call - no handlers present */ switch (current_syscall_ret(regs)) { switch (syscall_get_error(current, regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: Loading Loading @@ -559,6 +533,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused, /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) Loading
include/asm-x86/ptrace.h +5 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs) return regs->bp; } static inline unsigned long user_stack_pointer(struct pt_regs *regs) { return regs->sp; } /* * These are defined as per linux/ptrace.h, which see. */ Loading