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

Commit 3f471126 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King
Browse files

[ARM] 3262/4: allow ptraced syscalls to be overriden



Patch from Nicolas Pitre

This is needed by strace to properly handle the tracing of some system
calls. It could be useful for other applications as well.

Based on an earlier patch from Daniel Jacobowitz.

Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarDaniel Jacobowitz <dan@debian.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 6c90c872
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -214,11 +214,13 @@ ENTRY(vector_swi)
	 * context switches, and waiting for our parent to respond.
	 * context switches, and waiting for our parent to respond.
	 */
	 */
__sys_trace:
__sys_trace:
	mov	r2, scno
	add	r1, sp, #S_OFF
	add	r1, sp, #S_OFF
	mov	r0, #0				@ trace entry [IP = 0]
	mov	r0, #0				@ trace entry [IP = 0]
	bl	syscall_trace
	bl	syscall_trace


	adr	lr, __sys_trace_return		@ return address
	adr	lr, __sys_trace_return		@ return address
	mov	scno, r0			@ syscall number (possibly new)
	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
	cmp	scno, #NR_syscalls		@ check upper syscall limit
	cmp	scno, #NR_syscalls		@ check upper syscall limit
	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
	ldmccia	r1, {r0 - r3}			@ have to reload r0 - r3
@@ -227,6 +229,7 @@ __sys_trace:


__sys_trace_return:
__sys_trace_return:
	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
	mov	r2, scno
	mov	r1, sp
	mov	r1, sp
	mov	r0, #1				@ trace exit [IP = 1]
	mov	r0, #1				@ trace exit [IP = 1]
	bl	syscall_trace
	bl	syscall_trace
+12 −3
Original line number Original line Diff line number Diff line
@@ -766,6 +766,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
				       (unsigned long __user *) data);
				       (unsigned long __user *) data);
			break;
			break;


		case PTRACE_SET_SYSCALL:
			ret = 0;
			child->ptrace_message = data;
			break;

		default:
		default:
			ret = ptrace_request(child, request, addr, data);
			ret = ptrace_request(child, request, addr, data);
			break;
			break;
@@ -774,14 +779,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
	return ret;
	return ret;
}
}


asmlinkage void syscall_trace(int why, struct pt_regs *regs)
asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{
{
	unsigned long ip;
	unsigned long ip;


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


	/*
	/*
	 * Save IP.  IP is used to denote syscall entry/exit:
	 * Save IP.  IP is used to denote syscall entry/exit:
@@ -790,6 +795,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
	ip = regs->ARM_ip;
	ip = regs->ARM_ip;
	regs->ARM_ip = why;
	regs->ARM_ip = why;


	current->ptrace_message = scno;

	/* the 0x80 provides a way for the tracing parent to distinguish
	/* the 0x80 provides a way for the tracing parent to distinguish
	   between a syscall stop and SIGTRAP delivery */
	   between a syscall stop and SIGTRAP delivery */
	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
@@ -804,4 +811,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
		current->exit_code = 0;
		current->exit_code = 0;
	}
	}
	regs->ARM_ip = ip;
	regs->ARM_ip = ip;

	return current->ptrace_message;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,9 @@
#define PTRACE_OLDSETOPTIONS	21
#define PTRACE_OLDSETOPTIONS	21


#define PTRACE_GET_THREAD_AREA	22
#define PTRACE_GET_THREAD_AREA	22

#define PTRACE_SET_SYSCALL	23

/*
/*
 * PSR bits
 * PSR bits
 */
 */