#ident "$Header: /proj/irix6.5.7m/isms/irix/cmd/icrash/RCS/struct.c,v 1.3 1999/11/09 16:15:55 lucc Exp $" #include #define _KERNEL 0 #include #include #include #include #undef _KERNEL #include #include #include #include #include #include "icrash.h" /* XXX - 'TIL we get the current root/toolroot */ #ifndef NSCHEDCLASS #define NSCHEDCLASS (-(PWEIGHTLESS)+1) #endif #define INODE_TO_BHP(ip) \ ((k_ptr_t)((unsigned)ip + kl_member_offset("inode", "i_bhv_desc"))) #define XFS_INODE_TO_BHP(xip) \ ((k_ptr_t)((unsigned)xip + kl_member_offset("xfs_inode", "i_bhv_desc"))) #define LSNODE_TO_BHP(lsp) \ ((k_ptr_t)((unsigned)lsp + kl_member_offset("lsnode", "ls_bhv_desc"))) #define CSNODE_TO_BHP(csp) \ ((k_ptr_t)((unsigned)csp + kl_member_offset("csnode", "cs_bhv_desc"))) #define RNODE_TO_BHP(rp) \ ((k_ptr_t)((unsigned)rp + kl_member_offset("rnode", "r_bhv_desc"))) /* * Just a reminder: All the below address space macros take arguments which * are pointers in icrash process address space and not in kernel address * space. -- which is the same as k_ptr_t. * We use KL_* for any macro which is also defined by the kernel. */ #define UT_ASID(ut) ((k_ptr_t)((__psunsigned_t)ut + \ (__psunsigned_t)kl_member_offset("uthread_s","ut_asid"))) #define KL_ASID_TO_VAS(asid) ((kaddr_t)kl_kaddr(asid,"asid_t","as_obj")) #define KL_ASID_TO_PASID(asid) ((kaddr_t)kl_kaddr(asid,"asid_t","as_pasid")) #define KL_AS_ISNULL(asid) ((kaddr_t)KL_ASID_TO_VAS(asid) == (kaddr_t)0xf) /* our own macro. BHVH -- behavior head. */ #define VAS_TO_BHVH(vas) ((k_ptr_t)((__psunsigned_t)vas + \ (__psunsigned_t)kl_member_offset("vas_s","vas_bhvh"))) #define KL_BHV_HEAD_FIRST(bhvh) ((kaddr_t)kl_kaddr(bhvh,"bhv_head","bh_first")) #define KL_BHV_PDATA(bhv) ((kaddr_t)kl_kaddr(bhv,"bhv_desc","bd_pdata")) #define KL_BHV_OPS(bhv) ((kaddr_t)kl_kaddr(bhv,"bhv_desc","bd_ops")) #define KL_BHV_VOBJ(bhv) ((kaddr_t)kl_kaddr(bhv,"bhv_desc","bd_vobj")) #define KL_BHV_TO_PAS(bhv) ((kaddr_t)KL_BHV_PDATA(bhv)) #define KL_BHV_TO_VAS(bhv) ((kaddr_t)KL_BHV_VOBJ(bhv)) #define KL_PREG_FIRST(pregion_set) \ ((kaddr_t)kl_kaddr(pregion_set,"preg_set_t","avl_firstino")) /* * We can assume the pregion is the same as the avlnode... because the first * field in the pregion is the avlnode.. This won't change any time soon. */ #define KL_PREG_NEXT(pregion) \ ((kaddr_t)kl_kaddr(pregion,"avlnode_t","avl_nextino")) #define PAS_TO_PREG_SET(pas) ((k_ptr_t)((__psunsigned_t)(pas) + \ (__psunsigned_t)kl_member_offset("pas_s","pas_pregions"))) #define PPAS_TO_PREG_SET(ppas) ((k_ptr_t)((__psunsigned_t)(ppas) + \ (__psunsigned_t)kl_member_offset("ppas_s","ppas_pregions"))) typedef struct stype_s { char *name; /* struct name */ int size; /* struct size */ int links; /* struct contains linked list pointer(s) */ void (*banner)(FILE *, int); /* struct banner function */ int (*print)(kaddr_t, k_ptr_t, int, FILE *); /* struct print routine */ } stype_t; stype_t Struct[] = { /*----------------------------------------------------------------------*/ /* NAME SIZE LINKS BANNER() PRINT() */ /*----------------------------------------------------------------------*/ { "avlnode", 0, 1, avlnode_banner, print_avlnode }, { "bhv_desc", 0, 1, bhv_desc_banner, print_bhv_desc }, { "buf", 0, 1, buf_banner, print_buf }, { "eframe_s", 0, 0, eframe_s_banner, print_eframe_s }, { "file", 0, 1, vfile_banner, print_vfile }, { "graph_vertex_s", 0, 0, graph_vertex_s_banner, print_graph_vertex_s }, { "inode", 0, 1, inode_banner, print_inode }, { "inpcb", 0, 1, inpcb_banner, print_inpcb }, { "inventory_s", 0, 1, inventory_s_banner, print_inventory_s }, { "kthread", 0, 1, kthread_banner, print_kthread }, { "lsnode", 0, 1, lsnode_banner, print_lsnode }, { "mbstat", 0, 0, 0, 0 }, { "mbuf", 0, 1, mbuf_banner, print_mbuf }, { "ml_info", 0, 1, ml_info_banner, print_ml_info }, { "mntinfo", 0, 1, mntinfo_banner, print_mntinfo }, { "mrlock_s", 0, 0, mrlock_s_banner, print_mrlock_s }, { "nodepda_s", 0, 0, nodepda_s_banner, print_nodepda_s }, { "pda_s", 0, 0, pda_s_banner, print_pda_s }, { "pde", 0, 0, pde_banner, 0 }, { "pfdat", 0, 1, pfdat_banner, print_pfdat }, { "pid_entry", 0, 1, pid_entry_banner, print_pid_entry }, { "pmap", 0, 0, pmap_banner, print_pmap }, { "pregion", 0, 1, pregion_banner, print_pregion }, { "proc", 0, 1, proc_banner, print_proc }, { "queue", 0, 1, queue_banner, 0 }, { "region", 0, 1, region_banner, print_region }, { "rnode", 0, 1, rnode_banner, print_rnode }, { "sema_s", 0, 1, sema_s_banner, print_sema_s }, { "socket", 0, 1, socket_banner, 0 }, { "sthread_s", 0, 1, sthread_s_banner, print_sthread_s }, { "stdata", 0, 1, stream_banner, 0 }, { "swapinfo", 0, 0, swapinfo_banner, 0 }, { "tcpcb", 0, 0, tcpcb_banner, print_tcpcb }, { "unpcb", 0, 1, unpcb_banner, print_unpcb }, { "uthread_s", 0, 1, uthread_s_banner, print_uthread_s }, { "vfs", 0, 0, vfs_banner, 0 }, { "vfssw", 0, 0, vfssw_banner, 0 }, { "vnode", 0, 1, vnode_banner, print_vnode }, { "vproc", 0, 1, vproc_banner, print_vproc }, { "vsocket", 0, 1, vsocket_banner, print_vsocket }, { "xfs_inode", 0, 1, xfs_inode_banner, print_xfs_inode }, { "zone", 0, 1, zone_banner, print_zone }, { (char *)0, 0, 0, 0, 0 } }; /* * init_struct_table() */ void init_struct_table() { int i = 0; /* All we need to do is set the stuct sizes */ while(Struct[i].name) { Struct[i].size = kl_struct_len(Struct[i].name); i++; } } /* * struct_index() */ int struct_index(char *s) { int i = 0; while(Struct[i].name) { if (!strcmp(s, Struct[i].name)) { return(i); } i++; } return(-1); } /* * struct_banner() */ void struct_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, "NAME MEMBER " "NEXT SIZE OFFSET\n"); } else { fprintf(ofp, "NAME " " SIZE\n"); } } if (flags & SMAJOR) { if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, "====================================================" "============\n"); } else { fprintf(ofp, "====================================================" "===========\n"); } } if (flags & SMINOR) { if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, "----------------------------------------------------" "------------\n"); } else { fprintf(ofp, "----------------------------------------------------" "-----------\n"); } } } /* * print_struct() */ void print_struct(symdef_t *sdp, int flags, FILE *ofp) { symdef_t *sfp; if (DEBUG(DC_FUNCTRACE, 3)) { fprintf(ofp, "print_struct: sdp=0x%x\n", sdp); } if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, "%-30s %8x %8x %4d %6d\n", sdp->sd_name, sdp->sd_member, sdp->sd_next, sdp->sd_size, sdp->sd_offset); } else { fprintf(ofp, "%-38s %4d\n", sdp->sd_name, sdp->sd_size); } if (flags & C_FULL) { if (sfp = sdp->sd_member) { fprintf(ofp, "\n"); fprintf(ofp, " FIELD_NAME SIZE OFFSET " "BIT_OFF BIT_SIZE\n"); fprintf(ofp, " ---------- ---- ------ " "------- --------\n"); while (sfp) { if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, "%30s %8x %8x %4d %6d\n", sfp->sd_name, sfp->sd_member, sfp->sd_next, sfp->sd_size, sfp->sd_offset); } else { fprintf(ofp, "%30s %4d %6d %7d %8d\n", sfp->sd_name, sfp->sd_size, sfp->sd_offset, sfp->sd_bit_offset, sfp->sd_bit_size); } sfp = sfp->sd_member; } } else { fprintf(ofp, "\n"); } } } /* * structlist_banner() */ void structlist_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, "NUM NAME SIZE LINKS\n"); } if (flags & SMAJOR) { fprintf(ofp, "===================================\n"); } } /* * structlist() */ void structlist(FILE *ofp) { int i = 0; structlist_banner(ofp, BANNER|SMAJOR); while(Struct[i].name) { fprintf(ofp, "%3d %-16s %5d ", i, Struct[i].name, Struct[i].size); if (Struct[i].links) { fprintf(ofp, " YES\n"); } else { fprintf(ofp, " NO\n"); } i++; } structlist_banner(ofp, SMAJOR); } /* * struct_print() -- print out an arbitrary struct at addr */ int struct_print(char *s, kaddr_t addr, int flags, FILE *ofp) { int sid, size, count, firsttime = 1; k_ptr_t ptr; /* Make sure we have the right number of paramaters */ if (!s || !addr) { KL_SET_ERROR(KLE_BAD_STRUCT); return(1); } /* Get the index for struct name */ if ((sid = struct_index(s)) == -1) { KL_SET_ERROR_CVAL(KLE_BAD_STRUCT, s); return(1); } /* Get the struct size */ size = Struct[sid].size; if (!Struct[sid].banner) { fprintf(ofp, "%s: can't print struct banner\n", Struct[sid].name); return(1); } (*Struct[sid].banner)(ofp, BANNER|SMAJOR); /* Get an appropriately sized block of memory and load the contents * of the structure into it. */ ptr = kl_alloc_block(size, K_TEMP); kl_get_struct(addr, size, ptr, Struct[sid].name); if (KL_ERROR) { KL_ERROR |= KLE_BAD_STRUCT; return(1); } if (Struct[sid].print) { (*Struct[sid].print)(addr, ptr, flags, ofp); } else { fprintf(ofp, "%s: can't print struct\n", Struct[sid].name); } (*Struct[sid].banner)(ofp, SMAJOR); kl_free_block(ptr); return(0); } /* * walk_structs() -- walk linked lists of kernel data structures */ int walk_structs(char *s, char *f, int offset, kaddr_t addr, int flags, FILE *ofp) { int sid, size, count, firsttime = 1; kaddr_t last, next; k_ptr_t ptr; if (DEBUG(DC_FUNCTRACE, 3)) { fprintf(ofp, "walk_structs: s=%s, f=%s, offset=%d, addr=0x%llx, " "flags=0x%x, ofp=0x%x", s, f, offset, addr, flags, ofp); } /* Make sure we have the right number of paramaters */ if (!s || (!f && (offset == -1)) || !addr) { KL_SET_ERROR(KLE_BAD_STRUCT); return(1); } /* If we were passed a field name, determine its offset in the * struct. */ if (offset == -1) { if ((offset = kl_member_offset(s, f)) == -1) { KL_SET_ERROR_CVAL(KLE_BAD_FIELD, f); return(1); } } /* If the C_STRUCT flag is set, then print the structure in C-like * struct format. */ if (flags & C_STRUCT) { /* Get the struct size */ if ((size = kl_struct_len(s)) == 0) { KL_SET_ERROR(KLE_BAD_STRUCT); return(1); } next = addr; ptr = kl_alloc_block(size, K_TEMP); while(next) { kl_get_struct(next, size, ptr, s); if (KL_ERROR) { /* XXX -- should get struct specific error code from * some sort of struct_error() routine */ KL_ERROR |= KLE_BAD_STRUCT; kl_free_block(ptr); return(1); } dw_print_struct(s, next, ptr, flags, ofp); last = next; kl_get_kaddr(next+offset, &next, Struct[sid].name); if (KL_ERROR || (next == addr) || (next == last)) { break; } } kl_free_block(ptr); return(0); } /* Get the index for struct name */ if ((sid = struct_index(s)) == -1) { KL_SET_ERROR_CVAL(KLE_BAD_STRUCT, s); return(1); } /* Make sure the struct we selected has links we can follow */ if (!Struct[sid].links) { KL_SET_ERROR_CVAL(E_NO_LINKS, Struct[sid].name); return(1); } /* Get the struct size */ size = Struct[sid].size; if (size == 0) { if ((size = kl_struct_len(s)) == 0) { KL_SET_ERROR(KLE_BAD_STRUCT); return(1); } /* We must have added this type after startup (via another namelist). * So, set the size value for future reference. */ Struct[sid].size = size; } if (DEBUG(DC_STRUCT, 1)) { fprintf(ofp, "struct=%s, offset=%d, addr=0x%llx", s, offset, addr); } if (next = addr) { (*Struct[sid].banner)(ofp, BANNER|SMAJOR); } while(next) { ptr = kl_alloc_block(size, K_TEMP); kl_get_struct(next, size, ptr, Struct[sid].name); if (KL_ERROR) { /* XXX -- should get struct specific error code from some sort of * struct_error() routine */ KL_ERROR |= KLE_BAD_STRUCT; return(1); } else { if (DEBUG(DC_GLOBAL, 1) || (flags & C_FULL)) { if (!firsttime) { (*Struct[sid].banner)(ofp, BANNER|SMAJOR); } else { firsttime = 0; } } } if (Struct[sid].print) { (*Struct[sid].print)(next, ptr, flags, ofp); } else { fprintf(ofp, "%s: can't print struct\n", Struct[sid].name); } last = next; kl_get_kaddr(next+offset, &next, Struct[sid].name); if (KL_ERROR || (next == addr) || (next == last)) { break; } } (*Struct[sid].banner)(ofp, SMAJOR); kl_free_block(ptr); return(0); } /* * Print the flags with correct indentation */ void print_flags(int *firsttime,const char *str,char *indent,FILE *ofp) { if(!*firsttime) { fprintf(ofp, "%s", str); *firsttime = 1; } else { fprintf(ofp, "|%s", str); } if(!(*firsttime%5)) { fprintf(ofp, "\n%s\t", indent); } } /* * avlnode_banner() -- Print out banner information for avlnode structure */ void avlnode_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " AVLNODE FORW BACK " " PARENT\n"); } if (flags & SMAJOR) { fprintf(ofp, "======================================================" "================\n"); } if (flags & SMINOR) { fprintf(ofp, "------------------------------------------------------" "----------------\n"); } } /* * print_avlnode() -- Print out specific information in an avlnode sturct */ int print_avlnode(kaddr_t avl, k_ptr_t avlp, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_avlnode: avl=0x%llx, avlp=0x%x, flags=0x%x\n", avl, avlp, flags); } fprintf(ofp, "%16llx %16llx %16llx %16llx\n", avl, kl_kaddr(avlp, "avlnode", "avl_forw"), kl_kaddr(avlp, "avlnode", "avl_back"), kl_kaddr(avlp, "avlnode", "avl_parent")); if (flags & C_FULL) { fprintf(ofp, "AVL_NEXTINO=0x%llx, AVL_BALANCE=%lld\n", kl_kaddr(avlp, "avlnode", "avl_nextino"), KL_INT(avlp, "avlnode", "avl_balance")); fprintf(ofp, "\n"); } return(1); } /* * bhv_desc_banner() */ void bhv_desc_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " BHV PDATA " "VOBJ NEXT\n"); } if (flags & SMAJOR) { fprintf(ofp, "================================================" "======================\n"); } if (flags & SMINOR) { fprintf(ofp, "------------------------------------------------" "----------------------\n"); } } /* * print_bhv_desc() */ int print_bhv_desc(kaddr_t bhv, k_ptr_t bhvp, int flags, FILE *ofp) { fprintf(ofp, "%16llx %16llx %16llx %16llx\n", bhv, kl_kaddr(bhvp, "bhv_desc", "bd_pdata"), kl_kaddr(bhvp, "bhv_desc", "bd_vobj"), kl_kaddr(bhvp, "bhv_desc", "bd_next")); if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, " BD_OPS=0x%llx\n", kl_kaddr(bhvp, "bhv_desc", "bd_ops")); fprintf(ofp, "\n"); } return(1); } /* * buf_banner() */ void buf_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " BUF EDEV PROC/VP " "BCOUNT FLAGS\n"); } if (flags & SMAJOR) { fprintf(ofp, "================================================" "================\n"); } if (flags & SMINOR) { fprintf(ofp, "------------------------------------------------" "----------------\n"); } } /* * print_buf() */ int print_buf(kaddr_t buf, k_ptr_t bufp, int flags, FILE *ofp) { fprintf(ofp, "%16llx %8llx %16llx %8llu %8llx\n", buf, KL_UINT(bufp, "buf", "b_edev"), kl_kaddr(bufp, "buf", "b_obj"), KL_UINT(bufp, "buf", "b_bcount"), KL_INT(bufp, "buf", "b_flags")); if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, " B_FORW=0x%llx, B_BACK=0x%llx\n", kl_kaddr(bufp, "buf", "b_forw"), kl_kaddr(bufp, "buf", "b_back")); fprintf(ofp, " AV_FORW=0x%llx, AV_BACK=0x%llx\n", kl_kaddr(bufp, "buf", "av_forw"), kl_kaddr(bufp, "buf", "av_back")); fprintf(ofp, " B_DFORW=0x%llx, B_DBACK=0x%llx\n", kl_kaddr(bufp, "buf", "b_dforw"), kl_kaddr(bufp, "buf", "b_dback")); fprintf(ofp, " B_UN=0x%llx, B_PAGES=0x%llx\n", kl_kaddr(bufp, "buf", "b_un"), kl_kaddr(bufp, "buf", "b_pages")); fprintf(ofp, " B_BLKNO=%lld\n", KL_INT(bufp, "buf", "b_blkno")); fprintf(ofp, "\n"); } return(1); } /* * eframe_s_banner() -- Print out a banner around an exception frame. */ void eframe_s_banner(FILE *ofp, int flags) { if (flags & SMAJOR) { fprintf(ofp, "=======================================" "=======================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------" "---------------------------------------\n"); } } /* * print_eframe_s() */ int print_eframe_s(kaddr_t eframe, k_ptr_t e, int flags, FILE *ofp) { if (DEBUG(DC_TRACE, 1) || DEBUG(DC_FUNCTRACE, 3)) { fprintf(KL_ERRORFP, "print_eframe_s: e=0x%x, ofp=0x%x\n", e, ofp); } fprintf(ofp, " r0/zero:0000000000000000 r1/at:%016llx " "r2/v0:%016llx\n", kl_reg(e, "eframe_s", "ef_at"), kl_reg(e, "eframe_s", "ef_v0")); fprintf(ofp, " r3/v1:%016llx r4/a0:%016llx r5/a1:%016llx\n", kl_reg(e, "eframe_s", "ef_v1"), kl_reg(e, "eframe_s", "ef_a0"), kl_reg(e, "eframe_s", "ef_a1")); /* Have to handle the differences between _MIPS_SIM_ABI32 and * _MIPS_SIM_ABI64 eframe_s definition. The effected registers are * r8 through r15. */ if (PTRSZ32) { fprintf(ofp, " r6/a2:%016llx r7/a3:%016llx r8/t0:%016llx\n", kl_reg(e, "eframe_s", "ef_a2"), kl_reg(e, "eframe_s", "ef_a3"), kl_reg(e, "eframe_s", "ef_t0")); fprintf(ofp, " r9/t1:%016llx r10/t2:%016llx r11/t3:%016llx\n", kl_reg(e, "eframe_s", "ef_t1"), kl_reg(e, "eframe_s", "ef_t2"), kl_reg(e, "eframe_s", "ef_t3")); fprintf(ofp, " r12/t4:%016llx r13/t5:%016llx r14/t6:%016llx\n", kl_reg(e, "eframe_s", "ef_t4"), kl_reg(e, "eframe_s", "ef_t5"), kl_reg(e, "eframe_s", "ef_t6")); fprintf(ofp, " r15/t7:%016llx r16/s0:%016llx r17/s1:%016llx\n", kl_reg(e, "eframe_s", "ef_t7"), kl_reg(e, "eframe_s", "ef_s0"), kl_reg(e, "eframe_s", "ef_s1")); } else { fprintf(ofp, " r6/a2:%016llx r7/a3:%016llx r8/a4:%016llx\n", kl_reg(e, "eframe_s", "ef_a2"), kl_reg(e, "eframe_s", "ef_a3"), kl_reg(e, "eframe_s", "ef_a4")); fprintf(ofp, " r9/a5:%016llx r10/a6:%016llx r11/a7:%016llx\n", kl_reg(e, "eframe_s", "ef_a5"), kl_reg(e, "eframe_s", "ef_a6"), kl_reg(e, "eframe_s", "ef_a7")); fprintf(ofp, " r12/t0:%016llx r13/t1:%016llx r14/t2:%016llx\n", kl_reg(e, "eframe_s", "ef_t0"), kl_reg(e, "eframe_s", "ef_t1"), kl_reg(e, "eframe_s", "ef_t2")); fprintf(ofp, " r15/t3:%016llx r16/s0:%016llx r17/s1:%016llx\n", kl_reg(e, "eframe_s", "ef_t3"), kl_reg(e, "eframe_s", "ef_s0"), kl_reg(e, "eframe_s", "ef_s1")); } fprintf(ofp, " r18/s2:%016llx r19/s3:%016llx r20/s4:%016llx\n", kl_reg(e, "eframe_s", "ef_s2"), kl_reg(e, "eframe_s", "ef_s3"), kl_reg(e, "eframe_s", "ef_s4")); fprintf(ofp, " r21/s5:%016llx r22/s6:%016llx r23/s7:%016llx\n", kl_reg(e, "eframe_s", "ef_s5"), kl_reg(e, "eframe_s", "ef_s6"), kl_reg(e, "eframe_s", "ef_s7")); fprintf(ofp, " r24/t8:%016llx r25/t9:%016llx r26/k0:%016llx\n", kl_reg(e, "eframe_s", "ef_t8"), kl_reg(e, "eframe_s", "ef_t9"), kl_reg(e, "eframe_s", "ef_k0")); fprintf(ofp, " r27/k1:%016llx r28/gp:%016llx r29/sp:%016llx\n", kl_reg(e, "eframe_s", "ef_k1"), kl_reg(e, "eframe_s", "ef_gp"), kl_reg(e, "eframe_s", "ef_sp")); fprintf(ofp, " r30/s8:%016llx r31/ra:%016llx EPC:%016llx\n", kl_reg(e, "eframe_s", "ef_fp"), kl_reg(e, "eframe_s", "ef_ra"), kl_reg(e, "eframe_s", "ef_epc")); fprintf(ofp, " CAUSE=%llx, SR=%llx, BADVADDR=%llx\n", kl_reg(e, "eframe_s", "ef_cause"), kl_reg(e, "eframe_s", "ef_sr"), kl_reg(e, "eframe_s", "ef_badvaddr")); return(1); } /* * get_vfile() * * This routine returns a pointer to a file struct containing the * kernel file pointed to by addr if f_count is greater than zero or * the C_ALL flag is set. */ k_ptr_t get_vfile(kaddr_t addr, k_ptr_t vfbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_vfile: addr=0x%llx, vfbufp=0x%x, flags=0x%x\n", addr, vfbufp, flags); } if (vfbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_VFILE); return((k_ptr_t)NULL); } kl_get_struct(addr, VFILE_SIZE, vfbufp, "vfile"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_VFILE; return((k_ptr_t)NULL); } else { if ((KL_INT(vfbufp, "vfile", "vf_count")) && kl_kaddr(vfbufp, "vfile", "__vf_data__")) { return(vfbufp); } else if (flags & C_ALL) { return(vfbufp); } else { KL_SET_ERROR_NVAL(KLE_BAD_VFILE, addr, 2); return((k_ptr_t)NULL); } } } /* * vfile_banner() -- Print out the banner information for each fp. */ void vfile_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " VFILE RCNT DATA BH" " FLAGS\n"); } if (flags & SMAJOR) { fprintf(ofp, "==========================================================" "==========\n"); } if (flags & SMINOR) { fprintf(ofp, "----------------------------------------------------------" "----------\n"); } } /* * print_vfile() -- Print out the data in the vfile pointer. */ int print_vfile(kaddr_t addr, k_ptr_t vfilep, int flags, FILE *ofp) { k_ptr_t vobjp; kaddr_t data; if (DEBUG(DC_FUNCTRACE, 3)) { fprintf(ofp, "print_vfile: addr=0x%llx, vfilep=0x%x, flags=0x%x\n", addr, vfilep, flags); } data = kl_kaddr(vfilep, "vfile", "__vf_data__"); fprintf(ofp, "%16llx %4lld %16llx %16llx %8llx\n", addr, KL_INT(vfilep, "vfile", "vf_count"), data, kl_kaddr(vfilep, "vfile", "vf_bh"), KL_UINT(vfilep, "vfile", "vf_flag")); if (flags & C_NEXT) { if (KL_UINT(vfilep, "vfile", "vf_flag") & FSOCKET) { vobjp = kl_alloc_block(VSOCKET_SIZE, K_TEMP); kl_get_struct(data, VSOCKET_SIZE, vobjp, "vsocket"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_VSOCKET; kl_free_block(vobjp); fprintf(ofp, "\n"); return(-1); } fprintf(ofp, "\n"); fprintf(ofp, " "); vsocket_banner(ofp, BANNER); fprintf(ofp, " "); vsocket_banner(ofp, SMINOR); flags |= C_INDENT; print_vsocket(data, vobjp, flags, ofp); } else { vobjp = kl_alloc_block(VNODE_SIZE, K_TEMP); get_vnode(data, vobjp, flags); if (KL_ERROR) { kl_free_block(vobjp); fprintf(ofp, "\n"); return(-1); } fprintf(ofp, "\n"); fprintf(ofp, " "); vnode_banner(ofp, BANNER); fprintf(ofp, " "); vnode_banner(ofp, SMINOR); flags |= C_INDENT; print_vnode(data, vobjp, flags, ofp); } kl_free_block(vobjp); fprintf(ofp, "\n"); } return(0); } /* * graph_edge_s_banner() -- Print out the banner information for each * graph_edge_s struct. */ void graph_edge_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, "EDGE LABEL NAME VERTEX\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "========================================================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "--------------------------------------------------------\n"); } } /* * print_graph_edge_s() -- Print out the data in the graph_edge_s struct. * * Note that this print routine cannot be called by the struct or walk * commands. That is because it has an extra paramater (i). This was * necessary because there was no other way to determine the edge index. * You have to know what the vertex is in order to determine that (which * would also have required a non-standard set of parameters). */ int print_graph_edge_s(int i, kaddr_t addr, k_ptr_t gep, int flags, FILE *ofp) { kaddr_t labelp; char label[256]; /* Get the pointer to the label string */ labelp = kl_kaddr(gep, "graph_edge_s", "e_label"); /* Get the label string */ kl_get_block(labelp, 24, label, "graph_info_label"); indent_it(flags, ofp); fprintf(ofp, "%4d %16llx %-24s %6llu\n", i, labelp, label, KL_UINT(gep, "graph_edge_s", "e_vertex")); return(0); } /* * graph_info_s_banner() -- Print out the banner information for each * graph_info_s struct. */ void graph_info_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, "INFO LABEL NAME " "INFO_DESC INFO\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "====================================================" "==========================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "----------------------------------------------------" "--------------------------\n"); } } /* * print_graph_info_s() -- Print out the data in the graph_info_s struct. * * Note that this print routine cannot be called by the struct or walk * commands. That is because it has an extra paramater (i). This was * necessary because there was no other way to determine the edge index. * You have to know what the vertex is in order to determine that (which * would also have required a non-standard set of parameters). */ int print_graph_info_s(int i, kaddr_t addr, k_ptr_t gip, int flags, FILE *ofp) { kaddr_t labelp; char label[256]; /* Get the pointer to the label string */ labelp = kl_kaddr(gip, "graph_edge_s", "e_label"); /* Get the label string */ kl_get_block(labelp, 24, label, "graph_info_label"); indent_it(flags, ofp); fprintf(ofp, "%4d %16llx %-20s %16llx %16llx\n", i, labelp, label, KL_UINT(gip, "graph_info_s", "i_info_desc"), KL_UINT(gip, "graph_info_s", "i_info")); return(0); } /* * graph_vertex_s_banner() -- Print out the banner information for each * graph_vertex_s struct. */ void graph_vertex_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, "HNDL VERTEX REFCNT NUM_EDGE NUM_INFO " "INFO_LIST\n"); } if (flags & SMAJOR) { fprintf(ofp, "===========================================================" "=========\n"); } if (flags & SMINOR) { fprintf(ofp, "-----------------------------------------------------------" "---------\n"); } } /* * print_graph_vertex_s() -- Print out the data in the file pointer. */ int print_graph_vertex_s(kaddr_t addr, k_ptr_t gp, int flags, FILE *ofp) { k_ptr_t infop; k_uint_t hndl, num_edge, num_info; kaddr_t info_list, next_info; if (DEBUG(DC_FUNCTRACE, 3)) { fprintf(ofp, "print_graph_vertex_s: addr=0x%llx, " "gp=0x%x, flags=0x%x, ofp=0x%x\n", addr, gp, flags, ofp); } kl_is_valid_kaddr(addr, (k_ptr_t)NULL, WORD_ALIGN_FLAG); if (KL_ERROR) { hndl = addr; addr = kl_handle_to_vertex(hndl); kl_reset_error(); } else { hndl = kl_vertex_to_handle(addr); } num_edge = KL_UINT(gp, "graph_vertex_s", "v_num_edge"); num_info = KL_UINT(gp, "graph_vertex_s", "v_num_info_LBL"); info_list = kl_kaddr(gp, "graph_vertex_s", "v_info_list"); fprintf(ofp, "%4lld %16llx %6lld %8lld %8lld %16llx\n", hndl, addr, KL_INT(gp, "graph_vertex_s", "v_refcnt"), num_edge, num_info, info_list); if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, "CONNECT_POINT=%llu\n", kl_uint(gp, "graph_vertex_s", "v_info_list", (2 * K_NBPW))); fprintf(ofp, "INDEX[0]=0x%llx, INDEX[1]=0x%llx, INDEX[2]=0x%llx\n", kl_uint(gp, "graph_vertex_s", "v_info_list", (K_NBPW)), kl_uint(gp, "graph_vertex_s", "v_info_list", (2 * K_NBPW)), kl_uint(gp, "graph_vertex_s", "v_info_list", (3 * K_NBPW))); } if (flags & C_NEXT) { int i; kaddr_t labelp; char label[256]; fprintf(ofp, "\n"); next_info = info_list; if (num_edge) { infop = kl_alloc_block(GRAPH_EDGE_S_SIZE, K_TEMP); fprintf(ofp, "EDGES:\n\n"); graph_edge_s_banner(ofp, C_INDENT|BANNER|SMINOR); for (i = 0; i < num_edge; i++) { kl_get_graph_edge_s(gp, i, 0, infop, flags); if (KL_ERROR) { break; } print_graph_edge_s(i, next_info, infop, C_INDENT, ofp); next_info += GRAPH_EDGE_S_SIZE; } kl_free_block(infop); fprintf(ofp, "\n"); } if (num_info) { fprintf(ofp, "INFOS:\n\n"); graph_info_s_banner(ofp, C_INDENT|BANNER|SMINOR); infop = kl_alloc_block(GRAPH_INFO_S_SIZE, K_TEMP); for (i = 0; i < num_info; i++) { kl_get_graph_info_s(gp, i, 0, infop, flags); if (KL_ERROR) { break; } print_graph_info_s(i, next_info, infop, C_INDENT, ofp); next_info += GRAPH_EDGE_S_SIZE; } kl_free_block(infop); fprintf(ofp, "\n"); } } return(0); } /* * get_inode() -- Try and get a patched inode pointer. * * The best we can do here is try and check the vnode pointer for * validity. */ k_ptr_t get_inode(kaddr_t addr, k_ptr_t ibufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_inode: addr=0x%llx, ibufp=0x%x, flags=0x%x\n", addr, ibufp, flags); } if (ibufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_INODE); return((k_ptr_t)NULL); } kl_get_struct(addr, INODE_SIZE, ibufp, "inode"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_INODE; } else { if (addr == kl_bhvp_pdata(INODE_TO_BHP(ibufp))) { return(ibufp); } else if (flags & C_ALL) { return(ibufp); } else { KL_SET_ERROR_NVAL(KLE_BAD_INODE, addr, 2); } } return((k_ptr_t)NULL); } /* * inode_banner() -- Print out banner information for inode structure. */ void inode_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " INODE UID GID NUMBER " " BH SIZE\n"); } else { fprintf(ofp, " INODE UID GID NUMBER " " BH SIZE\n"); } } if (flags & SMAJOR) { fprintf(ofp, "===========================================================" "==================\n"); } if (flags & SMINOR) { fprintf(ofp, "-----------------------------------------------------------" "------------------\n"); } } /* * print_inode() -- Print out the inode information. */ int print_inode(kaddr_t addr, k_ptr_t ip, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_inode: addr=0x%llx, ip=0x%x, flags=0x%x\n", addr, ip, flags); } indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%5lld %5lld %8llu ", KL_INT(ip, "inode", "i_uid"), KL_INT(ip, "inode", "i_gid"), KL_UINT(ip, "inode", "i_number")); fprintf(ofp, "%16llx ", kl_kaddr(ip, "inode", "i_bhv_desc")); fprintf(ofp, "%8lld\n", KL_INT(ip, "inode", "i_size")); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "NEXT: %llx, PREVP: %llx\n", kl_kaddr(ip, "inode", "i_next"), kl_kaddr(ip, "inode", "i_prevp")); indent_it(flags, ofp); fprintf(ofp, "NLINK: %lld, GEN #: %llu, FLAGS: 0x%llx\n", KL_INT(ip, "inode", "i_nlink"), KL_UINT(ip, "inode", "i_gen"), KL_UINT(ip, "inode", "i_flags")); indent_it(flags, ofp); fprintf(ofp, "ATIME: %lld, MTIME: %lld, CTIME: %lld\n", KL_INT(ip, "inode", "i_atime"), KL_INT(ip, "inode", "i_mtime"), KL_INT(ip, "inode", "i_ctime")); indent_it(flags, ofp); fprintf(ofp, "# EXTENTS: %lld, # INDIRS: %lld\n", KL_INT(ip, "inode", "i_numextents"), KL_INT(ip, "inode", "i_numindirs")); indent_it(flags, ofp); fprintf(ofp, "EXTENT LIST: %llx, INDIRECT LIST: %llx\n", kl_kaddr(ip, "inode", "i_extents"), kl_kaddr(ip, "inode", "i_indirbytes")); indent_it(flags, ofp); fprintf(ofp, "BLOCKS: %lld, ", kl_kaddr(ip, "inode", "i_blocks")); fprintf(ofp, "LOCKTRIPS: %lld\n", KL_INT(ip, "inode", "i_locktrips")); fprintf(ofp, "\n"); } return(1); } /* * inpcb_banner() -- Print out banner information for inpcb structure. */ void inpcb_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " INPCB SOCKET " " LOCAL ADDRESS FOREIGN ADDRESS\n"); } else { fprintf(ofp, " INPCB SOCKET " " LOCAL ADDRESS FOREIGN ADDRESS\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "===========================================" "==================================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-------------------------------------------" "----------------------------------\n"); } } /* * print_inpcb() -- Print out an address as an incpb structure. */ int print_inpcb(kaddr_t in, k_ptr_t inp, int flags, FILE *ofp) { int i, proto; short port; uint addr; k_uint_t tcpaddr; k_ptr_t tmp1, tmp2, tcpp; char ipaddr[256]; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_inpcb: in=0x%llx, inp=0x%x, flags=0x%x\n", in, inp, flags); } ipaddr[0] = 0; proto = flags >> 16; FPRINTF_KADDR(ofp, " ", in); fprintf(ofp, "%16llx ", kl_kaddr(inp, "inpcb", "inp_u")); /* * Print out the local address. */ tmp1 = (k_ptr_t)((uint)inp + kl_member_offset("inpcb", "inp_iap")); tmp2 = (k_ptr_t)((unsigned)tmp1 + kl_member_offset("inaddrpair", "iap_laddr")); tcpaddr = KL_UINT(tmp2, "in_addr", "s_addr"); get_tcpaddr(tcpaddr, KL_UINT(tmp1, "inaddrpair", "iap_lport"), ipaddr); fprintf(ofp, "%+20s ", ipaddr); /* Print out the foreign address. */ ipaddr[0] = 0; tmp2 = (k_ptr_t)((unsigned)tmp1 + kl_member_offset("inaddrpair", "iap_faddr")); tcpaddr = KL_UINT(tmp2, "in_addr", "s_addr"); get_tcpaddr(tcpaddr, KL_UINT(tmp1, "inaddrpair", "iap_fport"), ipaddr); fprintf(ofp, "%+20s\n", ipaddr); return(1); } /* * inventory_s_banner() -- Print out banner information for inventory_s * structure. */ void inventory_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " INVENTORY NEXT CLASS TYPE CONTROLLER " "UNIT STATE\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=============================================================" "===========\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-------------------------------------------------------------" "-----------\n"); } } /* * print_inventory_s() -- Print out an address as an inventory_s structure. */ int print_inventory_s(kaddr_t inv, k_ptr_t invp, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_inventory_s: inv=0x%llx, invp=0x%x, flags=0x%x\n", inv, invp, flags); } indent_it(flags, ofp); fprintf(ofp, "%16llx %16llx %5lld %4lld %10llu %4llu %5lld\n", inv, kl_kaddr(invp, "inventory_s", "inv_next"), KL_INT(invp, "inventory_s", "inv_class"), KL_INT(invp, "inventory_s", "inv_type"), KL_UINT(invp, "inventory_s", "inv_controller"), KL_UINT(invp, "inventory_s", "inv_unit"), KL_INT(invp, "inventory_s", "inv_state")); return(1); } /* * xthread_s_banner() */ void xthread_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " XTHREAD NEXT PREV NAME\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=================================================" "============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-------------------------------------------------" "----------------------------\n"); } } /* * print_xthread_s() * * Print out selected fields from the xthread struct and check the flags * options for full print status. */ int print_xthread_s(kaddr_t xthread, k_ptr_t itp, int flags, FILE *ofp) { k_ptr_t kt_name; if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(ofp, "print_xthread_s: xthread=0x%llx, itp=0x%x, flags=0x%x, " "ofp=0x%x\n", xthread, itp, flags, ofp); } indent_it(flags, ofp); fprintf(ofp, "%16llx %16llx %16llx %s\n", xthread, kl_kaddr(itp, "xthread_s", "xt_next"), kl_kaddr(itp, "xthread_s", "xt_prev"), kl_kthread_name(itp)); return(1); } /* * list_active_uthreads() */ int list_active_uthreads(int flags, FILE *ofp) { int i, first_time = 1, uthread_cnt = 0, kthread_cnt; k_ptr_t pidp, vprocp, bhvdp, procp, utp; kaddr_t pid, vproc, bhv, proc, kthread; pidp = kl_alloc_block(PID_ENTRY_SIZE, K_TEMP); vprocp = kl_alloc_block(VPROC_SIZE, K_TEMP); pid = K_PID_ACTIVE_LIST; /* We have to step over the first entry as it is just * the list head. */ kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); if (KL_ERROR) { kl_free_block(pidp); kl_free_block(vprocp); return(0); } if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { uthread_s_banner(ofp, BANNER|SMAJOR); } do { kl_get_struct(pid, PID_ENTRY_SIZE, pidp, "pid_entry"); if (KL_ERROR) { break; } vproc = kl_kaddr(pidp, "pid_entry", "pe_vproc"); kl_get_struct(vproc, VPROC_SIZE, vprocp, "vproc"); bhv = kl_kaddr(vprocp, "vproc", "vp_bhvh"); proc = kl_bhv_pdata(bhv); if (KL_ERROR) { kl_print_error(); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); if (KL_ERROR) { break; } continue; } procp = kl_get_proc(proc, 2, flags); if (KL_ERROR) { kl_print_error(); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); if (KL_ERROR) { break; } continue; } kthread = kl_proc_to_kthread(procp, &kthread_cnt); kl_free_block(procp); for (i = 0; i < kthread_cnt; i++) { utp = kl_get_uthread_s(kthread, 2, flags); if (KL_ERROR) { kl_print_error(); break; } if (first_time == TRUE) { first_time = FALSE; } else if (flags & (C_FULL|C_NEXT)) { if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { uthread_s_banner(ofp, BANNER|SMAJOR); } } if (flags & C_KTHREAD) { print_kthread(kthread, utp, flags, ofp); } else { print_uthread_s(kthread, utp, flags, ofp); } uthread_cnt++; kthread = kl_kaddr(utp, "uthread_s", "ut_next"); kl_free_block(utp); } kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); if (KL_ERROR) { break; } } while (pid != K_PID_ACTIVE_LIST); kl_free_block(pidp); kl_free_block(vprocp); return(uthread_cnt); } /* * list_active_xthreads() */ int list_active_xthreads(int flags, FILE *ofp) { int xthread_cnt = 0, first_time = 1; k_ptr_t xtp; kaddr_t xthread; xtp = kl_alloc_block(XTHREAD_S_SIZE, K_TEMP); kl_get_struct(K_XTHREADLIST, XTHREAD_S_SIZE, xtp, "xthread_s"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_XTHREAD_S; kl_print_error(); return(1); } xthread = kl_kaddr(xtp, "xthread_s", "xt_next"); kl_free_block(xtp); if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { xthread_s_banner(ofp, BANNER|SMAJOR); } while(xthread != K_XTHREADLIST) { xtp = kl_get_xthread_s(xthread, 2, flags); if (KL_ERROR) { KL_ERROR |= KLE_BAD_XTHREAD_S; kl_print_error(); return(xthread_cnt); } else { if (first_time == TRUE) { first_time = FALSE; } else if (flags & (C_FULL|C_NEXT)) { if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { xthread_s_banner(ofp, BANNER|SMAJOR); } } if (flags & C_KTHREAD) { print_kthread(xthread, xtp, flags, ofp); } else { print_xthread_s(xthread, xtp, flags, ofp); } if (KL_ERROR) { kl_print_error(); } kl_free_block(xtp); xthread_cnt++; xthread = kl_kaddr(xtp, "xthread_s", "xt_next"); } } return(xthread_cnt); } /* * kthread_banner() */ void kthread_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " KTHREAD TYPE ID " " WCHAN NAME\n"); } else { fprintf(ofp, " KTHREAD TYPE ID " "WCHAN NAME\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=================================================" "============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-------------------------------------------------" "----------------------------\n"); } } /* * print_kthread() * * Print out selected fields from the kthread struct and check the flags * options for full print status. Note that the buff pointer ktp really * points to a proc struct sized buffer. */ int print_kthread(kaddr_t kthread, k_ptr_t ktp, int flags, FILE *ofp) { kaddr_t tp, procp; k_ptr_t p, cp, kt_name; k_ptr_t nktp=kl_get_kthread(kthread, K_TEMP); if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(ofp, "print_kthread: kthread=0x%llx, ktp=0x%x, flags=0x%x, " "ofp=0x%x\n", kthread, ktp, flags, ofp); } indent_it(flags, ofp); fprintf(ofp, "%16llx %4llu %16llx ", kthread, KL_UINT(nktp, "kthread", "k_type"), KL_UINT(nktp, "kthread", "k_id")); if (kl_kaddr(nktp, "kthread", "k_wchan")) { if (PTRSZ64) { fprintf(ofp, "%16llx ", kl_kaddr(nktp, "kthread", "k_wchan")); } else { fprintf(ofp, "%8llx ", kl_kaddr(nktp, "kthread", "k_wchan")); } } else { if (PTRSZ64) { fprintf(ofp, "0000000000000000 "); } else { fprintf(ofp, "00000000 "); } } if (kt_name = kl_kthread_name(nktp)) { fprintf(ofp, "%s", kt_name); } fprintf(ofp, "\n"); if (flags & C_FULL) { print_kthread_full(nktp, flags, ofp); } if (flags & C_NEXT) { if (IS_STHREAD(nktp)) { fprintf(ofp, "\n"); indent_it(flags, ofp); sthread_s_banner(ofp, BANNER|SMINOR); indent_it(flags, ofp); print_sthread_s(kthread, nktp, flags, ofp); } else if (IS_UTHREAD(nktp)) { fprintf(ofp, "\n"); indent_it(flags, ofp); uthread_s_banner(ofp, BANNER|SMINOR); indent_it(flags, ofp); print_uthread_s(kthread, nktp, flags, ofp); } else if (IS_XTHREAD(nktp)) { fprintf(ofp, "\n"); indent_it(flags, ofp); xthread_s_banner(ofp, BANNER|SMINOR); indent_it(flags, ofp); print_xthread_s(kthread, nktp, flags, ofp); } fprintf(ofp, "\n"); } kl_free_block(nktp); return(1); } /* * print_k_flags() * * Print out the k_flags in a user-understandable format. */ #define NUM_K_FLAGS_PER_LINE 5 /* Number we print per line. */ int print_k_flags(int k_flags, int flags, FILE *ofp) { int i = 0; int unknown = 0; char *Pchar; fprintf(ofp,"K_FLAGS(0x%x)=",k_flags); while(k_flags) { Pchar = ((k_flags & KT_MUTEX_INHERIT) ? (k_flags &= ~KT_MUTEX_INHERIT, "KT_MUTEX_INHERIT") : (k_flags & KT_NOAFF) ? (k_flags &= ~KT_NOAFF, "KT_NOAFF") : (k_flags & KT_SERVER) ? (k_flags &= ~KT_SERVER, "KT_SERVER") : (k_flags & KT_BHVINTR) ? (k_flags &= ~KT_BHVINTR, "KT_BHVINTR") : (k_flags & KT_LTWAIT) ? (k_flags &= ~KT_LTWAIT, "KT_LTWAIT") : (k_flags & KT_NWAKE) ? (k_flags &= ~KT_NWAKE, "KT_NWAKE") : (k_flags & KT_SLEEP) ? (k_flags &= ~KT_SLEEP, "KT_SLEEP") : (k_flags & KT_INTERRUPTED) ? (k_flags &= ~KT_INTERRUPTED, "KT_INTERRUPTED") : (k_flags & KT_PSPIN) ? (k_flags &= ~KT_PSPIN, "KT_PSPIN") : (k_flags & KT_HOLD) ? (k_flags &= ~KT_HOLD, "KT_HOLD") : (k_flags & KT_PSMR) ? (k_flags &= ~KT_PSMR, "KT_PSMR") : (k_flags & KT_NBASEPRMPT) ? (k_flags &= ~KT_NBASEPRMPT, "KT_NBASEPRMPT") : (k_flags & KT_BASEPS) ? (k_flags &= ~KT_BASEPS, "KT_BASEPS") : (k_flags & KT_NPRMPT) ? (k_flags &= ~KT_NPRMPT, "KT_NPRMPT") : (k_flags & KT_BIND) ? (k_flags &= ~KT_BIND, "KT_BIND") : (k_flags & KT_PS) ? (k_flags &= ~KT_PS, "KT_PS") : (k_flags & KT_WUPD) ? (k_flags &= ~KT_WUPD, "KT_WUPD") : (k_flags & KT_ISEMA) ? (k_flags &= ~KT_ISEMA, "KT_ISEMA") : (k_flags & KT_WMRLOCK) ? (k_flags &= ~KT_WMRLOCK, "KT_WMRLOCK") : (k_flags & KT_WSEMA) ? (k_flags &= ~KT_WSEMA, "KT_WSEMA") : (k_flags & KT_INDIRECTQ) ? (k_flags &= ~KT_INDIRECTQ, "KT_INDIRECTQ") : (k_flags & KT_WSVQUEUEING) ? (k_flags &= ~KT_WSVQUEUEING, "KT_WSVQUEUEING") : (k_flags & KT_WSV) ? (k_flags &= ~KT_WSV, "KT_WSV") : (k_flags & KT_WACC) ? (k_flags &= ~KT_WACC, "KT_WACC") : (k_flags & KT_LOCK) ? (k_flags &= ~KT_LOCK, "KT_LOCK") : (k_flags & KT_WMUTEX) ? (k_flags &= ~KT_WMUTEX, "KT_WMUTEX") : (k_flags & KT_WSEMA) ? (k_flags &= ~KT_WSEMA, "KT_WSEMA") : (k_flags & KT_STACK_MALLOC)? (k_flags &= ~KT_STACK_MALLOC,"KT_STACK_MALLOC") : (k_flags) ? (unknown = 1, "*UNKNOWN FLAG*") : ""); if(i && i%NUM_K_FLAGS_PER_LINE == 0) { fprintf(ofp,"\n "); indent_it(flags, ofp); } fprintf(ofp,Pchar); if(k_flags) { fprintf(ofp,"|"); } i++; if(unknown) { break; } } fprintf(ofp,"\n"); return(0); } /* * print_kthread_full() */ int print_kthread_full(k_ptr_t ktp, int flags, FILE *ofp) { fprintf(ofp, "\n"); indent_it(flags, ofp); print_k_flags((int)KL_UINT(ktp, "kthread", "k_flags"), flags,ofp); indent_it(flags, ofp); fprintf(ofp, "K_W2CHAN=0x%llx,K_STACK=0x%llx, K_STACKSIZE=%llu\n", kl_kaddr(ktp, "kthread", "k_w2chan"), kl_kaddr(ktp, "kthread", "k_stack"), KL_UINT(ktp, "kthread", "k_stacksize")); indent_it(flags, ofp); fprintf(ofp, "K_PRTN=%lld, K_PRI=%lld, K_BASEPRI=%lld, ", KL_INT(ktp, "kthread", "k_prtn"), KL_INT(ktp, "kthread", "k_pri"), KL_INT(ktp, "kthread", "k_basepri")); fprintf(ofp, "K_SQSELF=%lld, K_ONRQ=%lld\n", KL_INT(ktp, "kthread", "k_sqself"), KL_INT(ktp, "kthread", "k_onrq")); indent_it(flags, ofp); fprintf(ofp, "K_SONPROC=%lld, K_BINDING=%lld, K_MUSTRUN=%lld\n", KL_INT(ktp, "kthread", "k_sonproc"), KL_INT(ktp, "kthread", "k_binding"), KL_INT(ktp, "kthread", "k_mustrun")); indent_it(flags, ofp); fprintf(ofp, "K_LASTRUN=%lld, K_CPUSET=%lld, ", KL_INT(ktp,"kthread", "k_lastrun"), KL_INT(ktp,"kthread", "k_cpuset")); fprintf(ofp, "K_EFRAME=0x%llx, K_LINK=0x%llx\n", kl_kaddr(ktp, "kthread", "k_eframe"), kl_kaddr(ktp, "kthread", "k_link")); indent_it(flags, ofp); fprintf(ofp, "K_INHERIT=0x%llx, K_INDIRECTWAIT=0x%llx\n", kl_kaddr(ktp, "kthread", "k_inherit"), kl_kaddr(ktp, "kthread", "k_indirectwait")); indent_it(flags, ofp); fprintf(ofp, "K_RFLINK=0x%llx, K_RBLINK=0x%llx\n", kl_kaddr(ktp, "kthread", "k_rflink"), kl_kaddr(ktp, "kthread", "k_rblink")); indent_it(flags, ofp); fprintf(ofp, "K_FLINK=0x%llx, K_BLINK=0x%llx\n", kl_kaddr(ktp, "kthread", "k_flink"), kl_kaddr(ktp, "kthread", "k_blink")); fprintf(ofp, "\n"); return(0); } /* * mbuf_banner() -- Print out banner information for mbuf structure. */ void mbuf_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " MBUF NEXT OFF " "LEN TYPE FLAGS\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "========================================================" "================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "--------------------------------------------------------" "----------------\n"); } } /* * print_mbuf() -- Print out contents of mbuf structure */ int print_mbuf(kaddr_t addr, k_ptr_t m, int flags, FILE *ofp) { k_int_t offset; offset = KL_INT(m, "mbuf", "m_off"); indent_it(flags, ofp); fprintf(ofp, "%16llx %16llx %16lld %5llu %4llu %5llx\n", addr, kl_kaddr(m, "mbuf", "m_next"), offset, KL_UINT(m, "mbuf", "m_len"), KL_UINT(m, "mbuf", "m_type"), KL_UINT(m, "mbuf", "m_flags")); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, " DATA=0x%llx\n", (offset ? (addr + (long long)offset) : (k_uint_t)NULL)); if (KL_UINT(m, "mbuf", "m_flags") & MCL_CLUSTER) { /* XXX - Need to convert the following to access specific * members of union. For now just brute force it. */ indent_it(flags, ofp); fprintf(ofp, " FREEFUNC=0x%llx, ", kl_kaddr(m, "mbuf", "m_u")); fprintf(ofp, "FARG=0x%llx\n", *(kaddr_t*)(ADDR(m, "mbuf", "m_u") + K_NBPW)); indent_it(flags, ofp); fprintf(ofp, " DUPFUNC=0x%llx, ", *(kaddr_t*)(ADDR(m, "mbuf", "m_u") + (2 * K_NBPW))); fprintf(ofp, "DARG=0x%llx\n", *(kaddr_t*)(ADDR(m, "mbuf", "m_u") + (3 * K_NBPW))); } } return(0); } /* * ml_info_banner() -- Print out banner information for ml_info structure. */ void ml_info_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " ML_INFO FLAGS NEXT " "TEXT END\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "======================================================" "=======================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "------------------------------------------------------" "-----------------------\n"); } } /* * print_ml_info() -- Print out contents of ml_info structure */ int print_ml_info(kaddr_t addr, k_ptr_t mlp, int flags, FILE *ofp) { indent_it(flags, ofp); fprintf(ofp, "%16llx %5lld %16llx %16llx %16llx\n", addr, KL_INT(mlp, "ml_info", "flags"), kl_kaddr(mlp, "ml_info", "ml_next"), kl_kaddr(mlp, "ml_info", "ml_text"), kl_kaddr(mlp, "ml_info", "ml_end")); if (flags & C_FULL) { int i, nsyms; kaddr_t sym, addr; k_ptr_t symp; fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "ML_OBJ=0x%llx, ", kl_kaddr(mlp, "ml_info", "ml_obj")); fprintf(ofp, "ML_SYMTAB=0x%llx, ", kl_kaddr(mlp, "ml_info", "ml_symtab")); fprintf(ofp, "ML_STRINGTAB=0x%llx\n", kl_kaddr(mlp, "ml_info", "ml_stringtab")); indent_it(flags, ofp); fprintf(ofp, "ML_DESC=0x%llx, ", kl_kaddr(mlp, "ml_info", "ml_desc")); fprintf(ofp, "ML_BASE=0x%llx\n", kl_kaddr(mlp, "ml_info", "ml_base")); indent_it(flags, ofp); nsyms = KL_INT(mlp, "ml_info", "ml_nsyms"); fprintf(ofp, "ML_NSYMS=%d, ", nsyms); fprintf(ofp, "ML_STRTABSZ=%lld\n", KL_INT(mlp, "ml_info", "ml_strtabsz")); fprintf(ofp, "\n"); /* If there are any symbols for this module, dump their * information out here. We have to check to make sure * that if nsyms is > 0 that there are ml_symtab and * ml_streamtab pointers (there have been cases where * there wasn't). */ sym = kl_kaddr(mlp, "ml_info", "ml_symtab"); if (!sym || (kl_kaddr(mlp, "ml_info", "ml_stringtab") == 0)) { return(0); } symp = kl_alloc_block(ML_SYM_SIZE, K_TEMP); for (i = 0; i < nsyms; i++) { kl_get_block(sym, ML_SYM_SIZE, symp, "ml_sym"); if (PTRSZ64) { addr = *(uint64*)symp; } else { addr = *(uint*)symp; } print_ml_sym(addr, symp, mlp, ofp); sym += ML_SYM_SIZE; } kl_free_block(symp); } return(1); } /* * print_ml_sym() */ int print_ml_sym(kaddr_t addr, k_ptr_t symp, k_ptr_t mlp, FILE *ofp) { int strtabsz; char *str, *strtab; kaddr_t stringtab; if (DEBUG(DC_GLOBAL, 3)) { fprintf(stderr, "addr=0x%llx, symp=0x%x, mlp=0x%x\n", addr, symp, mlp); } stringtab = kl_kaddr(mlp, "ml_info", "ml_stringtab"); strtabsz = KL_INT(mlp, "ml_info", "ml_strtabsz"); strtab = (char*)kl_alloc_block(strtabsz, K_TEMP); kl_get_block(stringtab, strtabsz, strtab, "ml_sym"); if (PTRSZ64) { str = strtab + *(uint*)((uint)symp + 8); } else { str = strtab + *(uint*)((uint)symp + 4); } fprintf(ofp, "%30s %16llx\n", str, addr); kl_free_block((k_ptr_t)strtab); return(1); } /* * mntinfo_banner() -- Print out banner information for mntinfo structure. */ void mntinfo_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " HOST ROOTVP" " REFCT BASETYPE\n"); } if (flags & SMAJOR) { fprintf(ofp, "=============================================" "==================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------------" "----------------------------------\n"); } } /* * get_mntinfo() -- This routine returns a pointer to an mntinfo. */ k_ptr_t get_mntinfo(kaddr_t addr, k_ptr_t rbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_mntinfo: addr=0x%llx, rbufp=0x%x, " "flags=0x%x\n", addr, rbufp, flags); } if (rbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_MNTINFO); return((k_ptr_t)NULL); } kl_get_struct(addr, MNTINFO_SIZE, rbufp, "mntinfo"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_MNTINFO; } else { return(rbufp); } return((k_ptr_t)NULL); } /* * print_mntinfo() -- Print out information inside an mntinfo. */ int print_mntinfo(kaddr_t addr, k_ptr_t rp, int flags, FILE *ofp) { int mntinfo_cnt = 0; k_ptr_t nnp, bufp; kaddr_t np; char hostname[32]; char basetype[16]; bcopy(K_PTR(rp, "mntinfo", "mi_hostname"), hostname, 32); bcopy(K_PTR(rp, "mntinfo", "mi_basetype"), basetype, 16); indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%16s %16llx %10lld %10s\n", hostname, kl_kaddr(rp, "mntinfo", "mi_rootvp"), KL_UINT(rp, "mntinfo", "mi_refct"), basetype); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "NEXT=0x%llx, PREV=0x%llx\n", kl_kaddr(rp, "mntinfo", "mi_next"), kl_kaddr(rp, "mntinfo", "mi_prev")); indent_it(flags, ofp); fprintf(ofp, "LOCK=0x%llx, NLMFLAG=0x%llx\n", kl_kaddr(rp, "mntinfo", "mi_lock"), KL_UINT(rp, "mntinfo", "mi_nlm")); indent_it(flags, ofp); fprintf(ofp, "TSIZE=%lld, STSIZE=%lld, BSIZE=%lld, TIMEO=%lld\n", KL_UINT(rp, "mntinfo", "mi_tsize"), KL_UINT(rp, "mntinfo", "mi_stsize"), KL_UINT(rp, "mntinfo", "mi_bsize"), KL_UINT(rp, "mntinfo", "mi_timeo")); indent_it(flags, ofp); fprintf(ofp, "RETRANS=%lld, MNTNO =%lld\n", KL_UINT(rp, "mntinfo", "mi_retrans"), KL_UINT(rp, "mntinfo", "mi_mntno")); indent_it(flags, ofp); fprintf(ofp, "ROOTFSID=0x%llx, FSIDMAPS=0x%llx, RNODE=0x%llx\n", kl_kaddr(rp, "mntinfo", "mi_rootfsid"), kl_kaddr(rp, "mntinfo", "mi_fsidmaps"), kl_kaddr(rp, "mntinfo", "mi_rnodes")); indent_it(flags, ofp); fprintf(ofp, "ASYNC_REQS=0x%llx, THREADS=%lld, ASYNCCNT=%lld\n", kl_kaddr(rp, "mntinfo", "mi_async_reqs"), KL_UINT(rp, "mntinfo", "mi_threads"), KL_UINT(rp, "mntinfo", "mi_mi_async_count")); } mntinfo_cnt++; if (flags & C_NEXT) { np = kl_kaddr(rp, "mntinfo", "mi_next"); while ( np ) { bufp = alloc_block(kl_struct_len("mntinfo"), K_TEMP); kl_get_struct(np, MNTINFO_SIZE, bufp, "mntinfo"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_MNTINFO; kl_free_block(bufp); fprintf(ofp, "\n"); return(1); } else { nnp = bufp; fprintf(ofp, "\n"); mntinfo_banner(ofp, BANNER|SMINOR); bcopy(K_PTR(nnp, "mntinfo", "mi_hostname"), hostname, 32); bcopy(K_PTR(nnp, "mntinfo", "mi_basetype"), basetype, 16); FPRINTF_KADDR(ofp, " ", np); fprintf(ofp, "%16s %16llx %10lld %10s\n", hostname, kl_kaddr(nnp, "mntinfo", "mi_rootvp"), KL_UINT(nnp, "mntinfo", "mi_refct"), basetype); mntinfo_cnt++; } np = kl_kaddr(nnp, "mntinfo", "mi_next"); kl_free_block(bufp); } fprintf(ofp, "\n"); } return(mntinfo_cnt); } /* * mrlock_s_banner() -- Print out banner information for mrlock_s structure. */ void mrlock_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " MRLOCK LBITS QCOUNT QFLAGS " " QBITS\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "====================================================" "================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "----------------------------------------------------" "----------------\n"); } } /* Some #define's "borrowed" from sys/sema_private.h */ /* LBITS */ #define MR_ACCINC 0x00000001 #define MR_ACC 0x00003fff /* # of current access locks */ #define MR_ACCMAX 0x00002000 /* no more accesses beyond here */ #define MR_UPD 0x00004000 /* have update lock */ #define MR_BARRIER 0x00008000 /* there are access barriers */ #define MR_WAITINC 0x00010000 /* increment waiters by this */ #define MR_WAIT 0x3fff0000 /* waiters of any kind */ #define MR_WAITSHFT 16 /* QBITS */ #define MR_QLOCK 0x0001 #define MR_V 0x0002 #define MR_BEHAVIOR 0x0004 #define MR_DBLTRIPPABLE 0x0008 /* XXX - This define is here only so we can look at older dumps */ #define OLD_MRI /* * mri_to_mria_kt_p() */ kaddr_t mri_to_mria_kt_p(kaddr_t mri, k_ptr_t mrip) { kaddr_t mria_kt, kthread; #ifdef OLD_MRI if (KL_INT(mrip, "mri_s", "mri_offset")) { mria_kt = mri - KL_INT(mrip, "mri_s", "mri_offset"); } else { #endif mria_kt = mri - (KL_INT(mrip, "mri_s", "mri_index") * kl_struct_len("mri_s")) - K_NBPW; #ifdef OLD_MRI } #endif kl_get_kaddr(mria_kt, (k_ptr_t)&kthread, "kthread"); return(kthread); } #define PRINT_COMMA(bcount) \ if (bcount) { \ fprintf(ofp, ", "); \ } /* * print_mrlock_s() -- Print the contents of a mrlock structure. */ int print_mrlock_s(kaddr_t addr, k_ptr_t mrlockp, int flags, FILE *ofp) { int i; k_uint_t lbits, qbits; short ishorttmp; k_ptr_t unp; indent_it(flags, ofp); fprintf(ofp, "%16llx ", addr); lbits = KL_UINT(mrlockp, "mrlock_s", "mr_lbits"); fprintf(ofp, "%16llx ", lbits); unp = (k_ptr_t)((uint)mrlockp + kl_member_offset("mrlock_s", "mr_un")); /* Because the mrlock_s struct contains a union, and that union * contains a struct that does not have a struct type (it is defined * in-line), it is necessary to get the qcount, and qflags values * by brute force. */ ishorttmp = *(short *)(unp); fprintf(ofp, "%6hd ", ishorttmp); ishorttmp = *(short *)((uint_t)unp + 2); fprintf(ofp, "%6hd ", ishorttmp); qbits = KL_UINT(mrlockp, "mrlock_s", "mr_un"); fprintf(ofp, "%16llx\n", KL_UINT(mrlockp, "mrlock_s", "mr_un")); if (flags & C_FULL) { int bcount = 0, k_flags; kaddr_t waiters, holders, pg_pq; kaddr_t firstkt, nextkt, kt; kaddr_t firstmri, nextmri, mri; k_ptr_t ktp, mrip = 0, kt_name; fprintf(ofp, "\n"); fprintf(ofp, "LBITS:\n"); fprintf(ofp, " "); if (lbits & MR_ACCINC) { fprintf(ofp, "MR_ACCINC"); bcount++; } if (lbits & MR_ACC) { PRINT_COMMA(bcount); fprintf(ofp, "MR_ACC=%lld", (lbits & MR_ACC)); bcount++; } if (lbits & MR_ACCMAX) { PRINT_COMMA(bcount); fprintf(ofp, "MR_ACCMAX"); bcount++; } if (lbits & MR_UPD) { PRINT_COMMA(bcount); fprintf(ofp, "MR_UPD"); bcount++; } if (lbits & MR_BARRIER) { PRINT_COMMA(bcount); fprintf(ofp, "MR_BARRIER"); bcount++; } if (lbits & MR_WAITINC) { PRINT_COMMA(bcount); fprintf(ofp, "MR_WAITINC"); bcount++; } if (lbits & MR_WAIT) { PRINT_COMMA(bcount); fprintf(ofp, "WAITERS=%lld", (lbits & MR_WAIT) >> MR_WAITSHFT); bcount++; } if (bcount) { fprintf(ofp, "\n"); } fprintf(ofp, "\n"); bcount = 0; fprintf(ofp, "QBITS:\n"); fprintf(ofp, " "); if (qbits & MR_QLOCK) { fprintf(ofp, "MR_QLOCK"); bcount++; } if (qbits & MR_V) { PRINT_COMMA(bcount); fprintf(ofp, "MR_V"); bcount++; } if (qbits & MR_BEHAVIOR) { PRINT_COMMA(bcount); fprintf(ofp, "MR_BEHAVIOR"); bcount++; } if (qbits & MR_DBLTRIPPABLE) { PRINT_COMMA(bcount); fprintf(ofp, "MR_DBLTRIPPABLE"); bcount++; } if (bcount) { fprintf(ofp, "\n"); } fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "WAITERS:\n"); waiters = (kaddr_t)(addr + kl_member_offset("mrlock_s", "mr_waiters")); for (i = 0; i < NSCHEDCLASS; i++) { fprintf(ofp, " CLASS %2d: ", -i); pg_pq = (kaddr_t)(waiters + (i * K_NBPW)); kl_get_kaddr(pg_pq, (k_ptr_t)&firstkt, "kthread"); if (flags & C_NEXT) { if (kt = firstkt) { fprintf(ofp, "\n\n"); fprintf(ofp, " KTHREAD TYPE MRQPRI BASEPRI " "PRI FLAG NAME\n"); fprintf(ofp, " -------------------------------------" "-----------------------------\n"); } while (kt) { ktp = kl_get_kthread(kt, 0); if (!ktp) { break; } /* Print out the kthread information */ fprintf(ofp, " %16llx %4llu ", kt, KL_UINT(ktp, "kthread", "k_type")); fprintf(ofp, "%6lld %7lld %3lld ", KL_INT(ktp, "kthread", "k_mrqpri"), KL_INT(ktp, "kthread", "k_basepri"), KL_INT(ktp, "kthread", "k_pri")); k_flags = KL_UINT(ktp, "kthread", "k_flags"); if (k_flags & KT_WACC) { fprintf(ofp, "WACC "); } else if (k_flags & KT_WUPD) { fprintf(ofp, "WUPD "); } else { fprintf(ofp, " "); } if (kt_name = kl_kthread_name(ktp)) { fprintf(ofp, "%s", kt_name); } fprintf(ofp, "\n"); kt = kl_kaddr(ktp, "kthread", "k_flink"); kl_free_block(ktp); if (kt == firstkt) { break; } } if (firstkt) { fprintf(ofp, " -------------------------------------" "------------------------\n"); } } else { fprintf(ofp, "0x%llx", firstkt); } fprintf(ofp, "\n"); } fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "HOLDERS:\n"); holders = (kaddr_t)(addr + kl_member_offset("mrlock_s", "mr_holders")); for (i = 0; i < NSCHEDCLASS; i++) { fprintf(ofp, " CLASS %2d: ", -i); pg_pq = (kaddr_t)(holders + (i * K_NBPW)); kl_get_kaddr(pg_pq, (k_ptr_t)&firstmri, "kthread"); if (flags & C_NEXT) { if (mri = firstmri) { fprintf(ofp, "\n\n"); fprintf(ofp, " MRI PRI COUNT " "KTHREAD BASEPRI PRI NAME\n"); fprintf(ofp, " -------------------------- ---------" "----------------------------------------\n"); /* Allocate a block for the mri_s struct */ mrip = kl_alloc_block(kl_struct_len("mri_s"), K_TEMP); } while (mri) { kl_get_struct(mri, kl_struct_len("mri_s"), mrip, "mri_s"); if (KL_ERROR) { break; } /* Print out the mri_s information */ fprintf(ofp, " %16llx %3lld %5lld ", mri, KL_INT(mrip, "mri_s", "mri_pri"), KL_UINT(mrip, "mri_s", "mri_count")); kt = mri_to_mria_kt_p(mri, mrip); fprintf(ofp, "%16llx ", kt); ktp = kl_get_kthread(kt, 0); if(!ktp || KL_ERROR) { fprintf(ofp, "\n"); kl_reset_error(); break; } fprintf(ofp, "%7lld %3lld ", KL_INT(ktp, "kthread", "k_basepri"), KL_INT(ktp, "kthread", "k_pri")); if (kt_name = kl_kthread_name(ktp)) { fprintf(ofp, "%s", kt_name); } if (ktp) { kl_free_block(ktp); } fprintf(ofp, "\n"); mri = kl_kaddr(mrip, "mri_s", "mri_flink"); if (mri == firstmri) { break; } } if (mrip) { kl_free_block(mrip); mrip = 0; } if (firstmri) { fprintf(ofp, " -------------------------- ---------" "----------------------------------------\n"); } } else { fprintf(ofp, "0x%llx", firstmri); } fprintf(ofp, "\n"); } } return(1); } /* * nodepda_s_banner() -- Print out a nodepda_s banner */ void nodepda_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, "NODE NODEPDA \n"); } if (flags & SMAJOR) { fprintf (ofp, "================================================" "==============================\n"); } if (flags & SMINOR) { fprintf (ofp, "------------------------------------------------" "------------------------------\n"); } } /* * print_nodepda_s() -- Print out the node PDA information */ int print_nodepda_s(kaddr_t nodepda, k_ptr_t npdap, int flags, FILE *ofp) { int nodeid; k_ptr_t npgdp; if (DEBUG(DC_FUNCTRACE, 3)) { fprintf(ofp, "print_nodepda_s: nodepda=0x%llx, npdap=0x%x, " "flags=0x%x\n", nodepda, npdap, flags); } nodeid = kl_get_nodeid(nodepda); if (KL_ERROR) { kl_print_error(); return(0); } fprintf(ofp, "%4d %16llx\n", nodeid, nodepda); if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, "NODE_PG_DATA:\n\n"); npgdp = (k_ptr_t)((unsigned)npdap + kl_member_offset("nodepda_s", "node_pg_data")); fprintf(ofp, "PG_FREELIST=0x%llx\n", kl_kaddr(npgdp, "pg_data", "pg_freelst")); fprintf(ofp, "NODE_FREEMEM=%lld, NODE_FUTURE_FREEMEM=%lld\n", KL_INT(npgdp, "pg_data", "node_freemem"), KL_INT(npgdp, "pg_data", "node_future_freemem")); fprintf(ofp, "NODE_EMPTYMEM=%lld, NODE_TOTAL_MEM=%lld\n", KL_INT(npgdp, "pg_data", "node_emptymem"), KL_INT(npgdp, "pg_data", "node_total_mem")); fprintf(ofp, "\n"); } return(1); } /* * pda_s_banner() -- Print out a pda_s banner for 32 and 64 bit machines. */ void pda_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, "CPU PDA STKFLG STACK " " CURKTHREAD LTICKS\n"); } if (flags & SMAJOR) { fprintf (ofp, "================================================" "==============================\n"); } if (flags & SMINOR) { fprintf (ofp, "------------------------------------------------" "------------------------------\n"); } } /* * print_pda_s() -- Print out the internal PDA information. */ int print_pda_s(kaddr_t pda, k_ptr_t pdap, int flags, FILE *ofp) { int stkflg; kaddr_t curkthread; k_ptr_t k; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_pda_s: pda=0x%llx, pdap=0x%x, flags=0x%x\n", pda, pdap, flags); } stkflg = KL_UINT(pdap, "pda_s", "p_kstackflag"); curkthread = kl_kaddr(pdap, "pda_s", "p_curkthread"); fprintf(ofp, "%3lld ", KL_INT(pdap, "pda_s", "p_cpuid")); fprintf(ofp, "%16llx ", pda); fprintf(ofp, "%6d ", stkflg); switch (stkflg) { case 0 : /* process user mode stack */ fprintf(ofp, " USER "); break; case 1 : /* process kthread stack */ k = kl_get_kthread(curkthread, flags); if (!k) { fprintf(ofp, " ERROR! "); } else { fprintf(ofp, "%16llx ", kl_kaddr(k, "kthread", "k_stack")); kl_free_block(k); } break; case 2 : /* interrupt stack */ fprintf(ofp, "%16llx ", kl_kaddr(pdap, "pda_s", "p_intstack")); break; case 3 : /* boot stack (idle) */ fprintf(ofp, "%16llx ", kl_kaddr(pdap, "pda_s", "p_bootstack")); break; } fprintf(ofp, "%16llx ", kl_kaddr(pdap, "pda_s", "p_curkthread")); fprintf(ofp, "%10lld\n", KL_INT(pdap, "pda_s", "p_lticks")); if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, " P_CURLOCK=0x%llx, P_LASTLOCK=0x%llx\n", kl_kaddr(pdap, "pda_s", "p_curlock"), kl_kaddr(pdap, "pda_s", "p_lastlock")); fprintf(ofp, " P_RUNRUN=%llu, P_FLAGS=0x%llx\n", KL_UINT(pdap, "pda_s", "p_runrun"), KL_INT(pdap, "pda_s", "p_flags")); fprintf(ofp, " P_INTSTACK=0x%llx, P_INTLASTFRAME=0x%llx\n", kl_kaddr(pdap, "pda_s", "p_intstack"), kl_kaddr(pdap, "pda_s", "p_intlastframe")); fprintf(ofp, " P_BOOTSTACK=0x%llx, P_BOOTLASTFRAME=0x%llx\n", kl_kaddr(pdap, "pda_s", "p_bootstack"), kl_kaddr(pdap, "pda_s", "p_bootlastframe")); fprintf(ofp, " P_NESTED_INTR=%llu, P_IDLESTACKDEPTH=%llu\n", KL_UINT(pdap, "pda_s", "p_nested_intr"), KL_UINT(pdap, "pda_s", "p_idlstkdepth")); fprintf(ofp, " P_SWITCHING=%llu, P_IDLETKN=%lld\n", KL_UINT(pdap, "pda_s", "p_switching"), KL_INT(pdap, "pda_s", "p_idletkn")); fprintf(ofp, " P_PDALO=0x%llx\n", kl_get_pgi(K_PTR(pdap, "pda_s", "p_pdalo"))); } return(1); } /* * pde_banner() -- Print out banner information for pde structure. */ void pde_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf (ofp, " PDE PGI PFN N M " "VR G CC D SV NR EOP\n"); } if (flags & SMAJOR) { fprintf (ofp, "=====================================================" "=========================\n"); } if (flags & SMINOR) { fprintf (ofp, "-----------------------------------------------------" "-------------------------\n"); } } /* * print_pde() -- Print out the information in a pde_t structure. */ int print_pde(kaddr_t pde, k_ptr_t pp, FILE *ofp) { k_uint_t pgi, value; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_pde: pde=0x%llx, pp=0x%x\n", pde, pp); } pgi = kl_get_pgi(pp); if (DEBUG(DC_PAGE, 1)) { fprintf(ofp, "print_pde: pgi=0x%llx\n", pgi); } fprintf(ofp, "%16llx %16llx %8d ", pde, pgi, kl_pte_to_pfn(pp)); value = kl_member_baseval(pp, "pte", "pte_n"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_m"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_vr"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_g"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_cc"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_dirty"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_sv"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_nr"); if (KL_ERROR) { fprintf(ofp, "- "); } else { fprintf(ofp, "%lld ", value); } value = kl_member_baseval(pp, "pte", "pte_eop"); if (KL_ERROR) { fprintf(ofp, "-\n"); } else { fprintf(ofp, "%lld\n", value); } return(1); } /* * pfdat_banner() -- Print out banner information for pfdat structure */ void pfdat_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " PFDAT USE FLAGS PGNO VP/TAG" " HASH PFN\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=========================================================" "======================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "---------------------------------------------------------" "----------------------\n"); } } void decode_pfdat_flags(k_ptr_t pfd,FILE *ofp) { int vce_avoidance = kl_is_member("pfdat","pf_vcolor"); int i,firsttime; k_uint_t pf_flags,pf_vcolor; const char **Ptable; const char *tab_flags[] = { "Q", /* 0x000001 */ "BAD", /* 0x000002 */ "HASH", /* 0x000004 */ "DONE", /* 0x000008 */ "SWAP", /* 000x0010 */ "WAIT", /* 0x000020 */ "DIRTY", /* 0x000040 */ "DQ", /* 0x000080 */ "ANON", /* 0x000100 */ "SQ", /* 0x000200 */ "CW", /* 0x000400 */ "DUMP", /* 0x000800 */ "HOLE", /* 0x001000 */ "CSTALE", /* 0x002000 */ "LPGINDEX1", /* 0x004000 */ "LPGINDEX2", /* 0x008000 */ "LPGINDEX3", /* 0x010000 */ "LPGPOISON", /* 0x020000 */ "SANON", /* 0x040000 */ "RECYCLE", /* 0x080000 */ "ECCSTALE", /* 0x100000 */ "REPLICA", /* 0x200000 */ 0 }; const char *tab_no_vceavoidflags[] = { "POISONED", /* 0x400000 */ "MIGRATING", /* 0x800000 */ "ERROR", /* 0x1000000*/ "HWBAD", /* 0x2000000*/ "XP", /* 0x4000000*/ "LOCK", /* 0x8000000*/ "USERDMA", /* 0x10000000*/ "BULKDATA", /* 0x20000000*/ "HWSBE", /* 0x40000000*/ 0 }; const char *tab_vceavoidflags[] = { "USERDMA", /* 0x400000 */ "MULTICOLOR", /* 0x800000 */ 0 }; const char *tab_vceavoidflags_pre657[] = { "BAD!", /* 0x400000 */ "MULTICOLOR", /* 0x800000 */ 0 }; pf_flags = kl_member_baseval(pfd, "pfdat", "pf_flags"); if (KL_ERROR) { return; } if(pf_flags) { fprintf(ofp," PF_FLAGS : "); } else { return; } for(i = 0, firsttime = 0; tab_flags[i]; i++) { if(pf_flags & (1 << i)) { pf_flags &= ~(1 << i); print_flags(&firsttime,tab_flags[i]," ",ofp); } } if(!vce_avoidance) { Ptable = tab_no_vceavoidflags; } else { char *get_releasename(); char *rel=get_releasename(); /* make sure we display the proper flag names (they changed at 6.5.7) */ if(rel && strcmp(rel, "6.5.7f") >= 0) { Ptable = tab_vceavoidflags; } else { Ptable = tab_vceavoidflags_pre657; } } for(i = 0; Ptable[i]; i++) { if(pf_flags & (0x400000 << i)) { pf_flags &= ~(0x400000 << i); print_flags(&firsttime,Ptable[i]," ",ofp); } } if(pf_flags) { fprintf(ofp,"|Unknown(%lld)",pf_flags); } pf_vcolor = kl_member_baseval(pfd, "pfdat", "pf_vcolor"); if (KL_ERROR) { fprintf(ofp,"\n"); return; } #define PE_COLOR_SHIFT 1 #define PE_RAWWAIT 1 (pf_vcolor >> PE_COLOR_SHIFT) ? fprintf(ofp," VCOLOR : %llx",pf_vcolor >> PE_COLOR_SHIFT) : 1; (pf_vcolor & PE_RAWWAIT) ? fprintf(ofp," RAWWAIT : %lld",pf_vcolor & PE_RAWWAIT) : 1; fprintf(ofp,"\n"); } /* * print_pfdat() -- Print page frame data information. */ int print_pfdat(kaddr_t pf, k_ptr_t pfp, int flags, FILE *ofp) { fprintf(ofp, "%16llx %3d %8llx %5llu %16llx %16llx %9d\n", pf, (short)KL_INT(pfp, "pfdat", "pf_use"), KL_UINT(pfp, "pfdat", "pf_flags"), KL_UINT(pfp, "pfdat", "pf_pageno"), kl_kaddr(pfp, "pfdat", "p_un"), kl_kaddr(pfp, "pfdat", "pf_hchain"), kl_pfdattopfn(pf)); if (flags & C_FULL) { fprintf(ofp, "\n"); decode_pfdat_flags(pfp,ofp); fprintf(ofp, " PDEP1 : 0x%llx, PDEP2 : 0x%llx\n", kl_kaddr(pfp, "pfdat", "pf_pdep1"), kl_kaddr(pfp, "pfdat", "p_rmapun")); fprintf(ofp, " NEXT : 0x%llx, PREV : 0x%llx,", kl_kaddr(pfp, "pfdat", "pf_next"), kl_kaddr(pfp, "pfdat", "pf_prev")); fprintf(ofp, " RAWCNT : 0x%x\n", (short)KL_UINT(pfp, "pfdat", "pf_rawcnt")); } return(1); } /* * pid_entry_banner() -- Print out banner information for pid_entry structure */ void pid_entry_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " PID_ENTRY PID BUSY " "VPROC NEXT\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "===============================================" "=====================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-----------------------------------------------" "---------------------\n"); } } /* * print_pid_entry() -- Print page frame data information. */ int print_pid_entry(kaddr_t pid, k_ptr_t pidp, int flags, FILE *ofp) { fprintf(ofp, "%16llx %8lld %4lld %16llx %16llx\n", pid, KL_INT(pidp, "pid_entry", "pe_pid"), KL_UINT(pidp, "pid_entry", "pe_ubusy"), kl_kaddr(pidp, "pid_entry", "pe_vproc"), kl_kaddr(pidp, "pid_entry", "pe_next")); if (flags & C_NEXT) { kaddr_t vproc; k_ptr_t vprocp; fprintf(ofp, "\n"); if (!KL_UINT(pidp, "pid_entry", "pe_ubusy")) { fprintf(ofp, "0x%llx: pid_entry on freelist\n", pid); fprintf(ofp, "\n"); return(0); } else { vproc = kl_kaddr(pidp, "pid_entry", "pe_vproc"); vprocp = kl_alloc_block(VPROC_SIZE, K_TEMP); kl_get_struct(vproc, VPROC_SIZE, vprocp, "vproc"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_VPROC; return(0); } fprintf(ofp, " "); vproc_banner(ofp, BANNER); fprintf(ofp, " "); vproc_banner(ofp, SMINOR); flags |= C_INDENT; print_vproc(vproc, vprocp, flags, ofp); kl_free_block(vprocp); fprintf(ofp, "\n"); } } return(1); } /* * pmap_banner() */ void pmap_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf (ofp, " PMAP PREGION TYPE " "FLAGS SCOUNT PTR\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf (ofp, "==========================================" "===============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf (ofp, "------------------------------------------" "-------------------------------\n"); } } /* * print_pmap() -- Print out the information in a pmap_t struct. */ int print_pmap(kaddr_t p, k_ptr_t pmp, int flags, FILE *ofp) { fprintf(ofp, "%16llx %16llx %3llu %4llx %2lld %16llx\n", p, kl_kaddr(pmp, "pmap", "pmap_preg"), KL_UINT(pmp, "pmap", "pmap_type"), KL_UINT(pmp, "pmap", "pmap_flags"), KL_INT(pmp, "pmap", "pmap_scount"), kl_kaddr(pmp, "pmap", "pmap_ptr")); return(0); } /* * pregion_banner() -- Print out banner information for pregion structure. */ void pregion_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " PREGION REGION PGLEN " " VALID TYPE FLAGS\n"); } else { fprintf(ofp, " PREGION REGION PGLEN " " VALID TYPE FLAGS\n"); } } if (flags & SMAJOR) { fprintf(ofp, "=====================================" "===========================\n"); } if (flags & SMINOR) { fprintf(ofp, "-------------------------------------" "---------------------------\n"); } } /* Taken from region.h. Only used by pregion_type... So we define it here. */ #define PT_UNUSED 0x00 /* Unused region. */ #define PT_STACK 0x03 /* Stack region. */ #define PT_SHMEM 0x04 /* Shared memory region. */ #define PT_MEM 0x05 /* Generic memory region. */ /* Space was Double mapped memory.*/ #define PT_GR 0x08 /* Graphics region */ #define PT_MAPFILE 0x09 /* Memory mapped file region */ #define PT_PRDA 0x0a /* PRDA region */ const char * pregion_type(int type) { return((type == PT_MAPFILE) ? "MAPFILE" : (type == PT_STACK) ? "STACK " : (type == PT_MEM) ? "GEN MEM" : (type == PT_SHMEM) ? "SH MEM " : (type == PT_GR) ? "GRAPHIC" : (type == PT_PRDA) ? "PRDA " : (type == PT_UNUSED) ? "UNUSED " : "UNKNOWN"); } void decode_pregion_flags(k_ptr_t prp,FILE *ofp) { int p_flags = KL_UINT(prp, "pregion", "p_flags"); int i,firsttime; const char *tab_flags[] = { "PF_DUP", /* 0x1 Dup on fork. */ "PF_NOPTRES", /* 0x2 No pmap reservations made */ "PF_NOSHARE", /* 0x4 Do not share on sproc */ "PF_SHARED", /* 0x8 It is possible that this pregion's * pmap is shared with someone */ "PF_AUDITR", /* 0x10 Read audit */ "PF_AUDITW", /* 0x20 Write audit */ "PF_FAULT", /* 0x40 Vfault logging enabled */ "PF_TSAVE", /* 0x80 if a tsave'd pregion */ "PF_PRIVATE", /* 0x100 pregion is on private list */ "PF_PRIMARY", /* 0x200 pregion is 'primary' exec'd object * */ "PF_TXTPVT", /* 0x400 privatized text pregion */ "PF_LCKNPROG", /* 0x800 pregion lockdown in progress */ 0 }; if(p_flags) { fprintf(ofp,"\n P_FLAGS : "); } else { return; } for(i = 0, firsttime = 0; tab_flags[i]; i++) { if(p_flags & (1<ut_kthread * * We don't have to get the proc_proxy struct since it is * the first element in the proc struct. */ uthread = kl_kaddr(procp, "proc_proxy_s", "prxy_threads"); /* If there is no uthread pointer, check to see if the proc is * a zombie. We can do this by checking the p_stat filed in * the proc struct. If it is a zombile, print the appropriate * string for wchan and proc name respectively and then return. */ if (uthread == (kaddr_t)NULL) { if (PTRSZ64) { fprintf(ofp, "0000000000000000 \n"); } else { fprintf(ofp, "00000000 \n"); } return(0); } utp = kl_get_uthread_s(uthread, 2, flags); if (KL_ERROR) { kl_print_error(); return(1); } if (kl_kaddr(utp, "kthread", "k_wchan")) { if (PTRSZ64) { fprintf(ofp, "%16llx ", kl_kaddr(utp, "kthread", "k_wchan")); } else { fprintf(ofp, "%8llx ", kl_kaddr(utp, "kthread", "k_wchan")); } } else { if (PTRSZ64) { fprintf(ofp, "0000000000000000 "); } else { fprintf(ofp, "00000000 "); } } name = kl_kthread_name(utp); if (KL_ERROR) { fprintf(ofp, "ERROR\n"); } else if (name) { fprintf(ofp, "%s\n", name); } else { fprintf(ofp, "\n"); } if (flags & C_FULL) { k_ptr_t tptr; fprintf(ofp, "\n"); fprintf(ofp, "SELECTED FIELDS FROM THE KTHREAD STRUCT AT 0x%llx:\n", uthread); print_kthread_full(utp, flags, ofp); fprintf(ofp, "\n"); fprintf(ofp, "SELECTED FIELDS FROM THE PROC STRUCT:\n"); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "P_CHILDPIDS=0x%llx, ", kl_kaddr(procp, "proc", "p_childpids")); /* The following values are from the rusage struct, which is * impedded in the proc struct. */ tptr = (k_ptr_t)((uint)procp + kl_member_offset("proc", "p_cru")); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "P_CRU:\n"); indent_it(flags, ofp); fprintf(ofp, " RU_UTIME=%lld, ", KL_UINT(tptr, "rusage", "ru_utime")); fprintf(ofp, "RU_STIME=%lld\n", KL_UINT(tptr, "rusage", "ru_stime")); indent_it(flags, ofp); fprintf(ofp, "P_SLINK=0x%llx, P_SHADDR=0x%llx\n\n", kl_kaddr(procp, "proc", "p_slink"), kl_kaddr(procp, "proc", "p_shaddr")); list_proc_files(proc, 2, (flags & (~C_FULL)), ofp); fprintf(ofp, "\n"); } kl_free_block(utp); return(1); } /* * list_active_procs() */ int list_active_procs(int flags, FILE *ofp) { int i, first_time = 1, proc_cnt = 0; k_ptr_t pidp, bhvdp, vprocp, procp; kaddr_t pid, vproc, proc, bhv; pidp = kl_alloc_block(PID_ENTRY_SIZE, K_TEMP); vprocp = kl_alloc_block(VPROC_SIZE, K_TEMP); pid = K_PID_ACTIVE_LIST; /* We have to step over the first entry as it is just * the list head. */ kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); do { kl_get_struct(pid, PID_ENTRY_SIZE, pidp, "pid_entry"); if (KL_ERROR) { break; } vproc = kl_kaddr(pidp, "pid_entry", "pe_vproc"); kl_get_struct(vproc, VPROC_SIZE, vprocp, "vproc"); if (KL_ERROR) { kl_print_error(); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); continue; } bhv = kl_kaddr(vprocp, "vproc", "vp_bhvh"); proc = kl_bhv_pdata(bhv); if (KL_ERROR) { kl_print_error(); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); continue; } /* If proc turns out to be invalid, print an error message and * continue. It's hard to say what might happen. We might just * get the next proc struct. Or, there might have been some * corruption in the pid_active_list. We'll just hope for the * best... */ procp = kl_get_proc(proc, 2, flags); if (KL_ERROR) { kl_print_error(); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); continue; } if ((first_time == TRUE) || (flags & C_FULL)) { proc_banner(ofp, BANNER|SMAJOR); first_time = FALSE; } print_proc(proc, procp, flags, ofp); kl_free_block(procp); proc_cnt++; kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); } while (pid != K_PID_ACTIVE_LIST); kl_free_block(pidp); kl_free_block(vprocp); return(proc_cnt); } /* queue.c -- XXX TODO */ /* * region_banner() -- Print out banner information for region structure. */ void region_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " REGION TYPE RCNT PGSZ " " NOFREE VNODE FLAGS\n"); } else { fprintf(ofp, " REGION TYPE RCNT PGSZ " " NOFREE VNODE FLAGS\n"); } } if (flags & SMAJOR) { fprintf(ofp, "===============================================" "==========================\n"); } if (flags & SMINOR) { fprintf(ofp, "-----------------------------------------------" "--------------------------\n"); } } void decode_region_flags(k_ptr_t prp,FILE *ofp) { int r_flags = KL_UINT(prp, "region", "r_flags"); int i,firsttime; const char *tab_flags[] = { "RG_NOFREE", /* 0x0001 Don't free region on last detach */ "RG_LOCKED", /* 0x0002 region is locked for user DMA WAR */ "RG_LOADV", /* 0x0004 region has a loadvnode */ "RG_CW", /* 0x0008 cw region */ "RG_DFILL", /* 0x0010 Demand fill pages (not demand zero) */ "RG_AUTOGROW", /* 0x0020 Pages become autogrow after ip * shrinks */ "RG_PHYS", /* 0x0040 Region describes physical memory */ "RG_ISOLATE", /* 0x0080 Region is isolated for real-time, * no aging */ "RG_ANON", /* 0x0100 (some) pages mapped anonymously */ "RG_USYNC", /* 0x0200 Region aspace represents usync * objects */ "RG_HASSANON", /* 0x0400 region has SANON pages */ "RG_TEXT", /* 0x0800 region contains pure, read-only text * (unmodified with respect to a.out) */ "RG_AUTORESRV", /* 0x1000 reserve availsmem on demand when * page goes anonymous */ "UNK(0x2000)", /* 0x2000 UNKNOWN!!. */ "RG_PHYSIO", /* 0x4000 Region maps a physical device space */ "RG_MAPZERO", /* 0x8000 region is maps dev zero pages */ 0 }; if(r_flags) { fprintf(ofp,"\n R_FLAGS : "); } else { return; } for(i = 0, firsttime = 0; tab_flags[i]; i++) { if(r_flags & (1 << i)) { r_flags &= ~(1 << i); print_flags(&firsttime, tab_flags[i], " ", ofp); } } fprintf(ofp,"\n"); } /* * print_region() -- Print information in a region structure. */ int print_region(kaddr_t reg, k_ptr_t rp, int flags, FILE *ofp) { int firsttime; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_region: reg=0x%llx, rp=0x%x, flags=0x%x\n", reg, rp, flags); } FPRINTF_KADDR(ofp, " ", reg); fprintf(ofp, "%4llu %4llu %5lld %8llu ", KL_UINT(rp, "region", "r_type"), KL_UINT(rp, "region", "r_refcnt"), KL_INT(rp, "region", "r_pgsz"), KL_UINT(rp, "region", "r_nofree")); fprintf(ofp, "%16llx ", kl_kaddr(rp, "region", "r_vnode")); fprintf(ofp, " %5llx\n", KL_UINT(rp, "region", "r_flags")); if(flags & C_FULL) { decode_region_flags(rp,ofp); fprintf(ofp," SWAPRES = 0x%x, FILEOFF = 0x%x, " "MAXFILESZ = 0x%x\n", (__int32_t)KL_UINT(rp, "region", "r_swapres"), (__int32_t)KL_UINT(rp, "region", "r_fileoff"), (__int32_t)KL_UINT(rp, "region", "r_maxfsize")); fprintf(ofp," ANON = 0x%llx\n", kl_kaddr(rp, "region", "r_anon")); fprintf(ofp,"\n"); } return(1); } /* * list_region_pfdats() */ int list_region_pfdats(k_ptr_t rp, int flags, FILE *ofp) { int i, first_time = 1; kaddr_t value = 0, map; k_ptr_t pfp, pfbuf; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "list_region_pfdats: rp=0x%x, flags=0x%x\n", rp, flags); } if (kl_kaddr(rp, "region", "r_anon")) { map = kl_kaddr(rp, "region", "r_anon"); } else if (kl_kaddr(rp, "region", "r_vnode")) { map = kl_kaddr(rp, "region", "r_vnode"); } else { fprintf(ofp, "Don't know how to map this region!\n"); return(1); } pfbuf = kl_alloc_block(PFDAT_SIZE, K_TEMP); for (i = 0; i < KL_INT(rp, "region", "r_pgsz"); i++) { if (pfp = kl_locate_pfdat((k_uint_t)i, map, pfbuf, &value)) { if (first_time) { fprintf(ofp, "\n"); pfdat_banner(ofp, flags|(BANNER|SMINOR|C_INDENT)); first_time = 0; } indent_it((flags|C_INDENT), ofp); print_pfdat(value, pfp, flags, ofp); } } kl_free_block(pfbuf); return(0); } /* * get_rnode() -- This routine returns a pointer to an rnode. */ k_ptr_t get_rnode(kaddr_t addr, k_ptr_t rbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_rnode: addr=0x%llx, rbufp=0x%x, flags=0x%x\n", addr, rbufp, flags); } if (rbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_RNODE); return((k_ptr_t)NULL); } kl_get_struct(addr, RNODE_SIZE, rbufp, "rnode"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_RNODE; } else { return(rbufp); } return((k_ptr_t)NULL); } /* * rnode_banner() -- Print out banner information for rnode structure. */ void rnode_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " RNODE SIZE VNODE " "IOCOUNT ERROR FLAGS\n"); } else { fprintf(ofp, " RNODE SIZE VNODE " "IOCOUNT ERROR FLAGS\n"); } } if (flags & SMAJOR) { fprintf (ofp, "=======================================" "==============================\n"); } if (flags & SMINOR) { fprintf (ofp, "---------------------------------------" "------------------------------\n"); } } /* * print_rnode() -- Print out information inside an rnode. */ int print_rnode(kaddr_t addr, k_ptr_t rp, int flags, FILE *ofp) { int rnode_cnt=0; k_ptr_t nnp, bufp; kaddr_t np; indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%10lld %16llx %7lld %5lld %5llx\n", KL_INT(rp, "rnode", "r_size"), kl_bhvp_vobj(RNODE_TO_BHP(rp)), kl_kaddr(rp, "rnode", "r_bhv_desc"), KL_INT(rp, "rnode", "r_iocount"), KL_INT(rp, "rnode", "r_error")); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "NEXT=0x%llx, PREVP=0x%llx\n", kl_kaddr(rp, "rnode", "r_next"), kl_kaddr(rp, "rnode", "r_prevp")); indent_it(flags, ofp); fprintf(ofp, "MNEXT=0x%llx, MPREVP=0x%llx\n", kl_kaddr(rp, "rnode", "r_mnext"), kl_kaddr(rp, "rnode", "r_mprevp")); indent_it(flags, ofp); fprintf(ofp, "LASTR=0x%llx, LOCKTRIPS=%lld\n", kl_kaddr(rp, "rnode", "r_lastr"), KL_INT(rp, "rnode", "r_locktrips")); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "\nIOWAIT:\n\n"); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s(addr + kl_member_offset("rnode", "r_iowait"), K_PTR(rp, "rnode", "r_iowait"), flags, ofp); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "RWLOCK:\n\n"); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s(addr + kl_member_offset("rnode", "r_rwlock"), K_PTR(rp, "rnode", "r_rwlock"), flags, ofp); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "LOCK:\n\n"); indent_it(flags, ofp); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s(addr + kl_member_offset("rnode", "r_statelock"), K_PTR(rp, "rnode", "r_statelock"), flags, ofp); fprintf(ofp, "\n"); } rnode_cnt++; if (flags & C_NEXT) { np = kl_kaddr(rp, "rnode", "r_next"); while ( np ) { bufp = alloc_block(kl_struct_len("rnode"), K_TEMP); kl_get_struct(np, RNODE_SIZE, bufp, "rnode"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_RNODE; kl_free_block(bufp); fprintf(ofp, "\n"); return(-1); } else { nnp = bufp; fprintf(ofp, "\n"); rnode_banner(ofp, BANNER|SMINOR); FPRINTF_KADDR(ofp, " ", np); fprintf(ofp, "%10lld %16llx %7lld %5lld 0x%5llx\n", KL_INT(nnp, "rnode", "r_size"), kl_bhvp_vobj(RNODE_TO_BHP(nnp)), KL_INT(nnp, "rnode", "r_iocount"), KL_INT(nnp, "rnode", "r_error"), KL_UINT(nnp, "rnode", "r_flags")); rnode_cnt++; } np = kl_kaddr(nnp, "rnode", "r_next"); kl_free_block(bufp); } fprintf(ofp, "\n"); } return(rnode_cnt); } /* * sema_s_banner() -- Print out banner information for sema structure. */ void sema_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " SEMA COUNT FLAGS LOCK QUEUE\n"); } else { fprintf(ofp, " SEMA COUNT FLAGS LOCK QUEUE\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, "==================================================" "========\n"); } else { fprintf(ofp, "==================================================\n"); } } if (flags & SMINOR) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, "--------------------------------------------------" "--------\n"); } else { fprintf(ofp, "--------------------------------------------------\n"); } } } /* * print_sema_s() -- Print the contents of a semaphore structure. */ int print_sema_s(kaddr_t addr, k_ptr_t semap, int flags, FILE *ofp) { short ishorttmp; uint32_t i32tmp; uint64_t i64tmp; indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); /* Because the sema_s contains a union, and that union contains * a struct that do not have a struct type (they are defined * in-line), it is necessary to get the s_count, s_flags, and * s_lock values by brute force. */ ishorttmp = *(short *)(semap); fprintf(ofp, "%5hd", ishorttmp); ishorttmp = *(short *)((uint_t)semap + 2); fprintf(ofp, " %5hd", ishorttmp); i32tmp = *(uint32_t *)((uint_t)semap); fprintf(ofp, " %8x", i32tmp); if (PTRSZ64) { fprintf(ofp, " %16llx\n", kl_kaddr(semap, "sema_s", "s_queue")); } else { fprintf(ofp, " %8llx\n", kl_kaddr(semap, "sema_s", "s_queue")); } return(1); } /* * get_lsnode() * * This routine only returns a pointer to a "local" snode if the lsnode * at addr is valid (there is a positive reference count) or the C_ALL * flag is set. */ k_ptr_t get_lsnode(kaddr_t addr, k_ptr_t sbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_lsnode: addr=0x%llx, sbufp=0x%x, flags=0x%x\n", addr, sbufp, flags); } if (sbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_LSNODE); return((k_ptr_t)NULL); } kl_get_struct(addr, LSNODE_SIZE, sbufp, "lsnode"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_LSNODE; } else { if (addr == kl_bhvp_pdata(LSNODE_TO_BHP(sbufp))) { if (KL_UINT(sbufp, "lsnode", "ls_opencnt")) { return(sbufp); } else if (flags & C_ALL) { return(sbufp); } } KL_SET_ERROR_NVAL(KLE_BAD_LSNODE, addr, 2); } return((k_ptr_t)NULL); } /* * lsnode_banner() -- Print out banner information for an lsnode structure. */ void lsnode_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " LSNODE RCNT DEV NEXT " " VNODE FLAGS\n"); } else { fprintf(ofp, " LSNODE RCNT DEV NEXT " " VNODE FLAGS\n"); } } if (flags & SMAJOR) { fprintf(ofp, "==============================================" "===============================\n"); } if (flags & SMINOR) { fprintf(ofp, "----------------------------------------------" "-------------------------------\n"); } } /* * print_lsnode() -- Print out lsnode structure specifics. */ int print_lsnode(kaddr_t addr, k_ptr_t sp, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_lsnode: addr=0x%llx, sp=0x%x, flags=0x%x\n", addr, sp, flags); } indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%4lld %8llx ", KL_UINT(sp, "lsnode", "ls_opencnt"), KL_UINT(sp, "lsnode", "ls_dev")); fprintf(ofp, "%16llx ", kl_kaddr(sp, "lsnode", "ls_next")); fprintf(ofp, "%16llx ", kl_bhvp_vobj(LSNODE_TO_BHP(sp))); fprintf(ofp, "%7llx\n", KL_INT(sp, "lsnode", "ls_flag")); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "CVP_HANDLE = 0x%llx\n", kl_kaddr(sp, "lsnode", "ls_cvp_handle")); indent_it(flags, ofp); fprintf(ofp, "ATIME = %lld, ", KL_INT(sp, "lsnode", "ls_atime")); fprintf(ofp, "MTIME = %lld, ", KL_INT(sp, "lsnode", "ls_mtime")); fprintf(ofp, "CTIME = %lld\n", KL_INT(sp, "lsnode", "ls_ctime")); indent_it(flags, ofp); fprintf(ofp, "FSID = 0x%llx, ", KL_UINT(sp, "lsnode", "ls_fsid")); fprintf(ofp, "SIZE = %lld\n", KL_UINT(sp, "lsnode", "ls_size")); indent_it(flags, ofp); #ifdef NOTTHIS fprintf(ofp, "LOCKPID = %lld, ", kl_kaddr(sp, "lsnode", "s_lockid")); fprintf(ofp, "LOCKTRIPS = %lld\n", KL_UINT(sp, "lsnode", "s_locktrips")); indent_it(flags, ofp); fprintf(ofp, "LOCK:\n"); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s(addr + kl_member_offset("lsnode", "s_lock"), K_PTR(sp, "lsnode", "s_lock"), flags, ofp); #endif /* NOTTHIS */ fprintf(ofp, "\n"); } return(1); } /* * get_socket() -- Get a socket structure. */ k_ptr_t get_socket(kaddr_t soc, k_ptr_t sbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_socket: soc=0x%llx, sp=0x%x, flags=0x%x\n", soc, sbufp, flags); } if (sbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_SOCKET); return((k_ptr_t)NULL); } kl_get_struct(soc, SOCKET_SIZE, sbufp, "socket"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_SOCKET; return((k_ptr_t)NULL); } return(sbufp); } /* * socket_banner() -- Print banner information for socket structure. */ void socket_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " SOCKET DOMAIN TYPE STATE PCB " "RECV-Q SEND-Q\n"); } else { fprintf(ofp, " SOCKET DOMAIN TYPE STATE PCB " "RECV-Q SEND-Q\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "==========================================================" "===================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "----------------------------------------------------------" "-------------------\n"); } } /* * print_socket() -- Print out contents of a socket structure */ int print_socket(kaddr_t soc, k_ptr_t sp, int flags, FILE *ofp) { k_ptr_t unpcp, protop; k_ptr_t rcvp, sndp, sophp, domainp; kaddr_t so_rcv, so_snd; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_socket: soc=0x%llx, sp=0x%x, flags=0x%x\n", soc, sp, flags); } /* * Determine the socket domain (AF_UNIX, AF_INET, etc.) */ protop = kl_alloc_block(PROTOSW_SIZE, K_TEMP); kl_get_struct(kl_kaddr(sp, "socket", "so_proto"), PROTOSW_SIZE, protop, "protosw"); KL_CHECK_ERROR_RETURN; domainp = kl_alloc_block(DOMAIN_SIZE, K_TEMP); kl_get_struct(kl_kaddr(protop, "protosw", "pr_domain"), DOMAIN_SIZE, domainp, "domain"); KL_CHECK_ERROR_RETURN; indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", soc); switch (KL_INT(domainp, "domain", "dom_family")) { case AF_UNIX : fprintf(ofp, " UNIX "); break; case AF_INET : fprintf(ofp, " INET "); break; default : fprintf(ofp, " OTHER "); } switch (KL_INT(sp, "socket", "so_type")) { case SOCK_STREAM : fprintf(ofp, "STREAM "); break; case SOCK_DGRAM : fprintf(ofp, " DGRAM "); break; case SOCK_RAW : fprintf(ofp, " RAW "); break; case SOCK_RDM : fprintf(ofp, " RDM "); break; case SOCK_SEQPACKET : fprintf(ofp, "SEQPKT "); break; default : fprintf(ofp, " BAD "); } /* Get the pointer (in the socket struct) for so_rcv and so_snd. */ rcvp = (k_ptr_t)((uint)sp + kl_member_offset("socket", "so_rcv")); sndp = (k_ptr_t)((uint)sp + kl_member_offset("socket", "so_snd")); /* XXX - could be a problem with the next fprintf() !?! */ fprintf(ofp, "%5llx ", KL_INT(sp, "socket", "so_state") & 0xffff); fprintf(ofp, "%16llx ", kl_kaddr(sp, "socket", "so_pcb")); fprintf(ofp, "%8llu %8llu\n", KL_UINT(rcvp, "sockbuf", "sb_cc"), KL_UINT(sndp, "sockbuf", "sb_cc")); if (flags & C_FULL) { /* Get the kernel address of the rcv and snd sockbuf structures * (actually part of the socket struct itself). */ so_rcv = soc + kl_member_offset("socket", "so_rcv"); so_snd = soc + kl_member_offset("socket", "so_snd"); fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "SO_OPTIONS=0x%llx, SO_LINGER=0x%llx, SO_PGID=%lld, " "SO_PROTO=0x%llx\n", KL_INT(sp, "socket", "so_options") & 0xffff, KL_INT(sp, "socket", "so_linger") & 0xffff, KL_INT(sp, "socket", "so_pgid") & 0xffff, kl_kaddr(sp, "socket", "so_proto")); indent_it(flags, ofp); fprintf(ofp, "SO_HEAD=0x%llx, SO_TIMO=%lld, SO_ERROR=%llu, " "SO_OOBMARK=%llu\n", kl_kaddr(sp, "socket", "so_head"), KL_INT(sp, "socket", "so_timeo"), KL_UINT(sp, "socket", "so_error"), KL_UINT(sp, "socket", "so_oobmark")); indent_it(flags, ofp); fprintf(ofp, "SO_Q0=0x%llx, SO_Q0LEN=%lld, SO_Q=0x%llx, SO_QLEN=%lld\n", kl_kaddr(sp, "socket", "so_q0"), KL_INT(sp, "socket", "so_q0len"), kl_kaddr(sp, "socket", "so_q"), KL_INT(sp, "socket", "so_qlen")); indent_it(flags, ofp); fprintf(ofp, "SO_QLIMIT=%lld, SO_LABEL=0x%llx, SO_SENDLABEL=0x%llx\n", KL_INT(sp, "socket", "so_qlimit"), kl_kaddr(sp, "socket", "so_label"), kl_kaddr(sp, "socket", "so_sendlabel")); indent_it(flags, ofp); fprintf(ofp, "SO_ACL=0x%llx, SO_CALLOUT=0x%llx, " "SO_CALLOUT_ARG=0x%llx\n", kl_kaddr(sp, "socket", "so_acl"), kl_kaddr(sp, "socket", "so_callout"), kl_kaddr(sp, "socket", "so_callout_arg")); sophp = K_PTR(sp, "socket", "so_ph"); indent_it(flags, ofp); fprintf(ofp, "SO_SEM:\n"); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s( soc + kl_member_offset("socket", "so_sem"), K_PTR(sp, "socket", "so_sem"), (flags & C_INDENT)|(flags & ~(C_FULL)), ofp); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); indent_it(flags, ofp); fprintf(ofp, "SO_PH:\n"); indent_it(flags, ofp); fprintf(ofp, " PH_LIST=0x%llx, PH_LOCK=0x%llx\n", kl_kaddr(sophp, "pollhead", "ph_list"), KL_UINT(sophp, "pollhead", "ph_lock")); indent_it(flags, ofp); fprintf(ofp, " PH_GEN=0x%llx, PH_EVENTS=0x%lld, PH_USER=%lld\n", KL_UINT(sophp, "pollhead", "ph_gen"), KL_INT(sophp, "pollhead", "ph_events"), KL_INT(sophp, "pollhead", "ph_user")); if (DEBUG(DC_SOCKET, 1)) { fprintf(ofp, "print_socket: so_rcv=0x%llx, rcvp=0x%x\n", so_rcv, rcvp); fprintf(ofp, "print_socket: so_snd=0x%llx, sndp=0x%x\n", so_snd, sndp); } indent_it(flags, ofp); fprintf(ofp, "SO_RCV:\n"); indent_it(flags, ofp); fprintf(ofp, " SB_CC=%llu, SB_LOWAT=%llu, SB_HIWAT=%llu, " "SB_MB=0x%llx\n", KL_UINT(rcvp, "sockbuf", "sb_cc"), KL_UINT(rcvp, "sockbuf", "sb_lowat"), KL_UINT(rcvp, "sockbuf", "sb_hiwat"), kl_kaddr(rcvp, "sockbuf", "sb_mb")); indent_it(flags, ofp); fprintf(ofp, " SB_TIMEO=%lld, SB_FLAGS=0x%llx\n", KL_INT(rcvp, "sockbuf", "sb_timeo"), KL_INT(rcvp, "sockbuf", "sb_flags")); indent_it(flags, ofp); fprintf(ofp, " SB_WANTSEM:\n"); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|BANNER); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, " "); print_sema_s( so_rcv + kl_member_offset("sockbuf", "sb_wantsem"), K_PTR(rcvp, "sockbuf", "sb_wantsem"), (flags & C_INDENT)|(flags & ~(C_FULL)), ofp); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); indent_it(flags, ofp); fprintf(ofp, " SB_WAITSEM:\n"); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|BANNER); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, " "); print_sema_s( so_rcv + kl_member_offset("sockbuf", "sb_waitsem"), K_PTR(rcvp, "sockbuf", "sb_waitsem"), (flags & C_INDENT)|(flags & ~(C_FULL)), ofp); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); indent_it(flags, ofp); fprintf(ofp, "SO_SND:\n"); indent_it(flags, ofp); fprintf(ofp, " SB_CC=%llu, SB_LOWAT=%llu, SB_HIWAT=%llu, " "SB_MB=0x%llx\n", KL_UINT(sndp, "sockbuf", "sb_cc"), KL_UINT(sndp, "sockbuf", "sb_lowat"), KL_UINT(sndp, "sockbuf", "sb_hiwat"), kl_kaddr(sndp, "sockbuf", "sb_mb")); indent_it(flags, ofp); fprintf(ofp, " SB_TIMEO=%lld, SB_FLAGS=0x%llx\n", KL_INT(sndp, "sockbuf", "sb_timeo"), KL_UINT(sndp, "sockbuf", "sb_flags")); indent_it(flags, ofp); fprintf(ofp, " SB_WANTSEM:\n"); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|BANNER); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, " "); print_sema_s( so_snd + kl_member_offset("sockbuf", "sb_wantsem"), K_PTR(sndp, "sockbuf", "sb_wantsem"), (flags & C_INDENT)|(flags & ~(C_FULL)), ofp); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); indent_it(flags, ofp); fprintf(ofp, " SB_WAITSEM:\n"); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|BANNER); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, " "); print_sema_s( so_rcv + kl_member_offset("sockbuf", "sb_waitsem"), K_PTR(rcvp, "sockbuf", "sb_waitsem"), (flags & C_INDENT)|(flags & ~(C_FULL)), ofp); fprintf(ofp, " "); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, "\n"); fprintf(ofp, "SO_CPU=0x%llx\n", KL_UINT(sp, "socket", "so_cpu") & 0xffff); } if (flags & C_NEXT) { fprintf(ofp, "\n"); /* stuff the protocol type into the upper part of flags */ flags |= (KL_INT(protop, "protosw", "pr_protocol") << 16); flags |= C_INDENT; switch (KL_INT(domainp, "domain", "dom_family")) { case AF_UNIX : unpcp = kl_alloc_block(UNPCB_SIZE, K_TEMP); kl_get_struct(kl_kaddr(sp, "socket", "so_pcb"), UNPCB_SIZE, unpcp, "unpcb"); if (!KL_ERROR) { unpcb_banner(ofp, flags|BANNER|SMINOR); indent_it(flags, ofp); print_unpcb(kl_kaddr(sp, "socket", "so_pcb"), unpcp, flags, ofp); fprintf(ofp, "\n"); } break; case AF_INET : unpcp = kl_alloc_block(INPCB_SIZE, K_TEMP); kl_get_struct(kl_kaddr(sp, "socket", "so_pcb"), INPCB_SIZE, unpcp, "inpcb"); if (!KL_ERROR) { inpcb_banner(ofp, flags|BANNER|SMINOR); indent_it(flags, ofp); print_inpcb(kl_kaddr(sp, "socket", "so_pcb"), unpcp, flags, ofp); fprintf(ofp, "\n"); } break; default : break; } } kl_free_block(protop); kl_free_block(domainp); return(0); } /* * list_sockets() -- List out sockets open on certain file structures. */ int list_sockets(int flags, FILE *ofp) { #ifdef NOTTHIS /* This whole function is not working, have it do nothing for now... */ int i, first_time = 1, soc_cnt = 0; kaddr_t nextfile; k_ptr_t kfp, vp, sp; vp = kl_alloc_block(VNODE_SIZE, K_TEMP); kfp = kl_alloc_block(VFILE_SIZE, K_TEMP); sp = kl_alloc_block(SOCKET_SIZE, K_TEMP); nextfile = K_ACTIVEFILES; while (nextfile) { get_vfile(nextfile, kfp, flags); if (KL_ERROR) { if (DEBUG(DC_SOCKET, 1)) { kl_print_debug("list_sockets"); } /* * XXX: The "file" struct does not exist anymore. * It's changed to "vfile". What should we * be doing here ?. * * There really is no way to get a listing of active sockets * on the system. We used to walk the list of active files, * but the file struct no longer exists and a list of active * vfiles only exists with debug kernels... */ nextfile = kl_kaddr(kfp, "file", "f_next"); continue; } if (KL_UINT(kfp, "vfile", "vf_count")) { get_vnode(kl_kaddr(kfp, "vfile", "__vf_data__"), vp, flags); if (KL_ERROR) { if (DEBUG(DC_GLOBAL, 1)) { kl_print_debug("list_sockets"); } nextfile = kl_kaddr(kfp, "vfile", "vf_next"); continue; } if (KL_UINT(vp, "vnode", "v_type") == VSOCK) { get_socket(kl_kaddr(vp, "vnode", "v_data"), sp, flags); if (!KL_ERROR) { if (flags & (C_FULL|C_NEXT)) { if (!first_time) { socket_banner(ofp, BANNER|SMAJOR); } else { first_time = 0; } } print_socket(kl_kaddr(vp, "vnode", "v_data"), sp, flags, ofp); soc_cnt++; } } } nextfile = kl_kaddr(kfp, "vfile", "vf_next"); } kl_free_block(vp); kl_free_block(kfp); kl_free_block(sp); return(soc_cnt); #else return(0); #endif /* NOTTHIS */ } /* * sthread_s_banner() */ void sthread_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " STHREAD NEXT PREV NAME\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=================================================" "============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-------------------------------------------------" "----------------------------\n"); } } /* * print_sthread_s() * * Print out selected fields from the sthread struct and check the flags * options for full print status. */ int print_sthread_s(kaddr_t sthread, k_ptr_t stp, int flags, FILE *ofp) { k_ptr_t kt_name; if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(ofp, "print_sthread_s: sthread=0x%llx, stp=0x%x, flags=0x%x, " "ofp=0x%x\n", sthread, stp, flags, ofp); } indent_it(flags, ofp); fprintf(ofp, "%16llx %16llx %16llx %s\n", sthread, kl_kaddr(stp, "sthread_s", "st_next"), kl_kaddr(stp, "sthread_s", "st_prev"), kl_kthread_name(stp)); return(1); } /* * list_active_sthreads() */ int list_active_sthreads(int flags, FILE *ofp) { int sthread_cnt = 0, first_time = 1; k_ptr_t stp; kaddr_t sthread; stp = kl_alloc_block(STHREAD_S_SIZE, K_TEMP); kl_get_struct(K_STHREADLIST, STHREAD_S_SIZE, stp, "sthread_s"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_STHREAD_S; kl_print_error(); return(1); } sthread = kl_kaddr(stp, "sthread_s", "st_next"); kl_free_block(stp); if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { sthread_s_banner(ofp, BANNER|SMAJOR); } while(sthread != K_STHREADLIST) { stp = kl_get_sthread_s(sthread, 2, flags); if (KL_ERROR) { KL_ERROR |= KLE_BAD_STHREAD_S; kl_print_error(); return(sthread_cnt); } else { if (first_time == TRUE) { first_time = FALSE; } else if (flags & (C_FULL|C_NEXT)) { if (flags & C_KTHREAD) { kthread_banner(ofp, BANNER|SMAJOR); } else { sthread_s_banner(ofp, BANNER|SMAJOR); } } if (flags & C_KTHREAD) { print_kthread(sthread, stp, flags, ofp); } else { print_sthread_s(sthread, stp, flags, ofp); } if (KL_ERROR) { kl_print_error(); } kl_free_block(stp); sthread_cnt++; sthread = kl_kaddr(stp, "sthread_s", "st_next"); } } return(sthread_cnt); } /* cmd_stream.c -- XXX TODO */ /* * tcpcb_banner() -- Print out banner information for tcpcb structure. */ void tcpcb_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " TCPCB STATE FLAGS INPCB\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, " ==================================================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, " --------------------------------------------------\n"); } } /* * print_tcpcb() -- Print out an address as an tccpb structure. */ int print_tcpcb(kaddr_t tcp, k_ptr_t tcpp, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_tcpcb: tcp=0x%llx, tcpp=0x%x, flags=0x%x\n", tcp, tcpp, flags); } fprintf(ofp, " %16llx %4llx %2llx %16llx\n", tcp, KL_INT(tcpp, "tcpcb", "t_state") & 0xffff, KL_UINT(tcpp, "tcpcb", "t_flags") & 0xff, kl_kaddr(tcpp, "tcpcb", "t_inpcb")); return(1); } /* * unpcb_banner() -- Print out banner information for unpcb structure. */ void unpcb_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " UNPCB SOCKET VNODE " "INUM\n"); } else { fprintf(ofp, " UNPCB SOCKET VNODE " "INUM\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "=========================================" "=====================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "-----------------------------------------" "---------------------\n"); } } /* * print_unpcb() -- Print out an address as an uncpb structure. */ int print_unpcb(kaddr_t un, k_ptr_t unp, int flags, FILE *ofp) { if (DEBUG(DC_GLOBAL, 3)) fprintf(ofp, "print_unpcb: un=0x%llx, unp=0x%x, flags=0x%x\n", un, unp, flags); FPRINTF_KADDR(ofp, " ", un); fprintf(ofp, "%16llx ", kl_kaddr(unp, "unpcb", "unp_socket")); fprintf(ofp, "%16llx ", kl_kaddr(unp, "unpcb", "unp_vnode")); fprintf(ofp, "%8lld\n", KL_INT(unp, "unpcb", "unp_ino")); return(1); } /* * get_vfs() -- Get a vfs structure. * * We assume that vbufp is already allocated to the caller. */ k_ptr_t get_vfs(kaddr_t addr, k_ptr_t vbufp, int flags) { int type; if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_vfs: addr=0x%llx, vbufp=0x%x, flags=0x%x\n", addr, vbufp, flags); } if (vbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_VFS); return((k_ptr_t)NULL); } kl_get_struct(addr, VFS_SIZE, vbufp, "vfs"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_VFS; } else { type = KL_INT(vbufp, "vfs", "vfs_fstype"); if ((type >= 0) && (type < nfstype)) { return(vbufp); } KL_SET_ERROR_NVAL(KLE_BAD_VFS, addr, 2); } return((k_ptr_t)NULL); } /* * vfs_banner() -- Print out vfs structure banner information. */ void vfs_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " VFS INDEX TYPE VNODECOV " " DEV BH\n"); } else { fprintf(ofp, " VFS INDEX TYPE VNODECOV " " DEV BH\n"); } } if (flags & SMAJOR) { fprintf(ofp, "=============================================" "==================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------------" "----------------------------------\n"); } } /* * print_vfs() -- Print the specific fields in a vfs structure */ int print_vfs(kaddr_t addr, k_ptr_t vfsp, int flags, FILE *ofp) { int type; k_ptr_t tmpptr; kaddr_t tmpaddr; char vfs_name[128]; type = KL_INT(vfsp, "vfs", "vfs_fstype"); tmpptr = (k_ptr_t)((unsigned)_vfssw + (type * VFSSW_SIZE)); tmpaddr = kl_kaddr(tmpptr, "vfssw", "vsw_name"); kl_get_block(tmpaddr, 128, vfs_name, "vfs_name"); if (vfs_name[0] == '\0') { FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%5lld %8s %16llx %8llx %16llx\n", KL_INT(vfsp, "vfs", "vfs_fstype"), "unknown", kl_kaddr(vfsp, "vfs", "vfs_vnodecovered"), KL_INT(vfsp, "vfs", "vfs_dev"), kl_kaddr(vfsp, "vfs", "vfs_data")); } else { FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%5lld %8s %16llx %8llx %16llx\n", KL_INT(vfsp, "vfs", "vfs_fstype"), vfs_name, kl_kaddr(vfsp, "vfs", "vfs_vnodecovered"), KL_INT(vfsp, "vfs", "vfs_dev"), kl_kaddr(vfsp, "vfs", "vfs_bh")); } if (flags & C_FULL) { fprintf(ofp, "\n"); fprintf(ofp, "VFS_NEXT=0x%llx, VFS_PREVP=0x%llx\n", kl_kaddr(vfsp, "vfs", "vfs_next"), kl_kaddr(vfsp, "vfs", "vfs_prevp")); fprintf(ofp, "VFS_FSID=0x%llx, VFS_OP=0x%llx\n", kl_kaddr(vfsp, "vfs", "vfs_fsid"), kl_kaddr(vfsp, "vfs", "vfs_op")); fprintf(ofp, "VFS_DCOUNT=%lld, VFS_FLAG=0x%llx, VFS_NSUBMOUNTS=%llu\n", KL_INT(vfsp, "vfs", "vfs_dcount"), KL_UINT(vfsp, "vfs", "vfs_flag"), KL_UINT(vfsp, "vfs", "vfs_nsubmounts")); fprintf(ofp, "VFS_BUSYCNT=%lld, VFS_BSIZE=%llu, VFS_BCOUNT=%llu\n", KL_INT(vfsp, "vfs", "vfs_busycnt"), KL_UINT(vfsp, "vfs", "vfs_bsize"), KL_UINT(vfsp, "vfs", "vfs_bcount")); fprintf(ofp, "VFS_WAIT:\n"); sema_s_banner(ofp, (flags & C_INDENT)|BANNER|SMINOR); print_sema_s(addr + kl_member_offset("vfs", "vfs_wait"), K_PTR(vfsp, "vfs", "vfs_wait"), (flags & ~(C_FULL)), ofp); sema_s_banner(ofp, (flags & C_INDENT)|SMINOR); fprintf(ofp, "VFS_MAC=0x%llx, VFS_ACL=0x%llx\n", kl_kaddr(vfsp, "vfs", "vfs_mac"), kl_kaddr(vfsp, "vfs", "vfs_acl")); fprintf(ofp, "VFS_CAP=0x%llx, VFS_INF=0x%llx\n", kl_kaddr(vfsp, "vfs", "vfs_cap"), kl_kaddr(vfsp, "vfs", "vfs_inf")); fprintf(ofp, "VFS_ALTFSID=0x%llx\n", kl_kaddr(vfsp, "vfs", "vfs_altfsid")); fprintf(ofp, "\n"); } return(1); } /* * get_vnode() * * This routine only returns a pointer to a vnode if the vnode at * addr is valid (there is a positive reference count) or the C_ALL * flag is set. */ k_ptr_t get_vnode(kaddr_t addr, k_ptr_t vbufp, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_vnode: addr=0x%llx, vbufp=0x%x, flags=0x%x\n", addr, vbufp, flags); } if (vbufp == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_VNODE); return((k_ptr_t)NULL); } kl_get_struct(addr, VNODE_SIZE, vbufp, "vnode"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_VNODE; } else { if (!KL_ERROR) { if (KL_INT(vbufp, "vnode", "v_count")) { return(vbufp); } else if (flags & C_ALL) { return(vbufp); } } addr = kl_bhv_vobj(kl_kaddr(vbufp, "vnode", "v_bh")); KL_SET_ERROR_NVAL(KLE_BAD_VNODE, addr, 2);; } return((k_ptr_t)NULL); } /* * vnode_banner() -- Print out the banner for vnode information. */ void vnode_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " VNODE RCNT TYPE VFSP DEV " " BH\n"); } else { fprintf(ofp, " VNODE RCNT TYPE VFSP DEV " " BH\n"); } } if (flags & SMAJOR) { fprintf(ofp, "=============================================" "================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------------" "--------------------------------\n"); } } /* * print_vnode() -- Print out the contents of a vnode at a certain address */ int print_vnode(kaddr_t addr, k_ptr_t vp, int flags, FILE *ofp) { int vfs_type; char vfs_name[128]; kaddr_t vfs_data; k_ptr_t vfs_ptr = 0, vfsp, vfsswp; indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); fprintf(ofp, "%4lld ", KL_INT(vp, "vnode", "v_count")); switch (KL_INT(vp, "vnode", "v_type")) { case 0 : fprintf(ofp, " VNON "); break; case 1 : fprintf(ofp, " VREG "); break; case 2 : fprintf(ofp, " VDIR "); break; case 3 : fprintf(ofp, " VBLK "); break; case 4 : fprintf(ofp, " VCHR "); break; case 5 : fprintf(ofp, " VLNK "); break; case 6 : fprintf(ofp, "VFIFO "); break; case 7 : fprintf(ofp, "VXNAM "); break; case 8 : fprintf(ofp, " VBAD "); break; case 9 : fprintf(ofp, "VSOCK "); break; default : fprintf(ofp, " "); break; } fprintf(ofp, "%16llx ", kl_kaddr(vp, "vnode", "v_vfsp")); fprintf(ofp, "%8llx ", KL_INT(vp, "vnode", "v_rdev")); fprintf(ofp, "%16llx\n", kl_kaddr(vp, "vnode", "v_bh")); if (flags & C_FULL) { fprintf(ofp, "\n"); indent_it(flags, ofp); fprintf(ofp, "V_LIST:\n"); indent_it(flags, ofp); fprintf(ofp, " VL_NEXT=0x%llx, VL_PREV=0x%llx\n", kl_kaddr(vp, "vnlist", "vl_next"), kl_kaddr(vp, "vnlist", "vl_prev")); indent_it(flags, ofp); fprintf(ofp, "V_FLAG=0x%llx, V_NAMECAP=0x%llx\n", KL_UINT(vp, "vnode", "v_flag"), KL_UINT(vp, "vnode", "v_namecap")); indent_it(flags, ofp); fprintf(ofp, "V_VFSMOUNTEDHERE=0x%llx, V_STREAM=0x%llx\n", kl_kaddr(vp, "vnode", "v_vfsmountedhere"), kl_kaddr(vp, "vnode", "v_stream")); indent_it(flags, ofp); fprintf(ofp, "V_FILOCKS=0x%llx, V_FILOCKSEM=0x%llx\n", kl_kaddr(vp, "vnode", "v_filocks"), kl_kaddr(vp, "vnode", "v_filocksem")); indent_it(flags, ofp); fprintf(ofp, "V_NUMBER=%llu, V_LISTID=%lld, V_INTPCOUNT=%lld\n", KL_UINT(vp, "vnode", "v_number"), KL_INT(vp, "vnode", "v_listid"), KL_INT(vp, "vnode", "v_intpcount")); indent_it(flags, ofp); fprintf(ofp, "V_HASHP=0x%llx, V_HASHN=0x%llx\n", kl_kaddr(vp, "vnode", "v_hashp"), kl_kaddr(vp, "vnode", "v_hashn")); indent_it(flags, ofp); fprintf(ofp, " V_PGCNT=%lld, V_DBUF=%lld, V_DPAGES=0x%llx\n", KL_INT(vp, "vnode", "v_pgcnt"), KL_INT(vp, "vnode", "v_dbuf"), kl_kaddr(vp, "vnode", "v_dpages")); indent_it(flags, ofp); fprintf(ofp, " V_BUF=0x%llx, V_BUF_LOCK=0x%llx, V_BUFGEN=%lld\n", kl_kaddr(vp, "vnode", "v_buf"), kl_kaddr(vp, "vnode", "v_buf_lock"), KL_INT(vp, "vnode", "v_bufgen")); } if (flags & C_NEXT) { fprintf(ofp, "\n"); vfs_type = KL_INT(vp, "vnode", "v_type"); if (!(vfs_data = kl_bhv_pdata(kl_kaddr(vp, "vnode", "v_bh")))) { return(0); } flags |= C_INDENT; switch (vfs_type) { case VCHR: { k_uint_t flag; #define SCOMMON 0x20 /* from fs/specfs/spec_csnode.h */ kl_get_block(vfs_data + kl_member_offset("csnode", "cs_flag"), 8, (k_ptr_t)&flag, "cs_flag"); if (KL_ERROR) { return(0); } if (flag & SCOMMON) { vfs_ptr = kl_alloc_block(CSNODE_SIZE, K_TEMP); kl_get_struct(vfs_data, CSNODE_SIZE, vfs_ptr, "csnode"); /* XXX - Need to have print_lsnode() func */ } else { vfs_ptr = kl_alloc_block(LSNODE_SIZE, K_TEMP); kl_get_struct(vfs_data, LSNODE_SIZE, vfs_ptr, "lsnode"); fprintf(ofp, " "); lsnode_banner(ofp, BANNER); fprintf(ofp, " "); lsnode_banner(ofp, SMINOR); print_lsnode(vfs_data, vfs_ptr, flags, ofp); } kl_free_block(vfs_ptr); if (vfs_data = kl_kaddr(vp, "vnode", "v_stream")) { vfs_ptr = kl_alloc_block(STDATA_SIZE, K_TEMP); kl_get_struct(vfs_data, STDATA_SIZE, vfs_ptr, "stdata"); fprintf(ofp, "\n"); stream_banner(ofp, BANNER|SMINOR|C_INDENT); print_stream(vfs_data, vfs_ptr, 0, flags|C_INDENT, ofp); kl_free_block(vfs_ptr); } } break; default: vfsp = kl_alloc_block(VFS_SIZE, K_TEMP); get_vfs(kl_kaddr(vp, "vnode", "v_vfsp"), vfsp, flags); if (KL_ERROR) { kl_print_error(); kl_free_block(vfsp); return(0); } vfsswp = (k_ptr_t)((unsigned)_vfssw + (VFSSW_SIZE * KL_INT(vfsp, "vfs", "vfs_fstype"))); kl_free_block(vfsp); kl_get_block(kl_kaddr(vfsswp, "vfssw", "vsw_name"), 128, vfs_name, "vfs_name"); if (!strcmp(vfs_name, FSID_NFS)) { vfs_ptr = kl_alloc_block(RNODE_SIZE, K_TEMP); kl_get_struct(vfs_data, RNODE_SIZE, vfs_ptr, "rnode"); fprintf(ofp, " "); rnode_banner(ofp, BANNER); fprintf(ofp, " "); rnode_banner(ofp, SMINOR); print_rnode(vfs_data, vfs_ptr, flags, ofp); kl_free_block(vfs_ptr); } else if (!strcmp(vfs_name, FSID_EFS)) { vfs_ptr = kl_alloc_block(INODE_SIZE, K_TEMP); kl_get_struct(vfs_data, INODE_SIZE, vfs_ptr, "inode"); fprintf(ofp, " "); inode_banner(ofp, BANNER); fprintf(ofp, " "); inode_banner(ofp, SMINOR); print_inode(vfs_data, vfs_ptr, flags, ofp); kl_free_block(vfs_ptr); } else if (!strcmp(vfs_name, FSID_XFS)) { vfs_ptr = kl_alloc_block(XFS_INODE_SIZE, K_TEMP); kl_get_struct(vfs_data, XFS_INODE_SIZE, vfs_ptr, "inode"); fprintf(ofp, " "); xfs_inode_banner(ofp, BANNER); fprintf(ofp, " "); xfs_inode_banner(ofp, SMINOR); print_xfs_inode(vfs_data, vfs_ptr, flags, ofp); kl_free_block(vfs_ptr); } else if (!strcmp(vfs_name, FSID_FD)) { } else if (!strcmp(vfs_name, FSID_NAMEFS)) { } else if (!strcmp(vfs_name, FSID_FIFOFS)) { } else if (!strcmp(vfs_name, FSID_DOS)) { } else if (!strcmp(vfs_name, FSID_ISO9660)) { } else if (!strcmp(vfs_name, FSID_PROCFS)) { } else if (!strcmp(vfs_name, FSID_MAC)) { } break; } } return(1); } /* * Look through the pfdat chain to see if the pgno exists. Print the * pfdat if it matches pgno. */ int print_pfdat_hchain(kaddr_t *KPpfd, k_ptr_t Ppfd, unsigned int pgno, int flags, FILE *ofp) { int pfdat_count = 0; int Itemp; if(Ppfd == NULL) { return(-1); } while(*KPpfd && !kl_get_struct(*KPpfd,PFDAT_SIZE,Ppfd,"pfdat")) { Itemp = KL_UINT(Ppfd, "pfdat", "pf_pageno"); if(Itemp == pgno) { indent_it(flags, ofp); indent_it(flags, ofp); fprintf(ofp,"PFDAT="); FPRINTF_KADDR(ofp," ",*KPpfd); fprintf(ofp,"PGNO=%d\n",pgno); if(flags & C_NEXT) { pfdat_banner(ofp,SMINOR|BANNER); print_pfdat(*KPpfd,Ppfd,flags,ofp); pfdat_banner(ofp,SMINOR); } pfdat_count++; } *KPpfd = kl_kaddr(Ppfd,"pfdat","pf_hchain"); } return(pfdat_count); } /* * Look through the pfdat chain to see if the pgno exists. Print the * pfdat if it matches pgno. */ int print_pfdat_hchain_ignorepgno(kaddr_t *KPpfd, k_ptr_t Ppfd, unsigned int pgno, int flags, FILE *ofp) { int pfdat_count = 0; int Itemp; if(Ppfd == NULL) { return(-1); } while(*KPpfd && !kl_get_struct(*KPpfd,PFDAT_SIZE,Ppfd,"pfdat")) { Itemp = KL_UINT(Ppfd, "pfdat", "pf_pageno"); indent_it(flags, ofp); indent_it(flags, ofp); fprintf(ofp,"PFDAT="); FPRINTF_KADDR(ofp," ",*KPpfd); fprintf(ofp,"PGNO=%d\n",Itemp); if(flags & C_NEXT) { pfdat_banner(ofp,SMINOR|BANNER); print_pfdat(*KPpfd,Ppfd,flags,ofp); pfdat_banner(ofp,SMINOR); } pfdat_count++; *KPpfd = kl_kaddr(Ppfd,"pfdat","pf_hchain"); } return(pfdat_count); } /* * Hash table stuff for the page cache in the anonymous object. Given an * index into the hash table array return the head of the linked list. */ kaddr_t get_head_addr(kaddr_t KPcache, k_ptr_t Pcache,kaddr_t KPptr,int index) { int Itemp = KL_INT(Pcache,"pcache","pc_size"); KPptr = KPcache + kl_member_offset("pcache","pc_un"); if(Itemp == 1) { return(KPptr); } else { kl_get_kaddr(KPptr, &KPptr, "pc_bucket"); if(!KL_ERROR) { return(KPptr + index * K_NBPW); } } return(0); } /* * Hash table stuff for the page cache in the anonymous object. Given a * page no. (pgno in the pfdat) return the head of the linked list containing * the page no. */ kaddr_t phash_head_addr(kaddr_t KPcache, k_ptr_t Pcache,kaddr_t KPptr,int pgno) { int Itemp = KL_INT(Pcache,"pcache","pc_size"); return(get_head_addr(KPcache,Pcache,KPptr,(pgno & (Itemp-1)))); } /* * print_pcache() -- Print out the contents of a pcache at a certain address * Like idbg ... we also print pfdat's in ascending order of their pgno's. */ #define MAX_PCACHE_PAGES_TO_DISPLAY 25 #define IS_LINK_INDEX(ptr) (((__psunsigned_t)ptr) <= MAX_BUCKETS) #define LINK_INDEX(ptr) ((__psint_t)(ptr) - 1) #define MAX_BUCKETS (16*1024*1024) /* 16 million */ #define GET_HEAD_ADDR get_head_addr #define PHASH_HEAD_ADDR phash_head_addr int print_pcache_ignorepgno(kaddr_t addr, k_ptr_t vp, int flags, FILE *ofp) { kaddr_t KPptr0,KPptr1; k_ptr_t Pptr0, Pptr1; int i=0,pcache_size=kl_struct_len("pcache"),pgno; int pfdat_count=0; int max_pgno = 0; int maxpages; int Itemp; indent_it(flags, ofp); fprintf(ofp,"PCACHE="); FPRINTF_KADDR(ofp,"\n",addr); /* * Do we have more than we can handle... If so, just print a nice * message and return. */ if(!((max_pgno=KL_INT(vp,"pcache","pc_count")) < MAX_PCACHE_PAGES_TO_DISPLAY) && !(flags & C_FULL)) { indent_it(flags, ofp); fprintf(ofp, "...\n"); indent_it(flags, ofp); fprintf(ofp, "Too many pages, Use -a flag to display all of them.\n"); indent_it(flags, ofp); fprintf(ofp, "...\n"); return(0); } if(max_pgno) { indent_it(flags, ofp); fprintf(ofp,"Printing pfdat's in non-sorted order w.r.t " "pfdat.pf_pageno.\n"); } Pptr0 = kl_alloc_block(PFDAT_SIZE,K_TEMP); if(KL_INT(vp, "pcache", "pc_size") == 1) { /* Linked list. */ /* First pfdat in chain. */ KPptr0 = kl_kaddr(vp, "pcache", "pc_un"); KPptr1 = KPptr0; Itemp = print_pfdat_hchain_ignorepgno(&KPptr1, Pptr0,0, flags, ofp); max_pgno -= Itemp; pfdat_count += Itemp; } else { /* Hash table. */ maxpages = (PTRSZ64 ? Btoc(KL_HIUSRATTACH_64) : Btoc(KL_HIUSRATTACH_32)); for(pgno = 0; pgno < KL_INT(vp, "pcache", "pc_size"); pgno++) { KPptr0 = get_head_addr(addr, vp, KPptr0, pgno); kl_get_kaddr(KPptr0,&KPptr0,"pfdat"); if(KPptr0 && (Itemp = print_pfdat_hchain_ignorepgno(&KPptr0, Pptr0, pgno, flags, ofp))) { /* We don't get out of the loop as * soon as we find our pfdat * because there may be pfdat's with * duplicate pgno's.. -- see * comment in function pcache_next. */ pfdat_count +=Itemp; max_pgno -=Itemp; } if (DEBUG(DC_FUNCTRACE,3)) { fprintf(ofp,"MAX_PGNO=%lld, PFDAT_COUNT=%d, PGNO=%d\n", KL_INT(vp,"pcache","pc_count"), pfdat_count,pgno); } } /* max_pgno */ } kl_free_block(Pptr0); if(max_pgno > 0) { indent_it(flags|C_INDENT, ofp); fprintf(ofp,"ERROR: Could not find %d pfdat's\n",max_pgno); } indent_it(flags|C_INDENT, ofp); PLURAL("pfdat", pfdat_count, ofp); return(pfdat_count); } int print_pcache(kaddr_t addr, k_ptr_t vp, int flags, FILE *ofp) { kaddr_t KPptr0,KPptr1; k_ptr_t Pptr0, Pptr1; int i=0,pcache_size=kl_struct_len("pcache"),pgno; int pfdat_count=0; int max_pgno = 0; int maxpages; int Itemp; indent_it(flags, ofp); fprintf(ofp,"PCACHE="); FPRINTF_KADDR(ofp,"\n",addr); /* * Do we have more than we can handle... If so, just print a nice * message and return. */ if(!((max_pgno=KL_INT(vp,"pcache","pc_count")) < MAX_PCACHE_PAGES_TO_DISPLAY) && !(flags & C_ALL)) { indent_it(flags, ofp); fprintf(ofp, "...\n"); indent_it(flags, ofp); fprintf(ofp, "Too many pages, Use -a flag to display all of them.\n"); indent_it(flags, ofp); fprintf(ofp, "...\n"); return(0); } if(max_pgno) { indent_it(flags, ofp); fprintf(ofp,"Printing pfdat's in sorted order w.r.t " "pfdat.pf_pageno.\n"); } Pptr0 = kl_alloc_block(PFDAT_SIZE, K_TEMP); if(KL_INT(vp, "pcache", "pc_size") == 1) { /* Linked list. */ /* First pfdat in chain. */ KPptr0 = kl_kaddr(vp, "pcache", "pc_un"); for(pgno = 0; max_pgno; pgno++) { KPptr1 = KPptr0; Itemp = print_pfdat_hchain(&KPptr1,Pptr0,pgno, flags, ofp); max_pgno -= Itemp; pfdat_count += Itemp; } } else { /* Hash table. */ maxpages = (PTRSZ64 ? Btoc(KL_HIUSRATTACH_64) : Btoc(KL_HIUSRATTACH_32)); for(pgno=0;(max_pgno && (pgno != (maxpages + 1))); pgno++) { KPptr0 = PHASH_HEAD_ADDR(addr,vp,KPptr0,pgno); pfdat_is_link: kl_get_kaddr(KPptr0, &KPptr0, "pfdat"); if(KPptr0 && (Itemp = print_pfdat_hchain(&KPptr0, Pptr0, pgno, flags,ofp))) { /* We don't get out of the loop as * soon as we find our pfdat * because there may be pfdat's with * duplicate pgno's.. -- see * comment in function pcache_next. */ pfdat_count +=Itemp; max_pgno -=Itemp; } /* print_pfdat_hchain changes KPptr0. */ if(KPptr0 && IS_LINK_INDEX(KPptr0)) { Itemp = LINK_INDEX(KPptr0); KPptr0 = GET_HEAD_ADDR(addr, vp, KPptr0, Itemp); goto pfdat_is_link; } if (DEBUG(DC_FUNCTRACE,3)) { fprintf(ofp,"MAX_PGNO=%lld, PFDAT_COUNT=%d, PGNO=%d\n", KL_INT(vp,"pcache","pc_count"), pfdat_count,pgno); } } /* max_pgno */ } kl_free_block(Pptr0); indent_it(flags|C_INDENT, ofp); PLURAL("pfdat", pfdat_count, ofp); return(pfdat_count); } #define MAX_SCACHE_PAGES_TO_DISPLAY 25 /* * Below comes straight from scache_mgr.h */ #define SC_NONE 0 /* no cache allocated yet */ #define SC_ARRAY 1 /* cache is organized as linear array */ #define SC_HASH 2 /* cache is organized as hash table */ #define SM_SWAPHANDLE_SIZE 4 /* * Not visible to us, but typedef'd to * __uint32_t .. sizeof(__uint32_t) */ #define HANDLES_PER_BLOCK ((2*1024)/SM_SWAPHANDLE_SIZE) #define LPN_TO_BLOCK_INDEX(lpn) ((lpn) & (HANDLES_PER_BLOCK - 1)) /* * The following macro and function are exact copies of their namesakes * in the kernel. */ #define LPN_IN_BLOCK(block, lpn) \ (((lpn) >= KL_INT(block,"hashblock","hb_lpn")) && \ ((lpn) < KL_INT(block,"hashblock","hb_lpn")+HANDLES_PER_BLOCK)) #define LPN_TO_BLOCK_START(lpn) ((lpn) & ~((HANDLES_PER_BLOCK - 1))) kaddr_t scache_find_block(kaddr_t KPscache, k_ptr_t Pscache, k_ptr_t Pblock, int lpn) { kaddr_t KPblock; k_uint_t sc_size; int hash_index; if(Pblock) { sc_size = kl_member_baseval(Pscache,"scache","sc_size"); } if (KL_ERROR) { /* * Called sc_maxlpn in scache_mgr.h */ return(-1); } /* * SHASH... */ if(sc_size == 1) { KPblock = kl_kaddr(Pscache,"scache","sc_un"); } else { KPblock=kl_kaddr(Pscache,"scache","sc_un"); hash_index = ((LPN_TO_BLOCK_START(lpn) / HANDLES_PER_BLOCK) & (sc_size -1)); KPblock += (__uint64_t)(hash_index * K_NBPW); kl_get_kaddr(KPblock, &KPblock, "hashblock"); if(KL_ERROR) { return(-1); } } while (KPblock && kl_get_struct(KPblock, kl_struct_len("hashblock"), Pblock,"hashblock")) { if (LPN_IN_BLOCK(Pblock, lpn)) { return(KPblock); } KPblock = kl_kaddr(Pblock,"hashblock","hb_next"); } return(NULL); } /* * Handle printing the hash table for the scache.. once we have the * hashblock pointer... * * Mainly moved it to a separate function because indentation was getting * to be a pain. */ int print_scache_bucket(kaddr_t KPblock, k_ptr_t Pblock, int lpn, int flags, FILE *ofp) { int swap_handle_count = 0; kaddr_t KPptr; __uint32_t swaphandle; int j; int hb_count; if(Pblock == NULL) { return(-1); } hb_count = KL_INT(Pblock,"hashblock","hb_count"); for(j = 0; j < HANDLES_PER_BLOCK; j++) { KPptr = ADDR(KPblock, "hashblock", "hb_sh"); KPptr = (kaddr_t)((__uint64_t)KPptr + (LPN_TO_BLOCK_INDEX(lpn+j) * SM_SWAPHANDLE_SIZE)); if(kl_get_block(KPptr,SM_SWAPHANDLE_SIZE,&swaphandle, "sm_swaphandle_t") && swaphandle) { indent_it(flags, ofp); indent_it(flags, ofp); fprintf(ofp,"LPN=%d SWAP_HANDLE=%x\n", (lpn+j),swaphandle); swap_handle_count++; } } if (DEBUG(DC_FUNCTRACE,3)) { fprintf(ofp,"Block = %llx HB_COUNT= %d, OUR_COUNT=%d\n", KPblock, hb_count, swap_handle_count); } return(swap_handle_count); } /* * print_scache() -- Print out the contents of a scache at a certain address */ int print_scache(kaddr_t addr, k_ptr_t vp, int flags, FILE *ofp) { kaddr_t KPptr0,KPptr1; k_ptr_t Pptr0, Pptr1; int i=0,j,lpn; k_uint_t scache_mode,sc_size; int swap_handle_count=0; k_uint_t pgno,max_bucket,max_pgno; __uint32_t swaphandle; indent_it(flags, ofp); fprintf(ofp,"SCACHE="); FPRINTF_KADDR(ofp,"\n",addr); max_bucket = kl_member_baseval(vp,"scache","sc_count"); if (!KL_ERROR) { scache_mode = kl_member_baseval(vp,"scache","sc_mode"); } if (!KL_ERROR) { sc_size = kl_member_baseval(vp,"scache","sc_size"); } if (KL_ERROR) { /* * Error!. * * sc_size is called sc_maxlpn in scache_mgr.h */ return(-1); } /* * Display all the handles... */ if(scache_mode == SC_NONE) { goto end; } else if(scache_mode == SC_ARRAY) { if(!(sc_size< MAX_SCACHE_PAGES_TO_DISPLAY) && !(flags & C_ALL || flags & C_FULL)) { /* * Is this a valid check for SC_ARRAY ?.. */ indent_it(flags, ofp); fprintf(ofp, "...\n"); indent_it(flags, ofp); fprintf(ofp, "Too many handles, Use -a flag to " "display all of them.\n"); indent_it(flags, ofp); fprintf(ofp, "...\n"); return(0); } /* We do not have to worry about sorting here.. since we * look at it here in sorted order. */ for(i = 0; i < sc_size; i++) { KPptr0=kl_kaddr(vp,"scache","sc_un"); KPptr0 = (kaddr_t)((__uint64_t)KPptr0 + i * SM_SWAPHANDLE_SIZE); /* kl_get_block returns the 4-byte quantity in the * upper 4-bytes.. like in a character buffer... * that's why we have to do the shifting and stuff.. */ kl_get_block(KPptr0, SM_SWAPHANDLE_SIZE, &swaphandle,"sm_swaphandle_t"); if(KL_ERROR || (swaphandle == 0)) { continue; } indent_it(flags, ofp); indent_it(flags, ofp); fprintf(ofp,"LPN=%d SWAP_HANDLE=%x\n", i,(__uint32_t)swaphandle); swap_handle_count++; } } else if(scache_mode == SC_HASH) { if((max_bucket == 0)) { return(-1); } if(!(flags & C_ALL || flags & C_FULL)) { /* * We assume the hash table was created only because * the array got too large. */ indent_it(flags, ofp); fprintf(ofp, "...\n"); indent_it(flags, ofp); fprintf(ofp, "scache is a hash table, Use -a flag " "to display it's entries.\n"); indent_it(flags, ofp); fprintf(ofp, "...\n"); return(0); } Pptr0 = kl_alloc_block(kl_struct_len("hashblock"), K_TEMP); max_pgno = (PTRSZ64 ? Btoc(KL_HIUSRATTACH_64) : Btoc(KL_HIUSRATTACH_32)); for(pgno = 0; pgno <= max_pgno;) { KPptr0 = scache_find_block(addr,vp,Pptr0,pgno); if(KPptr0 && kl_get_struct(KPptr0, kl_struct_len("hashblock"),Pptr0, "hashblock")) { swap_handle_count += print_scache_bucket(KPptr0,Pptr0, pgno,flags, ofp); } pgno += HANDLES_PER_BLOCK; } /* max_pgno */ kl_free_block(Pptr0); } else { fprintf(KL_ERRORFP,"Bad scache mode = %llu\n",scache_mode); } end: indent_it(flags|C_INDENT, ofp); PLURAL("swap handle",swap_handle_count, ofp); return(swap_handle_count); } /* * Same as find_anonroot.... in vmidbg.c */ kaddr_t find_anonroot(kaddr_t anon) { k_ptr_t Panon; int anon_size = kl_struct_len("anon"); kaddr_t KPanon; Panon = kl_alloc_block(anon_size,K_TEMP); while(kl_get_struct(anon,anon_size,Panon,"anon") && (KPanon = kl_kaddr(Panon,"anon","a_parent"))) { anon = KPanon; } kl_free_block(Panon); return(anon); } /* * get_anon() * * This routine only returns a pointer to a anon if the anon at * addr is valid (there is a positive reference count) or the C_ALL * flag is set. */ k_ptr_t get_anon(kaddr_t KPanon, k_ptr_t Panon, int flags) { #ifdef ICRASH_DEBUG assert(Panon); #endif if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_anon: KPanon=0x%llx, Panon=0x%x, flags=0x%x\n", KPanon, Panon, flags); } if (Panon == (k_ptr_t)NULL) { KL_SET_ERROR(KLE_NULL_BUFF|KLE_BAD_ANON); } kl_get_struct(KPanon, kl_struct_len("anon"), Panon, "anon"); if (KL_ERROR) { KL_ERROR |= KLE_BAD_ANON; } else { if (!KL_ERROR) { if (KL_INT(Panon, "anon", "a_refcnt") > 0) { return(Panon); } else if (flags & C_ALL) { return(Panon); } } KL_SET_ERROR_NVAL(KLE_BAD_ANON, KPanon, 2); } return((k_ptr_t)NULL); } /* * anon_banner() -- Print out the banner for anon information. */ void anon_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " ANON LOCK REF " "DEPTH PARENT PC_COUNT PC_SIZE\n"); } else { fprintf(ofp, " ANON LOCK REF " "DEPTH PARENT PC_COUNT PC_SIZE\n"); } } if (flags & SMAJOR) { fprintf(ofp, "=============================================" "==================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------------" "----------------------------------\n"); } } /* * print_anon() -- Print out the contents of a anon at a certain address */ int print_anon(kaddr_t addr, k_ptr_t vp, int flags, FILE *ofp) { kaddr_t KPptr0,KPptr1; k_ptr_t Pptr0, Pptr1; int Itemp; indent_it(flags, ofp); FPRINTF_KADDR(ofp," ",addr); FPRINTF_KADDR(ofp," ",kl_kaddr(vp,"anon","a_lock")); fprintf(ofp,"%3lld %6llx ", KL_INT(vp,"anon","a_refcnt"), KL_INT(vp,"anon","a_depth")); FPRINTF_KADDR(ofp," ",kl_kaddr(vp,"anon","a_parent")); fprintf(ofp,"%8lld %7lld\n", KL_INT((k_ptr_t)((__psunsigned_t)vp + kl_member_offset("anon", "a_pcache")), "pcache","pc_count"), KL_INT((k_ptr_t)((__psunsigned_t)vp + kl_member_offset("anon", "a_pcache")), "pcache","pc_size")); if(flags & (C_FULL|C_NEXT|C_ALL)) { indent_it(flags|C_INDENT, ofp); fprintf(ofp,"LEFT=%-llx ", kl_kaddr(vp,"anon","a_left")); fprintf(ofp,"RIGHT=%-llx\n", kl_kaddr(vp,"anon","a_right")); /* If both the -a and -f flags are specified... then we will * do the -a route i.e., print the pfdat's in sorted order. */ if(flags & C_ALL) { Itemp = print_pcache((kaddr_t)((__uint64_t)addr + kl_member_offset("anon", "a_pcache")), (k_ptr_t) ((__psunsigned_t)vp + kl_member_offset("anon", "a_pcache")), (flags|C_INDENT),ofp); } else { Itemp = print_pcache_ignorepgno((kaddr_t)((__uint64_t)addr + kl_member_offset("anon", "a_pcache")), (k_ptr_t) ((__psunsigned_t)vp + kl_member_offset("anon", "a_pcache")), (flags|C_INDENT), ofp); } Itemp = print_scache((kaddr_t)((__uint64_t)addr + kl_member_offset("anon", "a_scache")), (k_ptr_t)((__psunsigned_t)vp + kl_member_offset("anon", "a_scache")), (flags|C_INDENT),ofp); } return(0); } int print_anontree(kaddr_t anon,int *anon_cnt,int flags,FILE *ofp) { k_ptr_t Panon; kaddr_t KPleft,KPright; Panon = kl_alloc_block(kl_struct_len("anon"),K_TEMP); if(flags & (C_FULL|C_ALL|C_NEXT)) { anon_banner(ofp, BANNER|SMINOR); } if(!kl_get_struct(anon, kl_struct_len("anon"), Panon, "anon")) { kl_free_block(Panon); return(-1); } (*anon_cnt)++; print_anon(anon,Panon,flags,ofp); if(flags & (C_FULL|C_ALL|C_NEXT)) { anon_banner(ofp, SMINOR); } KPleft = kl_kaddr(Panon,"anon","a_left"); KPright = kl_kaddr(Panon,"anon","a_right"); kl_free_block(Panon); if(KPleft) { print_anontree(KPleft,anon_cnt,flags,ofp); } if(KPright) { print_anontree(KPright,anon_cnt,flags,ofp); } return(0); } /* * zone_banner() */ void zone_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); if (PTRSZ64) { fprintf(ofp, " ZONE NAME SIZE " "TOTAL FREE PAGES NODE INDEX\n"); } else { fprintf(ofp, " ZONE NAME SIZE " "TOTAL FREE PAGES NODE INDEX\n"); } } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "================================================" "==============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "------------------------------------------------" "------------------------------\n"); } } /* * Ahem!.... defines from kern_heap.h * * Std. reminder: All the below address space macros take arguments which are * pointers in icrash process address space and not in kernel address space. * -- which is the same as k_ptr_t. * We use KL_* for any macro which is also defined by the kernel. */ /* types */ #define KL_ZONE_GLOBAL 1 /* global shared zone list */ #define KL_ZONE_GLOBAL_PRIVATE 2 /* global private zone list */ #define KL_ZONE_SET 3 /* Zone set type zones */ /* modes */ #define KL_ZONE_MODEMASK (0xf0) #define KL_ZONE_TYPEMASK (0x0f) #define KL_ZONE_NOPAGEALLOC (1 << 4) #define KL_ZONE_ENABLE_SHAKE (1 << 5) #define KL_ZONE_MODE(z) \ (kl_uint(z,"zone","zone_type",0) & KL_ZONE_MODEMASK) #define KL_ZONE_TYPE(z) \ (kl_uint(z,"zone","zone_type",0) & KL_ZONE_TYPEMASK) #define KL_ZONE_MODESET(z, mode) \ (kl_uint(z,"zone","zone_type") |= (mode & KL_ZONE_MODEMASK)) /* * print_zone() -- Print out specific zone information. */ int print_zone(kaddr_t z, k_ptr_t zbuf, int flags, FILE *ofp) { int i, count = 0, unitsize, freesize; kaddr_t bp, nbp; char zname[128]; kl_get_block(kl_kaddr(zbuf, "zone", "zone_name"), 128, &zname, "zname"); if (KL_ERROR) { return(-1); } if(!(unitsize = KL_INT(zbuf, "zone", "zone_unitsize"))) { return(-1); } freesize = KL_INT(zbuf, "zone", "zone_free_count"); FPRINTF_KADDR(ofp, " ", z); zname[20]=0; fprintf(ofp, "%20s %5d ", zname, unitsize); fprintf(ofp, "%5lld %5d %5lld %4lld %4lld", (KL_INT(zbuf, "zone", "zone_total_pages") * K_PAGESZ) / unitsize, freesize, KL_INT(zbuf, "zone", "zone_total_pages"), KL_INT(zbuf, "zone", "zone_node"), KL_INT(zbuf, "zone", "zone_index")); fprintf(ofp,"\n"); if (flags & C_FULL) { /* * Only compare the number of free blocks agianst the block free * count on non-active systems */ fprintf(ofp, "\n"); fprintf(ofp,"ZONE_TYPE = %x ",(int)KL_ZONE_TYPE(zbuf)); if (bp = kl_kaddr(zbuf, "zone", "zone_free")) { count = 1; i = 1; fprintf(ofp, "\nFREE %d BYTE BLOCKS :\n ", unitsize); while (bp) { if (PTRSZ64) { fprintf(ofp, "0x%16llx ", bp); if ((i % 4) == 0) { fprintf(ofp, "\n "); } } else { fprintf(ofp, "0x%8llx ", bp); if ((i % 6) == 0) { fprintf(ofp, "\n "); } } i++; kl_get_kaddr(bp, &nbp, "free block"); if (KL_ERROR) { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: 0x%llx is a bad block address!\n", z, bp); break; } if (nbp) { if (nbp != bp) { count++; bp = nbp; } else { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: block 0x%llx points to itself!\n", z, bp); break; } } else { bp = 0; } } } if ((i % 4) != 1) { fprintf(ofp, "\n"); } /* Direct-mapped stuff. */ if (bp = kl_kaddr(zbuf, "zone", "zone_free_dmap")) { count = 1; i = 1; fprintf(ofp, "\nFREE %d BYTE BLOCKS (DIRECT-MAPPED):\n ", unitsize); while (bp) { if (PTRSZ64) { fprintf(ofp, "0x%16llx ", bp); if ((i % 4) == 0) { fprintf(ofp, "\n "); } } else { fprintf(ofp, "0x%8llx ", bp); if ((i % 6) == 0) { fprintf(ofp, "\n "); } } i++; kl_get_kaddr(bp, &nbp, "free block"); if (KL_ERROR) { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: 0x%llx is a bad block address!\n", z, bp); break; } if (nbp) { if (nbp != bp) { count++; bp = nbp; } else { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: block 0x%llx points to itself!\n", z, bp); break; } } else { bp = 0; } } } if (freesize != count) { if (DEBUG(DC_GLOBAL, 1)) { fprintf(ofp, " ZONE 0x%llx: number of free blocks (%d) does not " "match free count (%d)\n", z, freesize, count); } fflush(ofp); } if ((i % 4) != 1) { fprintf(ofp, "\n"); } /* pfdat's allocated to this zone. */ if (bp = kl_kaddr(zbuf, "zone", "zone_page_list")) { count = 1; i = 1; fprintf(ofp, "\nLIST OF PFDATS :\n "); while (bp) { if (PTRSZ64) { fprintf(ofp, "0x%16llx ", bp); if ((i % 4) == 0) { fprintf(ofp, "\n "); } } else { fprintf(ofp, "0x%8llx ", bp); if ((i % 6) == 0) { fprintf(ofp, "\n "); } } i++; kl_get_kaddr(bp, &nbp, "pfdat"); if (KL_ERROR) { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: 0x%llx is a bad pfdat address!\n", z, bp); break; } if (nbp) { if (nbp != bp) { count++; bp = nbp; } else { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: pfdat 0x%llx points to itself!\n", z, bp); break; } } else { bp = 0; } } } if ((i % 4) != 1) { fprintf(ofp, "\n"); } /* direct-mapped pfdat's allocated to this zone. */ if (bp = kl_kaddr(zbuf, "zone", "zone_dmap_page_list")) { count = 1; i = 1; fprintf(ofp, "\nLIST OF PFDATS (DIRECT-MAPPED):\n "); while (bp) { if (PTRSZ64) { fprintf(ofp, "0x%16llx ", bp); if ((i % 4) == 0) { fprintf(ofp, "\n "); } } else { fprintf(ofp, "0x%8llx ", bp); if ((i % 6) == 0) { fprintf(ofp, "\n "); } } i++; kl_get_kaddr(bp, &nbp, "pfdat"); if (KL_ERROR) { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: 0x%llx is a bad pfdat address!\n", z, bp); break; } if (nbp) { if (nbp != bp) { count++; bp = nbp; } else { if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, " ZONE 0x%llx: pfdat 0x%llx points to itself!\n", z, bp); break; } } else { bp = 0; } } } if ((i % 4) != 1) { fprintf(ofp, "\n"); } fprintf(ofp, "\n"); } return(1); } /* * vfssw_banner() -- Print out banner information for vfssw structures. */ void vfssw_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, "INDEX NAME INIT " "VFSOPS VNODEOPS FLAG\n"); } if (flags & SMAJOR) { fprintf(ofp, "=============================================" "==================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------------" "----------------------------------\n"); } } /* * print_vfssw() -- Print the VFS table of file system names. */ int print_vfssw(int index, int flags, FILE *ofp) { kaddr_t vfs_ptr; k_ptr_t vfsswp; char vfs_name[128]; vfsswp = (k_ptr_t)((unsigned)_vfssw + (VFSSW_SIZE * index)); vfs_ptr = kl_kaddr(vfsswp, "vfssw", "vsw_name"); kl_get_block(vfs_ptr, 128, vfs_name, "vfs_name"); if (vfs_name[0] != '\0') { fprintf(ofp, "%5d %8s %16llx %16llx %16llx %8llx\n", index, vfs_name, kl_kaddr(vfsswp, "vfssw", "vsw_init"), kl_kaddr(vfsswp, "vfssw", "vsw_vfsops"), kl_kaddr(vfsswp, "vfssw", "vsw_vnodeops"), KL_INT(vfsswp, "vfssw", "vsw_flag")); return(1); } else { return(0); } } /* * vproc_banner() */ void vproc_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " VPROC PID REF_CNT BH\n"); } if (flags & SMAJOR) { fprintf(ofp, "=====================================================\n"); } if (flags & SMINOR) { fprintf(ofp, "-----------------------------------------------------\n"); } } /* * print_vproc() */ int print_vproc(kaddr_t vproc, k_ptr_t vpbuf, int flags, FILE *ofp) { indent_it(flags, ofp); fprintf(ofp, "%16llx %8lld %7lld %16llx\n", vproc, KL_INT(vpbuf, "vproc", "vp_pid"), KL_INT(vpbuf, "vproc", "vp_refcnt"), kl_kaddr(vpbuf, "vproc", "vp_bhvh")); if (flags & C_NEXT) { kaddr_t bhv, proc; k_ptr_t bhvdp, procp; fprintf(ofp, "\n"); bhv = kl_kaddr(vpbuf, "vproc", "vp_bhvh"); proc = kl_bhv_pdata(bhv); if (KL_ERROR) { kl_print_error(); return(0); } procp = kl_get_proc(proc, 2, flags); if (KL_ERROR) { kl_print_error(); return(0); } fprintf(ofp, " "); proc_banner(ofp, BANNER); fprintf(ofp, " "); proc_banner(ofp, SMINOR); flags |= C_INDENT; print_proc(proc, procp, flags, ofp); fprintf(ofp, "\n"); kl_free_block(procp); } return(1); } /* * vsocket_banner() */ void vsocket_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " VSOCKET TYPE BH FLAGS\n"); } if (flags & SMAJOR) { fprintf(ofp, "==================================================\n"); } if (flags & SMINOR) { fprintf(ofp, "--------------------------------------------------\n"); } } /* * print_vsocket() */ int print_vsocket(kaddr_t vsock, k_ptr_t vbuf, int flags, FILE *ofp) { kaddr_t socket, bhv; k_ptr_t sp; indent_it(flags, ofp); fprintf(ofp, "%16llx %4lld %16llx %8llx\n", vsock, KL_INT(vbuf, "vsocket", "vs_type"), kl_kaddr(vbuf, "vsocket", "vs_bh"), KL_UINT(vbuf, "vsocket", "vs_flags")); if (flags & C_FULL) { fprintf(ofp, "\n"); } if (flags & C_NEXT) { fprintf(ofp, "\n"); bhv = kl_kaddr(vbuf, "vsocket", "vs_bh"); socket = kl_bhv_pdata(bhv); if (KL_ERROR) { kl_print_error(); return(0); } sp = kl_alloc_block(SOCKET_SIZE, K_TEMP); get_socket(socket, sp, flags); if (KL_ERROR) { kl_print_error(); kl_free_block(sp); return(0); } fprintf(ofp, " "); socket_banner(ofp, BANNER); fprintf(ofp, " "); socket_banner(ofp, SMINOR); flags |= C_INDENT; print_socket(socket, sp, flags, ofp); fprintf(ofp, "\n"); kl_free_block(sp); } return(1); } /* * get_swapinfo() -- Return an allocated swapinfo block. */ k_ptr_t get_swapinfo(kaddr_t addr, k_ptr_t swapbuf, int flags) { if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(KL_ERRORFP, "get_swapinfo: addr=0x%llx, swapbuf=0x%x, " "flags=0x%x\n", addr, swapbuf, flags); } kl_get_struct(addr, SWAPINFO_SIZE, swapbuf, "swapinfo"); if (KL_ERROR) { KL_SET_ERROR_NVAL(KLE_BAD_SWAPINFO, addr, 2); return((k_ptr_t)0); } else { return(swapbuf); } } /* * swapinfo_banner() */ void swapinfo_banner(FILE *ofp, int flags) { if (flags & BANNER) { fprintf(ofp, " SWAPDEV VNODE PRI DEV " "NPGS NFPGS MAXPGS VPGS\n"); } if (flags & SMAJOR) { fprintf(ofp, "=======================================" "======================================\n"); } if (flags & SMINOR) { fprintf(ofp, "---------------------------------------" "--------------------------------------\n"); } } /* * print_swapinfo() */ int print_swapinfo(kaddr_t addr, k_ptr_t swapbuf, int flags, FILE *ofp) { char swapname[128]; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_swapinfo: addr=0x%llx, flags=0x%x\n", addr, flags); } fprintf(ofp, "%16llx %16llx %lld %lld %8lld %8lld %8lld %8lld\n", addr, kl_kaddr(swapbuf, "swapinfo", "st_vp"), KL_INT(swapbuf, "swapinfo", "st_pri"), KL_INT(swapbuf, "swapinfo", "st_lswap"), KL_INT(swapbuf, "swapinfo", "st_npgs"), KL_INT(swapbuf, "swapinfo", "st_nfpgs"), KL_INT(swapbuf, "swapinfo", "st_maxpgs"), KL_INT(swapbuf, "swapinfo", "st_vpgs")); if (flags & C_FULL) { bzero(&swapname, 128); kl_get_block(kl_kaddr(swapbuf, "swapinfo", "st_name"), 128, swapname, "swapname"); if (!KL_ERROR) { fprintf(ofp, "\nNAME = %s\n", swapname); } } return(1); } /* * uthread_s_banner() */ void uthread_s_banner(FILE *ofp, int flags) { if (flags & BANNER) { indent_it(flags, ofp); fprintf(ofp, " UTHREAD PID " "NEXT PREV NAME\n"); } if (flags & SMAJOR) { indent_it(flags, ofp); fprintf(ofp, "==================================================" "============================\n"); } if (flags & SMINOR) { indent_it(flags, ofp); fprintf(ofp, "---------------------------------------------------" "----------------------------\n"); } } /* * print_uthread_s() * * Print out selected fields from the uthread_s struct and check the flags * options for full print status. */ /* * Scheduling Policies */ #define SCHED_FIFO 1 #define SCHED_RR 2 #define SCHED_TS 3 #define SCHED_NP 4 int print_uthread_s(kaddr_t uthread, k_ptr_t utp, int flags, FILE *ofp) { kaddr_t proc; k_ptr_t kt_name, procp; char c; if (DEBUG(DC_FUNCTRACE, 2)) { fprintf(ofp, "print_uthread_s: uthread=0x%llx, utp=0x%x, flags=0x%x, " "ofp=0x%x\n", uthread, utp, flags, ofp); } indent_it(flags, ofp); fprintf(ofp, "%16llx %10d %16llx %16llx %s\n", uthread, kl_uthread_to_pid(utp), kl_kaddr(utp, "uthread_s", "ut_next"), kl_kaddr(utp, "uthread_s", "ut_prev"), kl_kthread_name(utp)); if (flags & C_FULL) { fprintf(ofp,"\n"); indent_it(flags, ofp); c = *CHAR(utp,"uthread_s","ut_policy"); fprintf(ofp,"UT_POLICY(%1d)=%s, ",c, ((c == SCHED_FIFO) ? "SCHED_FIFO" : (c == SCHED_RR) ? "SCHED_RR" : (c == SCHED_TS) ? "SCHED_TS" : (c == SCHED_NP) ? "SCHED_NP" : "UNKNOWN")); fprintf(ofp,"UT_TSLICE=%lld, UT_RTICKS=%lld, ", KL_INT(utp,"uthread_s","ut_tslice"), KL_INT(utp,"uthread_s","ut_rticks")); fprintf(ofp,"UT_JOB=%llx, ", kl_kaddr(utp, "uthread_s", "ut_job")); fprintf(ofp,"UT_STACK=%llx\n", KL_PHYS_TO_K0(kl_virtop(K_KERNELSTACK, utp))); list_uthread_pregions(uthread, 2, (flags & (~C_FULL)), ofp); fprintf(ofp, "\n"); } if (flags & C_NEXT) { if (proc = kl_kaddr(utp, "uthread_s", "ut_proc")) { procp = kl_get_proc(proc, 2, flags); if (KL_ERROR) { kl_print_error(); } else { fprintf(ofp, "\n"); proc_banner(ofp, BANNER|SMINOR); print_proc(proc, procp, flags, ofp); } kl_free_block(procp); } fprintf(ofp, "\n"); } return(1); } /* * xfs_inode_banner() -- Print out banner information for inode structure. */ void xfs_inode_banner(FILE *ofp, int flags) { if (flags & BANNER) { if (PTRSZ64) { fprintf(ofp, " XFS_INODE UID GID" " VNODE SIZE\n"); } else { fprintf(ofp, " XFS_INODE UID GID" " VNODE SIZE\n"); } } if (flags & SMAJOR) { fprintf(ofp, "==================================" "=================================\n"); } if (flags & SMINOR) { fprintf(ofp, "----------------------------------" "---------------------------------\n"); } } /* * print_xfs_inode() -- Print out the xfs_inode information. */ int print_xfs_inode(kaddr_t addr, k_ptr_t xip, int flags, FILE *ofp) { k_ptr_t dip; if (DEBUG(DC_GLOBAL, 3)) { fprintf(ofp, "print_inode: addr=0x%llx, xip=0x%x, flags=0x%x\n", addr, xip, flags); } indent_it(flags, ofp); FPRINTF_KADDR(ofp, " ", addr); dip = (k_ptr_t)((unsigned)xip + kl_member_offset("xfs_inode", "i_d")); fprintf(ofp, "%5llu %5llu ", KL_UINT(dip, "xfs_dinode_core", "di_uid"), KL_UINT(dip, "xfs_dinode_core", "di_gid")); fprintf(ofp, "%16llx ", kl_bhvp_vobj(XFS_INODE_TO_BHP(xip))); fprintf(ofp, "%8lld\n", KL_INT(dip, "xfs_dinode_core", "di_size")); if (flags & C_FULL) { fprintf(ofp, "\n"); } return(1); } /* * Found something on the net. Seems to work pretty well too. */ uint64_t fnv_hash(uchar_t *key, int len) { uint32_t val; /* current hash value */ uchar_t *key_end = key + len; /* * Fowler/Noll/Vo hash - hash each character in the string * * The basis of the hash algorithm was taken from an idea * sent by Email to the IEEE Posix P1003.2 mailing list from * Phong Vo (kpv@research.att.com) and Glenn Fowler * (gsf@research.att.com). * Landon Curt Noll (chongo@toad.com) later improved on their * algorithm to come up with Fowler/Noll/Vo hash. * */ for (val = 0; key < key_end; ++key) { val *= 16777619; val ^= *key; } /* our hash value, (was: mod the hash size) */ return((uint64_t)val); } int vfile_hash(kaddr_t key) { return((fnv_hash((uchar_t *) (PTRSZ32 ? ((__psunsigned_t)&key+4) : ((__psunsigned_t)&key)), K_NBPW)) % VFILE_HASHSIZE); } /* * We use this for binary trees. Once the btnode stuff changes are made. */ int val64_compare(list_of_ptrs_t *list1, list_of_ptrs_t *list2) { if(list1->val64 == list2->val64) { return(0); } else if (list1->val64 < list2->val64) { /* For our use it doesn't matter when we return -1 or 1... */ return(-1); } else { return(1); } } /* * At a high level, * This function returns all vsockets it can find in the corefile .... each * vsocket which returns true for the given function test_vsocket. * * At a lower level, * It returns a pointer to a hash table. The hash table is basically an array * of pointers to the root of binary trees. Each key in the binary tree is * a pointer to a kaddr_t (kernel pointer to a vsocket). The hash table itself * is also keyed on the same kaddr_t (value of the kernel pointer to the * vsocket). * The lower level implementation will change soon to use the generic * find_btnode, insert_btnode functions. * */ int find_all_vsockets( int flags, FILE *ofp, /* * This is the function, which if specified, will be * called on every vsocket we find. * The vsocket will be included in the list of * vsockets only if this function returns true. * */ int (*test_vsocket)(kaddr_t,kaddr_t,char *,int ,int , FILE *,list_of_ptrs_t *,int *), k_ptr_t **PPhashbase) { int i,kthread_cnt; k_ptr_t pidp, vprocp, procp, utp; kaddr_t pid, vproc, bhv, proc, kthread; *PPhashbase = (k_ptr_t *)kl_alloc_block(VFILE_HASHSIZE * sizeof(k_ptr_t *), K_TEMP); pidp = kl_alloc_block(PID_ENTRY_SIZE, K_TEMP); vprocp = kl_alloc_block(VPROC_SIZE, K_TEMP); pid = K_PID_ACTIVE_LIST; /* We have to step over the first entry as it is just * the list head. */ kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); do { kl_get_struct(pid, PID_ENTRY_SIZE, pidp, "pid_entry"); vproc = kl_kaddr(pidp, "pid_entry", "pe_vproc"); kl_get_struct(vproc, VPROC_SIZE, vprocp, "vproc"); bhv = kl_kaddr(vprocp, "vproc", "vp_bhvh"); proc = kl_bhv_pdata(bhv); if (KL_ERROR) { kl_free_block(pidp); kl_free_block(vprocp); kl_print_error(); } /* Let's find the vsockets.. */ findall_proc_vfiles(proc,2,flags,ofp,*PPhashbase, test_vsocket); kl_get_kaddr(pid, (k_ptr_t)&pid, "pid_entry"); } while (pid != K_PID_ACTIVE_LIST); kl_free_block(pidp); kl_free_block(vprocp); return(0); }