|
@@ -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>
|
|
@@ -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"
|
|
|
|
|
@@ -355,35 +357,6 @@ give_sigsegv:
|
|
|
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
|
|
|
*/
|
|
@@ -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;
|
|
@@ -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);
|
|
@@ -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;
|
|
@@ -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:
|
|
@@ -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)
|