um: split syscall_trace(), pass pt_regs to it
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> [richard@nod.at: Fixed some minor build issues] Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
committed by
Richard Weinberger
parent
a3170d2ec2
commit
1bfa2317b2
@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value);
|
|||||||
|
|
||||||
extern int arch_copy_tls(struct task_struct *new);
|
extern int arch_copy_tls(struct task_struct *new);
|
||||||
extern void clear_flushed_tls(struct task_struct *task);
|
extern void clear_flushed_tls(struct task_struct *task);
|
||||||
|
extern void syscall_trace_enter(struct pt_regs *regs);
|
||||||
|
extern void syscall_trace_leave(struct pt_regs *regs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
* Licensed under the GPL
|
* Licensed under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linux/audit.h"
|
#include <linux/audit.h>
|
||||||
#include "linux/ptrace.h"
|
#include <linux/ptrace.h>
|
||||||
#include "linux/sched.h"
|
#include <linux/sched.h>
|
||||||
#include "asm/uaccess.h"
|
#include <linux/tracehook.h>
|
||||||
#include "skas_ptrace.h"
|
#include <asm/uaccess.h>
|
||||||
|
#include <skas_ptrace.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
|
|||||||
* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
|
* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
|
||||||
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
|
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
|
||||||
*/
|
*/
|
||||||
void syscall_trace(struct uml_pt_regs *regs, int entryexit)
|
void syscall_trace_enter(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
|
|
||||||
int tracesysgood;
|
|
||||||
|
|
||||||
if (!entryexit)
|
|
||||||
audit_syscall_entry(HOST_AUDIT_ARCH,
|
audit_syscall_entry(HOST_AUDIT_ARCH,
|
||||||
UPT_SYSCALL_NR(regs),
|
UPT_SYSCALL_NR(®s->regs),
|
||||||
UPT_SYSCALL_ARG1(regs),
|
UPT_SYSCALL_ARG1(®s->regs),
|
||||||
UPT_SYSCALL_ARG2(regs),
|
UPT_SYSCALL_ARG2(®s->regs),
|
||||||
UPT_SYSCALL_ARG3(regs),
|
UPT_SYSCALL_ARG3(®s->regs),
|
||||||
UPT_SYSCALL_ARG4(regs));
|
UPT_SYSCALL_ARG4(®s->regs));
|
||||||
else
|
|
||||||
audit_syscall_exit(regs);
|
|
||||||
|
|
||||||
/* Fake a debug trap */
|
|
||||||
if (is_singlestep)
|
|
||||||
send_sigtrap(current, regs, 0);
|
|
||||||
|
|
||||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(current->ptrace & PT_PTRACED))
|
tracehook_report_syscall_entry(regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall_trace_leave(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
int ptraced = current->ptrace;
|
||||||
|
|
||||||
|
audit_syscall_exit(regs);
|
||||||
|
|
||||||
|
/* Fake a debug trap */
|
||||||
|
if (ptraced & PT_DTRACE)
|
||||||
|
send_sigtrap(current, ®s->regs, 0);
|
||||||
|
|
||||||
|
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
tracehook_report_syscall_exit(regs, 0);
|
||||||
* the 0x80 provides a way for the tracing parent to distinguish
|
/* force do_signal() --> is_syscall() */
|
||||||
* between a syscall stop and SIGTRAP delivery
|
if (ptraced & PT_PTRACED)
|
||||||
*/
|
|
||||||
tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
|
|
||||||
ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
|
|
||||||
|
|
||||||
if (entryexit) /* force do_signal() --> is_syscall() */
|
|
||||||
set_thread_flag(TIF_SIGPENDING);
|
set_thread_flag(TIF_SIGPENDING);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r)
|
|||||||
long result;
|
long result;
|
||||||
int syscall;
|
int syscall;
|
||||||
|
|
||||||
syscall_trace(r, 0);
|
syscall_trace_enter(regs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This should go in the declaration of syscall, but when I do that,
|
* This should go in the declaration of syscall, but when I do that,
|
||||||
@ -36,5 +36,5 @@ void handle_syscall(struct uml_pt_regs *r)
|
|||||||
|
|
||||||
PT_REGS_SET_SYSCALL_RETURN(regs, result);
|
PT_REGS_SET_SYSCALL_RETURN(regs, result);
|
||||||
|
|
||||||
syscall_trace(r, 1);
|
syscall_trace_leave(regs);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user