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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [proc-api.c] - Blame information for rev 853

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

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

powered by: WebSVN 2.1.0

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