1 /**********************************************************************
4 Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
7 Jeff Dike (jdike@karaya.com) : Modified for integration into uml
8 **********************************************************************/
13 #include <sys/types.h>
15 #include <sys/ptrace.h>
17 #include <asm/ptrace.h>
21 #include "user_util.h"
22 #include "kern_util.h"
23 #include "ptrace_user.h"
26 long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
27 long arg3, long arg4, pid_t child, int *ret)
34 if(debugger->debugee->died) return(-ESRCH);
38 if(debugger->debugee->traced) return(-EPERM);
40 debugger->debugee->pid = arg2;
41 debugger->debugee->traced = 1;
43 if(is_valid_pid(arg2) && (arg2 != child)){
44 debugger->debugee->in_context = 0;
46 debugger->debugee->event = 1;
47 debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
50 debugger->debugee->in_context = 1;
51 if(debugger->debugee->stopped)
52 child_proxy(child, W_STOPCODE(SIGSTOP));
53 else kill(child, SIGSTOP);
59 if(!debugger->debugee->traced) return(-EPERM);
61 debugger->debugee->traced = 0;
62 debugger->debugee->pid = 0;
63 if(!debugger->debugee->in_context)
69 if(!debugger->debugee->in_context) return(-EPERM);
71 return(ptrace(PTRACE_CONT, child, arg3, arg4));
73 #ifdef UM_HAVE_GETFPREGS
74 case PTRACE_GETFPREGS:
76 long regs[FP_FRAME_SIZE];
79 result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
80 if(result == -1) return(-errno);
82 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
83 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
89 #ifdef UM_HAVE_GETFPXREGS
90 case PTRACE_GETFPXREGS:
92 long regs[FPX_FRAME_SIZE];
95 result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
96 if(result == -1) return(-errno);
98 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
99 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
105 #ifdef UM_HAVE_GETREGS
108 long regs[FRAME_SIZE];
111 result = ptrace(PTRACE_GETREGS, child, 0, regs);
112 if(result == -1) return(-errno);
114 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
115 ptrace (PTRACE_POKEDATA, debugger->pid,
116 arg4 + 4 * i, regs[i]);
123 result = ptrace(PTRACE_KILL, child, arg3, arg4);
124 if(result == -1) return(-errno);
128 case PTRACE_PEEKDATA:
129 case PTRACE_PEEKTEXT:
130 case PTRACE_PEEKUSER:
131 /* The value being read out could be -1, so we have to
132 * check errno to see if there's an error, and zero it
133 * beforehand so we're not faked out by an old error
137 result = ptrace(arg1, child, arg3, 0);
138 if((result == -1) && (errno != 0)) return(-errno);
140 result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
141 if(result == -1) return(-errno);
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);
151 if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
154 #ifdef UM_HAVE_SETFPREGS
155 case PTRACE_SETFPREGS:
157 long regs[FP_FRAME_SIZE];
160 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
161 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
163 result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
164 if(result == -1) return(-errno);
170 #ifdef UM_HAVE_SETFPXREGS
171 case PTRACE_SETFPXREGS:
173 long regs[FPX_FRAME_SIZE];
176 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
177 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
179 result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
180 if(result == -1) return(-errno);
186 #ifdef UM_HAVE_SETREGS
189 long regs[FRAME_SIZE];
192 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
193 regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
195 result = ptrace(PTRACE_SETREGS, child, 0, regs);
196 if(result == -1) return(-errno);
202 case PTRACE_SINGLESTEP:
203 if(!debugger->debugee->in_context) return(-EPERM);
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);
211 status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
213 child_proxy(child, status);
217 if(!debugger->debugee->in_context) return(-EPERM);
218 result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
219 if(result == -1) return(-errno);
221 *ret = PTRACE_SYSCALL;
231 * Overrides for Emacs so that we follow Linus's tabbing style.
232 * Emacs will notice this stuff at the end of the file and automatically
233 * adjust the settings for this buffer only. This must remain at the end
235 * ---------------------------------------------------------------------------
237 * c-file-style: "linux"