Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bfa2317 authored by Al Viro's avatar Al Viro Committed by Richard Weinberger
Browse files

um: split syscall_trace(), pass pt_regs to it



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
[richard@nod.at: Fixed some minor build issues]
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent a3170d2e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 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

+30 −41
Original line number Diff line number Diff line
@@ -3,11 +3,12 @@
 * Licensed under the GPL
 */

#include "linux/audit.h"
#include "linux/ptrace.h"
#include "linux/sched.h"
#include "asm/uaccess.h"
#include "skas_ptrace.h"
#include <linux/audit.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/tracehook.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
 * 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,
				    UPT_SYSCALL_NR(regs),
				    UPT_SYSCALL_ARG1(regs),
				    UPT_SYSCALL_ARG2(regs),
				    UPT_SYSCALL_ARG3(regs),
				    UPT_SYSCALL_ARG4(regs));
	else
			    UPT_SYSCALL_NR(&regs->regs),
			    UPT_SYSCALL_ARG1(&regs->regs),
			    UPT_SYSCALL_ARG2(&regs->regs),
			    UPT_SYSCALL_ARG3(&regs->regs),
			    UPT_SYSCALL_ARG4(&regs->regs));

	if (!test_thread_flag(TIF_SYSCALL_TRACE))
		return;

	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 (is_singlestep)
		send_sigtrap(current, regs, 0);
	if (ptraced & PT_DTRACE)
		send_sigtrap(current, &regs->regs, 0);

	if (!test_thread_flag(TIF_SYSCALL_TRACE))
		return;

	if (!(current->ptrace & PT_PTRACED))
		return;

	/*
	 * the 0x80 provides a way for the tracing parent to distinguish
	 * between a syscall stop and SIGTRAP delivery
	 */
	tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
	ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));

	if (entryexit) /* force do_signal() --> is_syscall() */
	tracehook_report_syscall_exit(regs, 0);
	/* force do_signal() --> is_syscall() */
	if (ptraced & PT_PTRACED)
		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;
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r)
	long result;
	int syscall;

	syscall_trace(r, 0);
	syscall_trace_enter(regs);

	/*
	 * 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);

	syscall_trace(r, 1);
	syscall_trace_leave(regs);
}