1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <ctype.h>
33 #include <string.h>
34 #include <memory.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <sys/types.h>
38 #include <sys/stack.h>
39 #include <signal.h>
40 #include <sys/isa_defs.h>
41 #include <libproc.h>
42 #include <priv.h>
43 #include "ramdata.h"
44 #include "systable.h"
45 #include "print.h"
46 #include "proto.h"
47
48 /*
49 * Actions to take when process stops.
50 */
51
52 /*
53 * Function prototypes for static routines in this module.
54 */
55 int stopsig(private_t *);
56 void showpaths(private_t *, const struct systable *);
57 void showargs(private_t *, int);
58 void dumpargs(private_t *, long, const char *);
59
60 /*
61 * Report an lwp to be sleeping (if true).
62 */
63 void
report_sleeping(private_t * pri,int dotrace)64 report_sleeping(private_t *pri, int dotrace)
65 {
66 const lwpstatus_t *Lsp = pri->lwpstat;
67 int sys = Lsp->pr_syscall;
68
69 if (!prismember(&trace, sys) || !dotrace ||
70 !(Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP))) {
71 /* Make sure we catch sysexit even if we're not tracing it. */
72 (void) Psysexit(Proc, sys, TRUE);
73 return;
74 }
75
76 pri->length = 0;
77 pri->Errno = 0;
78 pri->ErrPriv = PRIV_NONE;
79 pri->Rval1 = pri->Rval2 = 0;
80 (void) sysentry(pri, dotrace);
81 make_pname(pri, 0);
82 putpname(pri);
83 timestamp(pri);
84 pri->length += printf("%s", pri->sys_string);
85 pri->sys_leng = 0;
86 *pri->sys_string = '\0';
87 pri->length >>= 3;
88 if (Lsp->pr_flags & PR_VFORKP)
89 pri->length += 2;
90 if (pri->length >= 4)
91 (void) fputc(' ', stdout);
92 for (; pri->length < 4; pri->length++)
93 (void) fputc('\t', stdout);
94 if (Lsp->pr_flags & PR_VFORKP)
95 (void) fputs("(waiting for child to exit()/exec()...)\n",
96 stdout);
97 else
98 (void) fputs("(sleeping...)\n", stdout);
99 pri->length = 0;
100 if (prismember(&verbose, sys)) {
101 int raw = prismember(&rawout, sys);
102 pri->Errno = 1;
103 expound(pri, 0, raw);
104 pri->Errno = 0;
105 }
106 Flush();
107 }
108
109 /*
110 * requested() gets called for these reasons:
111 * flag == JOBSIG: report nothing; change state to JOBSTOP
112 * flag == JOBSTOP: report "Continued ..."
113 * default: report sleeping system call
114 *
115 * It returns a new flag: JOBSTOP or SLEEPING or 0.
116 */
117 int
requested(private_t * pri,int flag,int dotrace)118 requested(private_t *pri, int flag, int dotrace)
119 {
120 const lwpstatus_t *Lsp = pri->lwpstat;
121 int sig = Lsp->pr_cursig;
122 int newflag = 0;
123
124 switch (flag) {
125 case JOBSIG:
126 return (JOBSTOP);
127
128 case JOBSTOP:
129 if (dotrace && !cflag && prismember(&signals, sig)) {
130 pri->length = 0;
131 putpname(pri);
132 timestamp(pri);
133 (void) printf(" Continued with signal #%d, %s",
134 sig, signame(pri, sig));
135 if (Lsp->pr_action.sa_handler == SIG_DFL)
136 (void) printf(" [default]");
137 else if (Lsp->pr_action.sa_handler == SIG_IGN)
138 (void) printf(" [ignored]");
139 else
140 (void) printf(" [caught]");
141 (void) fputc('\n', stdout);
142 Flush();
143 }
144 newflag = 0;
145 break;
146
147 default:
148 newflag = SLEEPING;
149 if (!cflag)
150 report_sleeping(pri, dotrace);
151 break;
152 }
153
154 return (newflag);
155 }
156
157 int
jobcontrol(private_t * pri,int dotrace)158 jobcontrol(private_t *pri, int dotrace)
159 {
160 const lwpstatus_t *Lsp = pri->lwpstat;
161 int sig = stopsig(pri);
162
163 if (sig == 0)
164 return (0);
165
166 if (dotrace && !cflag && /* not just counting */
167 prismember(&signals, sig)) { /* tracing this signal */
168 int sys;
169
170 pri->length = 0;
171 putpname(pri);
172 timestamp(pri);
173 (void) printf(" Stopped by signal #%d, %s",
174 sig, signame(pri, sig));
175 if ((Lsp->pr_flags & PR_ASLEEP) &&
176 (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS)
177 (void) printf(", in %s()",
178 sysname(pri, sys, getsubcode(pri)));
179 (void) fputc('\n', stdout);
180 Flush();
181 }
182
183 return (JOBSTOP);
184 }
185
186 /*
187 * Return the signal the process stopped on iff process is already stopped on
188 * PR_JOBCONTROL or is stopped on PR_SIGNALLED or PR_REQUESTED with a current
189 * signal that will cause a JOBCONTROL stop when the process is set running.
190 */
191 int
stopsig(private_t * pri)192 stopsig(private_t *pri)
193 {
194 const lwpstatus_t *Lsp = pri->lwpstat;
195 int sig = 0;
196
197 if (Lsp->pr_flags & PR_STOPPED) {
198 switch (Lsp->pr_why) {
199 case PR_JOBCONTROL:
200 sig = Lsp->pr_what;
201 if (sig < 0 || sig > PRMAXSIG)
202 sig = 0;
203 break;
204 case PR_SIGNALLED:
205 case PR_REQUESTED:
206 if (Lsp->pr_action.sa_handler == SIG_DFL) {
207 switch (Lsp->pr_cursig) {
208 case SIGSTOP:
209 sig = SIGSTOP;
210 break;
211 case SIGTSTP:
212 case SIGTTIN:
213 case SIGTTOU:
214 if (!(Lsp->pr_flags & PR_ORPHAN))
215 sig = Lsp->pr_cursig;
216 break;
217 }
218 }
219 break;
220 }
221 }
222
223 return (sig);
224 }
225
226 int
signalled(private_t * pri,int flag,int dotrace)227 signalled(private_t *pri, int flag, int dotrace)
228 {
229 const lwpstatus_t *Lsp = pri->lwpstat;
230 int sig = Lsp->pr_what;
231
232 if (sig <= 0 || sig > PRMAXSIG) /* check bounds */
233 return (0);
234
235 if (dotrace && cflag) { /* just counting */
236 (void) mutex_lock(&count_lock);
237 Cp->sigcount[sig]++;
238 (void) mutex_unlock(&count_lock);
239 }
240
241 if (sig == SIGCONT && (flag == JOBSIG || flag == JOBSTOP))
242 flag = requested(pri, JOBSTOP, dotrace);
243 else if ((flag = jobcontrol(pri, dotrace)) == 0 &&
244 !cflag && dotrace &&
245 prismember(&signals, sig)) {
246 int sys;
247
248 pri->length = 0;
249 putpname(pri);
250 timestamp(pri);
251 (void) printf(" Received signal #%d, %s",
252 sig, signame(pri, sig));
253 if ((Lsp->pr_flags & PR_ASLEEP) &&
254 (sys = Lsp->pr_syscall) > 0 && sys <= PRMAXSYS)
255 (void) printf(", in %s()",
256 sysname(pri, sys, getsubcode(pri)));
257 if (Lsp->pr_action.sa_handler == SIG_DFL)
258 (void) printf(" [default]");
259 else if (Lsp->pr_action.sa_handler == SIG_IGN)
260 (void) printf(" [ignored]");
261 else
262 (void) printf(" [caught]");
263 (void) fputc('\n', stdout);
264 if (Lsp->pr_info.si_code != 0 ||
265 Lsp->pr_info.si_pid != 0)
266 print_siginfo(pri, &Lsp->pr_info);
267 Flush();
268 }
269
270 if (flag == JOBSTOP)
271 flag = JOBSIG;
272 return (flag);
273 }
274
275 int
faulted(private_t * pri,int dotrace)276 faulted(private_t *pri, int dotrace)
277 {
278 const lwpstatus_t *Lsp = pri->lwpstat;
279 int flt = Lsp->pr_what;
280
281 if ((uint_t)flt > PRMAXFAULT || !prismember(&faults, flt) || !dotrace)
282 return (0);
283
284 (void) mutex_lock(&count_lock);
285 Cp->fltcount[flt]++;
286 (void) mutex_unlock(&count_lock);
287
288 if (cflag) /* just counting */
289 return (1);
290
291 pri->length = 0;
292 putpname(pri);
293 timestamp(pri);
294
295 (void) printf(" Incurred fault #%d, %s %%pc = 0x%.8lX",
296 flt, proc_fltname(flt, pri->flt_name, sizeof (pri->flt_name)),
297 (long)Lsp->pr_reg[R_PC]);
298
299 if (flt == FLTPAGE)
300 (void) printf(" addr = 0x%.8lX",
301 (long)Lsp->pr_info.si_addr);
302 (void) fputc('\n', stdout);
303 if (Lsp->pr_info.si_signo != 0)
304 print_siginfo(pri, &Lsp->pr_info);
305 Flush();
306 return (1);
307 }
308
309 /*
310 * Set up pri->sys_nargs and pri->sys_args[] (syscall args).
311 */
312 void
setupsysargs(private_t * pri,int what)313 setupsysargs(private_t *pri, int what)
314 {
315 const lwpstatus_t *Lsp = pri->lwpstat;
316 int nargs;
317 int i;
318
319 #if sparc
320 /* determine whether syscall is indirect */
321 pri->sys_indirect = (Lsp->pr_reg[R_G1] == SYS_syscall)? 1 : 0;
322 #else
323 pri->sys_indirect = 0;
324 #endif
325
326 (void) memset(pri->sys_args, 0, sizeof (pri->sys_args));
327 if (what != Lsp->pr_syscall) { /* assertion */
328 (void) printf("%s\t*** Inconsistent syscall: %d vs %d ***\n",
329 pri->pname, what, Lsp->pr_syscall);
330 }
331 nargs = Lsp->pr_nsysarg;
332 for (i = 0;
333 i < nargs && i < sizeof (pri->sys_args) / sizeof (pri->sys_args[0]);
334 i++)
335 pri->sys_args[i] = Lsp->pr_sysarg[i];
336 pri->sys_nargs = nargs;
337 }
338
339 #define ISREAD(code) \
340 ((code) == SYS_read || (code) == SYS_pread || \
341 (code) == SYS_pread64 || (code) == SYS_readv || \
342 (code) == SYS_recv || (code) == SYS_recvfrom)
343 #define ISWRITE(code) \
344 ((code) == SYS_write || (code) == SYS_pwrite || \
345 (code) == SYS_pwrite64 || (code) == SYS_writev || \
346 (code) == SYS_send || (code) == SYS_sendto)
347
348 /*
349 * Return TRUE iff syscall is being traced.
350 */
351 int
sysentry(private_t * pri,int dotrace)352 sysentry(private_t *pri, int dotrace)
353 {
354 pid_t pid = Pstatus(Proc)->pr_pid;
355 const lwpstatus_t *Lsp = pri->lwpstat;
356 long arg;
357 int nargs;
358 int i;
359 int x;
360 int len;
361 char *s;
362 const struct systable *stp;
363 int what = Lsp->pr_what;
364 int subcode;
365 int istraced;
366 int raw;
367
368 /* for reporting sleeping system calls */
369 if (what == 0 && (Lsp->pr_flags & (PR_ASLEEP|PR_VFORKP)))
370 what = Lsp->pr_syscall;
371
372 /* protect ourself from operating system error */
373 if (what <= 0 || what > PRMAXSYS)
374 what = 0;
375
376 /*
377 * Set up the system call arguments (pri->sys_nargs & pri->sys_args[]).
378 */
379 setupsysargs(pri, what);
380 nargs = pri->sys_nargs;
381
382 /* get systable entry for this syscall */
383 subcode = getsubcode(pri);
384 stp = subsys(what, subcode);
385
386 if (nargs > stp->nargs)
387 nargs = stp->nargs;
388 pri->sys_nargs = nargs;
389
390 /*
391 * Fetch and remember first argument if it's a string,
392 * or second argument if SYS_openat or SYS_openat64.
393 */
394 pri->sys_valid = FALSE;
395 if ((nargs > 0 && stp->arg[0] == STG) ||
396 (nargs > 1 && (what == SYS_openat || what == SYS_openat64))) {
397 long offset;
398 uint32_t offset32;
399
400 /*
401 * Special case for exit from exec().
402 * The address in pri->sys_args[0] refers to the old process
403 * image. We must fetch the string from the new image.
404 */
405 if (Lsp->pr_why == PR_SYSEXIT && what == SYS_execve) {
406 psinfo_t psinfo;
407 long argv;
408 auxv_t auxv[32];
409 int naux;
410
411 offset = 0;
412 naux = proc_get_auxv(pid, auxv, 32);
413 for (i = 0; i < naux; i++) {
414 if (auxv[i].a_type == AT_SUN_EXECNAME) {
415 offset = (long)auxv[i].a_un.a_ptr;
416 break;
417 }
418 }
419 if (offset == 0 &&
420 proc_get_psinfo(pid, &psinfo) == 0) {
421 argv = (long)psinfo.pr_argv;
422 if (data_model == PR_MODEL_LP64)
423 (void) Pread(Proc, &offset,
424 sizeof (offset), argv);
425 else {
426 offset32 = 0;
427 (void) Pread(Proc, &offset32,
428 sizeof (offset32), argv);
429 offset = offset32;
430 }
431 }
432 } else if (stp->arg[0] == STG) {
433 offset = pri->sys_args[0];
434 } else {
435 offset = pri->sys_args[1];
436 }
437 if ((s = fetchstring(pri, offset, PATH_MAX)) != NULL) {
438 pri->sys_valid = TRUE;
439 len = strlen(s);
440 /* reallocate if necessary */
441 while (len >= pri->sys_psize) {
442 free(pri->sys_path);
443 pri->sys_path = my_malloc(pri->sys_psize *= 2,
444 "pathname buffer");
445 }
446 (void) strcpy(pri->sys_path, s); /* remember pathname */
447 }
448 }
449
450 istraced = dotrace && prismember(&trace, what);
451 raw = prismember(&rawout, what);
452
453 /* force tracing of read/write buffer dump syscalls */
454 if (!istraced && nargs > 2) {
455 int fdp1 = (int)pri->sys_args[0] + 1;
456
457 if (ISREAD(what)) {
458 if (prismember(&readfd, fdp1))
459 istraced = TRUE;
460 } else if (ISWRITE(what)) {
461 if (prismember(&writefd, fdp1))
462 istraced = TRUE;
463 }
464 }
465
466 pri->sys_leng = 0;
467 if (cflag || !istraced) /* just counting */
468 *pri->sys_string = 0;
469 else {
470 int argprinted = FALSE;
471 const char *name;
472
473 name = sysname(pri, what, raw? -1 : subcode);
474 grow(pri, strlen(name) + 1);
475 pri->sys_leng = snprintf(pri->sys_string, pri->sys_ssize,
476 "%s(", name);
477 for (i = 0; i < nargs; i++) {
478 arg = pri->sys_args[i];
479 x = stp->arg[i];
480
481 if (!raw && pri->sys_valid &&
482 ((i == 0 && x == STG) ||
483 (i == 1 && (what == SYS_openat ||
484 what == SYS_openat64)))) { /* already fetched */
485 if (argprinted)
486 outstring(pri, ", ");
487 escape_string(pri, pri->sys_path);
488 argprinted = TRUE;
489 } else if (x != NOV && (x != HID || raw)) {
490 if (argprinted)
491 outstring(pri, ", ");
492 if (x == LLO)
493 (*Print[x])(pri, raw, arg,
494 pri->sys_args[++i]);
495 else
496 (*Print[x])(pri, raw, arg);
497 argprinted = TRUE;
498 }
499 }
500 outstring(pri, ")");
501 }
502
503 return (istraced);
504 }
505 #undef ISREAD
506 #undef ISWRITE
507
508 /*
509 * sysexit() returns non-zero if anything was printed.
510 */
511 int
sysexit(private_t * pri,int dotrace)512 sysexit(private_t *pri, int dotrace)
513 {
514 const lwpstatus_t *Lsp = pri->lwpstat;
515 int what = Lsp->pr_what;
516 struct syscount *scp;
517 const struct systable *stp;
518 int subcode;
519 int istraced;
520 int raw;
521
522 /* protect ourself from operating system error */
523 if (what <= 0 || what > PRMAXSYS)
524 return (0);
525
526 /*
527 * If we aren't supposed to be tracing this one, then
528 * delete it from the traced signal set. We got here
529 * because the process was sleeping in an untraced syscall.
530 */
531 if (!prismember(&traceeven, what)) {
532 (void) Psysexit(Proc, what, FALSE);
533 return (0);
534 }
535
536 /* pick up registers & set pri->Errno before anything else */
537 pri->Errno = Lsp->pr_errno;
538 pri->ErrPriv = Lsp->pr_errpriv;
539 pri->Rval1 = Lsp->pr_rval1;
540 pri->Rval2 = Lsp->pr_rval2;
541
542 switch (what) {
543 case SYS_exit: /* these are traced on entry */
544 case SYS_lwp_exit:
545 case SYS_context:
546 istraced = dotrace && prismember(&trace, what);
547 break;
548 case SYS_execve: /* this is normally traced on entry */
549 istraced = dotrace && prismember(&trace, what);
550 if (pri->exec_string && *pri->exec_string) {
551 if (!cflag && istraced) { /* print exec() string now */
552 if (pri->exec_pname[0] != '\0')
553 (void) fputs(pri->exec_pname, stdout);
554 timestamp(pri);
555 (void) fputs(pri->exec_string, stdout);
556 }
557 pri->exec_pname[0] = '\0';
558 pri->exec_string[0] = '\0';
559 break;
560 }
561 /* FALLTHROUGH */
562 default:
563 /* we called sysentry() in main() for these */
564 if (what == SYS_openat || what == SYS_openat64 ||
565 what == SYS_open || what == SYS_open64)
566 istraced = dotrace && prismember(&trace, what);
567 else
568 istraced = sysentry(pri, dotrace) && dotrace;
569 pri->length = 0;
570 if (!cflag && istraced) {
571 putpname(pri);
572 timestamp(pri);
573 pri->length += printf("%s", pri->sys_string);
574 }
575 pri->sys_leng = 0;
576 *pri->sys_string = '\0';
577 break;
578 }
579
580 /* get systable entry for this syscall */
581 subcode = getsubcode(pri);
582 stp = subsys(what, subcode);
583
584 if (cflag && istraced) {
585 (void) mutex_lock(&count_lock);
586 scp = Cp->syscount[what];
587 if (what == SYS_forksys && subcode >= 3)
588 scp += subcode - 3;
589 else if (subcode != -1 &&
590 (what != SYS_openat && what != SYS_openat64 &&
591 what != SYS_open && what != SYS_open64 &&
592 what != SYS_lwp_create))
593 scp += subcode;
594 scp->count++;
595 accumulate(&scp->stime, &Lsp->pr_stime, &pri->syslast);
596 accumulate(&Cp->usrtotal, &Lsp->pr_utime, &pri->usrlast);
597 pri->syslast = Lsp->pr_stime;
598 pri->usrlast = Lsp->pr_utime;
599 (void) mutex_unlock(&count_lock);
600 }
601
602 raw = prismember(&rawout, what);
603
604 if (!cflag && istraced) {
605 if ((what == SYS_vfork || what == SYS_forksys) &&
606 pri->Errno == 0 && pri->Rval2 != 0) {
607 pri->length &= ~07;
608 if (strlen(sysname(pri, what, raw? -1 : subcode)) < 6) {
609 (void) fputc('\t', stdout);
610 pri->length += 8;
611 }
612 pri->length +=
613 7 + printf("\t(returning as child ...)");
614 }
615 if (what == SYS_lwp_create &&
616 pri->Errno == 0 && pri->Rval1 == 0) {
617 pri->length &= ~07;
618 pri->length +=
619 7 + printf("\t(returning as new lwp ...)");
620 }
621 if (pri->Errno != 0 || what != SYS_execve) {
622 /* prepare to print the return code */
623 pri->length >>= 3;
624 if (pri->length >= 6)
625 (void) fputc(' ', stdout);
626 for (; pri->length < 6; pri->length++)
627 (void) fputc('\t', stdout);
628 }
629 }
630 pri->length = 0;
631
632 if (pri->Errno != 0) { /* error in syscall */
633 if (istraced) {
634 if (cflag)
635 scp->error++;
636 else {
637 const char *ename = errname(pri->Errno);
638 const char *privname;
639
640 (void) printf("Err#%d", pri->Errno);
641 if (ename != NULL) {
642 (void) fputc(' ', stdout);
643 (void) fputs(ename, stdout);
644 }
645 switch (pri->ErrPriv) {
646 case PRIV_NONE:
647 privname = NULL;
648 break;
649 case PRIV_ALL:
650 privname = "ALL";
651 break;
652 case PRIV_MULTIPLE:
653 privname = "MULTIPLE";
654 break;
655 case PRIV_ALLZONE:
656 privname = "ZONE";
657 break;
658 default:
659 privname = priv_getbynum(pri->ErrPriv);
660 break;
661 }
662 if (privname != NULL)
663 (void) printf(" [%s]", privname);
664
665 (void) fputc('\n', stdout);
666 }
667 }
668 } else {
669 /* show arguments on successful exec */
670 if (what == SYS_execve) {
671 if (!cflag && istraced)
672 showargs(pri, raw);
673 } else if (!cflag && istraced) {
674 const char *fmt = NULL;
675 long rv1 = pri->Rval1;
676 long rv2 = pri->Rval2;
677
678 /*
679 * 32-bit system calls return 32-bit values. We
680 * later mask out the upper bits if we want to
681 * print these as unsigned values.
682 */
683 if (data_model == PR_MODEL_ILP32) {
684 rv1 = (int)rv1;
685 rv2 = (int)rv2;
686 }
687
688 switch (what) {
689 case SYS_llseek:
690 rv1 &= 0xffffffff;
691 rv2 &= 0xffffffff;
692 #ifdef _LONG_LONG_LTOH /* first long of a longlong is the low order */
693 if (rv2 != 0) {
694 long temp = rv1;
695 fmt = "= 0x%lX%.8lX";
696 rv1 = rv2;
697 rv2 = temp;
698 break;
699 }
700 #else /* the other way around */
701 if (rv1 != 0) {
702 fmt = "= 0x%lX%.8lX";
703 break;
704 }
705 rv1 = rv2; /* ugly */
706 #endif
707 /* FALLTHROUGH */
708 case SYS_lseek:
709 case SYS_ulimit:
710 if (rv1 & 0xff000000) {
711 if (data_model == PR_MODEL_ILP32)
712 rv1 &= 0xffffffff;
713 fmt = "= 0x%.8lX";
714 }
715 break;
716 case SYS_sigtimedwait:
717 if (raw)
718 /* EMPTY */;
719 else if ((fmt = rawsigname(pri, rv1)) != NULL) {
720 rv1 = (long)fmt; /* filthy */
721 fmt = "= %s";
722 }
723 break;
724 case SYS_port:
725 if (data_model == PR_MODEL_LP64) {
726 rv2 = rv1 & 0xffffffff;
727 rv1 = rv1 >> 32;
728 }
729 break;
730 }
731
732 if (fmt == NULL) {
733 switch (stp->rval[0]) {
734 case HEX:
735 if (data_model == PR_MODEL_ILP32)
736 rv1 &= 0xffffffff;
737 fmt = "= 0x%.8lX";
738 break;
739 case HHX:
740 if (data_model == PR_MODEL_ILP32)
741 rv1 &= 0xffffffff;
742 fmt = "= 0x%.4lX";
743 break;
744 case OCT:
745 if (data_model == PR_MODEL_ILP32)
746 rv1 &= 0xffffffff;
747 fmt = "= %#lo";
748 break;
749 case UNS:
750 if (data_model == PR_MODEL_ILP32)
751 rv1 &= 0xffffffff;
752 fmt = "= %lu";
753 break;
754 default:
755 fmt = "= %ld";
756 break;
757 }
758 }
759
760 (void) printf(fmt, rv1, rv2);
761
762 switch (stp->rval[1]) {
763 case NOV:
764 fmt = NULL;
765 break;
766 case HEX:
767 if (data_model == PR_MODEL_ILP32)
768 rv2 &= 0xffffffff;
769 fmt = " [0x%.8lX]";
770 break;
771 case HHX:
772 if (data_model == PR_MODEL_ILP32)
773 rv2 &= 0xffffffff;
774 fmt = " [0x%.4lX]";
775 break;
776 case OCT:
777 if (data_model == PR_MODEL_ILP32)
778 rv2 &= 0xffffffff;
779 fmt = " [%#lo]";
780 break;
781 case UNS:
782 if (data_model == PR_MODEL_ILP32)
783 rv2 &= 0xffffffff;
784 fmt = " [%lu]";
785 break;
786 default:
787 fmt = " [%ld]";
788 break;
789 }
790
791 if (fmt != NULL)
792 (void) printf(fmt, rv2);
793 (void) fputc('\n', stdout);
794 }
795
796 if (what == SYS_vfork || what == SYS_forksys) {
797 if (pri->Rval2 == 0) /* child was created */
798 pri->child = pri->Rval1;
799 else if (cflag && istraced) /* this is the child */
800 scp->count--;
801 }
802 if (what == SYS_lwp_create && pri->Rval1 == 0 &&
803 cflag && istraced) /* this is the created lwp */
804 scp->count--;
805 }
806
807 #define ISREAD(code) \
808 ((code) == SYS_read || (code) == SYS_pread || (code) == SYS_pread64 || \
809 (code) == SYS_recv || (code) == SYS_recvfrom)
810 #define ISWRITE(code) \
811 ((code) == SYS_write || (code) == SYS_pwrite || \
812 (code) == SYS_pwrite64 || (code) == SYS_send || (code) == SYS_sendto)
813
814 if (!cflag && istraced) {
815 int fdp1 = (int)pri->sys_args[0] + 1; /* filedescriptor + 1 */
816
817 if (raw) {
818 if (what != SYS_execve)
819 showpaths(pri, stp);
820 if (ISREAD(what) || ISWRITE(what)) {
821 if (pri->iob_buf[0] != '\0')
822 (void) printf("%s 0x%.8lX: %s\n",
823 pri->pname, pri->sys_args[1],
824 pri->iob_buf);
825 }
826 }
827
828 /*
829 * Show buffer contents for read()/pread() or write()/pwrite().
830 * IOBSIZE bytes have already been shown;
831 * don't show them again unless there's more.
832 */
833 if ((ISREAD(what) && pri->Errno == 0 &&
834 prismember(&readfd, fdp1)) ||
835 (ISWRITE(what) && prismember(&writefd, fdp1))) {
836 long nb = ISWRITE(what) ? pri->sys_args[2] : pri->Rval1;
837
838 if (nb > IOBSIZE) {
839 /* enter region of lengthy output */
840 if (nb > MYBUFSIZ / 4)
841 Eserialize();
842
843 showbuffer(pri, pri->sys_args[1], nb);
844
845 /* exit region of lengthy output */
846 if (nb > MYBUFSIZ / 4)
847 Xserialize();
848 }
849 }
850 #undef ISREAD
851 #undef ISWRITE
852 /*
853 * Do verbose interpretation if requested.
854 * If buffer contents for read or write have been requested and
855 * this is a readv() or writev(), force verbose interpretation.
856 */
857 if (prismember(&verbose, what) ||
858 ((what == SYS_readv || what == SYS_recvmsg) &&
859 pri->Errno == 0 && prismember(&readfd, fdp1)) ||
860 ((what == SYS_writev || what == SYS_sendfilev ||
861 what == SYS_sendmsg) &&
862 prismember(&writefd, fdp1)))
863 expound(pri, pri->Rval1, raw);
864 }
865
866 return (!cflag && istraced);
867 }
868
869 void
showpaths(private_t * pri,const struct systable * stp)870 showpaths(private_t *pri, const struct systable *stp)
871 {
872 int what = pri->lwpstat->pr_what;
873 int i;
874
875 for (i = 0; i < pri->sys_nargs; i++) {
876 if (stp->arg[i] == ATC && (int)pri->sys_args[i] == AT_FDCWD) {
877 (void) printf("%s 0x%.8X: AT_FDCWD\n",
878 pri->pname, AT_FDCWD);
879 } else if ((stp->arg[i] == STG) ||
880 (stp->arg[i] == RST && !pri->Errno) ||
881 (stp->arg[i] == RLK && !pri->Errno && pri->Rval1 > 0)) {
882 long addr = pri->sys_args[i];
883 int maxleng =
884 (stp->arg[i] == RLK)? (int)pri->Rval1 : PATH_MAX;
885 char *s;
886
887 if (pri->sys_valid &&
888 ((i == 0 && stp->arg[0] == STG) ||
889 (i == 1 && (what == SYS_openat ||
890 what == SYS_openat64)))) /* already fetched */
891 s = pri->sys_path;
892 else
893 s = fetchstring(pri, addr,
894 maxleng > PATH_MAX ? PATH_MAX : maxleng);
895
896 if (s != (char *)NULL)
897 (void) printf("%s 0x%.8lX: \"%s\"\n",
898 pri->pname, addr, s);
899 }
900 }
901 }
902
903 /*
904 * Display arguments to successful exec().
905 */
906 void
showargs(private_t * pri,int raw)907 showargs(private_t *pri, int raw)
908 {
909 const lwpstatus_t *Lsp = pri->lwpstat;
910 int nargs;
911 long ap;
912 int ptrsize;
913 int fail;
914
915 pri->length = 0;
916 ptrsize = (data_model == PR_MODEL_LP64)? 8 : 4;
917
918 #if defined(__i386) || defined(__amd64) /* XX64 */
919 ap = (long)Lsp->pr_reg[R_SP];
920 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) != sizeof (nargs));
921 ap += ptrsize;
922 #endif /* i386 */
923
924 #if sparc
925 if (data_model == PR_MODEL_LP64) {
926 int64_t xnargs;
927 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int64_t)
928 + STACK_BIAS;
929 fail = (Pread(Proc, &xnargs, sizeof (xnargs), ap) !=
930 sizeof (xnargs));
931 nargs = (int)xnargs;
932 } else {
933 ap = (long)(Lsp->pr_reg[R_SP]) + 16 * sizeof (int32_t);
934 fail = (Pread(Proc, &nargs, sizeof (nargs), ap) !=
935 sizeof (nargs));
936 }
937 ap += ptrsize;
938 #endif /* sparc */
939
940 if (fail) {
941 (void) printf("\n%s\t*** Bad argument list? ***\n", pri->pname);
942 return;
943 }
944
945 (void) printf(" argc = %d\n", nargs);
946 if (raw)
947 showpaths(pri, &systable[SYS_execve]);
948
949 show_cred(pri, FALSE, FALSE);
950
951 if (aflag || eflag) { /* dump args or environment */
952
953 /* enter region of (potentially) lengthy output */
954 Eserialize();
955
956 if (aflag) /* dump the argument list */
957 dumpargs(pri, ap, "argv:");
958 ap += (nargs+1) * ptrsize;
959 if (eflag) /* dump the environment */
960 dumpargs(pri, ap, "envp:");
961
962 /* exit region of lengthy output */
963 Xserialize();
964 }
965 }
966
967 void
dumpargs(private_t * pri,long ap,const char * str)968 dumpargs(private_t *pri, long ap, const char *str)
969 {
970 char *string;
971 unsigned int leng = 0;
972 int ptrsize;
973 long arg = 0;
974 char *argaddr;
975 char badaddr[32];
976
977 if (interrupt)
978 return;
979
980 if (data_model == PR_MODEL_LP64) {
981 argaddr = (char *)&arg;
982 ptrsize = 8;
983 } else {
984 #if defined(_LITTLE_ENDIAN)
985 argaddr = (char *)&arg;
986 #else
987 argaddr = (char *)&arg + 4;
988 #endif
989 ptrsize = 4;
990 }
991 putpname(pri);
992 (void) fputc(' ', stdout);
993 (void) fputs(str, stdout);
994 leng += 1 + strlen(str);
995
996 while (!interrupt) {
997 if (Pread(Proc, argaddr, ptrsize, ap) != ptrsize) {
998 (void) printf("\n%s\t*** Bad argument list? ***\n",
999 pri->pname);
1000 return;
1001 }
1002 ap += ptrsize;
1003
1004 if (arg == 0)
1005 break;
1006 string = fetchstring(pri, arg, PATH_MAX);
1007 if (string == NULL) {
1008 (void) sprintf(badaddr, "BadAddress:0x%.8lX", arg);
1009 string = badaddr;
1010 }
1011 if ((leng += strlen(string)) < 63) {
1012 (void) fputc(' ', stdout);
1013 leng++;
1014 } else {
1015 (void) fputc('\n', stdout);
1016 leng = 0;
1017 putpname(pri);
1018 (void) fputs(" ", stdout);
1019 leng += 2 + strlen(string);
1020 }
1021 (void) fputs(string, stdout);
1022 }
1023 (void) fputc('\n', stdout);
1024 }
1025
1026 /*
1027 * Display contents of read() or write() buffer.
1028 */
1029 void
showbuffer(private_t * pri,long offset,long count)1030 showbuffer(private_t *pri, long offset, long count)
1031 {
1032 char buffer[320];
1033 int nbytes;
1034 char *buf;
1035 int n;
1036
1037 while (count > 0 && !interrupt) {
1038 nbytes = (count < sizeof (buffer))? count : sizeof (buffer);
1039 if ((nbytes = Pread(Proc, buffer, nbytes, offset)) <= 0)
1040 break;
1041 count -= nbytes;
1042 offset += nbytes;
1043 buf = buffer;
1044 while (nbytes > 0 && !interrupt) {
1045 char obuf[65];
1046
1047 n = (nbytes < 32)? nbytes : 32;
1048 showbytes(buf, n, obuf);
1049
1050 putpname(pri);
1051 (void) fputs(" ", stdout);
1052 (void) fputs(obuf, stdout);
1053 (void) fputc('\n', stdout);
1054 nbytes -= n;
1055 buf += n;
1056 }
1057 }
1058 }
1059
1060 void
showbytes(const char * buf,int n,char * obuf)1061 showbytes(const char *buf, int n, char *obuf)
1062 {
1063 int c;
1064
1065 while (--n >= 0) {
1066 int c1 = '\\';
1067 int c2;
1068
1069 switch (c = (*buf++ & 0xff)) {
1070 case '\0':
1071 c2 = '0';
1072 break;
1073 case '\b':
1074 c2 = 'b';
1075 break;
1076 case '\t':
1077 c2 = 't';
1078 break;
1079 case '\n':
1080 c2 = 'n';
1081 break;
1082 case '\v':
1083 c2 = 'v';
1084 break;
1085 case '\f':
1086 c2 = 'f';
1087 break;
1088 case '\r':
1089 c2 = 'r';
1090 break;
1091 default:
1092 if (isprint(c)) {
1093 c1 = ' ';
1094 c2 = c;
1095 } else {
1096 c1 = c>>4;
1097 c1 += (c1 < 10)? '0' : 'A'-10;
1098 c2 = c&0xf;
1099 c2 += (c2 < 10)? '0' : 'A'-10;
1100 }
1101 break;
1102 }
1103 *obuf++ = (char)c1;
1104 *obuf++ = (char)c2;
1105 }
1106
1107 *obuf = '\0';
1108 }
1109