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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [proc-api.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* 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
#ifdef HAVE_SYS_PROC_H
40
#include <sys/proc.h>   /* for struct proc */
41
#endif
42
#ifdef HAVE_SYS_USER_H
43
#include <sys/user.h>   /* for struct user */
44
#endif
45
#include <fcntl.h>      /* for O_RDWR etc. */
46
#include <sys/wait.h>
47
 
48
#include "proc-utils.h"
49
 
50
/*  Much of the information used in the /proc interface, particularly for
51
    printing status information, is kept as tables of structures of the
52
    following form.  These tables can be used to map numeric values to
53
    their symbolic names and to a string that describes their specific use. */
54
 
55
struct trans {
56
  long value;                   /* The numeric value */
57
  char *name;                   /* The equivalent symbolic value */
58
  char *desc;                   /* Short description of value */
59
};
60
 
61
static int   procfs_trace    = 0;
62
static FILE *procfs_file     = NULL;
63
static char *procfs_filename = "procfs_trace";
64
 
65
static void
66
prepare_to_trace (void)
67
{
68
  if (procfs_trace)                     /* if procfs tracing turned on */
69
    if (procfs_file == NULL)            /* if output file not yet open */
70
      if (procfs_filename != NULL)      /* if output filename known */
71
        procfs_file = fopen (procfs_filename, "a");     /* open output file */
72
}
73
 
74
static void
75
set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
76
{
77
#if 0   /* not sure what I might actually need to do here, if anything */
78
  if (procfs_file)
79
    fflush (procfs_file);
80
#endif
81
}
82
 
83
static void
84
set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
85
{
86
  /* Just changed the filename for procfs tracing.
87
     If a file was already open, close it.  */
88
  if (procfs_file)
89
    fclose (procfs_file);
90
  procfs_file = NULL;
91
}
92
 
93
 
94
#ifndef NEW_PROC_API
95
 
96
static struct trans ioctl_table[] = {
97
#ifdef PIOCACINFO                       /* irix */
98
  { PIOCACINFO,    "PIOCACINFO",   "get process account info" },
99
#endif
100
  { PIOCACTION,    "PIOCACTION",   "get signal action structs" },
101
#ifdef PIOCARGUMENTS                    /* osf */
102
  { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
103
#endif
104
#ifdef PIOCAUXV                         /* solaris aux vectors */
105
  { PIOCAUXV,      "PIOCAUXV",     "get aux vector" },
106
  { PIOCNAUXV,     "PIOCNAUXV",    "get number of aux vector entries" },
107
#endif /* AUXV */
108
  { PIOCCFAULT,    "PIOCCFAULT",   "clear current fault" },
109
  { PIOCCRED,      "PIOCCRED",     "get process credentials" },
110
#ifdef PIOCENEVCTRS                     /* irix event counters */
111
  { PIOCENEVCTRS,    "PIOCENEVCTRS",    "acquire and start event counters" },
112
  { PIOCGETEVCTRL,   "PIOCGETEVCTRL",   "get control info of event counters" },
113
  { PIOCGETEVCTRS,   "PIOCGETEVCTRS",   "dump event counters" },
114
  { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
115
  { PIOCRELEVCTRS,   "PIOCRELEVCTRS",   "release/stop event counters" },
116
  { PIOCSETEVCTRL,   "PIOCSETEVCTRL",   "set control info of event counters" },
117
  { PIOCGETPTIMER,   "PIOCGETPTIMER",   "get process timers" },
118
#endif  /* irix event counters */
119
  { PIOCGENTRY,    "PIOCGENTRY",   "get traced syscall entry set" },
120
#if defined (PIOCGETPR)
121
  { PIOCGETPR,     "PIOCGETPR",    "read struct proc" },
122
#endif
123
#if defined (PIOCGETU)
124
  { PIOCGETU,      "PIOCGETU",     "read user area" },
125
#endif
126
#if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
127
  { PIOCGETUTK,  "PIOCGETUTK", "get the utask struct" },
128
#endif
129
  { PIOCGEXIT,     "PIOCGEXIT",    "get traced syscall exit  set" },
130
  { PIOCGFAULT,    "PIOCGFAULT",   "get traced fault set" },
131
#ifdef PIOCGFPCR                        /* osf */
132
  { PIOCGFPCR,     "PIOCGFPCR",    "get FP control register" },
133
  { PIOCSFPCR,     "PIOCSFPCR",    "set FP conrtol register" },
134
#endif
135
  { PIOCGFPREG,    "PIOCGFPREG",   "get floating point registers" },
136
  { PIOCGHOLD,     "PIOCGHOLD",    "get held signal set" },
137
  { PIOCGREG,      "PIOCGREG",     "get general registers" },
138
  { PIOCGROUPS,    "PIOCGROUPS",   "get supplementary groups" },
139
#ifdef PIOCGSPCACT                      /* osf */
140
  { PIOCGSPCACT,   "PIOCGSPCACT",  "get special action" },
141
  { PIOCSSPCACT,   "PIOCSSPCACT",  "set special action" },
142
#endif
143
  { PIOCGTRACE,    "PIOCGTRACE",   "get traced signal set" },
144
#ifdef PIOCGWATCH                       /* irix watchpoints */
145
  { PIOCGWATCH,    "PIOCGWATCH",   "get watchpoint" },
146
  { PIOCSWATCH,    "PIOCSWATCH",   "set watchpoint" },
147
  { PIOCNWATCH,    "PIOCNWATCH",   "get number of watchpoints" },
148
#endif  /* irix watchpoints */
149
#ifdef PIOCGWIN                         /* solaris sparc */
150
  { PIOCGWIN,      "PIOCGWIN",     "get gwindows_t" },
151
#endif
152
#ifdef PIOCGXREG                        /* solaris sparc extra regs */
153
  { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
154
  { PIOCGXREG,     "PIOCGXREG",    "get extra register state" },
155
  { PIOCSXREG,     "PIOCSXREG",    "set extra register state" },
156
#endif /* XREG */
157
  { PIOCKILL,      "PIOCKILL",     "send signal" },
158
#ifdef PIOCLDT                          /* solaris i386 */
159
  { PIOCLDT,       "PIOCLDT",      "get LDT" },
160
  { PIOCNLDT,      "PIOCNLDT",     "get number of LDT entries" },
161
#endif
162
#ifdef PIOCLSTATUS                      /* solaris and unixware */
163
  { PIOCLSTATUS,   "PIOCLSTATUS",  "get status of all lwps" },
164
  { PIOCLUSAGE,    "PIOCLUSAGE",   "get resource usage of all lwps" },
165
  { PIOCOPENLWP,   "PIOCOPENLWP",  "get lwp file descriptor" },
166
  { PIOCLWPIDS,    "PIOCLWPIDS",   "get lwp identifiers" },
167
#endif /* LWP */
168
  { PIOCMAP,       "PIOCMAP",      "get memory map information" },
169
  { PIOCMAXSIG,    "PIOCMAXSIG",   "get max signal number" },
170
  { PIOCNICE,      "PIOCNICE",     "set nice priority" },
171
  { PIOCNMAP,      "PIOCNMAP",     "get number of memory mappings" },
172
  { PIOCOPENM,     "PIOCOPENM",    "open mapped object for reading" },
173
#ifdef PIOCOPENMOBS                     /* osf */
174
  { PIOCOPENMOBS,  "PIOCOPENMOBS", "open mapped object" },
175
#endif
176
#ifdef PIOCOPENPD       /* solaris */
177
  { PIOCOPENPD,    "PIOCOPENPD",   "get page data file descriptor" },
178
#endif
179
  { PIOCPSINFO,    "PIOCPSINFO",   "get ps(1) information" },
180
  { PIOCRESET,     "PIOCRESET",    "reset process flags" },
181
  { PIOCRFORK,     "PIOCRFORK",    "reset inherit-on-fork flag" },
182
  { PIOCRRLC,      "PIOCRRLC",     "reset run-on-last-close flag" },
183
  { PIOCRUN,       "PIOCRUN",      "make process runnable" },
184
#ifdef PIOCSAVECCNTRS                   /* irix */
185
  { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
186
#endif
187
  { PIOCSENTRY,    "PIOCSENTRY",   "set traced syscall entry set" },
188
  { PIOCSET,       "PIOCSET",      "set process flags" },
189
  { PIOCSEXIT,     "PIOCSEXIT",    "set traced syscall exit  set" },
190
  { PIOCSFAULT,    "PIOCSFAULT",   "set traced fault set" },
191
  { PIOCSFORK,     "PIOCSFORK",    "set inherit-on-fork flag" },
192
  { PIOCSFPREG,    "PIOCSFPREG",   "set floating point registers" },
193
  { PIOCSHOLD,     "PIOCSHOLD",    "set held signal set" },
194
  { PIOCSREG,      "PIOCSREG",     "set general registers" },
195
  { PIOCSRLC,      "PIOCSRLC",     "set run-on-last-close flag" },
196
  { PIOCSSIG,      "PIOCSSIG",     "set current signal" },
197
  { PIOCSTATUS,    "PIOCSTATUS",   "get process status" },
198
  { PIOCSTOP,      "PIOCSTOP",     "post stop request" },
199
  { PIOCSTRACE,    "PIOCSTRACE",   "set traced signal set" },
200
  { PIOCUNKILL,    "PIOCUNKILL",   "delete a signal" },
201
#ifdef PIOCUSAGE        /* solaris */
202
  { PIOCUSAGE,     "PIOCUSAGE",    "get resource usage" },
203
#endif
204
  { PIOCWSTOP,     "PIOCWSTOP",    "wait for process to stop" },
205
 
206
#ifdef PIOCNTHR                         /* osf threads */
207
  { PIOCNTHR,      "PIOCNTHR",     "get thread count" },
208
  { PIOCRTINH,     "PIOCRTINH",    "reset inherit-on-thread-creation" },
209
  { PIOCSTINH,     "PIOCSTINH",    "set   inherit-on-thread-creation" },
210
  { PIOCTLIST,     "PIOCTLIST",    "get thread ids" },
211
  { PIOCXPTH,      "PIOCXPTH",     "translate port to thread handle" },
212
  { PIOCTRUN,      "PIOCTRUN",     "make thread runnable" },
213
  { PIOCTSTATUS,   "PIOCTSTATUS",  "get thread status" },
214
  { PIOCTSTOP,     "PIOCTSTOP",    "stop a thread" },
215
  /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
216
     TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
217
     TGEXIT TSEXIT TSHOLD ... thread functions */
218
#endif /* osf threads */
219
  { -1,            NULL,           NULL }
220
};
221
 
222
int
223
ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
224
{
225
  int i = 0;
226
  int ret;
227
  int arg1;
228
 
229
  prepare_to_trace ();
230
 
231
  if (procfs_trace)
232
    {
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
    }
374
  errno = 0;
375
  ret = ioctl (fd, opcode, ptr);
376
  if (procfs_trace && ret < 0)
377
    {
378
      fprintf (procfs_file ? procfs_file : stdout,
379
               "[ioctl (%s) FAILED! (%s)]\n",
380
               ioctl_table[i].name != NULL ?
381
               ioctl_table[i].name : "<unknown>",
382
               safe_strerror (errno));
383
      if (procfs_file)
384
        fflush (procfs_file);
385
    }
386
 
387
  return ret;
388
}
389
 
390
#else   /* NEW_PROC_API */
391
 
392
static 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
#ifdef PCDSTOP                  /* solaris */
401
  { PCDSTOP,  "PCDSTOP",  "post stop request" },
402
#endif
403
  { PCKILL,   "PCKILL",   "post a signal" },
404
#ifdef PCNICE                   /* solaris */
405
  { PCNICE,   "PCNICE",   "set nice priority" },
406
#endif
407
#ifdef PCREAD                   /* solaris */
408
  { PCREAD,   "PCREAD",   "read from the address space" },
409
  { PCWRITE,  "PCWRITE",  "write to the address space" },
410
#endif
411
#ifdef PCRESET                  /* unixware */
412
  { PCRESET,  "PCRESET",  "unset modes" },
413
#endif
414
  { PCRUN,    "PCRUN",    "make process/lwp runnable" },
415
#ifdef PCSASRS                  /* solaris 2.7 only */
416
  { PCSASRS,  "PCSASRS",  "set ancillary state registers" },
417
#endif
418
#ifdef PCSCRED                  /* solaris */
419
  { PCSCRED,  "PCSCRED",  "set process credentials" },
420
#endif
421
  { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
422
  { PCSET,    "PCSET",    "set modes" },
423
  { PCSEXIT,  "PCSEXIT",  "set traced syscall exit  set" },
424
  { PCSFAULT, "PCSFAULT", "set traced fault set" },
425
  { PCSFPREG, "PCSFPREG", "set floating point registers" },
426
#ifdef PCSHOLD                  /* solaris */
427
  { PCSHOLD,  "PCSHOLD",  "set signal mask" },
428
#endif
429
  { PCSREG,   "PCSREG",   "set general registers" },
430
  { PCSSIG,   "PCSSIG",   "set current signal" },
431
  { PCSTOP,   "PCSTOP",   "post stop request and wait" },
432
  { PCSTRACE, "PCSTRACE", "set traced signal set" },
433
#ifdef PCSVADDR                 /* solaris */
434
  { PCSVADDR, "PCSVADDR", "set pc virtual address" },
435
#endif
436
#ifdef PCSXREG                  /* solaris sparc only */
437
  { PCSXREG,  "PCSXREG",  "set extra registers" },
438
#endif
439
#ifdef PCTWSTOP                 /* solaris */
440
  { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
441
#endif
442
#ifdef PCUNKILL                 /* solaris */
443
  { PCUNKILL, "PCUNKILL", "delete a pending signal" },
444
#endif
445
#ifdef PCUNSET                  /* solaris */
446
  { PCUNSET,  "PCUNSET",  "unset modes" },
447
#endif
448
#ifdef PCWATCH                  /* solaris */
449
  { PCWATCH,  "PCWATCH",  "set/unset watched memory area" },
450
#endif
451
  { PCWSTOP,  "PCWSTOP",  "wait for process/lwp to stop, no timeout" },
452
  { 0,        NULL,      NULL }
453
};
454
 
455
static off_t lseek_offset;
456
 
457
int
458
write_with_trace (int fd, void *varg, size_t len, char *file, int line)
459
{
460
  int  i;
461
  int ret;
462
  procfs_ctl_t *arg = (procfs_ctl_t *) varg;
463
 
464
  prepare_to_trace ();
465
  if (procfs_trace)
466
    {
467
      procfs_ctl_t opcode = arg[0];
468
      for (i = 0; rw_table[i].name != NULL; i++)
469
        if (rw_table[i].value == opcode)
470
          break;
471
 
472
      if (info_verbose)
473
        fprintf (procfs_file ? procfs_file : stdout,
474
                 "%s:%d -- ", file, line);
475
      switch (opcode) {
476
      case PCSET:
477
        fprintf (procfs_file ? procfs_file : stdout,
478
                 "write (PCSET,   %s) %s\n",
479
                 arg[1] == PR_FORK  ? "PR_FORK"  :
480
                 arg[1] == PR_RLC   ? "PR_RLC"   :
481
#ifdef PR_ASYNC
482
                 arg[1] == PR_ASYNC ? "PR_ASYNC" :
483
#endif
484
                 "<unknown flag>",
485
                 info_verbose ? rw_table[i].desc : "");
486
        break;
487
#ifdef PCUNSET
488
      case PCUNSET:
489
#endif
490
#ifdef PCRESET
491
#if PCRESET != PCUNSET
492
      case PCRESET:
493
#endif
494
#endif
495
        fprintf (procfs_file ? procfs_file : stdout,
496
                 "write (PCRESET, %s) %s\n",
497
                 arg[1] == PR_FORK  ? "PR_FORK"  :
498
                 arg[1] == PR_RLC   ? "PR_RLC"   :
499
#ifdef PR_ASYNC
500
                 arg[1] == PR_ASYNC ? "PR_ASYNC" :
501
#endif
502
                 "<unknown flag>",
503
                 info_verbose ? rw_table[i].desc : "");
504
        break;
505
      case PCSTRACE:
506
        fprintf (procfs_file ? procfs_file : stdout,
507
                 "write (PCSTRACE) ");
508
        proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
509
                                     (sigset_t *) &arg[1], 0);
510
        break;
511
      case PCSFAULT:
512
        fprintf (procfs_file ? procfs_file : stdout,
513
                 "write (PCSFAULT) ");
514
        proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
515
                                    (fltset_t *) &arg[1], 0);
516
        break;
517
      case PCSENTRY:
518
        fprintf (procfs_file ? procfs_file : stdout,
519
                 "write (PCSENTRY) ");
520
        proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
521
                                    (sysset_t *) &arg[1], 0);
522
        break;
523
      case PCSEXIT:
524
        fprintf (procfs_file ? procfs_file : stdout,
525
                 "write (PCSEXIT) ");
526
        proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
527
                                    (sysset_t *) &arg[1], 0);
528
        break;
529
#ifdef PCSHOLD
530
      case PCSHOLD:
531
        fprintf (procfs_file ? procfs_file : stdout,
532
                 "write (PCSHOLD) ");
533
        proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
534
                                     (sigset_t *) &arg[1], 0);
535
        break;
536
#endif
537
      case PCSSIG:
538
        fprintf (procfs_file ? procfs_file : stdout,
539
                 "write (PCSSIG) ");
540
        proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
541
                                  arg[1] ? ((siginfo_t *) &arg[1])->si_signo
542
                                         : 0,
543
                                  0);
544
        fprintf (procfs_file ? procfs_file : stdout, "\n");
545
        break;
546
      case PCRUN:
547
        fprintf (procfs_file ? procfs_file : stdout,
548
                 "write (PCRUN) ");
549
        if (arg[1] & PRCSIG)
550
          fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
551
        if (arg[1] & PRCFAULT)
552
          fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
553
        if (arg[1] & PRSTEP)
554
          fprintf (procfs_file ? procfs_file : stdout, "step ");
555
#ifdef PRSABORT
556
        if (arg[1] & PRSABORT)
557
          fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
558
#endif
559
#ifdef PRSTOP
560
        if (arg[1] & PRSTOP)
561
          fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
562
#endif
563
 
564
        fprintf (procfs_file ? procfs_file : stdout, "\n");
565
        break;
566
      case PCKILL:
567
        fprintf (procfs_file ? procfs_file : stdout,
568
                 "write (PCKILL) ");
569
        proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
570
                                  arg[1], 0);
571
        fprintf (procfs_file ? procfs_file : stdout, "\n");
572
        break;
573
      default:
574
        {
575
#ifdef BREAKPOINT
576
          static unsigned char break_insn[] = BREAKPOINT;
577
 
578
          if (len == sizeof (break_insn) &&
579
              memcmp (arg, &break_insn, len) == 0)
580
            fprintf (procfs_file ? procfs_file : stdout,
581
                     "write (<breakpoint at 0x%08lx>) \n",
582
                     (unsigned long) lseek_offset);
583
          else
584
#endif
585
          if (rw_table[i].name)
586
            fprintf (procfs_file ? procfs_file : stdout,
587
                     "write (%s) %s\n",
588
                     rw_table[i].name,
589
                     info_verbose ? rw_table[i].desc : "");
590
          else
591
            {
592
              if (lseek_offset != -1)
593
                fprintf (procfs_file ? procfs_file : stdout,
594
                         "write (<unknown>, %lud bytes at 0x%08lx) \n",
595
                         (unsigned long) len, (unsigned long) lseek_offset);
596
              else
597
                fprintf (procfs_file ? procfs_file : stdout,
598
                         "write (<unknown>, %lud bytes) \n",
599
                         (unsigned long) len);
600
            }
601
          break;
602
        }
603
      }
604
      if (procfs_file)
605
        fflush (procfs_file);
606
    }
