1 /* $OpenBSD: process.c,v 1.13 2003/08/18 17:55:57 jfb Exp $ */
2 /*
3 * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <sys/types.h>
28 #include <sys/ptrace.h>
29 #include <sys/wait.h>
30 #include <sys/stat.h>
31
32 #include <machine/reg.h>
33
34 #include <err.h>
35 #include <errno.h>
36 #include <signal.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include "pmdb.h"
43 #include "core.h"
44 #include "symbol.h"
45 #include "break.h"
46
47 int
process_load(struct pstate * ps)48 process_load(struct pstate *ps)
49 {
50 if (ps->ps_state == LOADED)
51 return (0);
52
53 if (access(*ps->ps_argv, R_OK|X_OK) < 0) {
54 fprintf(stderr, "%s: %s.\n", *ps->ps_argv,
55 strerror(errno));
56 return (1);
57 }
58
59 if (stat(ps->ps_argv[0], &(ps->exec_stat)) < 0)
60 err(1, "stat()");
61
62 if ((ps->ps_flags & PSF_SYMBOLS) == 0) {
63 sym_init_exec(ps, ps->ps_argv[0]);
64 ps->ps_flags |= PSF_SYMBOLS;
65 }
66
67 ps->ps_state = LOADED;
68
69 if (ps->ps_pid != 0) {
70 /* attach to an already running process */
71 if (ptrace(PT_ATTACH, ps->ps_pid, (caddr_t) 0, 0) < 0)
72 err(1, "failed to ptrace process");
73 ps->ps_state = STOPPED;
74 ps->ps_flags |= PSF_ATCH;
75 }
76
77 return (0);
78 }
79
80
81 int
process_setargv(struct pstate * ps,int argc,char ** argv)82 process_setargv(struct pstate *ps, int argc, char **argv)
83 {
84 int i;
85
86 if (ps->ps_argv != NULL) {
87 for (i = 0; i < ps->ps_argc; i++)
88 free(ps->ps_argv[i]);
89 free(ps->ps_argv);
90 }
91
92 ps->ps_argv = (char **)calloc((argc + 1), sizeof(char *));
93 if (ps->ps_argv == NULL) {
94 warn("failed to allocate argument vector");
95 return (-1);
96 }
97
98 ps->ps_argc = argc;
99 for (i = 0; i < argc; i++) {
100 ps->ps_argv[i] = strdup(argv[i]);
101 if (ps->ps_argv[i] == NULL) {
102 warn("failed to copy argument");
103 return (-1);
104 }
105 }
106
107 ps->ps_argv[i] = NULL;
108 return (0);
109 }
110
111
112 int
process_run(struct pstate * ps)113 process_run(struct pstate *ps)
114 {
115 int status;
116
117 if ((ps->ps_state == RUNNING) || (ps->ps_state == STOPPED)) {
118 warnx("process is already running");
119 return 0;
120 }
121
122 switch (ps->ps_pid = fork()) {
123 case 0:
124 if (ptrace(PT_TRACE_ME, getpid(), NULL, 0) != 0)
125 err(1, "ptrace(PT_TRACE_ME)");
126 execvp(*ps->ps_argv, ps->ps_argv);
127 err(1, "exec");
128 /* NOTREACHED */
129 case -1:
130 err(1, "fork");
131 /* NOTREACHED */
132 default:
133 warnx("process started with PID %d", ps->ps_pid);
134 break;
135 }
136
137 ps->ps_state = LOADED;
138
139 if (wait(&status) == 0)
140 err(1, "wait");
141
142 return (0);
143 }
144
145
146 int
process_kill(struct pstate * ps)147 process_kill(struct pstate *ps)
148 {
149 switch(ps->ps_state) {
150 case RUNNING:
151 case STOPPED:
152 if (ptrace(PT_KILL, ps->ps_pid, NULL, 0) != 0)
153 err(1, "ptrace(PT_KILL)");
154 return (1);
155 default:
156 return (0);
157 }
158 }
159
160 int
process_read(struct pstate * ps,off_t from,void * to,size_t size)161 process_read(struct pstate *ps, off_t from, void *to, size_t size)
162 {
163 struct ptrace_io_desc piod;
164
165 if (((ps->ps_state == NONE) || (ps->ps_state == LOADED) ||
166 (ps->ps_state == TERMINATED)) && (ps->ps_flags & PSF_CORE)) {
167 return core_read(ps, from, to, size);
168 } else {
169 piod.piod_op = PIOD_READ_D;
170 piod.piod_offs = (void *)(long)from;
171 piod.piod_addr = to;
172 piod.piod_len = size;
173
174 return (ptrace(PT_IO, ps->ps_pid, (caddr_t)&piod, 0) < 0?
175 -1 : piod.piod_len);
176 }
177 }
178
179 int
process_write(struct pstate * ps,off_t to,void * from,size_t size)180 process_write(struct pstate *ps, off_t to, void *from, size_t size)
181 {
182 struct ptrace_io_desc piod;
183
184 if ((ps->ps_state == NONE) && (ps->ps_flags & PSF_CORE)) {
185 return core_write(ps, to, from, size);
186 } else {
187 piod.piod_op = PIOD_WRITE_D;
188 piod.piod_offs = (void *)(long)to;
189 piod.piod_addr = from;
190 piod.piod_len = size;
191
192 return (ptrace(PT_IO, ps->ps_pid, (caddr_t)&piod, 0) < 0?
193 -1 : piod.piod_len);
194 }
195 }
196
197 int
process_getregs(struct pstate * ps,struct reg * r)198 process_getregs(struct pstate *ps, struct reg *r)
199 {
200
201 if (ps->ps_flags & PSF_CORE) {
202 memcpy(r, ps->ps_core->regs, sizeof(*r));
203
204 return (0);
205 }
206
207 return (ptrace(PT_GETREGS, ps->ps_pid, (caddr_t)r, 0));
208 }
209
210 int
cmd_process_kill(int argc,char ** argv,void * arg)211 cmd_process_kill(int argc, char **argv, void *arg)
212 {
213 struct pstate *ps = arg;
214
215 process_kill(ps);
216
217 return (1);
218 }
219
220 int
process_bkpt_main(struct pstate * ps,void * arg)221 process_bkpt_main(struct pstate *ps, void *arg)
222 {
223 sym_update(ps);
224
225 return (BKPT_DEL_CONT);
226 }
227
228 int
cmd_process_run(int argc,char ** argv,void * arg)229 cmd_process_run(int argc, char **argv, void *arg)
230 {
231 struct pstate *ps = arg;
232
233 if (ps->ps_state == NONE) {
234 reg main_addr;
235
236 if (process_load(ps) != 0)
237 return (0);
238
239 if (sym_lookup(ps, "main", &main_addr))
240 warnx("no main");
241 else if (bkpt_add_cb(ps, main_addr, process_bkpt_main, NULL))
242 warn("no bkpt at main 0x%lx", main_addr);
243 }
244
245 if (ps->ps_state != LOADED) {
246 fprintf(stderr, "Process already running.\n");
247 return (0);
248 }
249
250 process_run(ps);
251 /*
252 * XXX - there isn't really any difference between STOPPED and
253 * LOADED, we should probably get rid of one.
254 */
255 ps->ps_state = STOPPED;
256 ps->ps_signum = 0;
257
258 return (cmd_process_cont(argc, argv, arg));
259 }
260
261 int
cmd_process_cont(int argc,char ** argv,void * arg)262 cmd_process_cont(int argc, char **argv, void *arg)
263 {
264 struct pstate *ps = arg;
265 int signum;
266 int req = (ps->ps_flags & PSF_STEP) ? PT_STEP : PT_CONTINUE;
267
268 if (ps->ps_state != STOPPED) {
269 fprintf(stderr, "Process not loaded and stopped %d\n",
270 ps->ps_state);
271 return (0);
272 }
273
274 /* Catch SIGINT and SIGTRAP, pass all other signals. */
275 switch (ps->ps_signum) {
276 case SIGINT:
277 case SIGTRAP:
278 signum = 0;
279 break;
280 default:
281 signum = ps->ps_signum;
282 break;
283 }
284
285 if (ptrace(req, ps->ps_pid, (caddr_t)ps->ps_npc, signum) != 0) {
286 err(1, "ptrace(%s)", req == PT_STEP ? "PT_STEP":"PT_CONTINUE");
287 }
288
289 ps->ps_state = RUNNING;
290 ps->ps_npc = 1;
291
292 return (1);
293 }
294
295 int
cmd_process_setenv(int argc,char ** argv,void * arg)296 cmd_process_setenv(int argc, char **argv, void *arg)
297 {
298 if (setenv(argv[1], argv[2], 1))
299 err(1, "setenv");
300
301 return (0);
302 }
303