]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/proc_api.c
import gdb-2000-01-05 snapshot
[thirdparty/binutils-gdb.git] / gdb / proc_api.c
1 /*
2 * Pretty-print trace of api calls to the /proc api
3 * (ioctl or read/write calls).
4 *
5 */
6
7 #include "defs.h"
8 #include "gdbcmd.h"
9
10 #if defined (NEW_PROC_API)
11 #define _STRUCTURED_PROC 1
12 #endif
13
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <sys/procfs.h>
17 #include <sys/proc.h> /* for struct proc */
18 #include <sys/user.h> /* for struct user */
19 #include <fcntl.h> /* for O_RDWR etc. */
20
21 /* Much of the information used in the /proc interface, particularly for
22 printing status information, is kept as tables of structures of the
23 following form. These tables can be used to map numeric values to
24 their symbolic names and to a string that describes their specific use. */
25
26 struct trans {
27 long value; /* The numeric value */
28 char *name; /* The equivalent symbolic value */
29 char *desc; /* Short description of value */
30 };
31
32 static int procfs_trace = 1;
33 /*static int info_verbose = 1;*/ /* kludge */
34 static FILE *procfs_file = NULL;
35 static char *procfs_filename = "procfs_trace";
36
37 static void
38 set_procfs_trace_cmd (args, from_tty, c)
39 char *args;
40 int from_tty;
41 struct cmd_list_element *c;
42 {
43 #if 0 /* not sure what I might actually need to do here, if anything */
44 if (procfs_file)
45 fflush (procfs_file);
46 #endif
47 }
48
49 static void
50 set_procfs_file_cmd (args, from_tty, c)
51 char *args;
52 int from_tty;
53 struct cmd_list_element *c;
54 {
55 /* Just changed the filename for procfs tracing.
56 If a file was already open, close it. */
57 if (procfs_file)
58 fclose (procfs_file);
59 procfs_file = NULL;
60 }
61
62
63 #ifndef NEW_PROC_API
64
65 static struct trans ioctl_table[] = {
66 #ifdef PIOCACINFO /* irix */
67 { PIOCACINFO, "PIOCACINFO", "get process account info" },
68 #endif
69 { PIOCACTION, "PIOCACTION", "get signal action structs" },
70 #ifdef PIOCARGUMENTS /* osf */
71 { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
72 #endif
73 #ifdef PIOCAUXV /* solaris aux vectors */
74 { PIOCAUXV, "PIOCAUXV", "get aux vector" },
75 { PIOCNAUXV, "PIOCNAUXV", "get number of aux vector entries" },
76 #endif /* AUXV */
77 { PIOCCFAULT, "PIOCCFAULT", "clear current fault" },
78 { PIOCCRED, "PIOCCRED", "get process credentials" },
79 #ifdef PIOCENEVCTRS /* irix event counters */
80 { PIOCENEVCTRS, "PIOCENEVCTRS", "acquire and start event counters" },
81 { PIOCGETEVCTRL, "PIOCGETEVCTRL", "get control info of event counters" },
82 { PIOCGETEVCTRS, "PIOCGETEVCTRS", "dump event counters" },
83 { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
84 { PIOCRELEVCTRS, "PIOCRELEVCTRS", "release/stop event counters" },
85 { PIOCSETEVCTRL, "PIOCSETEVCTRL", "set control info of event counters" },
86 { PIOCGETPTIMER, "PIOCGETPTIMER", "get process timers" },
87 #endif /* irix event counters */
88 { PIOCGENTRY, "PIOCGENTRY", "get traced syscall entry set" },
89 { PIOCGETPR, "PIOCGETPR", "read struct proc" },
90 { PIOCGETU, "PIOCGETU", "read user area" },
91 #if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
92 { PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
93 #endif
94 { PIOCGEXIT, "PIOCGEXIT", "get traced syscall exit set" },
95 { PIOCGFAULT, "PIOCGFAULT", "get traced fault set" },
96 #ifdef PIOCGFPCR /* osf */
97 { PIOCGFPCR, "PIOCGFPCR", "get FP control register" },
98 { PIOCSFPCR, "PIOCSFPCR", "set FP conrtol register" },
99 #endif
100 { PIOCGFPREG, "PIOCGFPREG", "get floating point registers" },
101 { PIOCGHOLD, "PIOCGHOLD", "get held signal set" },
102 { PIOCGREG, "PIOCGREG", "get general registers" },
103 { PIOCGROUPS, "PIOCGROUPS", "get supplementary groups" },
104 #ifdef PIOCGSPCACT /* osf */
105 { PIOCGSPCACT, "PIOCGSPCACT", "get special action" },
106 { PIOCSSPCACT, "PIOCSSPCACT", "set special action" },
107 #endif
108 { PIOCGTRACE, "PIOCGTRACE", "get traced signal set" },
109 #ifdef PIOCGWATCH /* irix watchpoints */
110 { PIOCGWATCH, "PIOCGWATCH", "get watchpoint" },
111 { PIOCSWATCH, "PIOCSWATCH", "set watchpoint" },
112 { PIOCNWATCH, "PIOCNWATCH", "get number of watchpoints" },
113 #endif /* irix watchpoints */
114 #ifdef PIOCGWIN /* solaris sparc */
115 { PIOCGWIN, "PIOCGWIN", "get gwindows_t" },
116 #endif
117 #ifdef PIOCGXREG /* solaris sparc extra regs */
118 { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
119 { PIOCGXREG, "PIOCGXREG", "get extra register state" },
120 { PIOCSXREG, "PIOCSXREG", "set extra register state" },
121 #endif /* XREG */
122 { PIOCKILL, "PIOCKILL", "send signal" },
123 #ifdef PIOCLDT /* solaris i386 */
124 { PIOCLDT, "PIOCLDT", "get LDT" },
125 { PIOCNLDT, "PIOCNLDT", "get number of LDT entries" },
126 #endif
127 #ifdef PIOCLSTATUS /* solaris and unixware */
128 { PIOCLSTATUS, "PIOCLSTATUS", "get status of all lwps" },
129 { PIOCLUSAGE, "PIOCLUSAGE", "get resource usage of all lwps" },
130 { PIOCOPENLWP, "PIOCOPENLWP", "get lwp file descriptor" },
131 { PIOCLWPIDS, "PIOCLWPIDS", "get lwp identifiers" },
132 #endif /* LWP */
133 { PIOCMAP, "PIOCMAP", "get memory map information" },
134 { PIOCMAXSIG, "PIOCMAXSIG", "get max signal number" },
135 { PIOCNICE, "PIOCNICE", "set nice priority" },
136 { PIOCNMAP, "PIOCNMAP", "get number of memory mappings" },
137 { PIOCOPENM, "PIOCOPENM", "open mapped object for reading" },
138 #ifdef PIOCOPENMOBS /* osf */
139 { PIOCOPENMOBS, "PIOCOPENMOBS", "open mapped object" },
140 #endif
141 #ifdef PIOCOPENPD /* solaris */
142 { PIOCOPENPD, "PIOCOPENPD", "get page data file descriptor" },
143 #endif
144 { PIOCPSINFO, "PIOCPSINFO", "get ps(1) information" },
145 { PIOCRESET, "PIOCRESET", "reset process flags" },
146 { PIOCRFORK, "PIOCRFORK", "reset inherit-on-fork flag" },
147 { PIOCRRLC, "PIOCRRLC", "reset run-on-last-close flag" },
148 { PIOCRUN, "PIOCRUN", "make process runnable" },
149 #ifdef PIOCSAVECCNTRS /* irix */
150 { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
151 #endif
152 { PIOCSENTRY, "PIOCSENTRY", "set traced syscall entry set" },
153 { PIOCSET, "PIOCSET", "set process flags" },
154 { PIOCSEXIT, "PIOCSEXIT", "set traced syscall exit set" },
155 { PIOCSFAULT, "PIOCSFAULT", "set traced fault set" },
156 { PIOCSFORK, "PIOCSFORK", "set inherit-on-fork flag" },
157 { PIOCSFPREG, "PIOCSFPREG", "set floating point registers" },
158 { PIOCSHOLD, "PIOCSHOLD", "set held signal set" },
159 { PIOCSREG, "PIOCSREG", "set general registers" },
160 { PIOCSRLC, "PIOCSRLC", "set run-on-last-close flag" },
161 { PIOCSSIG, "PIOCSSIG", "set current signal" },
162 { PIOCSTATUS, "PIOCSTATUS", "get process status" },
163 { PIOCSTOP, "PIOCSTOP", "post stop request" },
164 { PIOCSTRACE, "PIOCSTRACE", "set traced signal set" },
165 { PIOCUNKILL, "PIOCUNKILL", "delete a signal" },
166 #ifdef PIOCUSAGE /* solaris */
167 { PIOCUSAGE, "PIOCUSAGE", "get resource usage" },
168 #endif
169 { PIOCWSTOP, "PIOCWSTOP", "wait for process to stop" },
170
171 #ifdef PIOCNTHR /* osf threads */
172 { PIOCNTHR, "PIOCNTHR", "get thread count" },
173 { PIOCRTINH, "PIOCRTINH", "reset inherit-on-thread-creation" },
174 { PIOCSTINH, "PIOCSTINH", "set inherit-on-thread-creation" },
175 { PIOCTLIST, "PIOCTLIST", "get thread ids" },
176 { PIOCXPTH, "PIOCXPTH", "translate port to thread handle" },
177 { PIOCTRUN, "PIOCTRUN", "make thread runnable" },
178 { PIOCTSTATUS, "PIOCTSTATUS", "get thread status" },
179 { PIOCTSTOP, "PIOCTSTOP", "stop a thread" },
180 /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
181 TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
182 TGEXIT TSEXIT TSHOLD ... thread functions */
183 #endif /* osf threads */
184 { -1, NULL, NULL }
185 };
186
187 int
188 ioctl_with_trace (fd, opcode, ptr, file, line)
189 int fd;
190 long opcode;
191 void *ptr;
192 char *file;
193 int line;
194 {
195 int i, ret, arg1;
196
197 if (procfs_trace)
198 {
199 if (procfs_file == NULL && procfs_filename != NULL)
200 procfs_file = fopen (procfs_filename, "a");
201
202 for (i = 0; ioctl_table[i].name != NULL; i++)
203 if (ioctl_table[i].value == opcode)
204 break;
205
206 if (info_verbose)
207 fprintf (procfs_file ? procfs_file : stdout,
208 "%s:%d -- ", file, line);
209 switch (opcode) {
210 case PIOCSET:
211 arg1 = ptr ? *(long *) ptr : 0;
212 fprintf (procfs_file ? procfs_file : stdout,
213 "ioctl (PIOCSET, %s) %s\n",
214 arg1 == PR_FORK ? "PR_FORK" :
215 arg1 == PR_RLC ? "PR_RLC" :
216 #ifdef PR_ASYNC
217 arg1 == PR_ASYNC ? "PR_ASYNC" :
218 #endif
219 "<unknown flag>",
220 info_verbose ? ioctl_table[i].desc : "");
221 break;
222 case PIOCRESET:
223 arg1 = ptr ? *(long *) ptr : 0;
224 fprintf (procfs_file ? procfs_file : stdout,
225 "ioctl (PIOCRESET, %s) %s\n",
226 arg1 == PR_FORK ? "PR_FORK" :
227 arg1 == PR_RLC ? "PR_RLC" :
228 #ifdef PR_ASYNC
229 arg1 == PR_ASYNC ? "PR_ASYNC" :
230 #endif
231 "<unknown flag>",
232 info_verbose ? ioctl_table[i].desc : "");
233 break;
234 case PIOCSTRACE:
235 fprintf (procfs_file ? procfs_file : stdout,
236 "ioctl (PIOCSTRACE) ");
237 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
238 (sigset_t *) ptr, 0);
239 break;
240 case PIOCSFAULT:
241 fprintf (procfs_file ? procfs_file : stdout,
242 "ioctl (%s) ",
243 opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
244 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
245 (fltset_t *) ptr, 0);
246 break;
247 case PIOCSENTRY:
248 fprintf (procfs_file ? procfs_file : stdout,
249 "ioctl (%s) ",
250 opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
251 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
252 (sysset_t *) ptr, 0);
253 break;
254 case PIOCSEXIT:
255 fprintf (procfs_file ? procfs_file : stdout,
256 "ioctl (%s) ",
257 opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
258 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
259 (sysset_t *) ptr, 0);
260 break;
261 case PIOCSHOLD:
262 fprintf (procfs_file ? procfs_file : stdout,
263 "ioctl (%s) ",
264 opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
265 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
266 (sigset_t *) ptr, 0);
267 break;
268 case PIOCSSIG:
269 fprintf (procfs_file ? procfs_file : stdout,
270 "ioctl (PIOCSSIG) ");
271 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
272 ptr ? ((siginfo_t *) ptr)->si_signo : 0,
273 0);
274 fprintf (procfs_file ? procfs_file : stdout, "\n");
275 break;
276 case PIOCRUN:
277 fprintf (procfs_file ? procfs_file : stdout,
278 "ioctl (PIOCRUN) ");
279
280 arg1 = ptr ? *(long *) ptr : 0;
281 if (arg1 & PRCSIG)
282 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
283 if (arg1 & PRCFAULT)
284 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
285 if (arg1 & PRSTRACE)
286 fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
287 if (arg1 & PRSHOLD)
288 fprintf (procfs_file ? procfs_file : stdout, "setHold ");
289 if (arg1 & PRSFAULT)
290 fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
291 if (arg1 & PRSVADDR)
292 fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
293 if (arg1 & PRSTEP)
294 fprintf (procfs_file ? procfs_file : stdout, "step ");
295 if (arg1 & PRSABORT)
296 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
297 if (arg1 & PRSTOP)
298 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
299
300 fprintf (procfs_file ? procfs_file : stdout, "\n");
301 break;
302 case PIOCKILL:
303 fprintf (procfs_file ? procfs_file : stdout,
304 "ioctl (PIOCKILL) ");
305 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
306 ptr ? *(long *) ptr : 0, 0);
307 fprintf (procfs_file ? procfs_file : stdout, "\n");
308 break;
309 #ifdef PIOCSSPCACT
310 case PIOCSSPCACT:
311 fprintf (procfs_file ? procfs_file : stdout,
312 "ioctl (PIOCSSPCACT) ");
313 arg1 = ptr ? *(long *) ptr : 0;
314 if (arg1 & PRFS_STOPFORK)
315 fprintf (procfs_file ? procfs_file : stdout, "stopFork ");
316 if (arg1 & PRFS_STOPEXEC)
317 fprintf (procfs_file ? procfs_file : stdout, "stopExec ");
318 if (arg1 & PRFS_STOPTERM)
319 fprintf (procfs_file ? procfs_file : stdout, "stopTerm ");
320 if (arg1 & PRFS_STOPTCR)
321 fprintf (procfs_file ? procfs_file : stdout, "stopThreadCreate ");
322 if (arg1 & PRFS_STOPTTERM)
323 fprintf (procfs_file ? procfs_file : stdout, "stopThreadTerm ");
324 if (arg1 & PRFS_KOLC)
325 fprintf (procfs_file ? procfs_file : stdout, "killOnLastClose ");
326 fprintf (procfs_file ? procfs_file : stdout, "\n");
327 break;
328 #endif /* PIOCSSPCACT */
329 default:
330 if (ioctl_table[i].name)
331 fprintf (procfs_file ? procfs_file : stdout,
332 "ioctl (%s) %s\n",
333 ioctl_table[i].name,
334 info_verbose ? ioctl_table[i].desc : "");
335 else
336 fprintf (procfs_file ? procfs_file : stdout,
337 "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
338 break;
339 }
340 if (procfs_file)
341 fflush (procfs_file);
342 }
343 ret = ioctl (fd, opcode, ptr);
344 if (procfs_trace && ret < 0)
345 {
346 fprintf (procfs_file ? procfs_file : stdout,
347 "[ioctl (%s) FAILED!]\n",
348 ioctl_table[i].name != NULL ?
349 ioctl_table[i].name : "<unknown>");
350 if (procfs_file)
351 fflush (procfs_file);
352 }
353
354 return ret;
355 }
356
357 #else /* NEW_PROC_API */
358
359 static struct trans rw_table[] = {
360 #ifdef PCAGENT /* solaris */
361 { PCAGENT, "PCAGENT", "create agent lwp with regs from argument" },
362 #endif
363 { PCCFAULT, "PCCFAULT", "clear current fault" },
364 #ifdef PCCSIG /* solaris */
365 { PCCSIG, "PCCSIG", "clear current signal" },
366 #endif
367 { PCDSTOP, "PCDSTOP", "post stop request" },
368 { PCKILL, "PCKILL", "post a signal" },
369 { PCNICE, "PCNICE", "set nice priority" },
370 #ifdef PCREAD /* solaris */
371 { PCREAD, "PCREAD", "read from the address space" },
372 { PCWRITE, "PCWRITE", "write to the address space" },
373 #endif
374 #ifdef PCRESET /* unixware */
375 { PCRESET, "PCRESET", "unset modes" },
376 #endif
377 { PCRUN, "PCRUN", "make process/lwp runnable" },
378 #ifdef PCSASRS /* solaris 2.7 only */
379 { PCSASRS, "PCSASRS", "set ancillary state registers" },
380 #endif
381 #ifdef PCSCRED /* solaris */
382 { PCSCRED, "PCSCRED", "set process credentials" },
383 #endif
384 { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
385 { PCSET, "PCSET", "set modes" },
386 { PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
387 { PCSFAULT, "PCSFAULT", "set traced fault set" },
388 { PCSFPREG, "PCSFPREG", "set floating point registers" },
389 { PCSHOLD, "PCSHOLD", "set signal mask" },
390 { PCSREG, "PCSREG", "set general registers" },
391 { PCSSIG, "PCSSIG", "set current signal" },
392 { PCSTOP, "PCSTOP", "post stop request and wait" },
393 { PCSTRACE, "PCSTRACE", "set traced signal set" },
394 #ifdef PCSVADDR /* solaris */
395 { PCSVADDR, "PCSVADDR", "set pc virtual address" },
396 #endif
397 #ifdef PCSXREG /* solaris sparc only */
398 { PCSXREG, "PCSXREG", "set extra registers" },
399 #endif
400 #ifdef PCTWSTOP /* solaris */
401 { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
402 #endif
403 { PCUNKILL, "PCUNKILL", "delete a pending signal" },
404 #ifdef PCUNSET /* solaris */
405 { PCUNSET, "PCUNSET", "unset modes" },
406 #endif
407 #ifdef PCWATCH /* solaris */
408 { PCWATCH, "PCWATCH", "set/unset watched memory area" },
409 #endif
410 { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
411 { 0, NULL, NULL }
412 };
413
414 static off_t lseek_offset;
415
416 int
417 write_with_trace (fd, arg, len, file, line)
418 int fd;
419 long *arg;
420 size_t len;
421 char *file;
422 int line;
423 {
424 int i;
425 long opcode = arg[0];
426 int ret;
427
428 if (procfs_trace)
429 {
430 if (procfs_file == NULL && procfs_filename != NULL)
431 procfs_file = fopen (procfs_filename, "a");
432
433 for (i = 0; rw_table[i].name != NULL; i++)
434 if (rw_table[i].value == opcode)
435 break;
436
437 if (info_verbose)
438 fprintf (procfs_file ? procfs_file : stdout,
439 "%s:%d -- ", file, line);
440 switch (opcode) {
441 case PCSET:
442 fprintf (procfs_file ? procfs_file : stdout,
443 "write (PCSET, %s) %s\n",
444 arg[1] == PR_FORK ? "PR_FORK" :
445 arg[1] == PR_RLC ? "PR_RLC" :
446 #ifdef PR_ASYNC
447 arg[1] == PR_ASYNC ? "PR_ASYNC" :
448 #endif
449 "<unknown flag>",
450 info_verbose ? rw_table[i].desc : "");
451 break;
452 #ifdef PCUNSET
453 case PCUNSET:
454 #endif
455 #ifdef PCRESET
456 case PCRESET:
457 #endif
458 fprintf (procfs_file ? procfs_file : stdout,
459 "write (PCRESET, %s) %s\n",
460 arg[1] == PR_FORK ? "PR_FORK" :
461 arg[1] == PR_RLC ? "PR_RLC" :
462 #ifdef PR_ASYNC
463 arg[1] == PR_ASYNC ? "PR_ASYNC" :
464 #endif
465 "<unknown flag>",
466 info_verbose ? rw_table[i].desc : "");
467 break;
468 case PCSTRACE:
469 fprintf (procfs_file ? procfs_file : stdout,
470 "write (PCSTRACE) ");
471 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
472 (sigset_t *) &arg[1], 0);
473 break;
474 case PCSFAULT:
475 fprintf (procfs_file ? procfs_file : stdout,
476 "write (PCSFAULT) ");
477 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
478 (fltset_t *) &arg[1], 0);
479 break;
480 case PCSENTRY:
481 fprintf (procfs_file ? procfs_file : stdout,
482 "write (PCSENTRY) ");
483 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
484 (sysset_t *) &arg[1], 0);
485 break;
486 case PCSEXIT:
487 fprintf (procfs_file ? procfs_file : stdout,
488 "write (PCSEXIT) ");
489 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
490 (sysset_t *) &arg[1], 0);
491 break;
492 case PCSHOLD:
493 fprintf (procfs_file ? procfs_file : stdout,
494 "write (PCSHOLD) ");
495 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
496 (sigset_t *) &arg[1], 0);
497 break;
498 case PCSSIG:
499 fprintf (procfs_file ? procfs_file : stdout,
500 "write (PCSSIG) ");
501 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
502 arg[1] ? ((siginfo_t *) &arg[1])->si_signo
503 : 0,
504 0);
505 fprintf (procfs_file ? procfs_file : stdout, "\n");
506 break;
507 case PCRUN:
508 fprintf (procfs_file ? procfs_file : stdout,
509 "write (PCRUN) ");
510 if (arg[1] & PRCSIG)
511 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
512 if (arg[1] & PRCFAULT)
513 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
514 if (arg[1] & PRSTEP)
515 fprintf (procfs_file ? procfs_file : stdout, "step ");
516 if (arg[1] & PRSABORT)
517 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
518 if (arg[1] & PRSTOP)
519 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
520
521 fprintf (procfs_file ? procfs_file : stdout, "\n");
522 break;
523 case PCKILL:
524 fprintf (procfs_file ? procfs_file : stdout,
525 "write (PCKILL) ");
526 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
527 arg[1], 0);
528 fprintf (procfs_file ? procfs_file : stdout, "\n");
529 break;
530 default:
531 {
532 static unsigned char break_insn[] = BREAKPOINT;
533
534 if (len == sizeof (break_insn) &&
535 memcmp (arg, &break_insn, len) == 0)
536 fprintf (procfs_file ? procfs_file : stdout,
537 "write (<breakpoint at 0x%08x>) \n", lseek_offset);
538 else if (rw_table[i].name)
539 fprintf (procfs_file ? procfs_file : stdout,
540 "write (%s) %s\n",
541 rw_table[i].name,
542 info_verbose ? rw_table[i].desc : "");
543 else
544 {
545 if (lseek_offset != -1)
546 fprintf (procfs_file ? procfs_file : stdout,
547 "write (<unknown>, %d bytes at 0x%08x) \n",
548 len, lseek_offset);
549 else
550 fprintf (procfs_file ? procfs_file : stdout,
551 "write (<unknown>, %d bytes) \n", len);
552 }
553 break;
554 }
555 }
556 if (procfs_file)
557 fflush (procfs_file);
558 }
559 ret = write (fd, arg, len);
560 if (procfs_trace && ret != len)
561 {
562 fprintf (procfs_file ? procfs_file : stdout,
563 "[write (%s) FAILED!\n",
564 rw_table[i].name != NULL ?
565 rw_table[i].name : "<unknown>");
566 if (procfs_file)
567 fflush (procfs_file);
568 }
569
570 lseek_offset = -1;
571 return ret;
572 }
573
574 off_t
575 lseek_with_trace (fd, offset, whence, file, line)
576 int fd;
577 off_t offset;
578 int whence;
579 char *file;
580 int line;
581 {
582 off_t ret;
583
584 #if 0 /* don't need output, just need address */
585 if (procfs_trace)
586 {
587 if (procfs_file == NULL && procfs_filename != NULL)
588 procfs_file = fopen (procfs_filename, "a");
589
590 if (info_verbose)
591 fprintf (procfs_file ? procfs_file : stdout,
592 "%s:%d -- ", file, line);
593 fprintf (procfs_file ? procfs_file : stdout,
594 "lseek (0x%08x, %s) \n", offset,
595 whence == SEEK_SET ? "SEEK_SET" :
596 whence == SEEK_CUR ? "SEEK_CUR" :
597 whence == SEEK_END ? "SEEK_END" :
598 "<unknown whence>");
599 if (procfs_file)
600 fflush (procfs_file);
601 }
602 #endif
603 ret = lseek (fd, offset, whence);
604 lseek_offset = ret;
605 if (procfs_trace && ret == -1)
606 {
607 if (procfs_file == NULL && procfs_filename != NULL)
608 procfs_file = fopen (procfs_filename, "a");
609
610 fprintf (procfs_file ? procfs_file : stdout,
611 "[lseek (0x%08x) FAILED!\n", offset);
612 if (procfs_file)
613 fflush (procfs_file);
614 }
615
616 return ret;
617 }
618
619 #endif /* NEW_PROC_API */
620
621 int
622 open_with_trace (filename, mode, file, line)
623 char *filename;
624 int mode;
625 char *file;
626 int line;
627 {
628 int ret = open (filename, mode);
629
630 if (procfs_trace)
631 {
632 if (procfs_file == NULL && procfs_filename != NULL)
633 procfs_file = fopen (procfs_filename, "a");
634
635 if (info_verbose)
636 fprintf (procfs_file ? procfs_file : stdout,
637 "%s:%d -- ", file, line);
638 fprintf (procfs_file ? procfs_file : stdout,
639 "%d = open (%s, ", ret, filename);
640 if (mode == O_RDONLY)
641 fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n", line);
642 else if (mode == O_WRONLY)
643 fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n", line);
644 else if (mode == O_RDWR)
645 fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n", line);
646 if (procfs_file)
647 fflush (procfs_file);
648 }
649
650 return ret;
651 }
652
653 int
654 close_with_trace (fd, file, line)
655 int fd;
656 char *file;
657 int line;
658 {
659 int ret = close (fd);
660
661 if (procfs_trace)
662 {
663 if (procfs_file == NULL && procfs_filename != NULL)
664 procfs_file = fopen (procfs_filename, "a");
665
666 if (info_verbose)
667 fprintf (procfs_file ? procfs_file : stdout,
668 "%s:%d -- ", file, line);
669 fprintf (procfs_file ? procfs_file : stdout,
670 "%d = close (%d)\n", ret, fd);
671 if (procfs_file)
672 fflush (procfs_file);
673 }
674
675 return ret;
676 }
677
678 int
679 wait_with_trace (wstat, file, line)
680 int *wstat;
681 char *file;
682 int line;
683 {
684 int ret, lstat = 0;
685
686 if (procfs_trace)
687 {
688 if (procfs_file == NULL && procfs_filename != NULL)
689 procfs_file = fopen (procfs_filename, "a");
690
691 if (info_verbose)
692 fprintf (procfs_file ? procfs_file : stdout,
693 "%s:%d -- ", file, line);
694 fprintf (procfs_file ? procfs_file : stdout,
695 "wait (line %d) ", line);
696 if (procfs_file)
697 fflush (procfs_file);
698 }
699 ret = wait (&lstat);
700 if (procfs_trace)
701 {
702 fprintf (procfs_file ? procfs_file : stdout,
703 "returned pid %d, status 0x%x\n", ret, lstat);
704 if (procfs_file)
705 fflush (procfs_file);
706 }
707 if (wstat)
708 *wstat = lstat;
709
710 return ret;
711 }
712
713 void
714 procfs_note (msg, file, line)
715 char *msg;
716 char *file;
717 int line;
718 {
719 if (procfs_trace)
720 {
721 if (procfs_file == NULL && procfs_filename != NULL)
722 procfs_file = fopen (procfs_filename, "a");
723
724 if (info_verbose)
725 fprintf (procfs_file ? procfs_file : stdout,
726 "%s:%d -- ", file, line);
727 fprintf (procfs_file ? procfs_file : stdout, msg);
728 if (procfs_file)
729 fflush (procfs_file);
730 }
731 }
732
733 void
734 proc_prettyfprint_status (flags, why, what, thread)
735 long flags;
736 int why;
737 int what;
738 int thread;
739 {
740 if (procfs_trace)
741 {
742 if (procfs_file == NULL && procfs_filename != NULL)
743 procfs_file = fopen (procfs_filename, "a");
744
745 if (thread)
746 fprintf (procfs_file ? procfs_file : stdout,
747 "Thread %d: ", thread);
748
749 proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
750 flags, 0);
751
752 if (flags & (PR_STOPPED | PR_ISTOP))
753 proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
754 why, what, 0);
755 if (procfs_file)
756 fflush (procfs_file);
757 }
758 }
759
760
761 void
762 _initialize_proc_api ()
763 {
764 struct cmd_list_element *c;
765
766 c = add_set_cmd ("procfs-trace", no_class,
767 var_boolean, (char *) &procfs_trace,
768 "Set tracing for /proc ioctl calls.\n", &setlist);
769
770 add_show_from_set (c, &showlist);
771 c->function.sfunc = set_procfs_trace_cmd;
772
773 c = add_set_cmd ("procfs-file", no_class, var_filename,
774 (char *) &procfs_filename,
775 "Set filename for /proc tracefile.\n", &setlist);
776
777 add_show_from_set (c, &showlist);
778 c->function.sfunc = set_procfs_file_cmd;
779
780 #ifdef TRACE_PROCFS
781 if (procfs_file == NULL && procfs_filename != NULL)
782 procfs_file = fopen (procfs_filename, "a");
783 #endif
784 }