607
  errno = 0;
608
  ret = write (fd, (void *) arg, len);
609
  if (procfs_trace && ret != len)
610
    {
611
      fprintf (procfs_file ? procfs_file : stdout,
612
               "[write (%s) FAILED! (%s)]\n",
613
               rw_table[i].name != NULL ?
614
               rw_table[i].name : "<unknown>",
615
               safe_strerror (errno));
616
      if (procfs_file)
617
        fflush (procfs_file);
618
    }
619
 
620
  lseek_offset = -1;
621
  return ret;
622
}
623
 
624
off_t
625
lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
626
{
627
  off_t ret;
628
 
629
  prepare_to_trace ();
630
  errno = 0;
631
  ret = lseek (fd, offset, whence);
632
  lseek_offset = ret;
633
  if (procfs_trace && (ret == -1 || errno != 0))
634
    {
635
      fprintf (procfs_file ? procfs_file : stdout,
636
               "[lseek (0x%08lx) FAILED! (%s)]\n",
637
               (unsigned long) offset, safe_strerror (errno));
638
      if (procfs_file)
639
        fflush (procfs_file);
640
    }
641
 
642
  return ret;
643
}
644
 
645
#endif /* NEW_PROC_API */
646
 
647
int
648
open_with_trace (char *filename, int mode, char *file, int line)
649
{
650
  int ret;
651
 
652
  prepare_to_trace ();
653
  errno = 0;
654
  ret = open (filename, mode);
655
  if (procfs_trace)
656
    {
657
      if (info_verbose)
658
        fprintf (procfs_file ? procfs_file : stdout,
659
                 "%s:%d -- ", file, line);
660
 
661
      if (errno)
662
        {
663
          fprintf (procfs_file ? procfs_file : stdout,
664
                   "[open FAILED! (%s) line %d]\\n",
665
                   safe_strerror (errno), line);
666
        }
667
      else
668
        {
669
          fprintf (procfs_file ? procfs_file : stdout,
670
                   "%d = open (%s, ", ret, filename);
671
          if (mode == O_RDONLY)
672
            fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
673
                     line);
674
          else if (mode == O_WRONLY)
675
            fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
676
                     line);
677
          else if (mode == O_RDWR)
678
            fprintf (procfs_file ? procfs_file : stdout, "O_RDWR)   %d\n",
679
                     line);
680
        }
