OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [proc-api.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.