1 /*
2  * simple example ptrace() code to help build basis for other tests
3  *
4  * Copyright (c) 2009 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later
7  */
8 
9 #define _GNU_SOURCE
10 
11 #include <config.h>
12 
13 #include <errno.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/ptrace.h>
19 #include <sys/syscall.h>
20 #include "ptrace.h"
21 
22 #include "test.h"
23 #include "spawn_ptrace_child.h"
24 
25 #include "syscalls.h"
26 
27 char *TCID = "simple_tracer";
28 int TST_TOTAL = 0;
29 
30 #define _decode(name, val) \
31 ({ \
32 	if (sizeof(long) == 4) \
33 		printf(name ":%08lx ", val); \
34 	else if (sizeof(long) == 8) \
35 		printf(name ":%016lx ", val); \
36 	else \
37 		printf(name ":%lx ", val); \
38 	val; \
39 })
40 #define decode(reg) _decode(#reg, pt->reg)
41 #define decode_user(name, offset) \
42 	_decode(name, vptrace(PTRACE_PEEKUSER, pid, offset, NULL));
43 #define decode_sysnum(nr) printf("%s ", get_sysnum(nr))
decode_regs(struct pt_regs * pt)44 static void decode_regs(struct pt_regs *pt)
45 {
46 #if defined(__bfin__)
47 	long nr = decode_user("orig_p0", PT_ORIG_P0);
48 	decode(p0);
49 	decode(r0);
50 	decode(r1);
51 	decode(r2);
52 	decode(r3);
53 	decode(r4);
54 	decode(r5);
55 	decode_sysnum(nr);
56 	puts("");
57 #elif defined(__i386__)
58 	long nr = decode_user("orig_eax", 4 * ORIG_EAX);
59 	decode(eax);
60 	decode(ebx);
61 	decode(ecx);
62 	decode(edx);
63 	decode(esi);
64 	decode(edi);
65 	decode(ebp);
66 	decode_sysnum(nr);
67 	puts("");
68 #elif defined(__x86_64__)
69 	long nr = decode_user("orig_rax", 8 * ORIG_RAX);
70 	decode(rax);
71 	decode(rbx);
72 	decode(rcx);
73 	decode(rdx);
74 	decode(rsi);
75 	decode(rdi);
76 	decode(rbp);
77 	decode_sysnum(nr);
78 	puts("");
79 #elif defined(__sparc__)
80 #define G1 u_regs[0]
81 #define G2 u_regs[1]
82 #define G3 u_regs[2]
83 #define G4 u_regs[3]
84 #define G5 u_regs[4]
85 #define G6 u_regs[5]
86 #define G7 u_regs[6]
87 #define O0 u_regs[7]
88 #define O1 u_regs[8]
89 #define O2 u_regs[9]
90 #define O3 u_regs[10]
91 #define O4 u_regs[11]
92 #define O5 u_regs[12]
93 #define O6 u_regs[13]
94 #define O7 u_regs[14]
95 	decode(G1);
96 	decode(G2);
97 	decode(G3);
98 	decode(G4);
99 	decode(G5);
100 	decode(G6);
101 	decode(G7);
102 	decode(O0);
103 	decode(O1);
104 	decode(O2);
105 	decode(O3);
106 	decode(O4);
107 	decode(O5);
108 	decode(O6);
109 	decode(O7);
110 	decode_sysnum(pt->G1);
111 	puts("");
112 #else
113 #warning "no idea how to decode your arch"
114 	puts("no idea how to decode your arch");
115 #endif
116 }
117 
main(int argc,char * argv[])118 int main(int argc, char *argv[])
119 {
120 	struct pt_regs pt_regs;
121 	long ret;
122 	int status;
123 
124 	make_a_baby(argc, argv);
125 
126 	while (1) {
127 		ret = vptrace(PTRACE_GETREGS, pid, NULL, &pt_regs);
128 		if (ret)
129 			break;
130 		decode_regs(&pt_regs);
131 
132 		ret = vptrace(PTRACE_SYSCALL, pid, NULL, NULL);
133 		if (ret)
134 			break;
135 
136 		if (waitpid(pid, &status, 0) == -1)
137 			break;
138 	}
139 
140 	/* hopefully this worked */
141 	vptrace(PTRACE_KILL, pid, NULL, NULL);
142 
143 	tst_exit();
144 }
145