681
      if (procfs_file)
682
        fflush (procfs_file);
683
    }
684
 
685
  return ret;
686
}
687
 
688
int
689
close_with_trace (int fd, char *file, int line)
690
{
691
  int ret;
692
 
693
  prepare_to_trace ();
694
  errno = 0;
695
  ret = close (fd);
696
  if (procfs_trace)
697
    {
698
      if (info_verbose)
699
        fprintf (procfs_file ? procfs_file : stdout,
700
                 "%s:%d -- ", file, line);
701
      if (errno)
702
        fprintf (procfs_file ? procfs_file : stdout,
703
                 "[close FAILED! (%s)]\n", safe_strerror (errno));
704
      else
705
        fprintf (procfs_file ? procfs_file : stdout,
706
                 "%d = close (%d)\n", ret, fd);
707
      if (procfs_file)
708
        fflush (procfs_file);
709
    }
710
 
711
  return ret;
712
}
713
 
714
pid_t
715
wait_with_trace (int *wstat, char *file, int line)
716
{
717
  int ret, lstat = 0;
718
 
719
  prepare_to_trace ();
720
  if (procfs_trace)
721
    {
722
      if (info_verbose)
723
        fprintf (procfs_file ? procfs_file : stdout,
724
                 "%s:%d -- ", file, line);
725
      fprintf (procfs_file ? procfs_file : stdout,
726
               "wait (line %d) ", line);
727
      if (procfs_file)
728
        fflush (procfs_file);
729
    }
730
  errno = 0;
731
  ret = wait (&lstat);
732
  if (procfs_trace)
733
    {
734
      if (errno)
735
        fprintf (procfs_file ? procfs_file : stdout,
736
                 "[wait FAILED! (%s)]\n", safe_strerror (errno));
737
      else
738
        fprintf (procfs_file ? procfs_file : stdout,
739
                 "returned pid %d, status 0x%x\n", ret, lstat);
740
      if (procfs_file)
741
        fflush (procfs_file);
742
    }
743
  if (wstat)
744
    *wstat = lstat;
745
 
746
  return ret;
747
}
748
 
