1 /* 2 * Copyright (c) 2006 "David Kirchner" <dpk@dpk.net>. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 #define L2CAP_SOCKET_CHECKED 30 31 #include <sys/types.h> 32 #include <sys/acl.h> 33 #include <sys/capsicum.h> 34 #include <sys/extattr.h> 35 #include <sys/linker.h> 36 #include <sys/mman.h> 37 #include <sys/mount.h> 38 #include <sys/procctl.h> 39 #include <sys/ptrace.h> 40 #include <sys/reboot.h> 41 #include <sys/resource.h> 42 #include <sys/rtprio.h> 43 #include <sys/sem.h> 44 #include <sys/shm.h> 45 #include <sys/socket.h> 46 #include <sys/stat.h> 47 #include <sys/thr.h> 48 #include <sys/umtx.h> 49 #include <netinet/in.h> 50 #include <netinet/sctp.h> 51 #include <netinet/tcp.h> 52 #include <netinet/udp.h> 53 #include <nfsserver/nfs.h> 54 #include <ufs/ufs/quota.h> 55 #include <vm/vm.h> 56 #include <vm/vm_param.h> 57 #include <aio.h> 58 #include <fcntl.h> 59 #include <sched.h> 60 #include <stdbool.h> 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <strings.h> 64 #include <sysdecode.h> 65 #include <unistd.h> 66 #include <sys/bitstring.h> 67 #include <netgraph/bluetooth/include/ng_hci.h> 68 #include <netgraph/bluetooth/include/ng_l2cap.h> 69 #include <netgraph/bluetooth/include/ng_btsocket.h> 70 71 /* 72 * This is taken from the xlat tables originally in truss which were 73 * in turn taken from strace. 74 */ 75 struct name_table { 76 uintmax_t val; 77 const char *str; 78 }; 79 80 #define X(a) { a, #a }, 81 #define XEND { 0, NULL } 82 83 #define TABLE_START(n) static struct name_table n[] = { 84 #define TABLE_ENTRY X 85 #define TABLE_END XEND }; 86 87 #include "tables.h" 88 89 #undef TABLE_START 90 #undef TABLE_ENTRY 91 #undef TABLE_END 92 93 /* 94 * These are simple support macros. print_or utilizes a variable 95 * defined in the calling function to track whether or not it should 96 * print a logical-OR character ('|') before a string. if_print_or 97 * simply handles the necessary "if" statement used in many lines 98 * of this file. 99 */ 100 #define print_or(fp,str,orflag) do { \ 101 if (orflag) fputc(fp, '|'); else orflag = true; \ 102 fprintf(fp, str); } \ 103 while (0) 104 #define if_print_or(fp,i,flag,orflag) do { \ 105 if ((i & flag) == flag) \ 106 print_or(fp,#flag,orflag); } \ 107 while (0) 108 109 static const char * 110 lookup_value(struct name_table *table, uintmax_t val) 111 { 112 113 for (; table->str != NULL; table++) 114 if (table->val == val) 115 return (table->str); 116 return (NULL); 117 } 118 119 /* 120 * Used when the value maps to a bitmask of #definition values in the 121 * table. This is a helper routine which outputs a symbolic mask of 122 * matched masks. Multiple masks are separated by a pipe ('|'). 123 * The value is modified on return to only hold unmatched bits. 124 */ 125 static void 126 print_mask_part(FILE *fp, struct name_table *table, uintmax_t *valp, 127 bool *printed) 128 { 129 uintmax_t rem; 130 131 rem = *valp; 132 for (; table->str != NULL; table++) { 133 if ((table->val & rem) == table->val) { 134 /* 135 * Only print a zero mask if the raw value is 136 * zero. 137 */ 138 if (table->val == 0 && *valp != 0) 139 continue; 140 fprintf(fp, "%s%s", *printed ? "|" : "", table->str); 141 *printed = true; 142 rem &= ~table->val; 143 } 144 } 145 146 *valp = rem; 147 } 148 149 /* 150 * Used when the value maps to a bitmask of #definition values in the 151 * table. The return value is true if something was printed. If 152 * rem is not NULL, *rem holds any bits not decoded if something was 153 * printed. If nothing was printed and rem is not NULL, *rem holds 154 * the original value. 155 */ 156 static bool 157 print_mask_int(FILE *fp, struct name_table *table, int ival, int *rem) 158 { 159 uintmax_t val; 160 bool printed; 161 162 printed = false; 163 val = (unsigned)ival; 164 print_mask_part(fp, table, &val, &printed); 165 if (rem != NULL) 166 *rem = val; 167 return (printed); 168 } 169 170 /* 171 * Used for a mask of optional flags where a value of 0 is valid. 172 */ 173 static bool 174 print_mask_0(FILE *fp, struct name_table *table, int val, int *rem) 175 { 176 177 if (val == 0) { 178 fputs("0", fp); 179 if (rem != NULL) 180 *rem = 0; 181 return (true); 182 } 183 return (print_mask_int(fp, table, val, rem)); 184 } 185 186 /* 187 * Like print_mask_0 but for a unsigned long instead of an int. 188 */ 189 static bool 190 print_mask_0ul(FILE *fp, struct name_table *table, u_long lval, u_long *rem) 191 { 192 uintmax_t val; 193 bool printed; 194 195 if (lval == 0) { 196 fputs("0", fp); 197 if (rem != NULL) 198 *rem = 0; 199 return (true); 200 } 201 202 printed = false; 203 val = lval; 204 print_mask_part(fp, table, &val, &printed); 205 if (rem != NULL) 206 *rem = val; 207 return (printed); 208 } 209 210 static void 211 print_integer(FILE *fp, int val, int base) 212 { 213 214 switch (base) { 215 case 8: 216 fprintf(fp, "0%o", val); 217 break; 218 case 10: 219 fprintf(fp, "%d", val); 220 break; 221 case 16: 222 fprintf(fp, "0x%x", val); 223 break; 224 default: 225 abort2("bad base", 0, NULL); 226 break; 227 } 228 } 229 230 static bool 231 print_value(FILE *fp, struct name_table *table, uintmax_t val) 232 { 233 const char *str; 234 235 str = lookup_value(table, val); 236 if (str != NULL) { 237 fputs(str, fp); 238 return (true); 239 } 240 return (false); 241 } 242 243 const char * 244 sysdecode_atfd(int fd) 245 { 246 247 if (fd == AT_FDCWD) 248 return ("AT_FDCWD"); 249 return (NULL); 250 } 251 252 static struct name_table semctlops[] = { 253 X(GETNCNT) X(GETPID) X(GETVAL) X(GETALL) X(GETZCNT) X(SETVAL) X(SETALL) 254 X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND 255 }; 256 257 const char * 258 sysdecode_semctl_cmd(int cmd) 259 { 260 261 return (lookup_value(semctlops, cmd)); 262 } 263 264 static struct name_table shmctlops[] = { 265 X(IPC_RMID) X(IPC_SET) X(IPC_STAT) XEND 266 }; 267 268 const char * 269 sysdecode_shmctl_cmd(int cmd) 270 { 271 272 return (lookup_value(shmctlops, cmd)); 273 } 274 275 const char * 276 sysdecode_msgctl_cmd(int cmd) 277 { 278 279 return (sysdecode_shmctl_cmd(cmd)); 280 } 281 282 static struct name_table semgetflags[] = { 283 X(IPC_CREAT) X(IPC_EXCL) X(SEM_R) X(SEM_A) X((SEM_R>>3)) X((SEM_A>>3)) 284 X((SEM_R>>6)) X((SEM_A>>6)) XEND 285 }; 286 287 bool 288 sysdecode_semget_flags(FILE *fp, int flag, int *rem) 289 { 290 291 return (print_mask_int(fp, semgetflags, flag, rem)); 292 } 293 294 static struct name_table idtypes[] = { 295 X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID) 296 X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID) 297 X(P_CTID) X(P_CPUID) X(P_PSETID) XEND 298 }; 299 300 /* XXX: idtype is really an idtype_t */ 301 const char * 302 sysdecode_idtype(int idtype) 303 { 304 305 return (lookup_value(idtypes, idtype)); 306 } 307 308 /* 309 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a 310 * protocol-specific value. 311 */ 312 const char * 313 sysdecode_sockopt_level(int level) 314 { 315 const char *str; 316 317 if (level == SOL_SOCKET) 318 return ("SOL_SOCKET"); 319 320 /* SOL_* constants for Bluetooth sockets. */ 321 str = lookup_value(ngbtsolevel, level); 322 if (str != NULL) 323 return (str); 324 325 /* 326 * IP and Infiniband sockets use IP protocols as levels. Not all 327 * protocols are valid but it is simpler to just allow all of them. 328 * 329 * XXX: IPPROTO_IP == 0, but UNIX domain sockets use a level of 0 330 * for private options. 331 */ 332 str = sysdecode_ipproto(level); 333 if (str != NULL) 334 return (str); 335 336 return (NULL); 337 } 338 339 bool 340 sysdecode_vmprot(FILE *fp, int type, int *rem) 341 { 342 343 return (print_mask_int(fp, vmprot, type, rem)); 344 } 345 346 static struct name_table sockflags[] = { 347 X(SOCK_CLOEXEC) X(SOCK_NONBLOCK) XEND 348 }; 349 350 bool 351 sysdecode_socket_type(FILE *fp, int type, int *rem) 352 { 353 const char *str; 354 uintmax_t val; 355 bool printed; 356 357 str = lookup_value(socktype, type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)); 358 if (str != NULL) { 359 fputs(str, fp); 360 *rem = 0; 361 printed = true; 362 } else { 363 *rem = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); 364 printed = false; 365 } 366 val = type & (SOCK_CLOEXEC | SOCK_NONBLOCK); 367 print_mask_part(fp, sockflags, &val, &printed); 368 return (printed); 369 } 370 371 bool 372 sysdecode_access_mode(FILE *fp, int mode, int *rem) 373 { 374 375 return (print_mask_int(fp, accessmode, mode, rem)); 376 } 377 378 /* XXX: 'type' is really an acl_type_t. */ 379 const char * 380 sysdecode_acltype(int type) 381 { 382 383 return (lookup_value(acltype, type)); 384 } 385 386 bool 387 sysdecode_cap_fcntlrights(FILE *fp, uint32_t rights, uint32_t *rem) 388 { 389 390 return (print_mask_int(fp, capfcntl, rights, rem)); 391 } 392 393 const char * 394 sysdecode_extattrnamespace(int namespace) 395 { 396 397 return (lookup_value(extattrns, namespace)); 398 } 399 400 const char * 401 sysdecode_fadvice(int advice) 402 { 403 404 return (lookup_value(fadvisebehav, advice)); 405 } 406 407 bool 408 sysdecode_open_flags(FILE *fp, int flags, int *rem) 409 { 410 bool printed; 411 int mode; 412 uintmax_t val; 413 414 mode = flags & O_ACCMODE; 415 flags &= ~O_ACCMODE; 416 switch (mode) { 417 case O_RDONLY: 418 if (flags & O_EXEC) { 419 flags &= ~O_EXEC; 420 fputs("O_EXEC", fp); 421 } else 422 fputs("O_RDONLY", fp); 423 printed = true; 424 mode = 0; 425 break; 426 case O_WRONLY: 427 fputs("O_WRONLY", fp); 428 printed = true; 429 mode = 0; 430 break; 431 case O_RDWR: 432 fputs("O_RDWR", fp); 433 printed = true; 434 mode = 0; 435 break; 436 default: 437 printed = false; 438 } 439 val = (unsigned)flags; 440 print_mask_part(fp, openflags, &val, &printed); 441 if (rem != NULL) 442 *rem = val | mode; 443 return (printed); 444 } 445 446 bool 447 sysdecode_fcntl_fileflags(FILE *fp, int flags, int *rem) 448 { 449 bool printed; 450 int oflags; 451 452 /* 453 * The file flags used with F_GETFL/F_SETFL mostly match the 454 * flags passed to open(2). However, a few open-only flag 455 * bits have been repurposed for fcntl-only flags. 456 */ 457 oflags = flags & ~(O_NOFOLLOW | FRDAHEAD); 458 printed = sysdecode_open_flags(fp, oflags, rem); 459 if (flags & O_NOFOLLOW) { 460 fprintf(fp, "%sFPOIXSHM", printed ? "|" : ""); 461 printed = true; 462 } 463 if (flags & FRDAHEAD) { 464 fprintf(fp, "%sFRDAHEAD", printed ? "|" : ""); 465 printed = true; 466 } 467 return (printed); 468 } 469 470 bool 471 sysdecode_flock_operation(FILE *fp, int operation, int *rem) 472 { 473 474 return (print_mask_int(fp, flockops, operation, rem)); 475 } 476 477 static struct name_table getfsstatmode[] = { 478 X(MNT_WAIT) X(MNT_NOWAIT) XEND 479 }; 480 481 const char * 482 sysdecode_getfsstat_mode(int mode) 483 { 484 485 return (lookup_value(getfsstatmode, mode)); 486 } 487 488 const char * 489 sysdecode_kldsym_cmd(int cmd) 490 { 491 492 return (lookup_value(kldsymcmd, cmd)); 493 } 494 495 const char * 496 sysdecode_kldunload_flags(int flags) 497 { 498 499 return (lookup_value(kldunloadfflags, flags)); 500 } 501 502 const char * 503 sysdecode_lio_listio_mode(int mode) 504 { 505 506 return (lookup_value(lio_listiomodes, mode)); 507 } 508 509 const char * 510 sysdecode_madvice(int advice) 511 { 512 513 return (lookup_value(madvisebehav, advice)); 514 } 515 516 const char * 517 sysdecode_minherit_inherit(int inherit) 518 { 519 520 return (lookup_value(minheritflags, inherit)); 521 } 522 523 bool 524 sysdecode_mlockall_flags(FILE *fp, int flags, int *rem) 525 { 526 527 return (print_mask_int(fp, mlockallflags, flags, rem)); 528 } 529 530 bool 531 sysdecode_mmap_prot(FILE *fp, int prot, int *rem) 532 { 533 534 return (print_mask_int(fp, mmapprot, prot, rem)); 535 } 536 537 bool 538 sysdecode_fileflags(FILE *fp, fflags_t flags, fflags_t *rem) 539 { 540 541 return (print_mask_0(fp, fileflags, flags, rem)); 542 } 543 544 bool 545 sysdecode_filemode(FILE *fp, int mode, int *rem) 546 { 547 548 return (print_mask_0(fp, filemode, mode, rem)); 549 } 550 551 bool 552 sysdecode_mount_flags(FILE *fp, int flags, int *rem) 553 { 554 555 return (print_mask_int(fp, mountflags, flags, rem)); 556 } 557 558 bool 559 sysdecode_msync_flags(FILE *fp, int flags, int *rem) 560 { 561 562 return (print_mask_int(fp, msyncflags, flags, rem)); 563 } 564 565 const char * 566 sysdecode_nfssvc_flags(int flags) 567 { 568 569 return (lookup_value(nfssvcflags, flags)); 570 } 571 572 static struct name_table pipe2flags[] = { 573 X(O_CLOEXEC) X(O_NONBLOCK) XEND 574 }; 575 576 bool 577 sysdecode_pipe2_flags(FILE *fp, int flags, int *rem) 578 { 579 580 return (print_mask_0(fp, pipe2flags, flags, rem)); 581 } 582 583 const char * 584 sysdecode_prio_which(int which) 585 { 586 587 return (lookup_value(prio, which)); 588 } 589 590 const char * 591 sysdecode_procctl_cmd(int cmd) 592 { 593 594 return (lookup_value(procctlcmd, cmd)); 595 } 596 597 const char * 598 sysdecode_ptrace_request(int request) 599 { 600 601 return (lookup_value(ptraceop, request)); 602 } 603 604 static struct name_table quotatypes[] = { 605 X(GRPQUOTA) X(USRQUOTA) XEND 606 }; 607 608 bool 609 sysdecode_quotactl_cmd(FILE *fp, int cmd) 610 { 611 const char *primary, *type; 612 613 primary = lookup_value(quotactlcmds, cmd >> SUBCMDSHIFT); 614 if (primary == NULL) 615 return (false); 616 fprintf(fp, "QCMD(%s,", primary); 617 type = lookup_value(quotatypes, cmd & SUBCMDMASK); 618 if (type != NULL) 619 fprintf(fp, "%s", type); 620 else 621 fprintf(fp, "%#x", cmd & SUBCMDMASK); 622 fprintf(fp, ")"); 623 return (true); 624 } 625 626 bool 627 sysdecode_reboot_howto(FILE *fp, int howto, int *rem) 628 { 629 630 return (print_mask_int(fp, rebootopt, howto, rem)); 631 } 632 633 bool 634 sysdecode_rfork_flags(FILE *fp, int flags, int *rem) 635 { 636 637 return (print_mask_int(fp, rforkflags, flags, rem)); 638 } 639 640 const char * 641 sysdecode_rlimit(int resource) 642 { 643 644 return (lookup_value(rlimit, resource)); 645 } 646 647 const char * 648 sysdecode_scheduler_policy(int policy) 649 { 650 651 return (lookup_value(schedpolicy, policy)); 652 } 653 654 bool 655 sysdecode_sendfile_flags(FILE *fp, int flags, int *rem) 656 { 657 658 return (print_mask_int(fp, sendfileflags, flags, rem)); 659 } 660 661 bool 662 sysdecode_shmat_flags(FILE *fp, int flags, int *rem) 663 { 664 665 return (print_mask_int(fp, shmatflags, flags, rem)); 666 } 667 668 const char * 669 sysdecode_shutdown_how(int how) 670 { 671 672 return (lookup_value(shutdownhow, how)); 673 } 674 675 const char * 676 sysdecode_sigbus_code(int si_code) 677 { 678 679 return (lookup_value(sigbuscode, si_code)); 680 } 681 682 const char * 683 sysdecode_sigchld_code(int si_code) 684 { 685 686 return (lookup_value(sigchldcode, si_code)); 687 } 688 689 const char * 690 sysdecode_sigfpe_code(int si_code) 691 { 692 693 return (lookup_value(sigfpecode, si_code)); 694 } 695 696 const char * 697 sysdecode_sigill_code(int si_code) 698 { 699 700 return (lookup_value(sigillcode, si_code)); 701 } 702 703 const char * 704 sysdecode_sigsegv_code(int si_code) 705 { 706 707 return (lookup_value(sigsegvcode, si_code)); 708 } 709 710 const char * 711 sysdecode_sigtrap_code(int si_code) 712 { 713 714 return (lookup_value(sigtrapcode, si_code)); 715 } 716 717 const char * 718 sysdecode_sigprocmask_how(int how) 719 { 720 721 return (lookup_value(sigprocmaskhow, how)); 722 } 723 724 const char * 725 sysdecode_socketdomain(int domain) 726 { 727 728 return (lookup_value(sockdomain, domain)); 729 } 730 731 const char * 732 sysdecode_sockaddr_family(int sa_family) 733 { 734 735 return (lookup_value(sockfamily, sa_family)); 736 } 737 738 const char * 739 sysdecode_ipproto(int protocol) 740 { 741 742 return (lookup_value(sockipproto, protocol)); 743 } 744 745 const char * 746 sysdecode_sockopt_name(int level, int optname) 747 { 748 749 if (level == SOL_SOCKET) 750 return (lookup_value(sockopt, optname)); 751 if (level == IPPROTO_IP) 752 /* XXX: UNIX domain socket options use a level of 0 also. */ 753 return (lookup_value(sockoptip, optname)); 754 if (level == IPPROTO_IPV6) 755 return (lookup_value(sockoptipv6, optname)); 756 if (level == IPPROTO_SCTP) 757 return (lookup_value(sockoptsctp, optname)); 758 if (level == IPPROTO_TCP) 759 return (lookup_value(sockopttcp, optname)); 760 if (level == IPPROTO_UDP) 761 return (lookup_value(sockoptudp, optname)); 762 return (NULL); 763 } 764 765 bool 766 sysdecode_thr_create_flags(FILE *fp, int flags, int *rem) 767 { 768 769 return (print_mask_int(fp, thrcreateflags, flags, rem)); 770 } 771 772 const char * 773 sysdecode_umtx_op(int op) 774 { 775 776 return (lookup_value(umtxop, op)); 777 } 778 779 const char * 780 sysdecode_vmresult(int result) 781 { 782 783 return (lookup_value(vmresult, result)); 784 } 785 786 bool 787 sysdecode_wait4_options(FILE *fp, int options, int *rem) 788 { 789 bool printed; 790 int opt6; 791 792 /* A flags value of 0 is normal. */ 793 if (options == 0) { 794 fputs("0", fp); 795 if (rem != NULL) 796 *rem = 0; 797 return (true); 798 } 799 800 /* 801 * These flags are implicit and aren't valid flags for wait4() 802 * directly (though they don't fail with EINVAL). 803 */ 804 opt6 = options & (WEXITED | WTRAPPED); 805 options &= ~opt6; 806 printed = print_mask_int(fp, wait6opt, options, rem); 807 if (rem != NULL) 808 *rem |= opt6; 809 return (printed); 810 } 811 812 bool 813 sysdecode_wait6_options(FILE *fp, int options, int *rem) 814 { 815 816 return (print_mask_int(fp, wait6opt, options, rem)); 817 } 818 819 const char * 820 sysdecode_whence(int whence) 821 { 822 823 return (lookup_value(seekwhence, whence)); 824 } 825 826 const char * 827 sysdecode_fcntl_cmd(int cmd) 828 { 829 830 return (lookup_value(fcntlcmd, cmd)); 831 } 832 833 static struct name_table fcntl_fd_arg[] = { 834 X(FD_CLOEXEC) X(0) XEND 835 }; 836 837 bool 838 sysdecode_fcntl_arg_p(int cmd) 839 { 840 841 switch (cmd) { 842 case F_GETFD: 843 case F_GETFL: 844 case F_GETOWN: 845 return (false); 846 default: 847 return (true); 848 } 849 } 850 851 void 852 sysdecode_fcntl_arg(FILE *fp, int cmd, uintptr_t arg, int base) 853 { 854 int rem; 855 856 switch (cmd) { 857 case F_SETFD: 858 if (!print_value(fp, fcntl_fd_arg, arg)) 859 print_integer(fp, arg, base); 860 break; 861 case F_SETFL: 862 if (!sysdecode_fcntl_fileflags(fp, arg, &rem)) 863 fprintf(fp, "%#x", rem); 864 else if (rem != 0) 865 fprintf(fp, "|%#x", rem); 866 break; 867 case F_GETLK: 868 case F_SETLK: 869 case F_SETLKW: 870 fprintf(fp, "%p", (void *)arg); 871 break; 872 default: 873 print_integer(fp, arg, base); 874 break; 875 } 876 } 877 878 bool 879 sysdecode_mmap_flags(FILE *fp, int flags, int *rem) 880 { 881 uintmax_t val; 882 bool printed; 883 int align; 884 885 /* 886 * MAP_ALIGNED can't be handled directly by print_mask_int(). 887 * MAP_32BIT is also problematic since it isn't defined for 888 * all platforms. 889 */ 890 printed = false; 891 align = flags & MAP_ALIGNMENT_MASK; 892 val = (unsigned)flags & ~MAP_ALIGNMENT_MASK; 893 print_mask_part(fp, mmapflags, &val, &printed); 894 #ifdef MAP_32BIT 895 if (val & MAP_32BIT) { 896 fprintf(fp, "%sMAP_32BIT", printed ? "|" : ""); 897 printed = true; 898 val &= ~MAP_32BIT; 899 } 900 #endif 901 if (align != 0) { 902 if (printed) 903 fputc('|', fp); 904 if (align == MAP_ALIGNED_SUPER) 905 fputs("MAP_ALIGNED_SUPER", fp); 906 else 907 fprintf(fp, "MAP_ALIGNED(%d)", 908 align >> MAP_ALIGNMENT_SHIFT); 909 printed = true; 910 } 911 if (rem != NULL) 912 *rem = val; 913 return (printed); 914 } 915 916 const char * 917 sysdecode_rtprio_function(int function) 918 { 919 920 return (lookup_value(rtpriofuncs, function)); 921 } 922 923 bool 924 sysdecode_msg_flags(FILE *fp, int flags, int *rem) 925 { 926 927 return (print_mask_0(fp, msgflags, flags, rem)); 928 } 929 930 const char * 931 sysdecode_sigcode(int sig, int si_code) 932 { 933 const char *str; 934 935 str = lookup_value(sigcode, si_code); 936 if (str != NULL) 937 return (str); 938 939 switch (sig) { 940 case SIGILL: 941 return (sysdecode_sigill_code(si_code)); 942 case SIGBUS: 943 return (sysdecode_sigbus_code(si_code)); 944 case SIGSEGV: 945 return (sysdecode_sigsegv_code(si_code)); 946 case SIGFPE: 947 return (sysdecode_sigfpe_code(si_code)); 948 case SIGTRAP: 949 return (sysdecode_sigtrap_code(si_code)); 950 case SIGCHLD: 951 return (sysdecode_sigchld_code(si_code)); 952 default: 953 return (NULL); 954 } 955 } 956 957 bool 958 sysdecode_umtx_cvwait_flags(FILE *fp, u_long flags, u_long *rem) 959 { 960 961 return (print_mask_0ul(fp, umtxcvwaitflags, flags, rem)); 962 } 963 964 bool 965 sysdecode_umtx_rwlock_flags(FILE *fp, u_long flags, u_long *rem) 966 { 967 968 return (print_mask_0ul(fp, umtxrwlockflags, flags, rem)); 969 } 970 971 void 972 sysdecode_cap_rights(FILE *fp, cap_rights_t *rightsp) 973 { 974 struct name_table *t; 975 bool comma; 976 977 comma = false; 978 for (t = caprights; t->str != NULL; t++) { 979 if (cap_rights_is_set(rightsp, t->val)) { 980 fprintf(fp, "%s%s", comma ? "," : "", t->str); 981 comma = true; 982 } 983 } 984 } 985