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"
25 long proxy_ptrace(struct debugger
*debugger
, int arg1
, pid_t arg2
,
26 long arg3
, long arg4
, pid_t child
, int *ret
)
33 if(debugger
->debugee
->died
) return(-ESRCH
);
37 if(debugger
->debugee
->traced
) return(-EPERM
);
39 debugger
->debugee
->pid
= arg2
;
40 debugger
->debugee
->traced
= 1;
42 if(is_valid_pid(arg2
) && (arg2
!= child
)){
43 debugger
->debugee
->in_context
= 0;
45 debugger
->debugee
->event
= 1;
46 debugger
->debugee
->wait_status
= W_STOPCODE(SIGSTOP
);
49 debugger
->debugee
->in_context
= 1;
50 if(debugger
->debugee
->stopped
)
51 child_proxy(child
, W_STOPCODE(SIGSTOP
));
52 else kill(child
, SIGSTOP
);
58 if(!debugger
->debugee
->traced
) return(-EPERM
);
60 debugger
->debugee
->traced
= 0;
61 debugger
->debugee
->pid
= 0;
62 if(!debugger
->debugee
->in_context
)
68 if(!debugger
->debugee
->in_context
) return(-EPERM
);
70 return(ptrace(PTRACE_CONT
, child
, arg3
, arg4
));
72 #ifdef UM_HAVE_GETFPREGS
73 case PTRACE_GETFPREGS
:
75 long regs
[FP_FRAME_SIZE
];
78 result
= ptrace(PTRACE_GETFPREGS
, child
, 0, regs
);
79 if(result
== -1) return(-errno
);
81 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
82 ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
+ 4 * i
,
88 #ifdef UM_HAVE_GETFPXREGS
89 case PTRACE_GETFPXREGS
:
91 long regs
[FPX_FRAME_SIZE
];
94 result
= ptrace(PTRACE_GETFPXREGS
, child
, 0, regs
);
95 if(result
== -1) return(-errno
);
97 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
98 ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
+ 4 * i
,
104 #ifdef UM_HAVE_GETREGS
107 long regs
[FRAME_SIZE
];
110 result
= ptrace(PTRACE_GETREGS
, child
, 0, regs
);
111 if(result
== -1) return(-errno
);
113 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
114 ptrace (PTRACE_POKEDATA
, debugger
->pid
,
115 arg4
+ 4 * i
, regs
[i
]);
122 result
= ptrace(PTRACE_KILL
, child
, arg3
, arg4
);
123 if(result
== -1) return(-errno
);
127 case PTRACE_PEEKDATA
:
128 case PTRACE_PEEKTEXT
:
130 /* The value being read out could be -1, so we have to
131 * check errno to see if there's an error, and zero it
132 * beforehand so we're not faked out by an old error
136 result
= ptrace(arg1
, child
, arg3
, 0);
137 if((result
== -1) && (errno
!= 0)) return(-errno
);
139 result
= ptrace(PTRACE_POKEDATA
, debugger
->pid
, arg4
, result
);
140 if(result
== -1) return(-errno
);
144 case PTRACE_POKEDATA
:
145 case PTRACE_POKETEXT
:
147 result
= ptrace(arg1
, child
, arg3
, arg4
);
148 if(result
== -1) return(-errno
);
150 if(arg1
== PTRACE_POKEUSR
) ptrace_pokeuser(arg3
, arg4
);
153 #ifdef UM_HAVE_SETFPREGS
154 case PTRACE_SETFPREGS
:
156 long regs
[FP_FRAME_SIZE
];
159 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
160 regs
[i
] = ptrace (PTRACE_PEEKDATA
, debugger
->pid
,
162 result
= ptrace(PTRACE_SETFPREGS
, child
, 0, regs
);
163 if(result
== -1) return(-errno
);
169 #ifdef UM_HAVE_SETFPXREGS
170 case PTRACE_SETFPXREGS
:
172 long regs
[FPX_FRAME_SIZE
];
175 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
176 regs
[i
] = ptrace (PTRACE_PEEKDATA
, debugger
->pid
,
178 result
= ptrace(PTRACE_SETFPXREGS
, child
, 0, regs
);
179 if(result
== -1) return(-errno
);
185 #ifdef UM_HAVE_SETREGS
188 long regs
[FRAME_SIZE
];
191 for (i
= 0; i
< sizeof(regs
)/sizeof(regs
[0]); i
++)
192 regs
[i
] = ptrace(PTRACE_PEEKDATA
, debugger
->pid
,
194 result
= ptrace(PTRACE_SETREGS
, child
, 0, regs
);
195 if(result
== -1) return(-errno
);
201 case PTRACE_SINGLESTEP
:
202 if(!debugger
->debugee
->in_context
) return(-EPERM
);
204 sigaddset(&relay
, SIGSEGV
);
205 sigaddset(&relay
, SIGILL
);
206 sigaddset(&relay
, SIGBUS
);
207 result
= ptrace(PTRACE_SINGLESTEP
, child
, arg3
, arg4
);
208 if(result
== -1) return(-errno
);
210 status
= wait_for_stop(child
, SIGTRAP
, PTRACE_SINGLESTEP
,
212 child_proxy(child
, status
);
216 if(!debugger
->debugee
->in_context
) return(-EPERM
);
217 result
= ptrace(PTRACE_SYSCALL
, child
, arg3
, arg4
);
218 if(result
== -1) return(-errno
);
220 *ret
= PTRACE_SYSCALL
;
230 * Overrides for Emacs so that we follow Linus's tabbing style.
231 * Emacs will notice this stuff at the end of the file and automatically
232 * adjust the settings for this buffer only. This must remain at the end
234 * ---------------------------------------------------------------------------
236 * c-file-style: "linux"