749
void
750
procfs_note (char *msg, char *file, int line)
751
{
752
  prepare_to_trace ();
753
  if (procfs_trace)
754
    {
755
      if (info_verbose)
756
        fprintf (procfs_file ? procfs_file : stdout,
757
                 "%s:%d -- ", file, line);
758
      fprintf (procfs_file ? procfs_file : stdout, msg);
759
      if (procfs_file)
760
        fflush (procfs_file);
761
    }
762
}
763
 
764
void
765
proc_prettyfprint_status (long flags, int why, int what, int thread)
766
{
767
  prepare_to_trace ();
768
  if (procfs_trace)
769
    {
770
      if (thread)
771
        fprintf (procfs_file ? procfs_file : stdout,
772
                 "Thread %d: ", thread);
773
 
774
      proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
775
                               flags, 0);
776
 
777
      if (flags & (PR_STOPPED | PR_ISTOP))
778
        proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
779
                               why, what, 0);
780
      if (procfs_file)
781
        fflush (procfs_file);
782
    }
783
}
784
 
785
 
786
void
787
_initialize_proc_api (void)
788
{
789
  struct cmd_list_element *c;
790
 
791
  c = add_set_cmd ("procfs-trace", no_class,
792
                   var_boolean, (char *) &procfs_trace,
793
                   "Set tracing for /proc api calls.\n", &setlist);
794
 
795
  add_show_from_set (c, &showlist);
796
  set_cmd_sfunc (c, set_procfs_trace_cmd);
797
  set_cmd_completer (c, filename_completer);
798
 
799
  c = add_set_cmd ("procfs-file", no_class, var_filename,
800
                   (char *) &procfs_filename,
801
                   "Set filename for /proc tracefile.\n", &setlist);
802
 
803
  add_show_from_set (c, &showlist);
804
  set_cmd_sfunc (c, set_procfs_file_cmd);
805
}

powered by: WebSVN 2.1.0

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