17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5b2eb1770Sudpa * Common Development and Distribution License (the "License"). 6b2eb1770Sudpa * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*eb9fe4caSDavid Valin * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 277c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h> 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/mman.h> 317c478bd9Sstevel@tonic-gate #include <sys/project.h> 327c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h> 337c478bd9Sstevel@tonic-gate #include <sys/shm_impl.h> 347c478bd9Sstevel@tonic-gate #include <sys/sem_impl.h> 357c478bd9Sstevel@tonic-gate #include <sys/msg_impl.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <vm/anon.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #define CMN_HDR_START "%<u>" 407c478bd9Sstevel@tonic-gate #define CMN_HDR_END "%</u>\n" 417c478bd9Sstevel@tonic-gate #define CMN_INDENT (4) 427c478bd9Sstevel@tonic-gate #define CMN_INACTIVE "%s facility inactive.\n" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 457c478bd9Sstevel@tonic-gate * Bitmap data for page protection flags suitable for use with %b. 467c478bd9Sstevel@tonic-gate */ 477c478bd9Sstevel@tonic-gate const mdb_bitmask_t prot_flag_bits[] = { 487c478bd9Sstevel@tonic-gate { "PROT_READ", PROT_READ, PROT_READ }, 497c478bd9Sstevel@tonic-gate { "PROT_WRITE", PROT_WRITE, PROT_WRITE }, 507c478bd9Sstevel@tonic-gate { "PROT_EXEC", PROT_EXEC, PROT_EXEC }, 517c478bd9Sstevel@tonic-gate { "PROT_USER", PROT_USER, PROT_USER }, 527c478bd9Sstevel@tonic-gate { NULL, 0, 0 } 537c478bd9Sstevel@tonic-gate }; 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate static void 567c478bd9Sstevel@tonic-gate printtime_nice(const char *str, time_t time) 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate if (time) 597c478bd9Sstevel@tonic-gate mdb_printf("%s%Y\n", str, time); 607c478bd9Sstevel@tonic-gate else 617c478bd9Sstevel@tonic-gate mdb_printf("%sn/a\n", str); 627c478bd9Sstevel@tonic-gate } 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * Print header common to all IPC types. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate static void 687c478bd9Sstevel@tonic-gate ipcperm_header() 697c478bd9Sstevel@tonic-gate { 707c478bd9Sstevel@tonic-gate mdb_printf(CMN_HDR_START "%?s %5s %5s %8s %5s %5s %6s %5s %5s %5s %5s" 717c478bd9Sstevel@tonic-gate CMN_HDR_END, "ADDR", "REF", "ID", "KEY", "MODE", "PRJID", "ZONEID", 727c478bd9Sstevel@tonic-gate "OWNER", "GROUP", "CREAT", "CGRP"); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate /* 767c478bd9Sstevel@tonic-gate * Print data common to all IPC types. 777c478bd9Sstevel@tonic-gate */ 787c478bd9Sstevel@tonic-gate static void 797c478bd9Sstevel@tonic-gate ipcperm_print(uintptr_t addr, kipc_perm_t *perm) 807c478bd9Sstevel@tonic-gate { 817c478bd9Sstevel@tonic-gate kproject_t proj; 827c478bd9Sstevel@tonic-gate int res; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate res = mdb_vread(&proj, sizeof (kproject_t), (uintptr_t)perm->ipc_proj); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate if (res == -1) 877c478bd9Sstevel@tonic-gate mdb_warn("failed to read kproject_t at %#p", perm->ipc_proj); 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate mdb_printf("%0?p %5d %5d", addr, perm->ipc_ref, perm->ipc_id); 907c478bd9Sstevel@tonic-gate if (perm->ipc_key) 917c478bd9Sstevel@tonic-gate mdb_printf(" %8x", perm->ipc_key); 927c478bd9Sstevel@tonic-gate else 937c478bd9Sstevel@tonic-gate mdb_printf(" %8s", "private"); 947c478bd9Sstevel@tonic-gate mdb_printf(" %5#o", perm->ipc_mode & 07777); 957c478bd9Sstevel@tonic-gate if (res == -1) 967c478bd9Sstevel@tonic-gate mdb_printf(" %5s %5s", "<flt>", "<flt>"); 977c478bd9Sstevel@tonic-gate else 987c478bd9Sstevel@tonic-gate mdb_printf(" %5d %6d", proj.kpj_id, proj.kpj_zoneid); 997c478bd9Sstevel@tonic-gate mdb_printf(" %5d %5d %5d %5d\n", perm->ipc_uid, perm->ipc_gid, 1007c478bd9Sstevel@tonic-gate perm->ipc_cuid, perm->ipc_cgid); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1057c478bd9Sstevel@tonic-gate static int 1067c478bd9Sstevel@tonic-gate ipcperm(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate kipc_perm_t perm; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 1117c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) 1147c478bd9Sstevel@tonic-gate ipcperm_header(); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate if (mdb_vread(&perm, sizeof (kipc_perm_t), addr) == -1) { 1177c478bd9Sstevel@tonic-gate mdb_warn("failed to read kipc_perm_t at %#lx", addr); 1187c478bd9Sstevel@tonic-gate return (DCMD_ERR); 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate ipcperm_print(addr, &perm); 1227c478bd9Sstevel@tonic-gate return (DCMD_OK); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1252c5b6df1Sdv142724 126*eb9fe4caSDavid Valin #define MSG_SND_SIZE 0x1 1272c5b6df1Sdv142724 static int 128*eb9fe4caSDavid Valin msgq_check_for_waiters(list_t *walk_this, int min, int max, 129*eb9fe4caSDavid Valin int copy_wait, uintptr_t addr, int flag) 1302c5b6df1Sdv142724 1312c5b6df1Sdv142724 { 1322c5b6df1Sdv142724 int found = 0; 1332c5b6df1Sdv142724 int ii; 134f03c4264Sdv142724 msgq_wakeup_t *walker, next; 1352c5b6df1Sdv142724 uintptr_t head; 1362c5b6df1Sdv142724 1372c5b6df1Sdv142724 for (ii = min; ii < max; ii++) { 1382c5b6df1Sdv142724 head = ((ulong_t)addr) + sizeof (list_t)*ii + 1392c5b6df1Sdv142724 sizeof (list_node_t); 1402c5b6df1Sdv142724 if (head != (uintptr_t)walk_this[ii].list_head.list_next) { 1412c5b6df1Sdv142724 walker = 1422c5b6df1Sdv142724 (msgq_wakeup_t *)walk_this[ii].list_head.list_next; 1432c5b6df1Sdv142724 while (head != (uintptr_t)walker) { 1442c5b6df1Sdv142724 if (mdb_vread(&next, sizeof (msgq_wakeup_t), 1452c5b6df1Sdv142724 (uintptr_t)walker) == -1) { 1462c5b6df1Sdv142724 mdb_warn( 1472c5b6df1Sdv142724 "Failed to read message queue\n"); 148*eb9fe4caSDavid Valin return (found); 1492c5b6df1Sdv142724 } 150*eb9fe4caSDavid Valin 151*eb9fe4caSDavid Valin if (flag & MSG_SND_SIZE) { 152*eb9fe4caSDavid Valin mdb_printf("%15lx\t%6d\t%15lx\t%15d\n", 153*eb9fe4caSDavid Valin next.msgw_thrd, next.msgw_type, 154*eb9fe4caSDavid Valin walker + (uintptr_t) 155*eb9fe4caSDavid Valin OFFSETOF(msgq_wakeup_t, 156*eb9fe4caSDavid Valin msgw_wake_cv), next.msgw_snd_size); 157*eb9fe4caSDavid Valin } else { 1582c5b6df1Sdv142724 mdb_printf("%15lx\t%6d\t%15lx\t%15s\n", 1592c5b6df1Sdv142724 next.msgw_thrd, next.msgw_type, 1602c5b6df1Sdv142724 walker + (uintptr_t) 161*eb9fe4caSDavid Valin OFFSETOF(msgq_wakeup_t, 162*eb9fe4caSDavid Valin msgw_wake_cv), 1632c5b6df1Sdv142724 (copy_wait ? "yes":"no")); 164*eb9fe4caSDavid Valin } 1652c5b6df1Sdv142724 found++; 1662c5b6df1Sdv142724 walker = 1672c5b6df1Sdv142724 (msgq_wakeup_t *)next.msgw_list.list_next; 1682c5b6df1Sdv142724 } 1692c5b6df1Sdv142724 } 1702c5b6df1Sdv142724 } 1712c5b6df1Sdv142724 return (found); 1722c5b6df1Sdv142724 } 1732c5b6df1Sdv142724 1747c478bd9Sstevel@tonic-gate static void 1757c478bd9Sstevel@tonic-gate msq_print(kmsqid_t *msqid, uintptr_t addr) 1767c478bd9Sstevel@tonic-gate { 1772c5b6df1Sdv142724 int total = 0; 178b2eb1770Sudpa 1797c478bd9Sstevel@tonic-gate mdb_printf("&list: %-?p\n", addr + OFFSETOF(kmsqid_t, msg_list)); 1807c478bd9Sstevel@tonic-gate mdb_printf("cbytes: 0t%lu qnum: 0t%lu qbytes: 0t%lu" 1817c478bd9Sstevel@tonic-gate " qmax: 0t%lu\n", msqid->msg_cbytes, msqid->msg_qnum, 1827c478bd9Sstevel@tonic-gate msqid->msg_qbytes, msqid->msg_qmax); 1837c478bd9Sstevel@tonic-gate mdb_printf("lspid: 0t%d lrpid: 0t%d\n", 1847c478bd9Sstevel@tonic-gate (int)msqid->msg_lspid, (int)msqid->msg_lrpid); 1857c478bd9Sstevel@tonic-gate printtime_nice("stime: ", msqid->msg_stime); 1867c478bd9Sstevel@tonic-gate printtime_nice("rtime: ", msqid->msg_rtime); 1877c478bd9Sstevel@tonic-gate printtime_nice("ctime: ", msqid->msg_ctime); 188b2eb1770Sudpa mdb_printf("snd_cnt: 0t%lld snd_cv: %hd (%p)\n", 189b2eb1770Sudpa msqid->msg_snd_cnt, msqid->msg_snd_cv._opaque, 190b2eb1770Sudpa addr + (uintptr_t)OFFSETOF(kmsqid_t, msg_snd_cv)); 1912c5b6df1Sdv142724 mdb_printf("Blocked recievers\n"); 1922c5b6df1Sdv142724 mdb_printf("%15s\t%6s\t%15s\t%15s\n", "Thread Addr", 1932c5b6df1Sdv142724 "Type", "cv addr", "copyout-wait?"); 194*eb9fe4caSDavid Valin total += msgq_check_for_waiters(&msqid->msg_cpy_block, 195*eb9fe4caSDavid Valin 0, 1, 1, addr + OFFSETOF(kmsqid_t, msg_cpy_block), 0); 196*eb9fe4caSDavid Valin total += msgq_check_for_waiters(msqid->msg_wait_snd_ngt, 1972c5b6df1Sdv142724 0, MSG_MAX_QNUM + 1, 0, 198*eb9fe4caSDavid Valin addr + OFFSETOF(kmsqid_t, msg_wait_snd_ngt), 0); 199*eb9fe4caSDavid Valin mdb_printf("Blocked senders\n"); 200*eb9fe4caSDavid Valin total += msgq_check_for_waiters(&msqid->msg_wait_rcv, 201*eb9fe4caSDavid Valin 0, 1, 1, addr + OFFSETOF(kmsqid_t, msg_wait_rcv), 202*eb9fe4caSDavid Valin MSG_SND_SIZE); 203*eb9fe4caSDavid Valin mdb_printf("%15s\t%6s\t%15s\t%15s\n", "Thread Addr", 204*eb9fe4caSDavid Valin "Type", "cv addr", "Msg Size"); 205*eb9fe4caSDavid Valin total += msgq_check_for_waiters(msqid->msg_wait_snd, 206*eb9fe4caSDavid Valin 0, MSG_MAX_QNUM + 1, 0, addr + OFFSETOF(kmsqid_t, 207*eb9fe4caSDavid Valin msg_wait_snd), 0); 2082c5b6df1Sdv142724 mdb_printf("Total number of waiters: %d\n", total); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 2137c478bd9Sstevel@tonic-gate static void 2147c478bd9Sstevel@tonic-gate shm_print(kshmid_t *shmid, uintptr_t addr) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate shmatt_t nattch; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate nattch = shmid->shm_perm.ipc_ref - (IPC_FREE(&shmid->shm_perm) ? 0 : 1); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate mdb_printf(CMN_HDR_START "%10s %?s %5s %7s %7s %7s %7s" CMN_HDR_END, 2217c478bd9Sstevel@tonic-gate "SEGSZ", "AMP", "LKCNT", "LPID", "CPID", "NATTCH", "CNATTCH"); 2227c478bd9Sstevel@tonic-gate mdb_printf("%10#lx %?p %5u %7d %7d %7lu %7lu\n", 2237c478bd9Sstevel@tonic-gate shmid->shm_segsz, shmid->shm_amp, shmid->shm_lkcnt, 2247c478bd9Sstevel@tonic-gate (int)shmid->shm_lpid, (int)shmid->shm_cpid, nattch, 2257c478bd9Sstevel@tonic-gate shmid->shm_ismattch); 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate printtime_nice("atime: ", shmid->shm_atime); 2287c478bd9Sstevel@tonic-gate printtime_nice("dtime: ", shmid->shm_dtime); 2297c478bd9Sstevel@tonic-gate printtime_nice("ctime: ", shmid->shm_ctime); 2307c478bd9Sstevel@tonic-gate mdb_printf("sptinfo: %-?p sptseg: %-?p\n", 2317c478bd9Sstevel@tonic-gate shmid->shm_sptinfo, shmid->shm_sptseg); 2327c478bd9Sstevel@tonic-gate mdb_printf("sptprot: <%lb>\n", shmid->shm_sptprot, prot_flag_bits); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 2377c478bd9Sstevel@tonic-gate static void 2387c478bd9Sstevel@tonic-gate sem_print(ksemid_t *semid, uintptr_t addr) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate mdb_printf("base: %-?p nsems: 0t%u\n", 2417c478bd9Sstevel@tonic-gate semid->sem_base, semid->sem_nsems); 2427c478bd9Sstevel@tonic-gate printtime_nice("otime: ", semid->sem_otime); 2437c478bd9Sstevel@tonic-gate printtime_nice("ctime: ", semid->sem_ctime); 2447c478bd9Sstevel@tonic-gate mdb_printf("binary: %s\n", semid->sem_binary ? "yes" : "no"); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate typedef struct ipc_ops_vec { 2487c478bd9Sstevel@tonic-gate char *iv_wcmd; /* walker name */ 2497c478bd9Sstevel@tonic-gate char *iv_ocmd; /* output dcmd */ 2507c478bd9Sstevel@tonic-gate char *iv_service; /* service pointer */ 2517c478bd9Sstevel@tonic-gate void (*iv_print)(void *, uintptr_t); /* output callback */ 2527c478bd9Sstevel@tonic-gate size_t iv_idsize; 2537c478bd9Sstevel@tonic-gate } ipc_ops_vec_t; 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate ipc_ops_vec_t msq_ops_vec = { 2567c478bd9Sstevel@tonic-gate "msq", 2577c478bd9Sstevel@tonic-gate "kmsqid", 2587c478bd9Sstevel@tonic-gate "msq_svc", 2597c478bd9Sstevel@tonic-gate (void(*)(void *, uintptr_t))msq_print, 2607c478bd9Sstevel@tonic-gate sizeof (kmsqid_t) 2617c478bd9Sstevel@tonic-gate }; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate ipc_ops_vec_t shm_ops_vec = { 2647c478bd9Sstevel@tonic-gate "shm", 2657c478bd9Sstevel@tonic-gate "kshmid", 2667c478bd9Sstevel@tonic-gate "shm_svc", 2677c478bd9Sstevel@tonic-gate (void(*)(void *, uintptr_t))shm_print, 2687c478bd9Sstevel@tonic-gate sizeof (kshmid_t) 2697c478bd9Sstevel@tonic-gate }; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate ipc_ops_vec_t sem_ops_vec = { 2727c478bd9Sstevel@tonic-gate "sem", 2737c478bd9Sstevel@tonic-gate "ksemid", 2747c478bd9Sstevel@tonic-gate "sem_svc", 2757c478bd9Sstevel@tonic-gate (void(*)(void *, uintptr_t))sem_print, 2767c478bd9Sstevel@tonic-gate sizeof (ksemid_t) 2777c478bd9Sstevel@tonic-gate }; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate /* 2817c478bd9Sstevel@tonic-gate * Generic IPC data structure display code 2827c478bd9Sstevel@tonic-gate */ 2837c478bd9Sstevel@tonic-gate static int 2847c478bd9Sstevel@tonic-gate ds_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 2857c478bd9Sstevel@tonic-gate ipc_ops_vec_t *iv) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate void *iddata; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) { 2907c478bd9Sstevel@tonic-gate uint_t oflags = 0; 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'l', MDB_OPT_SETBITS, 1, &oflags, 2937c478bd9Sstevel@tonic-gate NULL) != argc) 2947c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd(iv->iv_wcmd, oflags ? iv->iv_ocmd : "ipcperm", 2977c478bd9Sstevel@tonic-gate argc, argv) == -1) { 2987c478bd9Sstevel@tonic-gate mdb_warn("can't walk '%s'", iv->iv_wcmd); 2997c478bd9Sstevel@tonic-gate return (DCMD_ERR); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate return (DCMD_OK); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate iddata = mdb_alloc(iv->iv_idsize, UM_SLEEP | UM_GC); 3057c478bd9Sstevel@tonic-gate if (mdb_vread(iddata, iv->iv_idsize, addr) == -1) { 3067c478bd9Sstevel@tonic-gate mdb_warn("failed to read %s at %#lx", iv->iv_ocmd, addr); 3077c478bd9Sstevel@tonic-gate return (DCMD_ERR); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate if (!DCMD_HDRSPEC(flags) && iv->iv_print) 3117c478bd9Sstevel@tonic-gate mdb_printf("\n"); 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) || iv->iv_print) 3147c478bd9Sstevel@tonic-gate ipcperm_header(); 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate ipcperm_print(addr, (struct kipc_perm *)iddata); 3177c478bd9Sstevel@tonic-gate if (iv->iv_print) { 3187c478bd9Sstevel@tonic-gate mdb_inc_indent(CMN_INDENT); 3197c478bd9Sstevel@tonic-gate iv->iv_print(iddata, addr); 3207c478bd9Sstevel@tonic-gate mdb_dec_indent(CMN_INDENT); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate return (DCMD_OK); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate /* 3287c478bd9Sstevel@tonic-gate * Stubs to call ds_print with the appropriate ops vector 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate static int 3317c478bd9Sstevel@tonic-gate cmd_kshmid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 3327c478bd9Sstevel@tonic-gate { 3337c478bd9Sstevel@tonic-gate return (ds_print(addr, flags, argc, argv, &shm_ops_vec)); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate static int 3387c478bd9Sstevel@tonic-gate cmd_kmsqid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 3397c478bd9Sstevel@tonic-gate { 3407c478bd9Sstevel@tonic-gate return (ds_print(addr, flags, argc, argv, &msq_ops_vec)); 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate static int 3447c478bd9Sstevel@tonic-gate cmd_ksemid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 3457c478bd9Sstevel@tonic-gate { 3467c478bd9Sstevel@tonic-gate return (ds_print(addr, flags, argc, argv, &sem_ops_vec)); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* 3507c478bd9Sstevel@tonic-gate * Generic IPC walker 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate static int 3547c478bd9Sstevel@tonic-gate ds_walk_init(mdb_walk_state_t *wsp) 3557c478bd9Sstevel@tonic-gate { 3567c478bd9Sstevel@tonic-gate ipc_ops_vec_t *iv = wsp->walk_arg; 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate if (wsp->walk_arg != NULL && wsp->walk_addr != NULL) 3597c478bd9Sstevel@tonic-gate mdb_printf("ignoring provided address\n"); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if (wsp->walk_arg) 3627c478bd9Sstevel@tonic-gate if (mdb_readvar(&wsp->walk_addr, iv->iv_service) == -1) { 3637c478bd9Sstevel@tonic-gate mdb_printf("failed to read '%s'; module not present\n", 3647c478bd9Sstevel@tonic-gate iv->iv_service); 3657c478bd9Sstevel@tonic-gate return (WALK_DONE); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate else 3687c478bd9Sstevel@tonic-gate wsp->walk_addr = wsp->walk_addr + 3697c478bd9Sstevel@tonic-gate OFFSETOF(ipc_service_t, ipcs_usedids); 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if (mdb_layered_walk("list", wsp) == -1) 3727c478bd9Sstevel@tonic-gate return (WALK_ERR); 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate return (WALK_NEXT); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate static int 3797c478bd9Sstevel@tonic-gate ds_walk_step(mdb_walk_state_t *wsp) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 3827c478bd9Sstevel@tonic-gate wsp->walk_cbdata)); 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate /* 3867c478bd9Sstevel@tonic-gate * Generic IPC ID/key to pointer code 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate static int 3907c478bd9Sstevel@tonic-gate ipcid_impl(uintptr_t svcptr, uintptr_t id, uintptr_t *addr) 3917c478bd9Sstevel@tonic-gate { 3927c478bd9Sstevel@tonic-gate ipc_service_t service; 3937c478bd9Sstevel@tonic-gate kipc_perm_t perm; 3947c478bd9Sstevel@tonic-gate ipc_slot_t slot; 3957c478bd9Sstevel@tonic-gate uintptr_t slotptr; 3967c478bd9Sstevel@tonic-gate uint_t index; 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate if (id > INT_MAX) { 3997c478bd9Sstevel@tonic-gate mdb_warn("id out of range\n"); 4007c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate if (mdb_vread(&service, sizeof (ipc_service_t), svcptr) == -1) { 4047c478bd9Sstevel@tonic-gate mdb_warn("failed to read ipc_service_t at %#lx", svcptr); 4057c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate index = (uint_t)id & (service.ipcs_tabsz - 1); 4097c478bd9Sstevel@tonic-gate slotptr = (uintptr_t)(service.ipcs_table + index); 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate if (mdb_vread(&slot, sizeof (ipc_slot_t), slotptr) == -1) { 4127c478bd9Sstevel@tonic-gate mdb_warn("failed to read ipc_slot_t at %#lx", slotptr); 4137c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate if (slot.ipct_data == NULL) 4177c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate if (mdb_vread(&perm, sizeof (kipc_perm_t), 4207c478bd9Sstevel@tonic-gate (uintptr_t)slot.ipct_data) == -1) { 4217c478bd9Sstevel@tonic-gate mdb_warn("failed to read kipc_perm_t at %#p", 4227c478bd9Sstevel@tonic-gate slot.ipct_data); 4237c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate if (perm.ipc_id != (uint_t)id) 4277c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate *addr = (uintptr_t)slot.ipct_data; 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate return (DCMD_OK); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate typedef struct findkey_data { 4367c478bd9Sstevel@tonic-gate key_t fk_key; 4377c478bd9Sstevel@tonic-gate uintptr_t fk_addr; 4387c478bd9Sstevel@tonic-gate boolean_t fk_found; 4397c478bd9Sstevel@tonic-gate } findkey_data_t; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate static int 4427c478bd9Sstevel@tonic-gate findkey(uintptr_t addr, kipc_perm_t *perm, findkey_data_t *arg) 4437c478bd9Sstevel@tonic-gate { 4447c478bd9Sstevel@tonic-gate if (perm->ipc_key == arg->fk_key) { 4457c478bd9Sstevel@tonic-gate arg->fk_found = B_TRUE; 4467c478bd9Sstevel@tonic-gate arg->fk_addr = addr; 4477c478bd9Sstevel@tonic-gate return (WALK_DONE); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate return (WALK_NEXT); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate static int 4537c478bd9Sstevel@tonic-gate ipckey_impl(uintptr_t svcptr, uintptr_t key, uintptr_t *addr) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate ipc_service_t service; 4567c478bd9Sstevel@tonic-gate findkey_data_t fkdata; 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate if ((key == IPC_PRIVATE) || (key > INT_MAX)) { 4597c478bd9Sstevel@tonic-gate mdb_warn("key out of range\n"); 4607c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if (mdb_vread(&service, sizeof (ipc_service_t), svcptr) == -1) { 4647c478bd9Sstevel@tonic-gate mdb_warn("failed to read ipc_service_t at %#lx", svcptr); 4657c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate fkdata.fk_key = (key_t)key; 4697c478bd9Sstevel@tonic-gate fkdata.fk_found = B_FALSE; 4707c478bd9Sstevel@tonic-gate if ((mdb_pwalk("avl", (mdb_walk_cb_t)findkey, &fkdata, 4717c478bd9Sstevel@tonic-gate svcptr + OFFSETOF(ipc_service_t, ipcs_keys)) == -1) || 4727c478bd9Sstevel@tonic-gate !fkdata.fk_found) 4737c478bd9Sstevel@tonic-gate return (DCMD_ERR); 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate *addr = fkdata.fk_addr; 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate return (DCMD_OK); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate static int 4817c478bd9Sstevel@tonic-gate ipckeyid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 4827c478bd9Sstevel@tonic-gate int(*fp)(uintptr_t, uintptr_t, uintptr_t *)) 4837c478bd9Sstevel@tonic-gate { 4847c478bd9Sstevel@tonic-gate uintmax_t val; 4857c478bd9Sstevel@tonic-gate uintptr_t raddr; 4867c478bd9Sstevel@tonic-gate int result; 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || (argc != 1)) 4897c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate if (argv[0].a_type == MDB_TYPE_IMMEDIATE) 4927c478bd9Sstevel@tonic-gate val = argv[0].a_un.a_val; 4937c478bd9Sstevel@tonic-gate else if (argv[0].a_type == MDB_TYPE_STRING) 4947c478bd9Sstevel@tonic-gate val = mdb_strtoull(argv[0].a_un.a_str); 4957c478bd9Sstevel@tonic-gate else 4967c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate result = fp(addr, val, &raddr); 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate if (result == DCMD_OK) 5017c478bd9Sstevel@tonic-gate mdb_printf("%lx", raddr); 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate return (result); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate static int 5077c478bd9Sstevel@tonic-gate ipckey(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5087c478bd9Sstevel@tonic-gate { 5097c478bd9Sstevel@tonic-gate return (ipckeyid(addr, flags, argc, argv, ipckey_impl)); 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate static int 5137c478bd9Sstevel@tonic-gate ipcid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5147c478bd9Sstevel@tonic-gate { 5157c478bd9Sstevel@tonic-gate return (ipckeyid(addr, flags, argc, argv, ipcid_impl)); 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate static int 5197c478bd9Sstevel@tonic-gate ds_ptr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 5207c478bd9Sstevel@tonic-gate ipc_ops_vec_t *iv) 5217c478bd9Sstevel@tonic-gate { 5227c478bd9Sstevel@tonic-gate uint_t kflag = FALSE; 5237c478bd9Sstevel@tonic-gate uintptr_t svcptr, raddr; 5247c478bd9Sstevel@tonic-gate int result; 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) 5277c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv, 5307c478bd9Sstevel@tonic-gate 'k', MDB_OPT_SETBITS, TRUE, &kflag, NULL) != argc) 5317c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate if (mdb_readvar(&svcptr, iv->iv_service) == -1) { 5347c478bd9Sstevel@tonic-gate mdb_warn("failed to read '%s'; module not present\n", 5357c478bd9Sstevel@tonic-gate iv->iv_service); 5367c478bd9Sstevel@tonic-gate return (DCMD_ERR); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate result = kflag ? ipckey_impl(svcptr, addr, &raddr) : 5407c478bd9Sstevel@tonic-gate ipcid_impl(svcptr, addr, &raddr); 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate if (result == DCMD_OK) 5437c478bd9Sstevel@tonic-gate mdb_printf("%lx", raddr); 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate return (result); 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate /* 5497c478bd9Sstevel@tonic-gate * Stubs to call ds_ptr with the appropriate ops vector 5507c478bd9Sstevel@tonic-gate */ 5517c478bd9Sstevel@tonic-gate static int 5527c478bd9Sstevel@tonic-gate id2shm(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5537c478bd9Sstevel@tonic-gate { 5547c478bd9Sstevel@tonic-gate return (ds_ptr(addr, flags, argc, argv, &shm_ops_vec)); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate static int 5587c478bd9Sstevel@tonic-gate id2msq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5597c478bd9Sstevel@tonic-gate { 5607c478bd9Sstevel@tonic-gate return (ds_ptr(addr, flags, argc, argv, &msq_ops_vec)); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate static int 5647c478bd9Sstevel@tonic-gate id2sem(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5657c478bd9Sstevel@tonic-gate { 5667c478bd9Sstevel@tonic-gate return (ds_ptr(addr, flags, argc, argv, &sem_ops_vec)); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate /* 5717c478bd9Sstevel@tonic-gate * The message queue contents walker 5727c478bd9Sstevel@tonic-gate */ 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate static int 5757c478bd9Sstevel@tonic-gate msg_walk_init(mdb_walk_state_t *wsp) 5767c478bd9Sstevel@tonic-gate { 5777c478bd9Sstevel@tonic-gate wsp->walk_addr += OFFSETOF(kmsqid_t, msg_list); 5787c478bd9Sstevel@tonic-gate if (mdb_layered_walk("list", wsp) == -1) 5797c478bd9Sstevel@tonic-gate return (WALK_ERR); 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate return (WALK_NEXT); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate static int 5857c478bd9Sstevel@tonic-gate msg_walk_step(mdb_walk_state_t *wsp) 5867c478bd9Sstevel@tonic-gate { 5877c478bd9Sstevel@tonic-gate return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 5887c478bd9Sstevel@tonic-gate wsp->walk_cbdata)); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate /* 5927c478bd9Sstevel@tonic-gate * The "::ipcs" command itself. Just walks each IPC type in turn. 5937c478bd9Sstevel@tonic-gate */ 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 5967c478bd9Sstevel@tonic-gate static int 5977c478bd9Sstevel@tonic-gate ipcs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 5987c478bd9Sstevel@tonic-gate { 5997c478bd9Sstevel@tonic-gate uint_t oflags = 0; 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate if ((flags & DCMD_ADDRSPEC) || mdb_getopts(argc, argv, 'l', 6027c478bd9Sstevel@tonic-gate MDB_OPT_SETBITS, 1, &oflags, NULL) != argc) 6037c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate mdb_printf("Message queues:\n"); 6067c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("msq", oflags ? "kmsqid" : "ipcperm", argc, argv) == 6077c478bd9Sstevel@tonic-gate -1) { 6087c478bd9Sstevel@tonic-gate mdb_warn("can't walk 'msq'"); 6097c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate mdb_printf("\nShared memory:\n"); 6137c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("shm", oflags ? "kshmid" : "ipcperm", argc, argv) == 6147c478bd9Sstevel@tonic-gate -1) { 6157c478bd9Sstevel@tonic-gate mdb_warn("can't walk 'shm'"); 6167c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate mdb_printf("\nSemaphores:\n"); 6207c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("sem", oflags ? "ksemid" : "ipcperm", argc, argv) == 6217c478bd9Sstevel@tonic-gate -1) { 6227c478bd9Sstevel@tonic-gate mdb_warn("can't walk 'sem'"); 6237c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6247c478bd9Sstevel@tonic-gate } 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate return (DCMD_OK); 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate static int 6307c478bd9Sstevel@tonic-gate msgprint(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 6317c478bd9Sstevel@tonic-gate { 6327c478bd9Sstevel@tonic-gate struct msg message; 6337c478bd9Sstevel@tonic-gate uint_t lflag = FALSE; 6347c478bd9Sstevel@tonic-gate long type = 0; 6357c478bd9Sstevel@tonic-gate char *tflag = NULL; 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) || (mdb_getopts(argc, argv, 6387c478bd9Sstevel@tonic-gate 'l', MDB_OPT_SETBITS, TRUE, &lflag, 6397c478bd9Sstevel@tonic-gate 't', MDB_OPT_STR, &tflag, NULL) != argc)) 6407c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate /* 6437c478bd9Sstevel@tonic-gate * Handle negative values. 6447c478bd9Sstevel@tonic-gate */ 6457c478bd9Sstevel@tonic-gate if (tflag != NULL) { 6467c478bd9Sstevel@tonic-gate if (*tflag == '-') { 6477c478bd9Sstevel@tonic-gate tflag++; 6487c478bd9Sstevel@tonic-gate type = -1; 6497c478bd9Sstevel@tonic-gate } else { 6507c478bd9Sstevel@tonic-gate type = 1; 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate type *= mdb_strtoull(tflag); 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) 6567c478bd9Sstevel@tonic-gate mdb_printf("%<u>%?s %?s %8s %8s %8s%</u>\n", 6577c478bd9Sstevel@tonic-gate "ADDR", "TEXT", "SIZE", "TYPE", "REF"); 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate if (mdb_vread(&message, sizeof (struct msg), addr) == -1) { 6607c478bd9Sstevel@tonic-gate mdb_warn("failed to read msg at %#lx", addr); 6617c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate /* 6657c478bd9Sstevel@tonic-gate * If we are meeting our type contraints, display the message. 6667c478bd9Sstevel@tonic-gate * If -l was specified, we will also display the message 6677c478bd9Sstevel@tonic-gate * contents. 6687c478bd9Sstevel@tonic-gate */ 6697c478bd9Sstevel@tonic-gate if ((type == 0) || 6707c478bd9Sstevel@tonic-gate (type > 0 && message.msg_type == type) || 6717c478bd9Sstevel@tonic-gate (type < 0 && message.msg_type <= -type)) { 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate if (lflag && !DCMD_HDRSPEC(flags)) 6747c478bd9Sstevel@tonic-gate mdb_printf("\n"); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate mdb_printf("%0?lx %?p %8ld %8ld %8ld\n", addr, message.msg_addr, 6777c478bd9Sstevel@tonic-gate message.msg_size, message.msg_type, message.msg_copycnt); 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate if (lflag) { 6807c478bd9Sstevel@tonic-gate mdb_printf("\n"); 6817c478bd9Sstevel@tonic-gate mdb_inc_indent(CMN_INDENT); 6827c478bd9Sstevel@tonic-gate if (mdb_dumpptr( 6837c478bd9Sstevel@tonic-gate (uintptr_t)message.msg_addr, message.msg_size, 6847c478bd9Sstevel@tonic-gate MDB_DUMP_RELATIVE | MDB_DUMP_TRIM | 6857c478bd9Sstevel@tonic-gate MDB_DUMP_ASCII | MDB_DUMP_HEADER | 6867c478bd9Sstevel@tonic-gate MDB_DUMP_GROUP(4), 6877c478bd9Sstevel@tonic-gate (mdb_dumpptr_cb_t)mdb_vread, NULL)) { 6887c478bd9Sstevel@tonic-gate mdb_dec_indent(CMN_INDENT); 6897c478bd9Sstevel@tonic-gate return (DCMD_ERR); 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate mdb_dec_indent(CMN_INDENT); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate return (DCMD_OK); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate /* 6997c478bd9Sstevel@tonic-gate * MDB module linkage 7007c478bd9Sstevel@tonic-gate */ 7017c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 7027c478bd9Sstevel@tonic-gate /* Generic routines */ 7037c478bd9Sstevel@tonic-gate { "ipcperm", ":", "display an IPC perm structure", ipcperm }, 7047c478bd9Sstevel@tonic-gate { "ipcid", ":id", "perform an IPC id lookup", ipcid }, 7057c478bd9Sstevel@tonic-gate { "ipckey", ":key", "perform an IPC key lookup", ipckey }, 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate /* Specific routines */ 7087c478bd9Sstevel@tonic-gate { "kshmid", "?[-l]", "display a struct kshmid", cmd_kshmid }, 7097c478bd9Sstevel@tonic-gate { "kmsqid", "?[-l]", "display a struct kmsqid", cmd_kmsqid }, 7107c478bd9Sstevel@tonic-gate { "ksemid", "?[-l]", "display a struct ksemid", cmd_ksemid }, 7117c478bd9Sstevel@tonic-gate { "msg", ":[-l] [-t type]", "display contents of a message", msgprint }, 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate /* Convenience routines */ 7147c478bd9Sstevel@tonic-gate { "id2shm", ":[-k]", "convert shared memory ID to pointer", id2shm }, 7157c478bd9Sstevel@tonic-gate { "id2msq", ":[-k]", "convert message queue ID to pointer", id2msq }, 7167c478bd9Sstevel@tonic-gate { "id2sem", ":[-k]", "convert semaphore ID to pointer", id2sem }, 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate { "ipcs", "[-l]", "display System V IPC information", ipcs }, 7197c478bd9Sstevel@tonic-gate { NULL } 7207c478bd9Sstevel@tonic-gate }; 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 7237c478bd9Sstevel@tonic-gate { "ipcsvc", "walk a System V IPC service", 7247c478bd9Sstevel@tonic-gate ds_walk_init, ds_walk_step }, 7257c478bd9Sstevel@tonic-gate { "shm", "walk the active shmid_ds structures", 7267c478bd9Sstevel@tonic-gate ds_walk_init, ds_walk_step, NULL, &shm_ops_vec }, 7277c478bd9Sstevel@tonic-gate { "msq", "walk the active msqid_ds structures", 7287c478bd9Sstevel@tonic-gate ds_walk_init, ds_walk_step, NULL, &msq_ops_vec }, 7297c478bd9Sstevel@tonic-gate { "sem", "walk the active semid_ds structures", 7307c478bd9Sstevel@tonic-gate ds_walk_init, ds_walk_step, NULL, &sem_ops_vec }, 7317c478bd9Sstevel@tonic-gate { "msgqueue", "walk messages on a message queue", 7327c478bd9Sstevel@tonic-gate msg_walk_init, msg_walk_step }, 7337c478bd9Sstevel@tonic-gate { NULL } 7347c478bd9Sstevel@tonic-gate }; 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate const mdb_modinfo_t * 7397c478bd9Sstevel@tonic-gate _mdb_init(void) 7407c478bd9Sstevel@tonic-gate { 7417c478bd9Sstevel@tonic-gate return (&modinfo); 7427c478bd9Sstevel@tonic-gate } 743