1/* $OpenBSD: kdump.c,v 1.163 2024/05/18 05:20:22 guenther Exp $ */ 2 3/*- 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/time.h> 33#include <sys/signal.h> 34#include <sys/uio.h> 35#include <sys/ktrace.h> 36#include <sys/ioctl.h> 37#include <sys/malloc.h> 38#include <sys/namei.h> 39#include <sys/ptrace.h> 40#include <sys/sem.h> 41#include <sys/shm.h> 42#include <sys/socket.h> 43#include <sys/sysctl.h> 44#include <sys/siginfo.h> 45#include <sys/vmmeter.h> 46#include <sys/tty.h> 47#include <sys/wait.h> 48#define PLEDGENAMES 49#include <sys/pledge.h> 50#undef PLEDGENAMES 51#define _KERNEL 52#include <errno.h> 53#undef _KERNEL 54#include <ddb/db_var.h> 55#include <machine/cpu.h> 56 57#include <ctype.h> 58#include <err.h> 59#include <fcntl.h> 60#include <limits.h> 61#include <netdb.h> 62#include <poll.h> 63#include <signal.h> 64#include <stddef.h> 65#include <stdint.h> 66#include <stdio.h> 67#include <stdlib.h> 68#include <string.h> 69#include <unistd.h> 70#include <vis.h> 71 72#include "ktrace.h" 73#include "kdump.h" 74#include "kdump_subr.h" 75#include "extern.h" 76 77#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 78 79enum { 80 TIMESTAMP_NONE, 81 TIMESTAMP_ABSOLUTE, 82 TIMESTAMP_RELATIVE, 83 TIMESTAMP_ELAPSED 84} timestamp = TIMESTAMP_NONE; 85 86int decimal, iohex, fancy = 1, maxdata = INT_MAX; 87int needtid, tail, basecol; 88char *tracefile = DEF_TRACEFILE; 89struct ktr_header ktr_header; 90pid_t pid_opt = -1; 91const char *program; 92char* utracefilter; 93 94#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 95 96#include <sys/syscall.h> 97 98#define KTRACE 99#define PTRACE 100#define NFSCLIENT 101#define NFSSERVER 102#define SYSVSEM 103#define SYSVMSG 104#define SYSVSHM 105#define ACCOUNTING 106#include <kern/syscalls.c> 107#undef KTRACE 108#undef PTRACE 109#undef NFSCLIENT 110#undef NFSSERVER 111#undef SYSVSEM 112#undef SYSVMSG 113#undef SYSVSHM 114#undef ACCOUNTING 115 116 117static char *ptrace_ops[] = { 118 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 119 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 120 "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO", 121 "PT_SET_EVENT_MASK", "PT_GET_EVENT_MASK", "PT_GET_PROCESS_STATE", 122 "PT_GET_THREAD_FIRST", "PT_GET_THREAD_NEXT", 123}; 124 125static int fread_tail(void *, size_t, size_t); 126static void dumpheader(struct ktr_header *); 127static void ktrgenio(struct ktr_genio *, size_t); 128static void ktrnamei(const char *, size_t); 129static void ktrpsig(struct ktr_psig *); 130static void ktrsyscall(struct ktr_syscall *, size_t); 131static const char *kresolvsysctl(int, const int *); 132static void ktrsysret(struct ktr_sysret *, size_t); 133static void ktruser(struct ktr_user *, size_t); 134static void ktrexec(const char*, size_t); 135static void ktrpledge(struct ktr_pledge *, size_t); 136static void ktrpinsyscall(struct ktr_pinsyscall *, size_t); 137static void usage(void); 138static void ioctldecode(int); 139static void ptracedecode(int); 140static void atfd(int); 141static void polltimeout(int); 142static void wait4pid(int); 143static void signame(int); 144static void semctlname(int); 145static void shmctlname(int); 146static void semgetname(int); 147static void flagsandmodename(int); 148static void clockname(int); 149static void sockoptlevelname(int); 150static void ktraceopname(int); 151static void idtypeandid(int); 152 153static int screenwidth; 154 155int 156main(int argc, char *argv[]) 157{ 158 int ch, silent; 159 size_t ktrlen, size; 160 int trpoints = ALL_POINTS; 161 const char *errstr; 162 void *m; 163 164 if (screenwidth == 0) { 165 struct winsize ws; 166 167 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 168 ws.ws_col > 8) 169 screenwidth = ws.ws_col; 170 else 171 screenwidth = 80; 172 } 173 174 while ((ch = getopt(argc, argv, "f:dHlm:nP:p:RTt:u:xX")) != -1) 175 switch (ch) { 176 case 'f': 177 tracefile = optarg; 178 break; 179 case 'd': 180 decimal = 1; 181 break; 182 case 'H': 183 needtid = 1; 184 break; 185 case 'l': 186 tail = 1; 187 break; 188 case 'm': 189 maxdata = strtonum(optarg, 0, INT_MAX, &errstr); 190 if (errstr) 191 errx(1, "-m %s: %s", optarg, errstr); 192 break; 193 case 'n': 194 fancy = 0; 195 break; 196 case 'P': 197 program = optarg; 198 break; 199 case 'p': 200 pid_opt = strtonum(optarg, 1, INT_MAX, &errstr); 201 if (errstr) 202 errx(1, "-p %s: %s", optarg, errstr); 203 break; 204 case 'R': /* relative timestamp */ 205 if (timestamp == TIMESTAMP_ABSOLUTE) 206 timestamp = TIMESTAMP_ELAPSED; 207 else 208 timestamp = TIMESTAMP_RELATIVE; 209 break; 210 case 'T': 211 if (timestamp == TIMESTAMP_RELATIVE) 212 timestamp = TIMESTAMP_ELAPSED; 213 else 214 timestamp = TIMESTAMP_ABSOLUTE; 215 break; 216 case 't': 217 trpoints = getpoints(optarg, DEF_POINTS); 218 if (trpoints < 0) 219 errx(1, "unknown trace point in %s", optarg); 220 utracefilter = NULL; 221 break; 222 case 'u': 223 utracefilter = optarg; 224 trpoints = KTRFAC_USER; 225 break; 226 case 'x': 227 iohex = 1; 228 break; 229 case 'X': 230 iohex = 2; 231 break; 232 default: 233 usage(); 234 } 235 if (argc > optind) 236 usage(); 237 238 if (strcmp(tracefile, "-") != 0) 239 if (unveil(tracefile, "r") == -1) 240 err(1, "unveil %s", tracefile); 241 if (unveil(_PATH_PROTOCOLS, "r") == -1) 242 err(1, "unveil %s", _PATH_PROTOCOLS); 243 if (pledge("stdio rpath getpw", NULL) == -1) 244 err(1, "pledge"); 245 246 m = malloc(size = 1025); 247 if (m == NULL) 248 err(1, NULL); 249 if (strcmp(tracefile, "-") != 0) 250 if (!freopen(tracefile, "r", stdin)) 251 err(1, "%s", tracefile); 252 253 if (fread_tail(&ktr_header, sizeof(struct ktr_header), 1) == 0 || 254 ktr_header.ktr_type != htobe32(KTR_START)) 255 errx(1, "%s: not a dump", tracefile); 256 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 257 silent = 0; 258 if (pid_opt != -1 && pid_opt != ktr_header.ktr_pid) 259 silent = 1; 260 if (program != NULL && 261 strcmp(ktr_header.ktr_comm, program) != 0) 262 silent = 1; 263 if (utracefilter == NULL && silent == 0 && 264 trpoints & (1<<ktr_header.ktr_type)) 265 dumpheader(&ktr_header); 266 ktrlen = ktr_header.ktr_len; 267 if (ktrlen > size) { 268 void *newm; 269 270 if (ktrlen == SIZE_MAX) 271 errx(1, "data too long"); 272 newm = realloc(m, ktrlen+1); 273 if (newm == NULL) 274 err(1, "realloc"); 275 m = newm; 276 size = ktrlen; 277 } 278 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 279 errx(1, "data too short"); 280 if (silent) 281 continue; 282 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 283 continue; 284 switch (ktr_header.ktr_type) { 285 case KTR_SYSCALL: 286 ktrsyscall(m, ktrlen); 287 break; 288 case KTR_SYSRET: 289 ktrsysret(m, ktrlen); 290 break; 291 case KTR_NAMEI: 292 ktrnamei(m, ktrlen); 293 break; 294 case KTR_GENIO: 295 ktrgenio(m, ktrlen); 296 break; 297 case KTR_PSIG: 298 ktrpsig(m); 299 break; 300 case KTR_STRUCT: 301 ktrstruct(m, ktrlen); 302 break; 303 case KTR_USER: 304 ktruser(m, ktrlen); 305 break; 306 case KTR_EXECARGS: 307 case KTR_EXECENV: 308 ktrexec(m, ktrlen); 309 break; 310 case KTR_PLEDGE: 311 ktrpledge(m, ktrlen); 312 break; 313 case KTR_PINSYSCALL: 314 ktrpinsyscall(m, ktrlen); 315 break; 316 default: 317 printf("\n"); 318 break; 319 } 320 if (tail) 321 (void)fflush(stdout); 322 } 323 exit(0); 324} 325 326static int 327fread_tail(void *buf, size_t size, size_t num) 328{ 329 int i; 330 331 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 332 (void)sleep(1); 333 clearerr(stdin); 334 } 335 return (i); 336} 337 338static void 339dumpheader(struct ktr_header *kth) 340{ 341 static struct timespec prevtime; 342 char unknown[64], *type; 343 struct timespec temp; 344 345 switch (kth->ktr_type) { 346 case KTR_SYSCALL: 347 type = "CALL"; 348 break; 349 case KTR_SYSRET: 350 type = "RET "; 351 break; 352 case KTR_NAMEI: 353 type = "NAMI"; 354 break; 355 case KTR_GENIO: 356 type = "GIO "; 357 break; 358 case KTR_PSIG: 359 type = "PSIG"; 360 break; 361 case KTR_STRUCT: 362 type = "STRU"; 363 break; 364 case KTR_USER: 365 type = "USER"; 366 break; 367 case KTR_EXECARGS: 368 type = "ARGS"; 369 break; 370 case KTR_EXECENV: 371 type = "ENV "; 372 break; 373 case KTR_PLEDGE: 374 type = "PLDG"; 375 break; 376 case KTR_PINSYSCALL: 377 type = "PINS"; 378 break; 379 default: 380 /* htobe32() not guaranteed to work as case label */ 381 if (kth->ktr_type == htobe32(KTR_START)) { 382 type = "STRT"; 383 break; 384 } 385 (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%u)", 386 kth->ktr_type); 387 type = unknown; 388 } 389 390 basecol = printf("%6ld", (long)kth->ktr_pid); 391 if (needtid) 392 basecol += printf("/%-7ld", (long)kth->ktr_tid); 393 basecol += printf(" %-8s ", kth->ktr_comm); 394 if (timestamp != TIMESTAMP_NONE) { 395 if (timestamp == TIMESTAMP_ELAPSED) { 396 if (prevtime.tv_sec == 0) 397 prevtime = kth->ktr_time; 398 timespecsub(&kth->ktr_time, &prevtime, &temp); 399 } else if (timestamp == TIMESTAMP_RELATIVE) { 400 timespecsub(&kth->ktr_time, &prevtime, &temp); 401 prevtime = kth->ktr_time; 402 } else 403 temp = kth->ktr_time; 404 basecol += printf("%lld.%06ld ", (long long)temp.tv_sec, 405 temp.tv_nsec / 1000); 406 } 407 basecol += printf("%s ", type); 408} 409 410/* 411 * Base Formatters 412 */ 413 414/* some syscalls have padding that shouldn't be shown */ 415static int 416pad(long arg) 417{ 418 /* nothing printed */ 419 return (1); 420} 421 422/* a formatter that just saves the argument for the next formatter */ 423int arg1; 424static int 425pass_two(long arg) 426{ 427 arg1 = (int)arg; 428 429 /* nothing printed */ 430 return (1); 431} 432 433static int 434pdeclong(long arg) 435{ 436 (void)printf("%ld", arg); 437 return (0); 438} 439 440static int 441pdeculong(long arg) 442{ 443 (void)printf("%lu", arg); 444 return (0); 445} 446 447static int 448phexlong(long arg) 449{ 450 (void)printf("%#lx", arg); 451 return (0); 452} 453 454static int 455pnonfancy(long arg) 456{ 457 if (decimal) 458 (void)printf("%ld", arg); 459 else 460 (void)printf("%#lx", arg); 461 return (0); 462} 463 464static void 465pdecint(int arg) 466{ 467 (void)printf("%d", arg); 468} 469 470static void 471pdecuint(int arg) 472{ 473 (void)printf("%u", arg); 474} 475 476static void 477phexint(int arg) 478{ 479 (void)printf("%#x", arg); 480} 481 482static void 483poctint(int arg) 484{ 485 (void)printf("%#o", arg); 486} 487 488 489#ifdef __LP64__ 490 491/* on LP64, long long arguments are the same as long arguments */ 492#define Phexlonglong Phexlong 493#define phexll NULL /* not actually used on LP64 */ 494 495/* no padding before long long arguments, nor at end */ 496#define PAD64 0 497#define END64 end_of_args 498 499#else /* __LP64__ */ 500 501/* on ILP32, long long arguments are passed as two 32bit args */ 502#define Phexlonglong PASS_LONGLONG, Phexll 503 504static int 505phexll(long arg2) 506{ 507 long long val; 508 509#if _BYTE_ORDER == _LITTLE_ENDIAN 510 val = ((long long)arg2 << 32) | ((long long)arg1 & 0xffffffff); 511#else 512 val = ((long long)arg1 << 32) | ((long long)arg2 & 0xffffffff); 513#endif 514 515 if (fancy || !decimal) 516 (void)printf("%#llx", val); 517 else 518 (void)printf("%lld", val); 519 return (0); 520} 521 522/* 523 * Some ILP32 archs naturally align off_t arguments to 8byte boundaries 524 * Get the compiler to tell if this arch is one of them. 525 */ 526struct padding_test { 527 int padtest_one; 528 off_t padtest_two; 529}; 530#define PAD64 (offsetof(struct padding_test,padtest_two) == 8) 531#define END64 (PAD64 ? PASS_LONGLONG : end_of_args) 532 533#endif /* __LP64__ */ 534 535static int (*long_formatters[])(long) = { 536 NULL, 537 pdeclong, 538 pdeculong, 539 phexlong, 540 pass_two, 541 pass_two, 542 phexll, 543 pad, 544 pnonfancy, 545}; 546 547static void (*formatters[])(int) = { 548 NULL, 549 pdecint, 550 phexint, 551 poctint, 552 pdecuint, 553 ioctldecode, 554 ptracedecode, 555 atfd, 556 polltimeout, 557 wait4pid, 558 signame, 559 semctlname, 560 shmctlname, 561 semgetname, 562 flagsandmodename, 563 clockname, 564 sockoptlevelname, 565 ktraceopname, 566 fcntlcmdname, 567 modename, 568 flagsname, 569 openflagsname, 570 atflagsname, 571 accessmodename, 572 mmapprotname, 573 mmapflagsname, 574 wait4optname, 575 sendrecvflagsname, 576 mountflagsname, 577 rebootoptname, 578 flockname, 579 sockoptname, 580 sockipprotoname, 581 socktypename, 582 sockflagsname, 583 sockfamilyname, 584 mlockallname, 585 shmatname, 586 whencename, 587 pathconfname, 588 rlimitname, 589 shutdownhowname, 590 prioname, 591 madvisebehavname, 592 msyncflagsname, 593 clocktypename, 594 rusagewho, 595 sigactionflagname, 596 sigprocmaskhowname, 597 minheritname, 598 quotactlname, 599 sigill_name, 600 sigtrap_name, 601 sigemt_name, 602 sigfpe_name, 603 sigbus_name, 604 sigsegv_name, 605 sigchld_name, 606 ktracefacname, 607 itimername, 608 sigset, 609 uidname, 610 gidname, 611 syslogflagname, 612 futexflagname, 613 waitidoptname, 614 idtypeandid, 615}; 616 617enum { 618 /* the end of the (known) arguments is recognized by the zero fill */ 619 end_of_args = 0, 620 621 /* negative are the negative of the index into long_formatters[] */ 622 Pdeclong = -1, 623 Pdeculong = -2, 624 Phexlong = -3, 625 PASS_TWO = -4, 626 627/* the remaining long formatters still get called when non-fancy (-n option) */ 628#define FMT_IS_NONFANCY(x) ((x) <= PASS_LONGLONG) 629 PASS_LONGLONG = -5, 630 Phexll = -6, 631 PAD = -7, 632 Pnonfancy = -8, 633 634 /* positive values are the index into formatters[] */ 635 Pdecint = 1, 636 Phexint, 637 Poctint, 638 Pdecuint, 639 Ioctldecode, 640 Ptracedecode, 641 Atfd, 642 Polltimeout, 643 Wait4pid, 644 Signame, 645 Semctlname, 646 Shmctlname, 647 Semgetname, 648 Flagsandmodename, 649 Clockname, 650 Sockoptlevelname, 651 Ktraceopname, 652 Fcntlcmdname, 653 Modename, 654 Flagsname, 655 Openflagsname, 656 Atflagsname, 657 Accessmodename, 658 Mmapprotname, 659 Mmapflagsname, 660 Wait4optname, 661 Sendrecvflagsname, 662 Mountflagsname, 663 Rebootoptname, 664 Flockname, 665 Sockoptname, 666 Sockipprotoname, 667 Socktypename, 668 Sockflagsname, 669 Sockfamilyname, 670 Mlockallname, 671 Shmatname, 672 Whencename, 673 Pathconfname, 674 Rlimitname, 675 Shutdownhowname, 676 Prioname, 677 Madvisebehavname, 678 Msyncflagsname, 679 Clocktypename, 680 Rusagewho, 681 Sigactionflagname, 682 Sigprocmaskhowname, 683 Minheritname, 684 Quotactlname, 685 Sigill_name, 686 Sigtrap_name, 687 Sigemt_name, 688 Sigfpe_name, 689 Sigbus_name, 690 Sigsegv_name, 691 Sigchld_name, 692 Ktracefacname, 693 Itimername, 694 Sigset, 695 Uidname, 696 Gidname, 697 Syslogflagname, 698 Futexflagname, 699 Waitidoptname, 700 Idtypeandid, 701}; 702 703#define Pptr Phexlong 704#define Psize Pdeculong /* size_t for small buffers */ 705#define Pbigsize Phexlong /* size_t for I/O buffers */ 706#define Pcount Pdecint /* int for a count of something */ 707#define Pfd Pdecint 708#define Ppath Phexlong 709#define Pdev_t Pdecint 710#define Ppid_t Pdecint 711#define Ppgid Pdecint /* pid or negative pgid */ 712#define Poff_t Phexlonglong 713#define Pmsqid Pdecint 714#define Pshmid Pdecint 715#define Psemid Pdecint 716#define Pkey_t Pdecint 717#define Pucount Pdecuint 718#define Chflagsname Phexlong /* to be added */ 719#define Sockprotoname Phexlong /* to be added */ 720#define Swapctlname Phexlong /* to be added */ 721#define Msgflgname Phexlong /* to be added */ 722 723 724/* includes relevant entries as of syscalls.master rev 1.238 */ 725typedef signed char formatter; 726static const formatter scargs[][8] = { 727 [SYS_exit] = { Pdecint }, 728 [SYS_read] = { Pfd, Pptr, Pbigsize }, 729 [SYS_write] = { Pfd, Pptr, Pbigsize }, 730 [SYS_open] = { Ppath, PASS_TWO, Flagsandmodename }, 731 [SYS_close] = { Pfd }, 732 [SYS_getentropy] = { Pptr, Psize }, 733 [SYS___tfork] = { Pptr, Psize }, 734 [SYS_link] = { Ppath, Ppath }, 735 [SYS_unlink] = { Ppath }, 736 [SYS_wait4] = { Wait4pid, Pptr, Wait4optname }, 737 [SYS_chdir] = { Ppath }, 738 [SYS_fchdir] = { Pfd }, 739 [SYS_mknod] = { Ppath, Modename, Pdev_t }, 740 [SYS_chmod] = { Ppath, Modename }, 741 [SYS_chown] = { Ppath, Uidname, Gidname }, 742 [SYS_break] = { Pptr }, 743 [SYS_getrusage] = { Rusagewho, Pptr }, 744 [SYS_mount] = { Pptr, Ppath, Mountflagsname, Pptr }, 745 [SYS_unmount] = { Ppath, Mountflagsname }, 746 [SYS_setuid] = { Uidname }, 747 [SYS_ptrace] = { Ptracedecode, Ppid_t, Pptr, Pdecint }, 748 [SYS_recvmsg] = { Pfd, Pptr, Sendrecvflagsname }, 749 [SYS_sendmsg] = { Pfd, Pptr, Sendrecvflagsname }, 750 [SYS_recvfrom] = { Pfd, Pptr, Pbigsize, Sendrecvflagsname }, 751 [SYS_accept] = { Pfd, Pptr, Pptr }, 752 [SYS_getpeername] = { Pfd, Pptr, Pptr }, 753 [SYS_getsockname] = { Pfd, Pptr, Pptr }, 754 [SYS_access] = { Ppath, Accessmodename }, 755 [SYS_chflags] = { Ppath, Chflagsname }, 756 [SYS_fchflags] = { Pfd, Chflagsname }, 757 [SYS_stat] = { Ppath, Pptr }, 758 [SYS_lstat] = { Ppath, Pptr }, 759 [SYS_dup] = { Pfd }, 760 [SYS_fstatat] = { Atfd, Ppath, Pptr, Atflagsname }, 761 [SYS_profil] = { Pptr, Pbigsize, Pbigsize, Pdecuint }, 762 [SYS_ktrace] = { Ppath, Ktraceopname, Ktracefacname, Ppgid }, 763 [SYS_sigaction] = { Signame, Pptr, Pptr }, 764 [SYS_sigprocmask] = { Sigprocmaskhowname, Sigset }, 765 [SYS_mmap] = { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 }, 766 [SYS_setlogin] = { Pptr }, 767 [SYS_acct] = { Ppath }, 768 [SYS_fstat] = { Pfd, Pptr }, 769 [SYS_ioctl] = { Pfd, Ioctldecode, Pptr }, 770 [SYS_reboot] = { Rebootoptname }, 771 [SYS_revoke] = { Ppath }, 772 [SYS_symlink] = { Ppath, Ppath }, 773 [SYS_readlink] = { Ppath, Pptr, Psize }, 774 [SYS_execve] = { Ppath, Pptr, Pptr }, 775 [SYS_umask] = { Modename }, 776 [SYS_chroot] = { Ppath }, 777 [SYS_getfsstat] = { Pptr, Pbigsize, Mountflagsname }, 778 [SYS_statfs] = { Ppath, Pptr }, 779 [SYS_fstatfs] = { Pfd, Pptr }, 780 [SYS_fhstatfs] = { Pptr, Pptr }, 781 [SYS_gettimeofday] = { Pptr, Pptr }, 782 [SYS_settimeofday] = { Pptr, Pptr }, 783 [SYS_setitimer] = { Itimername, Pptr, Pptr }, 784 [SYS_getitimer] = { Itimername, Pptr }, 785 [SYS_select] = { Pcount, Pptr, Pptr, Pptr, Pptr }, 786 [SYS_kevent] = { Pfd, Pptr, Pcount, Pptr, Pcount, Pptr }, 787 [SYS_munmap] = { Pptr, Pbigsize }, 788 [SYS_mprotect] = { Pptr, Pbigsize, Mmapprotname }, 789 [SYS_madvise] = { Pptr, Pbigsize, Madvisebehavname }, 790 [SYS_utimes] = { Ppath, Pptr }, 791 [SYS_futimes] = { Pfd, Pptr }, 792 [SYS_mquery] = { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 }, 793 [SYS_getgroups] = { Pcount, Pptr }, 794 [SYS_setgroups] = { Pcount, Pptr }, 795 [SYS_setpgid] = { Ppid_t, Ppid_t }, 796 [SYS_futex] = { Pptr, Futexflagname, Pcount, Pptr, Pptr }, 797 [SYS_utimensat] = { Atfd, Ppath, Pptr, Atflagsname }, 798 [SYS_futimens] = { Pfd, Pptr }, 799 [SYS_kbind] = { Pptr, Psize, Phexlonglong }, 800 [SYS_clock_gettime] = { Clockname, Pptr }, 801 [SYS_clock_settime] = { Clockname, Pptr }, 802 [SYS_clock_getres] = { Clockname, Pptr }, 803 [SYS_dup2] = { Pfd, Pfd }, 804 [SYS_nanosleep] = { Pptr, Pptr }, 805 [SYS_fcntl] = { Pfd, PASS_TWO, Fcntlcmdname }, 806 [SYS_accept4] = { Pfd, Pptr, Pptr, Sockflagsname }, 807 [SYS___thrsleep] = { Pptr, Clockname, Pptr, Pptr, Pptr }, 808 [SYS_fsync] = { Pfd }, 809 [SYS_setpriority] = { Prioname, Ppid_t, Pdecint }, 810 [SYS_socket] = { Sockfamilyname, Socktypename, Sockprotoname }, 811 [SYS_connect] = { Pfd, Pptr, Pucount }, 812 [SYS_getdents] = { Pfd, Pptr, Pbigsize }, 813 [SYS_getpriority] = { Prioname, Ppid_t }, 814 [SYS_pipe2] = { Pptr, Flagsname }, 815 [SYS_dup3] = { Pfd, Pfd, Flagsname }, 816 [SYS_sigreturn] = { Pptr }, 817 [SYS_bind] = { Pfd, Pptr, Pucount }, 818 [SYS_setsockopt] = { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pdecint }, 819 [SYS_listen] = { Pfd, Pdecint }, 820 [SYS_chflagsat] = { Atfd, Ppath, Chflagsname, Atflagsname }, 821 [SYS_pledge] = { Pptr, Pptr }, 822 [SYS_ppoll] = { Pptr, Pucount, Pptr, Pptr }, 823 [SYS_pselect] = { Pcount, Pptr, Pptr, Pptr, Pptr, Pptr }, 824 [SYS_sigsuspend] = { Sigset }, 825 [SYS_sendsyslog] = { Pptr, Psize, Syslogflagname }, 826 [SYS_unveil] = { Ppath, Pptr }, 827 [SYS___realpath] = { Ppath, Pptr }, 828 [SYS_recvmmsg] = { Pfd, Pptr, Pucount, Sendrecvflagsname, Pptr }, 829 [SYS_sendmmsg] = { Pfd, Pptr, Pucount, Sendrecvflagsname }, 830 [SYS_getsockopt] = { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pptr }, 831 [SYS_thrkill] = { Ppid_t, Signame, Pptr }, 832 [SYS_readv] = { Pfd, Pptr, Pcount }, 833 [SYS_writev] = { Pfd, Pptr, Pcount }, 834 [SYS_kill] = { Ppgid, Signame }, 835 [SYS_fchown] = { Pfd, Uidname, Gidname }, 836 [SYS_fchmod] = { Pfd, Modename }, 837 [SYS_setreuid] = { Uidname, Uidname }, 838 [SYS_setregid] = { Gidname, Gidname }, 839 [SYS_rename] = { Ppath, Ppath }, 840 [SYS_flock] = { Pfd, Flockname }, 841 [SYS_mkfifo] = { Ppath, Modename }, 842 [SYS_sendto] = { Pfd, Pptr, Pbigsize, Sendrecvflagsname }, 843 [SYS_shutdown] = { Pfd, Shutdownhowname }, 844 [SYS_socketpair] = { Sockfamilyname, Socktypename, Sockprotoname, Pptr }, 845 [SYS_mkdir] = { Ppath, Modename }, 846 [SYS_rmdir] = { Ppath }, 847 [SYS_adjtime] = { Pptr, Pptr }, 848 [SYS_getlogin_r] = { Pptr, Psize }, 849 [SYS_getthrname] = { Ppid_t, Pptr, Psize }, 850 [SYS_setthrname] = { Ppid_t, Pptr }, 851 [SYS_quotactl] = { Ppath, Quotactlname, Uidname, Pptr }, 852 [SYS_ypconnect] = { Socktypename }, 853 [SYS_nfssvc] = { Phexint, Pptr }, 854 [SYS_mimmutable] = { Pptr, Pbigsize }, 855 [SYS_waitid] = { PASS_TWO, Idtypeandid, Pptr, Waitidoptname }, 856 [SYS_getfh] = { Ppath, Pptr }, 857 [SYS___tmpfd] = { Openflagsname }, 858 [SYS_sysarch] = { Pdecint, Pptr }, 859 [SYS_lseek] = { Pfd, Poff_t, Whencename, END64 }, 860 [SYS_truncate] = { Ppath, Poff_t, END64 }, 861 [SYS_ftruncate] = { Pfd, Poff_t, END64 }, 862 [SYS_pread] = { Pfd, Pptr, Pbigsize, Poff_t, END64 }, 863 [SYS_pwrite] = { Pfd, Pptr, Pbigsize, Poff_t, END64 }, 864 [SYS_preadv] = { Pfd, Pptr, Pcount, Poff_t, END64 }, 865 [SYS_pwritev] = { Pfd, Pptr, Pcount, Poff_t, END64 }, 866 [SYS_setgid] = { Gidname }, 867 [SYS_setegid] = { Gidname }, 868 [SYS_seteuid] = { Uidname }, 869 [SYS_pathconfat] = { Atfd, Ppath, Pathconfname, Atflagsname }, 870 [SYS_pathconf] = { Ppath, Pathconfname }, 871 [SYS_fpathconf] = { Pfd, Pathconfname }, 872 [SYS_swapctl] = { Swapctlname, Pptr, Pdecint }, 873 [SYS_getrlimit] = { Rlimitname, Pptr }, 874 [SYS_setrlimit] = { Rlimitname, Pptr }, 875 [SYS_sysctl] = { Pptr, Pcount, Pptr, Pptr, Pptr, Psize }, 876 [SYS_mlock] = { Pptr, Pbigsize }, 877 [SYS_munlock] = { Pptr, Pbigsize }, 878 [SYS_getpgid] = { Ppid_t }, 879 [SYS_utrace] = { Pptr, Pptr, Psize }, 880 [SYS_semget] = { Pkey_t, Pcount, Semgetname }, 881 [SYS_msgget] = { Pkey_t, Msgflgname }, 882 [SYS_msgsnd] = { Pmsqid, Pptr, Psize, Msgflgname }, 883 [SYS_msgrcv] = { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname }, 884 [SYS_shmat] = { Pshmid, Pptr, Shmatname }, 885 [SYS_shmdt] = { Pptr }, 886 [SYS_minherit] = { Pptr, Pbigsize, Minheritname }, 887 [SYS_poll] = { Pptr, Pucount, Polltimeout }, 888 [SYS_lchown] = { Ppath, Uidname, Gidname }, 889 [SYS_getsid] = { Ppid_t }, 890 [SYS_msync] = { Pptr, Pbigsize, Msyncflagsname }, 891 [SYS_pipe] = { Pptr }, 892 [SYS_fhopen] = { Pptr, Openflagsname }, 893 [SYS_kqueue1] = { Flagsname }, 894 [SYS_mlockall] = { Mlockallname }, 895 [SYS_getresuid] = { Pptr, Pptr, Pptr }, 896 [SYS_setresuid] = { Uidname, Uidname, Uidname }, 897 [SYS_getresgid] = { Pptr, Pptr, Pptr }, 898 [SYS_setresgid] = { Gidname, Gidname, Gidname }, 899 [SYS_closefrom] = { Pfd }, 900 [SYS_sigaltstack] = { Pptr, Pptr }, 901 [SYS_shmget] = { Pkey_t, Pbigsize, Semgetname }, 902 [SYS_semop] = { Psemid, Pptr, Psize }, 903 [SYS_fhstat] = { Pptr, Pptr }, 904 [SYS___semctl] = { Psemid, Pcount, Semctlname, Pptr }, 905 [SYS_shmctl] = { Pshmid, Shmctlname, Pptr }, 906 [SYS_msgctl] = { Pmsqid, Shmctlname, Pptr }, 907 [SYS___thrwakeup] = { Pptr, Pcount }, 908 [SYS___threxit] = { Pptr }, 909 [SYS___thrsigdivert] = { Sigset, Pptr, Pptr }, 910 [SYS___getcwd] = { Pptr, Psize }, 911 [SYS_adjfreq] = { Pptr, Pptr }, 912 [SYS_setrtable] = { Pdecint }, 913 [SYS_faccessat] = { Atfd, Ppath, Accessmodename, Atflagsname }, 914 [SYS_fchmodat] = { Atfd, Ppath, Modename, Atflagsname }, 915 [SYS_fchownat] = { Atfd, Ppath, Uidname, Gidname, Atflagsname }, 916 [SYS_linkat] = { Atfd, Ppath, Atfd, Ppath, Atflagsname }, 917 [SYS_mkdirat] = { Atfd, Ppath, Modename }, 918 [SYS_mkfifoat] = { Atfd, Ppath, Modename }, 919 [SYS_mknodat] = { Atfd, Ppath, Modename, Pdev_t }, 920 [SYS_openat] = { Atfd, Ppath, PASS_TWO, Flagsandmodename }, 921 [SYS_readlinkat] = { Atfd, Ppath, Pptr, Psize }, 922 [SYS_renameat] = { Atfd, Ppath, Atfd, Ppath }, 923 [SYS_symlinkat] = { Ppath, Atfd, Ppath }, 924 [SYS_unlinkat] = { Atfd, Ppath, Atflagsname }, 925 [SYS___set_tcb] = { Pptr }, 926}; 927 928 929static void 930ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen) 931{ 932 register_t *ap; 933 int narg, code; 934 char sep; 935 936 if (ktr->ktr_argsize > ktrlen) 937 errx(1, "syscall argument length %d > ktr header length %zu", 938 ktr->ktr_argsize, ktrlen); 939 940 narg = ktr->ktr_argsize / sizeof(register_t); 941 sep = '\0'; 942 943 code = ktr->ktr_code; 944 if (code >= SYS_MAXSYSCALL || code < 0) 945 (void)printf("[%d]", code); 946 else 947 (void)printf("%s", syscallnames[code]); 948 ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall)); 949 (void)putchar('('); 950 951 if (code == SYS_sysctl && fancy) { 952 const char *s; 953 int n, i, *top; 954 955 n = ap[1]; 956 if (n > CTL_MAXNAME) 957 n = CTL_MAXNAME; 958 if (n < 0) 959 errx(1, "invalid sysctl length %d", n); 960 if (n > 0) { 961 top = (int *)(ap + 6); 962 printf("%d", top[0]); 963 for (i = 1; i < n; i++) 964 printf(".%d", top[i]); 965 if ((s = kresolvsysctl(0, top)) != NULL) { 966 printf("<%s", s); 967 for (i = 1; i < n; i++) { 968 if ((s = kresolvsysctl(i, top)) != NULL) 969 printf(".%s", s); 970 else 971 printf(".%d", top[i]); 972 } 973 putchar('>'); 974 } 975 } 976 977 sep = ','; 978 ap += 2; 979 narg -= 2; 980 } else if (code < nitems(scargs)) { 981 const formatter *fmts = scargs[code]; 982 int fmt; 983 int arg = 0; 984 985 while (arg < narg && (fmt = *fmts) != 0) { 986 if (PAD64 && fmt == PASS_LONGLONG && (arg & 1)) 987 goto skip; 988 if (sep) 989 putchar(sep); 990 sep = ','; 991 if (!fancy && !FMT_IS_NONFANCY(fmt)) 992 fmt = Pnonfancy; 993 if (fmt > 0) 994 formatters[fmt]((int)*ap); 995 else if (long_formatters[-fmt](*ap)) 996 sep = '\0'; 997 fmts++; 998skip: 999 ap++; 1000 arg++; 1001 } 1002 narg -= arg; 1003 } 1004 1005 while (narg > 0) { 1006 if (sep) 1007 putchar(sep); 1008 if (decimal) 1009 (void)printf("%ld", (long)*ap); 1010 else 1011 (void)printf("%#lx", (long)*ap); 1012 sep = ','; 1013 ap++; 1014 narg--; 1015 } 1016 (void)printf(")\n"); 1017} 1018 1019static struct ctlname topname[] = CTL_NAMES; 1020static struct ctlname kernname[] = CTL_KERN_NAMES; 1021static struct ctlname vmname[] = CTL_VM_NAMES; 1022static struct ctlname fsname[] = CTL_FS_NAMES; 1023static struct ctlname netname[] = CTL_NET_NAMES; 1024static struct ctlname hwname[] = CTL_HW_NAMES; 1025static struct ctlname debugname[CTL_DEBUG_MAXID]; 1026static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 1027static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 1028static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 1029static struct ctlname kernprocname[] = { 1030 { NULL }, 1031 { "all" }, 1032 { "pid" }, 1033 { "pgrp" }, 1034 { "session" }, 1035 { "tty" }, 1036 { "uid" }, 1037 { "ruid" }, 1038 { "kthread" }, 1039}; 1040static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES; 1041static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 1042static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 1043static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 1044static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES; 1045#ifdef CTL_MACHDEP_NAMES 1046static struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 1047#endif 1048static struct ctlname ddbname[] = CTL_DDB_NAMES; 1049 1050#ifndef nitems 1051#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1052#endif 1053 1054#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0) 1055 1056static const char * 1057kresolvsysctl(int depth, const int *top) 1058{ 1059 struct ctlname *names; 1060 size_t limit; 1061 int idx = top[depth]; 1062 1063 names = NULL; 1064 1065 switch (depth) { 1066 case 0: 1067 SETNAME(topname); 1068 break; 1069 case 1: 1070 switch (top[0]) { 1071 case CTL_KERN: 1072 SETNAME(kernname); 1073 break; 1074 case CTL_VM: 1075 SETNAME(vmname); 1076 break; 1077 case CTL_FS: 1078 SETNAME(fsname); 1079 break; 1080 case CTL_NET: 1081 SETNAME(netname); 1082 break; 1083 case CTL_DEBUG: 1084 SETNAME(debugname); 1085 break; 1086 case CTL_HW: 1087 SETNAME(hwname); 1088 break; 1089#ifdef CTL_MACHDEP_NAMES 1090 case CTL_MACHDEP: 1091 SETNAME(machdepname); 1092 break; 1093#endif 1094 case CTL_DDB: 1095 SETNAME(ddbname); 1096 break; 1097 } 1098 break; 1099 case 2: 1100 switch (top[0]) { 1101 case CTL_KERN: 1102 switch (top[1]) { 1103 case KERN_MALLOCSTATS: 1104 SETNAME(kernmallocname); 1105 break; 1106 case KERN_FORKSTAT: 1107 SETNAME(forkstatname); 1108 break; 1109 case KERN_NCHSTATS: 1110 SETNAME(nchstatsname); 1111 break; 1112 case KERN_TTY: 1113 SETNAME(ttysname); 1114 break; 1115 case KERN_SEMINFO: 1116 SETNAME(semname); 1117 break; 1118 case KERN_SHMINFO: 1119 SETNAME(shmname); 1120 break; 1121 case KERN_WATCHDOG: 1122 SETNAME(watchdogname); 1123 break; 1124 case KERN_PROC: 1125 idx++; /* zero is valid at this level */ 1126 SETNAME(kernprocname); 1127 break; 1128 case KERN_TIMECOUNTER: 1129 SETNAME(tcname); 1130 break; 1131 } 1132 } 1133 break; 1134 } 1135 if (names != NULL && idx > 0 && idx < limit) 1136 return (names[idx].ctl_name); 1137 return (NULL); 1138} 1139 1140static void 1141ktrsysret(struct ktr_sysret *ktr, size_t ktrlen) 1142{ 1143 register_t ret = 0; 1144 long long retll; 1145 int error = ktr->ktr_error; 1146 int code = ktr->ktr_code; 1147 1148 if (ktrlen < sizeof(*ktr)) 1149 errx(1, "sysret length %zu < ktr header length %zu", 1150 ktrlen, sizeof(*ktr)); 1151 ktrlen -= sizeof(*ktr); 1152 if (error == 0) { 1153 if (ktrlen == sizeof(ret)) { 1154 memcpy(&ret, ktr+1, sizeof(ret)); 1155 retll = ret; 1156 } else if (ktrlen == sizeof(retll)) 1157 memcpy(&retll, ktr+1, sizeof(retll)); 1158 else 1159 errx(1, "sysret bogus length %zu", ktrlen); 1160 } 1161 1162 if (code >= SYS_MAXSYSCALL || code < 0) 1163 (void)printf("[%d] ", code); 1164 else 1165 (void)printf("%s ", syscallnames[code]); 1166 1167doerr: 1168 if (error == 0) { 1169 if (fancy) { 1170 switch (code) { 1171 case SYS_lseek: 1172 (void)printf("%lld", retll); 1173 if (retll < 0 || retll > 9) 1174 (void)printf("/%#llx", retll); 1175 break; 1176 case SYS_sigprocmask: 1177 case SYS_sigpending: 1178 sigset(ret); 1179 break; 1180 case SYS___thrsigdivert: 1181 signame(ret); 1182 break; 1183 case SYS_getuid: 1184 case SYS_geteuid: 1185 uidname(ret); 1186 break; 1187 case SYS_getgid: 1188 case SYS_getegid: 1189 gidname(ret); 1190 break; 1191 /* syscalls that return errno values */ 1192 case SYS_getlogin_r: 1193 case SYS___thrsleep: 1194 case SYS_getthrname: 1195 case SYS_setthrname: 1196 if ((error = ret) != 0) 1197 goto doerr; 1198 /* FALLTHROUGH */ 1199 default: 1200 (void)printf("%ld", (long)ret); 1201 if (ret < 0 || ret > 9) 1202 (void)printf("/%#lx", (long)ret); 1203 } 1204 } else { 1205 if (decimal) 1206 (void)printf("%lld", retll); 1207 else 1208 (void)printf("%#llx", retll); 1209 } 1210 } else if (error == ERESTART) 1211 (void)printf("RESTART"); 1212 else if (error == EJUSTRETURN) 1213 (void)printf("JUSTRETURN"); 1214 else { 1215 (void)printf("-1 errno %d", error); 1216 if (fancy) 1217 (void)printf(" %s", strerror(error)); 1218 } 1219 (void)putchar('\n'); 1220} 1221 1222static void 1223ktrnamei(const char *cp, size_t len) 1224{ 1225 showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL); 1226} 1227 1228void 1229showbufc(int col, unsigned char *dp, size_t datalen, int flags) 1230{ 1231 int width; 1232 unsigned char visbuf[5], *cp; 1233 1234 flags |= VIS_CSTYLE; 1235 putchar('"'); 1236 col++; 1237 for (; datalen > 0; datalen--, dp++) { 1238 (void)vis(visbuf, *dp, flags, *(dp+1)); 1239 cp = visbuf; 1240 1241 /* 1242 * Keep track of printables and 1243 * space chars (like fold(1)). 1244 */ 1245 if (col == 0) { 1246 (void)putchar('\t'); 1247 col = 8; 1248 } 1249 switch (*cp) { 1250 case '\n': 1251 col = 0; 1252 (void)putchar('\n'); 1253 continue; 1254 case '\t': 1255 width = 8 - (col&07); 1256 break; 1257 default: 1258 width = strlen(cp); 1259 } 1260 if (col + width > (screenwidth-2)) { 1261 (void)printf("\\\n\t"); 1262 col = 8; 1263 } 1264 col += width; 1265 do { 1266 (void)putchar(*cp++); 1267 } while (*cp); 1268 } 1269 if (col == 0) 1270 (void)printf(" "); 1271 (void)printf("\"\n"); 1272} 1273 1274static void 1275showbuf(unsigned char *dp, size_t datalen) 1276{ 1277 size_t i, j; 1278 int col = 0, bpl; 1279 unsigned char c; 1280 char visbuf[4 * KTR_USER_MAXLEN + 1]; 1281 1282 if (utracefilter != NULL) { 1283 strvisx(visbuf, dp, datalen, VIS_SAFE | VIS_OCTAL); 1284 printf("%s", visbuf); 1285 return; 1286 } 1287 if (iohex == 1) { 1288 putchar('\t'); 1289 col = 8; 1290 for (i = 0; i < datalen; i++) { 1291 printf("%02x", dp[i]); 1292 col += 3; 1293 if (i < datalen - 1) { 1294 if (col + 3 > screenwidth) { 1295 printf("\n\t"); 1296 col = 8; 1297 } else 1298 putchar(' '); 1299 } 1300 } 1301 putchar('\n'); 1302 return; 1303 } 1304 if (iohex == 2) { 1305 bpl = (screenwidth - 13)/4; 1306 if (bpl <= 0) 1307 bpl = 1; 1308 for (i = 0; i < datalen; i += bpl) { 1309 printf(" %04zx: ", i); 1310 for (j = 0; j < bpl; j++) { 1311 if (i+j >= datalen) 1312 printf(" "); 1313 else 1314 printf("%02x ", dp[i+j]); 1315 } 1316 putchar(' '); 1317 for (j = 0; j < bpl; j++) { 1318 if (i+j >= datalen) 1319 break; 1320 c = dp[i+j]; 1321 if (!isprint(c)) 1322 c = '.'; 1323 putchar(c); 1324 } 1325 putchar('\n'); 1326 } 1327 return; 1328 } 1329 1330 (void)printf(" "); 1331 showbufc(7, dp, datalen, 0); 1332} 1333 1334static void 1335ktrgenio(struct ktr_genio *ktr, size_t len) 1336{ 1337 unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); 1338 size_t datalen; 1339 1340 if (len < sizeof(struct ktr_genio)) 1341 errx(1, "invalid ktr genio length %zu", len); 1342 1343 datalen = len - sizeof(struct ktr_genio); 1344 1345 printf("fd %d %s %zu bytes\n", ktr->ktr_fd, 1346 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); 1347 if (maxdata == 0) 1348 return; 1349 if (datalen > maxdata) 1350 datalen = maxdata; 1351 if (iohex && !datalen) 1352 return; 1353 showbuf(dp, datalen); 1354} 1355 1356void 1357siginfo(const siginfo_t *si, int show_signo) 1358{ 1359 if (show_signo) { 1360 printf("signo="); 1361 signame(si->si_signo); 1362 } 1363 if (si->si_code) { 1364 printf(" code="); 1365 if (!fancy) 1366 printf("<%d>", si->si_code); 1367 else { 1368 switch (si->si_signo) { 1369 case SIGILL: 1370 sigill_name(si->si_code); 1371 break; 1372 case SIGTRAP: 1373 sigtrap_name(si->si_code); 1374 break; 1375 case SIGEMT: 1376 sigemt_name(si->si_code); 1377 break; 1378 case SIGFPE: 1379 sigfpe_name(si->si_code); 1380 break; 1381 case SIGBUS: 1382 sigbus_name(si->si_code); 1383 break; 1384 case SIGSEGV: 1385 sigsegv_name(si->si_code); 1386 break; 1387 case SIGCHLD: 1388 sigchld_name(si->si_code); 1389 break; 1390 default: 1391 printf("<%d>", si->si_code); 1392 break; 1393 } 1394 } 1395 } 1396 1397 switch (si->si_signo) { 1398 case SIGSEGV: 1399 case SIGILL: 1400 case SIGBUS: 1401 case SIGFPE: 1402 printf(" addr=%p trapno=%d", si->si_addr, si->si_trapno); 1403 break; 1404 case SIGCHLD: 1405 if (si->si_code == CLD_EXITED) { 1406 printf(" status=%d", si->si_status); 1407 if (si->si_status < 0 || si->si_status > 9) 1408 (void)printf("/%#x", si->si_status); 1409 } else { 1410 printf(" status="); 1411 signame(si->si_status); 1412 } 1413 printf(" pid=%d uid=", si->si_pid); 1414 uidname(si->si_uid); 1415 break; 1416 default: 1417 break; 1418 } 1419} 1420 1421static void 1422ktrpsig(struct ktr_psig *psig) 1423{ 1424 signame(psig->signo); 1425 printf(" "); 1426 if (psig->action == SIG_DFL) 1427 printf("SIG_DFL"); 1428 else { 1429 printf("caught handler=0x%lx mask=", (u_long)psig->action); 1430 sigset(psig->mask); 1431 } 1432 siginfo(&psig->si, 0); 1433 putchar('\n'); 1434} 1435 1436static void 1437ktruser(struct ktr_user *usr, size_t len) 1438{ 1439 if (len < sizeof(struct ktr_user)) 1440 errx(1, "invalid ktr user length %zu", len); 1441 len -= sizeof(struct ktr_user); 1442 if (utracefilter == NULL) { 1443 printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); 1444 printf(" %zu bytes\n", len); 1445 showbuf((unsigned char *)(usr + 1), len); 1446 } else if (strncmp(usr->ktr_id, utracefilter, KTR_USER_MAXIDLEN) == 0) 1447 showbuf((unsigned char *)(usr + 1), len); 1448} 1449 1450static void 1451ktrexec(const char *ptr, size_t len) 1452{ 1453 int i, col; 1454 size_t l; 1455 1456 putchar('\n'); 1457 i = 0; 1458 while (len > 0) { 1459 l = strnlen(ptr, len); 1460 col = printf("\t[%d] = ", i++); 1461 col += 7; /* tab expands from 1 to 8 columns */ 1462 showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL); 1463 if (l == len) { 1464 printf("\tunterminated argument\n"); 1465 break; 1466 } 1467 len -= l + 1; 1468 ptr += l + 1; 1469 } 1470} 1471 1472static void 1473ktrpledge(struct ktr_pledge *pledge, size_t len) 1474{ 1475 const char *name = ""; 1476 int i; 1477 1478 if (len < sizeof(struct ktr_pledge)) 1479 errx(1, "invalid ktr pledge length %zu", len); 1480 1481 if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0) 1482 (void)printf("[%d]", pledge->syscall); 1483 else 1484 (void)printf("%s", syscallnames[pledge->syscall]); 1485 printf(", "); 1486 for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) { 1487 if (pledgenames[i].bits & pledge->code) { 1488 name = pledgenames[i].name; 1489 break; 1490 } 1491 } 1492 printf("\"%s\"", name); 1493 (void)printf(", errno %d", pledge->error); 1494 if (fancy) 1495 (void)printf(" %s", strerror(pledge->error)); 1496 printf("\n"); 1497} 1498 1499static void 1500ktrpinsyscall(struct ktr_pinsyscall *pinsyscall, size_t len) 1501{ 1502 const char *name = ""; 1503 int i; 1504 1505 if (len < sizeof(struct ktr_pinsyscall)) 1506 errx(1, "invalid ktr pinsyscall length %zu", len); 1507 1508 if (pinsyscall->syscall >= SYS_MAXSYSCALL || pinsyscall->syscall < 0) 1509 (void)printf("[%d]", pinsyscall->syscall); 1510 else 1511 (void)printf("%s", syscallnames[pinsyscall->syscall]); 1512 (void)printf(", addr %lx, errno %d", pinsyscall->addr, 1513 pinsyscall->error); 1514 (void)printf(", errno %d", pinsyscall->error); 1515 if (fancy) 1516 (void)printf(" %s", strerror(pinsyscall->error)); 1517 printf("\n"); 1518} 1519 1520static void 1521usage(void) 1522{ 1523 1524 extern char *__progname; 1525 fprintf(stderr, "usage: %s " 1526 "[-dHlnRTXx] [-f file] [-m maxdata] [-P program] [-p pid] " 1527 "[-t trstr]\n\t[-u label]\n", __progname); 1528 exit(1); 1529} 1530 1531 1532/* 1533 * FORMATTERS 1534 */ 1535 1536static void 1537ioctldecode(int cmd) 1538{ 1539 char dirbuf[4], *dir = dirbuf; 1540 const char *cp; 1541 1542 if ((cp = ioctlname((unsigned)cmd)) != NULL) { 1543 (void)printf("%s", cp); 1544 return; 1545 } 1546 1547 if (cmd & IOC_IN) 1548 *dir++ = 'W'; 1549 if (cmd & IOC_OUT) 1550 *dir++ = 'R'; 1551 *dir = '\0'; 1552 1553 printf("_IO%s('%c',%d", 1554 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff); 1555 if ((cmd & IOC_VOID) == 0) 1556 printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff); 1557 else 1558 printf(")"); 1559} 1560 1561static void 1562ptracedecode(int request) 1563{ 1564 if (request >= 0 && request < nitems(ptrace_ops)) 1565 (void)printf("%s", ptrace_ops[request]); 1566 else switch(request) { 1567#ifdef PT_GETFPREGS 1568 case PT_GETFPREGS: 1569 (void)printf("PT_GETFPREGS"); 1570 break; 1571#endif 1572 case PT_GETREGS: 1573 (void)printf("PT_GETREGS"); 1574 break; 1575#ifdef PT_GETXMMREGS 1576 case PT_GETXMMREGS: 1577 (void)printf("PT_GETXMMREGS"); 1578 break; 1579#endif 1580#ifdef PT_SETFPREGS 1581 case PT_SETFPREGS: 1582 (void)printf("PT_SETFPREGS"); 1583 break; 1584#endif 1585 case PT_SETREGS: 1586 (void)printf("PT_SETREGS"); 1587 break; 1588#ifdef PT_SETXMMREGS 1589 case PT_SETXMMREGS: 1590 (void)printf("PT_SETXMMREGS"); 1591 break; 1592#endif 1593#ifdef PT_STEP 1594 case PT_STEP: 1595 (void)printf("PT_STEP"); 1596 break; 1597#endif 1598#ifdef PT_WCOOKIE 1599 case PT_WCOOKIE: 1600 (void)printf("PT_WCOOKIE"); 1601 break; 1602#endif 1603 default: 1604 pdecint(request); 1605 } 1606} 1607 1608 1609static void 1610atfd(int fd) 1611{ 1612 if (fd == AT_FDCWD) 1613 (void)printf("AT_FDCWD"); 1614 else 1615 pdecint(fd); 1616} 1617 1618static void 1619polltimeout(int timeout) 1620{ 1621 if (timeout == INFTIM) 1622 (void)printf("INFTIM"); 1623 else 1624 pdecint(timeout); 1625} 1626 1627static void 1628wait4pid(int pid) 1629{ 1630 if (pid == WAIT_ANY) 1631 (void)printf("WAIT_ANY"); 1632 else if (pid == WAIT_MYPGRP) 1633 (void)printf("WAIT_MYPGRP"); 1634 else 1635 pdecint(pid); /* ppgid */ 1636} 1637 1638static void 1639signame(int sig) 1640{ 1641 if (sig > 0 && sig < NSIG) 1642 (void)printf("SIG%s", sys_signame[sig]); 1643 else 1644 (void)printf("SIG %d", sig); 1645} 1646 1647void 1648sigset(int ss) 1649{ 1650 int or = 0; 1651 int cnt = 0; 1652 int i; 1653 1654 for (i = 1; i < NSIG; i++) 1655 if (sigismember(&ss, i)) 1656 cnt++; 1657 if (cnt > (NSIG-1)/2) { 1658 ss = ~ss; 1659 putchar('~'); 1660 } 1661 1662 if (ss == 0) { 1663 (void)printf("0<>"); 1664 return; 1665 } 1666 1667 printf("%#x<", ss); 1668 for (i = 1; i < NSIG; i++) 1669 if (sigismember(&ss, i)) { 1670 if (or) putchar('|'); else or=1; 1671 signame(i); 1672 } 1673 printf(">"); 1674} 1675 1676static void 1677semctlname(int cmd) 1678{ 1679 switch (cmd) { 1680 case GETNCNT: 1681 (void)printf("GETNCNT"); 1682 break; 1683 case GETPID: 1684 (void)printf("GETPID"); 1685 break; 1686 case GETVAL: 1687 (void)printf("GETVAL"); 1688 break; 1689 case GETALL: 1690 (void)printf("GETALL"); 1691 break; 1692 case GETZCNT: 1693 (void)printf("GETZCNT"); 1694 break; 1695 case SETVAL: 1696 (void)printf("SETVAL"); 1697 break; 1698 case SETALL: 1699 (void)printf("SETALL"); 1700 break; 1701 case IPC_RMID: 1702 (void)printf("IPC_RMID"); 1703 break; 1704 case IPC_SET: 1705 (void)printf("IPC_SET"); 1706 break; 1707 case IPC_STAT: 1708 (void)printf("IPC_STAT"); 1709 break; 1710 default: /* Should not reach */ 1711 (void)printf("<invalid=%d>", cmd); 1712 } 1713} 1714 1715static void 1716shmctlname(int cmd) 1717{ 1718 switch (cmd) { 1719 case IPC_RMID: 1720 (void)printf("IPC_RMID"); 1721 break; 1722 case IPC_SET: 1723 (void)printf("IPC_SET"); 1724 break; 1725 case IPC_STAT: 1726 (void)printf("IPC_STAT"); 1727 break; 1728 default: /* Should not reach */ 1729 (void)printf("<invalid=%d>", cmd); 1730 } 1731} 1732 1733 1734static void 1735semgetname(int flag) 1736{ 1737 int or = 0; 1738 if_print_or(flag, IPC_CREAT, or); 1739 if_print_or(flag, IPC_EXCL, or); 1740 if_print_or(flag, SEM_R, or); 1741 if_print_or(flag, SEM_A, or); 1742 if_print_or(flag, (SEM_R>>3), or); 1743 if_print_or(flag, (SEM_A>>3), or); 1744 if_print_or(flag, (SEM_R>>6), or); 1745 if_print_or(flag, (SEM_A>>6), or); 1746 1747 if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)| 1748 ((SEM_R|SEM_A)>>6))) 1749 printf("<invalid=%#x>", flag); 1750} 1751 1752 1753/* 1754 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the 1755 * mode argument is unused (and often bogus and misleading). 1756 */ 1757static void 1758flagsandmodename(int mode) 1759{ 1760 openflagsname(arg1); 1761 if ((arg1 & O_CREAT) == O_CREAT) { 1762 (void)putchar(','); 1763 modename(mode); 1764 } else if (!fancy) 1765 (void)printf(",<unused>%#o", mode); 1766} 1767 1768static void 1769clockname(int clockid) 1770{ 1771 clocktypename(__CLOCK_TYPE(clockid)); 1772 if (__CLOCK_PTID(clockid) != 0) 1773 printf("(%d)", __CLOCK_PTID(clockid)); 1774} 1775 1776/* 1777 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value 1778 * referring to a line in /etc/protocols. 1779 */ 1780static void 1781sockoptlevelname(int optname) 1782{ 1783 struct protoent *pe; 1784 1785 if (arg1 == SOL_SOCKET) { 1786 (void)printf("SOL_SOCKET,"); 1787 sockoptname(optname); 1788 } else { 1789 pe = getprotobynumber(arg1); 1790 (void)printf("%u<%s>,%d", arg1, 1791 pe != NULL ? pe->p_name : "unknown", optname); 1792 } 1793} 1794 1795static void 1796ktraceopname(int ops) 1797{ 1798 int invalid = 0; 1799 1800 printf("%#x<", ops); 1801 switch (KTROP(ops)) { 1802 case KTROP_SET: 1803 printf("KTROP_SET"); 1804 break; 1805 case KTROP_CLEAR: 1806 printf("KTROP_CLEAR"); 1807 break; 1808 case KTROP_CLEARFILE: 1809 printf("KTROP_CLEARFILE"); 1810 break; 1811 default: 1812 printf("KTROP(%d)", KTROP(ops)); 1813 invalid = 1; 1814 break; 1815 } 1816 if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND"); 1817 printf(">"); 1818 if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND))) 1819 (void)printf("<invalid>%d", ops); 1820} 1821 1822static void 1823idtypeandid(int id) 1824{ 1825 switch (arg1) { 1826 case P_PID: 1827 printf("P_PID,%d", id); 1828 break; 1829 case P_PGID: 1830 printf("P_PGID,%d", id); 1831 break; 1832 case P_ALL: 1833 printf("P_ALL,<unused>%d", id); 1834 break; 1835 default: /* Should not reach */ 1836 printf("<invalid=%d>, <unused>%d", arg1, id); 1837 } 1838} 1839