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