trace.c revision 9a2ad351a1c3215dc596ff3e2e3fd4bc24445a6b
1#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <stdlib.h>
6#include <stddef.h>
7#include <sys/types.h>
8#include <sys/wait.h>
9#include <signal.h>
10#include <sys/ptrace.h>
11#include <string.h>
12#include <asm/ptrace_offsets.h>
13#include <asm/rse.h>
14
15#include "ltrace.h"
16
17/* What we think of as a bundle, ptrace thinks of it as two unsigned
18 * longs */
19union bundle_t {
20       /* An IA64 instruction bundle has a 5 bit header describing the
21        * type of bundle, then 3 41 bit instructions
22	*/
23	struct {
24		struct {
25			unsigned long template  : 5 ;
26			unsigned long slot0     : 41;
27			unsigned long bot_slot1 : 18;
28		} word0;
29		struct {
30			unsigned long top_slot1 : 23;
31			unsigned long slot2     : 41;
32		} word1;
33	} bitmap;
34	unsigned long code[2];
35};
36
37int
38syscall_p(struct process * proc, int status, int * sysnum) {
39
40	if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
41		unsigned long slot = (ptrace (PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 0x3;
42		unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
43
44		/* r15 holds the system call number */
45		unsigned long r15 = ptrace (PTRACE_PEEKUSER, proc->pid, PT_R15, 0);
46		unsigned long insn;
47
48		union bundle_t bundle;
49
50		/* On fault, the IP has moved forward to the next
51		 * slot.  If that is zero, then the actual place we
52		 * broke was in the previous bundle, so wind back the
53		 * IP.
54		 */
55		if (slot == 0)
56			ip = ip - 16;
57		bundle.code[0] = ptrace (PTRACE_PEEKTEXT, proc->pid, ip, 0);
58		bundle.code[1] = ptrace (PTRACE_PEEKTEXT, proc->pid, ip+8, 0);
59
60		unsigned long bot = 0UL | bundle.bitmap.word0.bot_slot1;
61		unsigned long top = 0UL | bundle.bitmap.word1.top_slot1;
62
63		/* handle the rollback, slot 0 is actually slot 2 of
64		 * the previous instruction (see above) */
65		switch (slot) {
66		case 0:
67			insn = bundle.bitmap.word1.slot2;
68			break;
69		case 1:
70			insn = bundle.bitmap.word0.slot0;
71			break;
72		case 2:
73			/* make sure we're shifting about longs */
74			insn =  0UL | bot | (top << 18UL);
75			break;
76		default:
77			printf("Ummm, can't find instruction slot?\n");
78			exit(1);
79		}
80
81		/* We need to support both the older break instruction
82		 * type syscalls, and the new epc type ones.
83		 *
84		 * Bit 20 of the break constant is encoded in the "i"
85		 * bit (bit 36) of the instruction, hence you should
86		 * see 0x1000000000.
87		 *
88		 *  An EPC call is just 0x1ffffffffff
89		 */
90		if (insn == 0x1000000000 || insn == 0x1ffffffffff) {
91			*sysnum = r15;
92			if (proc->callstack_depth > 0 &&
93			    proc->callstack[proc->callstack_depth-1].is_syscall) {
94				return 2;
95			}
96			return 1;
97		}
98	}
99	return 0;
100}
101
102long
103gimme_arg(enum tof type, struct process * proc, int arg_num) {
104
105	unsigned long bsp, cfm;
106
107	bsp = ptrace (PTRACE_PEEKUSER, proc->pid, PT_AR_BSP, 0);
108	cfm = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CFM, 0);
109
110	if (arg_num==-1) 		/* return value */
111		return ptrace (PTRACE_PEEKUSER, proc->pid, PT_R8, 0);
112
113	/* First 8 arguments are passed in registers on the register
114	 * stack, the following arguments are passed on the stack
115	 * after a 16 byte scratch area
116	 */
117	if (type==LT_TOF_FUNCTION || LT_TOF_FUNCTIONR) {
118		if (arg_num < 8)
119			return ptrace (PTRACE_PEEKDATA, proc->pid, (long)ia64_rse_skip_regs((long*)bsp, -cfm+arg_num), 0);
120		else {
121			unsigned long sp = ptrace (PTRACE_PEEKUSER, proc->pid, PT_R12, 0) + 16;
122			return ptrace (PTRACE_PEEKDATA, proc->pid, sp + (8*(arg_num - 8)));
123		}
124	}
125
126	if (type==LT_TOF_SYSCALL || LT_TOF_SYSCALLR )
127		return ptrace (PTRACE_PEEKDATA, proc->pid, (long)ia64_rse_skip_regs((long *) bsp, arg_num), 0);
128
129	/* error if we get here */
130	fprintf(stderr, "gimme_arg called with wrong arguments\n");
131	exit(1);
132}
133
134void
135save_register_args(enum tof type, struct process * proc) {
136}
137
138void
139get_arch_dep(struct process * proc) {
140}
141