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