trace.c revision 2d45b1a8e26a36a9f85dc49e721c4390ca93dc40
1#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/types.h>
6#include <sys/wait.h>
7#include <signal.h>
8#include <sys/ptrace.h>
9#include <asm/ptrace.h>
10
11#include "ltrace.h"
12
13#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
14# define PTRACE_PEEKUSER PTRACE_PEEKUSR
15#endif
16
17#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
18# define PTRACE_POKEUSER PTRACE_POKEUSR
19#endif
20
21/* syscall tracing protocol: ArmLinux
22 on the way in, ip is 0
23 on the way out, ip is non-zero
24*/
25#define off_r0 0
26#define off_ip 48
27#define off_pc 60
28
29void get_arch_dep(struct process *proc)
30{
31}
32
33/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
34 */
35int syscall_p(struct process *proc, int status, int *sysnum)
36{
37	if (WIFSTOPPED(status)
38	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
39		/* get the user's pc (plus 8) */
40		int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
41		/* fetch the SWI instruction */
42		int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
43
44		*sysnum = insn & 0xFFFF;
45		/* if it is a syscall, return 1 or 2 */
46		if ((insn & 0xFFFF0000) == 0xef900000) {
47			return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
48				      0) ? 2 : 1;
49		}
50	}
51	return 0;
52}
53
54long gimme_arg(enum tof type, struct process *proc, int arg_num)
55{
56	if (arg_num == -1) {	/* return value */
57		return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
58	}
59
60	/* deal with the ARM calling conventions */
61	if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
62		if (arg_num < 4) {
63			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
64				      0);
65		} else {
66			return ptrace(PTRACE_PEEKDATA, proc->pid,
67				      proc->stack_pointer + 4 * (arg_num - 4),
68				      0);
69		}
70	} else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
71		if (arg_num < 5) {
72			return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
73				      0);
74		} else {
75			return ptrace(PTRACE_PEEKDATA, proc->pid,
76				      proc->stack_pointer + 4 * (arg_num - 5),
77				      0);
78		}
79	} else {
80		fprintf(stderr, "gimme_arg called with wrong arguments\n");
81		exit(1);
82	}
83
84	return 0;
85}
86
87void save_register_args(enum tof type, struct process *proc)
88{
89}
90