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>
19 #include "user_util.h"
20 #include "kern_util.h"
21 #include "ptrace_user.h"
24 long proxy_ptrace(struct debugger
*debugger
, int arg1
, pid_t arg2
,
25 long arg3
, long arg4
, pid_t child
, int *ret
)
32 if(debugger
->debugee
->died
) return(-ESRCH
);
36 if(debugger
->debugee
->traced
) return(-EPERM
);
38 debugger
->debugee
->pid
= arg2
;
39 debugger
->debugee
->traced
= 1;
41 if(is_valid_pid(arg2
) && (arg2
!= child
)){
42 debugger
->debugee
->in_context
= 0;
44 debugger
->debugee
->event
= 1;
45 debugger
->debugee
->wait_status
= W_STOPCODE(SIGSTOP
);
48 debugger
->debugee
->in_context
= 1;
49 if(debugger
->debugee
->stopped
)
50 child_proxy(child
, W_STOPCODE(SIGSTOP
));
51 else kill(child
, SIGSTOP
);
57 if(!debugger
->debugee
->traced
) return(-EPERM
);
59 debugger
->debugee
->traced
= 0;
60 debugger
->debugee
->pid
= 0;
61 if(!debugger
->debugee
->in_context
)
67 if(!debugger
->debugee
->in_context
) return(-EPERM
);
69 return(ptrace(PTRACE_CONT
, child
, arg3
, arg4
));
71 #ifdef UM_HAVE_GETFPREGS
72 case PTRACE_GETFPREGS
:
74 long regs
[FP_FRAME_SIZE
];
77 result
= ptrace(PTRACE_GETFPREGS
, child
, 0, regs
);
78 if(result
== -1) return(-errno
);
80 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
81 ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
+ 4 * i
,
87 #ifdef UM_HAVE_GETFPXREGS
88 case PTRACE_GETFPXREGS
:
90 long regs
[FPX_FRAME_SIZE
];
93 result
= ptrace(PTRACE_GETFPXREGS
, child
, 0, regs
);
94 if(result
== -1) return(-errno
);
96 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
97 ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
+ 4 * i
,
103 #ifdef UM_HAVE_GETREGS
106 long regs
[FRAME_SIZE
];
109 result
= ptrace(PTRACE_GETREGS
, child
, 0, regs
);
110 if(result
== -1) return(-errno
);
112 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
113 ptrace (PTRACE_POKEDATA
, debugger
->pid
,
114 arg4
+ 4 * i
, regs
[i
]);
121 result
= ptrace(PTRACE_KILL
, child
, arg3
, arg4
);
122 if(result
== -1) return(-errno
);
126 case PTRACE_PEEKDATA
:
127 case PTRACE_PEEKTEXT
:
129 /* The value being read out could be -1, so we have to
130 * check errno to see if there's an error, and zero it
131 * beforehand so we're not faked out by an old error
135 result
= ptrace(arg1
, child
, arg3
, 0);
136 if((result
== -1) && (errno
!= 0)) return(-errno
);
138 result
= ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
, result
);
139 if(result
== -1) return(-errno
);
143 case PTRACE_POKEDATA
:
144 case PTRACE_POKETEXT
:
146 result
= ptrace(arg1
, child
, arg3
, arg4
);
147 if(result
== -1) return(-errno
);
149 if(arg1
== PTRACE_POKEUSR
) ptrace_pokeuser(arg3
, arg4
);
152 #ifdef UM_HAVE_SETFPREGS
153 case PTRACE_SETFPREGS
:
155 long regs
[FP_FRAME_SIZE
];
158 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
159 regs
[i
] = ptrace (PTRACE_PEEKDATA
, debugger
->pid
,
161 result
= ptrace(PTRACE_SETFPREGS
, child
, 0, regs
);
162 if(result
== -1) return(-errno
);
168 #ifdef UM_HAVE_SETFPXREGS
169 case PTRACE_SETFPXREGS
:
171 long regs
[FPX_FRAME_SIZE
];
174 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
175 regs
[i
] = ptrace (PTRACE_PEEKDATA
, debugger
->pid
,
177 result
= ptrace(PTRACE_SETFPXREGS
, child
, 0, regs
);
178 if(result
== -1) return(-errno
);
184 #ifdef UM_HAVE_SETREGS
187 long regs
[FRAME_SIZE
];
190 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
191 regs
[i
] = ptrace(PTRACE_PEEKDATA
, debugger
->pid
,
193 result
= ptrace(PTRACE_SETREGS
, child
, 0, regs
);
194 if(result
== -1) return(-errno
);
200 case PTRACE_SINGLESTEP
:
201 if(!debugger
->debugee
->in_context
) return(-EPERM
);
203 sigaddset(&relay
, SIGSEGV
);
204 sigaddset(&relay
, SIGILL
);
205 sigaddset(&relay
, SIGBUS
);
206 result
= ptrace(PTRACE_SINGLESTEP
, child
, arg3
, arg4
);
207 if(result
== -1) return(-errno
);
209 status
= wait_for_stop(child
, SIGTRAP
, PTRACE_SINGLESTEP
,
211 child_proxy(child
, status
);
215 if(!debugger
->debugee
->in_context
) return(-EPERM
);
216 result
= ptrace(PTRACE_SYSCALL
, child
, arg3
, arg4
);
217 if(result
== -1) return(-errno
);
219 *ret
= PTRACE_SYSCALL
;
229 * Overrides for Emacs so that we follow Linus's tabbing style.
230 * Emacs will notice this stuff at the end of the file and automatically
231 * adjust the settings for this buffer only. This must remain at the end
233 * ---------------------------------------------------------------------------
235 * c-file-style: "linux"