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#include <elf.h>
11
12#include "ltrace.h"
13
14#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
15# define PTRACE_PEEKUSER PTRACE_PEEKUSR
16#endif
17
18#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
19# define PTRACE_POKEUSER PTRACE_POKEUSR
20#endif
21
22void get_arch_dep(struct process *proc)
23{
24#ifdef __powerpc64__
25	if (proc->arch_ptr)
26		return;
27	proc->mask_32bit = (proc->e_machine == EM_PPC);
28	proc->arch_ptr = (void *)1;
29#endif
30}
31
32/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
33 */
34#define SYSCALL_INSN   0x44000002
35int syscall_p(struct process *proc, int status, int *sysnum)
36{
37	if (WIFSTOPPED(status)
38	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
39		long pc = (long)get_instruction_pointer(proc);
40		int insn =
41		    (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(long),
42				0);
43
44		if (insn == SYSCALL_INSN) {
45			*sysnum =
46			    (int)ptrace(PTRACE_PEEKUSER, proc->pid,
47					sizeof(long) * PT_R0, 0);
48			if (proc->callstack_depth > 0
49			    && proc->callstack[proc->callstack_depth -
50					       1].is_syscall) {
51				return 2;
52			}
53			return 1;
54		}
55	}
56	return 0;
57}
58
59long gimme_arg(enum tof type, struct process *proc, int arg_num)
60{
61	if (arg_num == -1) {	/* return value */
62		return ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_R3,
63			      0);
64	} else if (arg_num < 8) {
65		return ptrace(PTRACE_PEEKUSER, proc->pid,
66			      sizeof(long) * (arg_num + PT_R3), 0);
67	} else {
68		return ptrace(PTRACE_PEEKDATA, proc->pid,
69			      proc->stack_pointer + 8 * (arg_num - 8), 0);
70	}
71	return 0;
72}
73
74void save_register_args(enum tof type, struct process *proc)
75{
76}
77