1
2
3
4
5
6
7
8
9
10#include <errno.h>
11#include <unistd.h>
12#include <signal.h>
13#include <sys/types.h>
14#include <sys/time.h>
15#include <sys/ptrace.h>
16#include <sys/wait.h>
17#include <asm/ptrace.h>
18
19#include "ptproxy.h"
20#include "debug.h"
21#include "user_util.h"
22#include "kern_util.h"
23#include "ptrace_user.h"
24#include "tt.h"
25
26long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
27 long arg3, long arg4, pid_t child, int *ret)
28{
29 sigset_t relay;
30 long result;
31 int status;
32
33 *ret = 0;
34 if(debugger->debugee->died) return(-ESRCH);
35
36 switch(arg1){
37 case PTRACE_ATTACH:
38 if(debugger->debugee->traced) return(-EPERM);
39
40 debugger->debugee->pid = arg2;
41 debugger->debugee->traced = 1;
42
43 if(is_valid_pid(arg2) && (arg2 != child)){
44 debugger->debugee->in_context = 0;
45 kill(arg2, SIGSTOP);
46 debugger->debugee->event = 1;
47 debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
48 }
49 else {
50 debugger->debugee->in_context = 1;
51 if(debugger->debugee->stopped)
52 child_proxy(child, W_STOPCODE(SIGSTOP));
53 else kill(child, SIGSTOP);
54 }
55
56 return(0);
57
58 case PTRACE_DETACH:
59 if(!debugger->debugee->traced) return(-EPERM);
60
61 debugger->debugee->traced = 0;
62 debugger->debugee->pid = 0;
63 if(!debugger->debugee->in_context)
64 kill(child, SIGCONT);
65
66 return(0);
67
68 case PTRACE_CONT:
69 if(!debugger->debugee->in_context) return(-EPERM);
70 *ret = PTRACE_CONT;
71 return(ptrace(PTRACE_CONT, child, arg3, arg4));
72
73#ifdef UM_HAVE_GETFPREGS
74 case PTRACE_GETFPREGS:
75 {
76 long regs[FP_FRAME_SIZE];
77 int i, result;
78
79 result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
80 if(result == -1) return(-errno);
81
82 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
83 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
84 regs[i]);
85 return(result);
86 }
87#endif
88
89#ifdef UM_HAVE_GETFPXREGS
90 case PTRACE_GETFPXREGS:
91 {
92 long regs[FPX_FRAME_SIZE];
93 int i, result;
94
95 result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
96 if(result == -1) return(-errno);
97
98 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
99 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
100 regs[i]);
101 return(result);
102 }
103#endif
104
105#ifdef UM_HAVE_GETREGS
106 case PTRACE_GETREGS:
107 {
108 long regs[FRAME_SIZE];
109 int i, result;
110
111 result = ptrace(PTRACE_GETREGS, child, 0, regs);
112 if(result == -1) return(-errno);
113
114 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
115 ptrace (PTRACE_POKEDATA, debugger->pid,
116 arg4 + 4 * i, regs[i]);
117 return(result);
118 }
119 break;
120#endif
121
122 case PTRACE_KILL:
123 result = ptrace(PTRACE_KILL, child, arg3, arg4);
124 if(result == -1) return(-errno);
125
126 return(result);
127
128 case PTRACE_PEEKDATA:
129 case PTRACE_PEEKTEXT:
130 case PTRACE_PEEKUSER:
131
132
133
134
135
136 errno = 0;
137 result = ptrace(arg1, child, arg3, 0);
138 if((result == -1) && (errno != 0)) return(-errno);
139
140 result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
141 if(result == -1) return(-errno);
142
143 return(result);
144
145 case PTRACE_POKEDATA:
146 case PTRACE_POKETEXT:
147 case PTRACE_POKEUSER:
148 result = ptrace(arg1, child, arg3, arg4);
149 if(result == -1) return(-errno);
150
151 if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
152 return(result);
153
154#ifdef UM_HAVE_SETFPREGS
155 case PTRACE_SETFPREGS:
156 {
157 long regs[FP_FRAME_SIZE];
158 int i;
159
160 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
161 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
162 arg4 + 4 * i, 0);
163 result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
164 if(result == -1) return(-errno);
165
166 return(result);
167 }
168#endif
169
170#ifdef UM_HAVE_SETFPXREGS
171 case PTRACE_SETFPXREGS:
172 {
173 long regs[FPX_FRAME_SIZE];
174 int i;
175
176 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
177 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
178 arg4 + 4 * i, 0);
179 result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
180 if(result == -1) return(-errno);
181
182 return(result);
183 }
184#endif
185
186#ifdef UM_HAVE_SETREGS
187 case PTRACE_SETREGS:
188 {
189 long regs[FRAME_SIZE];
190 int i;
191
192 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
193 regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
194 arg4 + 4 * i, 0);
195 result = ptrace(PTRACE_SETREGS, child, 0, regs);
196 if(result == -1) return(-errno);
197
198 return(result);
199 }
200#endif
201
202 case PTRACE_SINGLESTEP:
203 if(!debugger->debugee->in_context) return(-EPERM);
204 sigemptyset(&relay);
205 sigaddset(&relay, SIGSEGV);
206 sigaddset(&relay, SIGILL);
207 sigaddset(&relay, SIGBUS);
208 result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
209 if(result == -1) return(-errno);
210
211 status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
212 &relay);
213 child_proxy(child, status);
214 return(result);
215
216 case PTRACE_SYSCALL:
217 if(!debugger->debugee->in_context) return(-EPERM);
218 result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
219 if(result == -1) return(-errno);
220
221 *ret = PTRACE_SYSCALL;
222 return(result);
223
224 case PTRACE_TRACEME:
225 default:
226 return(-EINVAL);
227 }
228}
229
230
231
232
233
234
235
236
237
238
239
240