trace.c revision 65b53df7fa2577c4138aef86c115873eab684a0a
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, arg_type_info *info)
60{
61	int arg_num = info->arg_num;
62
63	if (arg_num == -1) {	/* return value */
64		return ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long) * PT_R3,
65			      0);
66	} else if (arg_num < 8) {
67		return ptrace(PTRACE_PEEKUSER, proc->pid,
68			      sizeof(long) * (arg_num + PT_R3), 0);
69	} else {
70		return ptrace(PTRACE_PEEKDATA, proc->pid,
71			      proc->stack_pointer + 8 * (arg_num - 8), 0);
72	}
73	return 0;
74}
75
76void save_register_args(enum tof type, struct process *proc)
77{
78}
79