The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kgmacros

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 
    2 # Kernel gdb macros
    3 #
    4 #  These gdb macros should be useful during kernel development in
    5 #  determining what's going on in the kernel.
    6 #
    7 #  All the convenience variables used by these macros begin with $kgm_
    8 
    9 set print asm-demangle on
   10 set cp-abi gnu-v2
   11 
   12 # This option tells gdb to relax its stack tracing heuristics
   13 # Useful for debugging across stack switches
   14 # (to the interrupt stack, for instance). Requires gdb-675 or greater.
   15 set backtrace sanity-checks off
   16 
   17 echo Loading Kernel GDB Macros package.  Type "help kgm" for more info.\n
   18 
   19 define kgm
   20 printf ""
   21 echo  These are the gdb macros for kernel debugging.  Type "help kgm" for more info.\n
   22 end
   23 
   24 document kgm
   25 | These are the kernel gdb macros.  These gdb macros are intended to be
   26 | used when debugging a remote kernel via the kdp protocol.  Typically, you
   27 | would connect to your remote target like so:
   28 |                (gdb) target remote-kdp
   29 |                (gdb) attach <name-of-remote-host>
   30 |
   31 | The following macros are available in this package:
   32 |     showversion    Displays a string describing the remote kernel version
   33 |
   34 |     showalltasks   Display a summary listing of all tasks
   35 |     showallthreads Display info about all threads in the system
   36 |     showallstacks  Display the stack for each thread in the system
   37 |     showcurrentthreads   Display info about the thread running on each cpu
   38 |     showcurrentstacks    Display the stack for the thread running on each cpu
   39 |     showallvm      Display a summary listing of all the vm maps
   40 |     showallvme     Display a summary listing of all the vm map entries
   41 |     showallipc     Display a summary listing of all the ipc spaces
   42 |     showipcsummary     Display a summary listing of the ipc spaces of all tasks
   43 |     showallrights  Display a summary listing of all the ipc rights
   44 |     showallkexts   Display a summary listing of all loaded kexts (alias: showallkmods)
   45 |     showallknownkexts   Display a summary listing of all kexts, loaded or not
   46 |     showallbusyports    Display a listing of all ports with unread messages
   47 |     showallprocessors   Display a listing of all psets and processors
   48 |
   49 |     showallclasses    Display info about all OSObject subclasses in the system
   50 |     showobject        Show info about an OSObject - its vtable ptr and retain count, & more info for simple container classes.
   51 |     showregistry      Show info about all registry entries in the current plane
   52 |     showregistryprops Show info about all registry entries in the current plane, and their properties
   53 |     showregistryentry Show info about a registry entry; its properties and descendants in the current plane
   54 |     setregistryplane  Set the plane to be used for the iokit registry macros (pass zero for list)
   55 |
   56 |     setfindregistrystr  Set the encoded string for matching with
   57 |                         findregistryentry or findregistryprop (created from
   58 |                         strcmp_arg_pack64)
   59 |     findregistryentry   Find a registry entry that matches the encoded string
   60 |     findregistryentries Find all the registry entries that match the encoded string
   61 |     findregistryprop    Search the registry entry for a property that matches
   62 |                         the encoded string
   63 |
   64 |     showtask       Display info about the specified task
   65 |     showtaskthreads      Display info about the threads in the task
   66 |     showtaskstacks Display the stack for each thread in the task
   67 |     showtaskvm     Display info about the specified task's vm_map
   68 |     showtaskvme    Display info about the task's vm_map entries
   69 |     showtaskipc    Display info about the specified task's ipc space
   70 |     showtaskrights Display info about the task's ipc space entries
   71 |     showtaskrightsbt Display info about the task's ipc space entries with back traces
   72 |     showtaskbusyports    Display all of the task's ports with unread messages
   73 |
   74 |     showact        Display info about a thread specified by activation
   75 |     showactstack   Display the stack for a thread specified by activation
   76 |
   77 |     showmap        Display info about the specified vm_map
   78 |     showmapvme     Display a summary list of the specified vm_map's entries
   79 |
   80 |     showipc        Display info about the specified ipc space
   81 |     showrights     Display a summary list of all the rights in an ipc space
   82 |
   83 |     showpid        Display info about the process identified by pid
   84 |     showproc       Display info about the process identified by proc struct
   85 |     showprocinfo   Display detailed info about the process identified by proc struct
   86 |     showprocfiles  Given a proc_t pointer, display the list of open file descriptors
   87 |     showproclocks  Given a proc_t pointer, display the list of advisory file locks
   88 |     zombproc       Print out all procs in the zombie list
   89 |     showproctree   Show all the processes in a hierarchical tree form
   90 |     allproc        Print out all process in the system not in the zombie list
   91 |     zombstacks     Print out all stacks of tasks that are exiting
   92 |
   93 |     showinitchild  Print out all processes in the system which are children of init process
   94 |
   95 |     showkext       Display info about a kext (alias: showkmod)
   96 |     showkextaddr   Given an address, display the kext and offset (alias: showkmodaddr)
   97 |
   98 |     dumpcallqueue  Dump out all the entries given a queue head
   99 |
  100 |     showallmtx     Display info about mutexes usage
  101 |     showallrwlck   Display info about reader/writer locks usage
  102 |
  103 |     zprint         Display info about the memory zones
  104 |     showioalloc    Display info about iokit allocations
  105 |     paniclog       Display the panic log info
  106 |
  107 |     switchtoact    Switch to different context specified by activation
  108 |     switchtoctx    Switch to different context
  109 |     showuserstack  Display numeric backtrace of the user stack for an 
  110 |                    activation
  111 |     showtaskuserstacks         Display user stacks for a specified task
  112 |     showuserregisters          Display user registers for the specified thread
  113 |     showtaskuserregisters              Display user registers for the specified task
  114 |
  115 |     switchtouserthread Switch to the user context of the specified thread
  116 |     resetstacks    Return to the original kernel context
  117 |
  118 |     resetctx       Reset context
  119 |     resume_on      Resume when detaching from gdb
  120 |     resume_off     Don't resume when detaching from gdb 
  121 |
  122 |     sendcore       Configure kernel to send a coredump to the specified IP
  123 |     sendsyslog     Configure kernel to send a system log to the specified IP
  124 |     sendpaniclog   Configure kernel to send a panic log to the specified IP
  125 |     disablecore    Configure the kernel to disable coredump transmission
  126 |     getdumpinfo    Retrieve the current remote dump parameters
  127 |     setdumpinfo    Configure the remote dump parameters
  128 |
  129 |     switchtocorethread Corefile version of "switchtoact"
  130 |     resetcorectx   Corefile version of "resetctx"
  131 |
  132 |     readphys8      Reads the specified untranslated address (8-bit read)
  133 |     readphys16     Reads the specified untranslated address (16-bit read)
  134 |     readphys32     Reads the specified untranslated address (32-bit read)
  135 |     readphys64     Reads the specified untranslated address (64-bit read)
  136 |     writephys8     Writes to the specified untranslated address (8-bit write)
  137 |     writephys16    Writes to the specified untranslated address (16-bit write)
  138 |     writephys32    Writes to the specified untranslated address (32-bit write)
  139 |     writephys64    Writes to the specified untranslated address (64-bit write)
  140 |
  141 |     readioport8    Read 8-bits from the specified I/O Port
  142 |     readioport16   Read 16-bits from the specified I/O Port
  143 |     readioport32   Read 32-bits from the specified I/O Port
  144 |     writeioport8   Write 8-bits into the specified I/O Port
  145 |     writeioport16  Write 16-bits into the specified I/O Port
  146 |     writeioport32  Write 32-bits into the specified I/O Port
  147 |
  148 |     readmsr64      Read 64-bits from the specified MSR
  149 |     writemsr64     Write 64-bits into the specified MSR
  150 |
  151 |     rtentry_showdbg Print the debug information of a route entry
  152 |     rtentry_trash  Walk the list of trash route entries
  153 |
  154 |     inifa_showdbg  Print the debug information of an IPv4 interface address
  155 |     in6ifa_showdbg Print the debug information of an IPv6 interface address
  156 |     inm_showdbg    Print the debug information of an IPv4 multicast address
  157 |     ifma_showdbg   Print the debug information of a link multicast address
  158 |     ifpref_showdbg Print the debug information of an interface ref count
  159 |
  160 |     ndpr_showdbg   Print the debug information of a nd_prefix structure
  161 |     nddr_showdbg   Print the debug information of a nd_defrouter structure
  162 |
  163 |     imo_showdbg    Print the debug information of a ip_moptions structure
  164 |     im6o_showdbg   Print the debug information of a ip6_moptions structure
  165 |
  166 |     inifa_trash    Walk the list of trash in_ifaddr entries
  167 |     in6ifa_trash   Walk the list of trash in6_ifaddr entries
  168 |     inm_trash      Walk the list of trash in_multi entries
  169 |     in6m_trash     Walk the list of trash in6_multi entries
  170 |     ifma_trash     Walk the list of trash ifmultiaddr entries
  171 |
  172 |     mbuf_walkpkt   Walk the mbuf packet chain (m_nextpkt)
  173 |     mbuf_walk      Walk the mbuf chain (m_next)
  174 |     mbuf_buf2slab  Find the slab structure of the corresponding buffer
  175 |     mbuf_buf2mca   Find the mcache audit structure of the corresponding mbuf
  176 |     mbuf_showmca   Print the contents of an mbuf mcache audit structure
  177 |     mbuf_showactive   Print all active/in-use mbuf objects
  178 |     mbuf_showinactive Print all freed/in-cache mbuf objects 
  179 |     mbuf_showall   Print all mbuf objects
  180 |     mbuf_slabs     Print all slabs in the group
  181 |     mbuf_slabstbl  Print slabs table
  182 |     mbuf_stat      Print extended mbuf allocator statistics
  183 |     mbuf_countchain   Count the length of an mbuf chain
  184 |     mbuf_topleak   Print the top suspected mbuf leakers
  185 |     mbuf_traceleak Print the leak information for a given leak address
  186 |
  187 |     mcache_walkobj     Walk the mcache object chain (obj_next)
  188 |     mcache_stat        Print all mcaches in the system
  189 |     mcache_showcache   Display the number of objects in the cache
  190 |
  191 |     showbootargs       Display boot arguments passed to the target kernel
  192 |     showbootermemorymap Dump phys memory map from EFI
  193 |
  194 |     systemlog          Display the kernel's printf ring buffer
  195 |
  196 |     hexdump            Show the contents of memory as a hex/ASCII dump
  197 |
  198 |     showvnodepath      Print the path for a vnode
  199 |     showvnodelocks     Display list of advisory locks held/blocked on a vnode
  200 |     showvnodedev       Display information about a device vnode
  201 |     showtty            Display information about a struct tty
  202 |     showallvols        Display a summary of mounted volumes
  203 |     showvnode          Display info about one vnode
  204 |     showvolvnodes      Display info about all vnodes of a given volume
  205 |     showvolbusyvnodes  Display info about busy (iocount!=0) vnodes of a given volume
  206 |     showallbusyvnodes  Display info about all busy (iocount!=0) vnodes
  207 |     showallvnodes      Display info about all vnodes
  208 |     print_vnode        Print out the fields of a vnode struct
  209 |     showprocvnodes     Print out all the open fds which are vnodes in a process
  210 |     showallprocvnodes  Print out all the open fds which are vnodes in any process
  211 |     showmountvnodes    Print the vnode list
  212 |     showmountallvnodes Print the vnode inactive list
  213 |     showworkqvnodes    Print the vnode worker list
  214 |     shownewvnodes      Print the new vnode list
  215 |
  216 |     ifconfig           display ifconfig-like output
  217 |     showifnets         show the list of attached and detached interfaces
  218 |     showifaddrs        show the list of addresses for the given ifp
  219 |     showifmultiaddrs   show the list of multicast addresses for the given ifp
  220 |     showinmultiaddrs   show the list of IPv4 multicast addresses records 
  221 |     showin6multiaddrs  show the list of IPv6 multicast addresses records
  222 |
  223 |     showsocket         Display information about a socket
  224 |     showprocsockets    Given a proc_t pointer, display information about its sockets
  225 |     showallprocsockets Display information about the sockets of all the processes
  226 |
  227 |     show_tcp_pcbinfo   Display the list of the TCP protocol control blocks
  228 |     show_tcp_timewaitslots Display the list of the TCP protocol control blocks in TIMEWAIT
  229 |     show_udp_pcbinfo   Display the list of UDP protocol control blocks
  230 |
  231 |     show_rt_inet       Display the IPv4 routing table
  232 |     show_rt_inet6      Display the IPv6 routing table
  233 |
  234 |     showpmworkqueue       Display the IOPMWorkQueue object
  235 |     showregistrypmstate   Display power management state for all IOPower registry entries
  236 |     showioservicepm       Display the IOServicePM object
  237 |     showstacksaftertask   showallstacks starting after a given task
  238 |     showstacksafterthread showallstacks starting after a given thread
  239 |
  240 |     showMCAstate      Print machine-check register state after MC exception.
  241 |
  242 |     showallgdbstacks  Cause GDB to trace all thread stacks
  243 |     showallgdbcorestacks Corefile equivalent of "showallgdbstacks"
  244 |     kdp-reenter       Schedule reentry into the debugger and continue.
  245 |     kdp-reboot        Restart remote target
  246 |     kdp-version       Get KDP version number
  247 |
  248 |     zstack            Print zalloc caller stack (zone leak debugging)
  249 |     findoldest        Find oldest zone leak debugging record
  250 |     countpcs          Print how often a pc occurs in the zone leak log
  251 |
  252 |     showtopztrace     Print the ztrace with the most outstanding allocated memory
  253 |     showztrace                Print a backtrace record given its index
  254 |     showzalloc            Print an allocation record + stacktrace at index
  255 |     showztraceaddr    Print a backtrace record given its address
  256 |     showztracesabove  Print all the backtrace records with a size bigger than X
  257 |     showzstacktrace   Symbolicate and print a stored OSBacktrace
  258 |     
  259 |     showztraces       Finds all in-use traces in the ztraces table
  260 |     showzallocs       Finds all in-use allocations in the zallocs table
  261 |     showzstats        Shows the statistics gathered about the hash tables
  262 |
  263 |     showzallocsfortrace   Print all the allocations that refer to a trace
  264 |     showztracehistogram   Prints a histogram of the ztraces table
  265 |     showzallochistogram   Prints a histogram of the zallocs table     
  266 |
  267 |     pmap_walk     Perform a page-table walk
  268 |     pmap_vtop     Translate a virtual address to physical address
  269 |
  270 |     showuserdyldinfo       Show dyld information and error messages
  271 |                            in the target task
  272 |     showuserlibraries      Show binary images known by dyld in the
  273 |                            target task
  274 |     showallvmstats    Prints a summary of vm statistics in a table format
  275 |     memstats                  Displays memory statistics in a table format
  276 |
  277 |     showthreadfortid  Displays the address of the thread structure
  278 |                       for a given thread_id value. 
  279 |     
  280 |     strcmp_nomalloc   A version of strcmp that avoids the use of malloc
  281 |                       through the use of encoded strings created via
  282 |                       strcmp_arg_pack64.
  283 |     strcmp_arg_pack64 Pack a string into a 64-bit quantity for use by
  284 |                       strcmp_nomalloc
  285 |
  286 |     pci_cfg_read8     Read 8-bits from a PCI config space register
  287 |     pci_cfg_read16    Read 16-bits from a PCI config space register
  288 |     pci_cfg_read32    Read 32-bits from a PCI config space register
  289 |     pci_cfg_write8    Write 8-bits into a PCI config space register
  290 |     pci_cfg_write16   Write 16-bits into a PCI config space register
  291 |     pci_cfg_write32   Write 32-bits into a PCI config space register
  292 |     pci_cfg_dump      Dump entire config space for a PCI device
  293 |     pci_cfg_scan      Perform a scan for PCI devices
  294 |     pci_cfg_dump_all  Dump config spaces for all detected PCI devices
  295 |
  296 |     lapic_read32      Read APIC entry
  297 |     lapic_write32     Write APIC entry
  298 |     lapic_dump        Dump APIC entries
  299 |
  300 |     ioapic_read32     Read IOAPIC entry
  301 |     ioapic_write32    Write IOAPIC entry
  302 |     ioapic_dump       Dump IOAPIC entries
  303 |
  304 |     showallproviders  Display summary listing of all dtrace_providers
  305 |     showallmodctls    Display summary listing of all dtrace modctls
  306 |     showmodctl        Display info about a dtrace modctl
  307 |     showfbtprobe      Display info about an fbt probe given an id (traverses fbt_probetab)
  308 |     processortimers   Display all processor timers, noting any inconsistencies
  309 |         
  310 |     maplocalcache     Enable local caching in GDB for improved debug speeds
  311 |     flushlocalcahe    Disable local caching in GDB (deletes all memory regions)
  312 |
  313 | Type "help <macro>" for more specific help on a particular macro.
  314 | Type "show user <macro>" to see what the macro is really doing.
  315 end
  316 
  317 # This macro should appear before any symbol references, to facilitate
  318 # a gdb "source" without a loaded symbol file.
  319 define showversion
  320     kdp-kernelversion
  321 end
  322 
  323 document showversion
  324 Syntax: showversion
  325 | Read the kernel version string from a fixed address in low
  326 | memory. Useful if you don't know which kernel is on the other end,
  327 | and need to find the appropriate symbols. Beware that if you've
  328 | loaded a symbol file, but aren't connected to a remote target,
  329 | the version string from the symbol file will be displayed instead.
  330 | This macro expects to be connected to the remote kernel to function
  331 | correctly.
  332 end
  333 
  334 set $kgm_mtype_ppc      = 0x00000012
  335 set $kgm_mtype_arm      = 0x0000000C
  336 
  337 set $kgm_mtype_i386     = 0x00000007
  338 set $kgm_mtype_x86_64   = 0x01000007
  339 set $kgm_mtype_x86_any  = $kgm_mtype_i386
  340 set $kgm_mtype_x86_mask = 0xFEFFFFFF
  341 
  342 set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
  343 set $kgm_lp64 = $kgm_mtype & 0x01000000
  344 
  345 set $kgm_manual_pkt_ppc    = 0x549C
  346 set $kgm_manual_pkt_i386   = 0x249C
  347 set $kgm_manual_pkt_x86_64 = 0xFFFFFF8000002930
  348 set $kgm_manual_pkt_arm    = 0xFFFF04A0
  349 
  350 set $kgm_kdp_pkt_data_len   = 128
  351 
  352 # part of data packet
  353 set $kgm_kdp_pkt_hdr_req_off = 0
  354 set $kgm_kdp_pkt_hdr_seq_off = 1
  355 set $kgm_kdp_pkt_hdr_len_off = 2
  356 set $kgm_kdp_pkt_hdr_key_off = 4
  357 
  358 # after data packet
  359 set $kgm_kdp_pkt_len_off     = $kgm_kdp_pkt_data_len
  360 set $kgm_kdp_pkt_input_off   = $kgm_kdp_pkt_data_len + 4
  361 
  362 set $kgm_kdp_pkt_hostreboot = 0x13
  363 set $kgm_kdp_pkt_hdr_size   = 8
  364 
  365 
  366 set $kgm_readphys_force_kdp     = 0
  367 set $kgm_readphys_force_physmap = 0
  368 
  369 set $kgm_lcpu_self      = 0xFFFE
  370 
  371 set $kgm_reg_depth = 0
  372 set $kgm_reg_depth_max = 0xFFFF
  373 set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
  374 set $kgm_namekey = (OSSymbol *) 0
  375 set $kgm_childkey = (OSSymbol *) 0
  376 
  377 set $kgm_show_object_addrs = 0
  378 set $kgm_show_object_retain = 0
  379 set $kgm_show_props = 0
  380 set $kgm_show_data_alwaysbytes = 0
  381 
  382 set $kgm_show_kmod_syms = 0
  383 
  384 # send a manual packet header that doesn't require knowing the location
  385 # of everything.
  386 define manualhdrint
  387        set $req = $arg0
  388 
  389        set $hdrp = (uint32_t *) $kgm_manual_pkt_i386
  390        if ($kgm_mtype == $kgm_mtype_ppc)
  391           set $hdrp = (uint32_t *) $kgm_manual_pkt_ppc
  392           set $req = $req << 1 # shift to deal with endiannness
  393        end
  394        if ($kgm_mtype == $kgm_mtype_x86_64)
  395           set $hdrp = (uint64_t *) $kgm_manual_pkt_x86_64
  396        end
  397        if ($kgm_mtype == $kgm_mtype_arm)
  398           set $hdrp = (uint32_t *) $kgm_manual_pkt_arm
  399        end
  400 
  401        set $pkt_hdr = *$hdrp
  402        set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off))    = 0
  403        set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_len_off))     = $kgm_kdp_pkt_hdr_size
  404 
  405        set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_req_off))  = $req
  406        set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_seq_off))  = 0
  407        set *((uint16_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_len_off)) = $kgm_kdp_pkt_hdr_size
  408        set *((uint32_t *) ($pkt_hdr + $kgm_kdp_pkt_hdr_key_off)) = 0
  409        set *((uint8_t *) ($pkt_hdr + $kgm_kdp_pkt_input_off))    = 1
  410 
  411        # dummy to make sure manual packet is executed
  412        set $kgm_dummy = &_mh_execute_header
  413 end
  414 
  415 # Print a pointer
  416 define showptr
  417     if $kgm_lp64
  418         printf "0x%016llx", $arg0
  419     else
  420         printf "0x%08x", $arg0
  421     end
  422 end
  423 
  424 # for headers, leave 8 chars for LP64 pointers
  425 define showptrhdrpad
  426     if $kgm_lp64
  427         printf "        "
  428     end
  429 end
  430 
  431 # Print a userspace pointer, using $kgm_tasp
  432 define showuserptr
  433     set $kgm_userptr_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
  434     if $kgm_userptr_task_64
  435         printf "0x%016llx", $arg0
  436     else
  437         printf "0x%08x", $arg0
  438     end
  439 end
  440 
  441 define showkmodheader
  442     printf   "kmod_info "
  443     showptrhdrpad
  444     printf "  address   "
  445     showptrhdrpad
  446     printf "  size      "
  447     showptrhdrpad
  448     printf "  id    refs     version  name\n"
  449 end
  450 
  451 define showkmodint
  452     set $kgm_kmodp = (struct kmod_info *)$arg0
  453     showptr $kgm_kmodp
  454     printf "  "
  455     showptr $kgm_kmodp->address
  456     printf "  "
  457     showptr $kgm_kmodp->size
  458     printf "  "
  459     printf "%3d  ", $kgm_kmodp->id
  460     printf "%5d  ", $kgm_kmodp->reference_count
  461     printf "%10s  ", $kgm_kmodp->version
  462     printf "%s\n", $kgm_kmodp->name
  463 end
  464 
  465 # cached info of the last kext found, to speed up subsequent lookups
  466 set $kgm_pkmod = 0
  467 set $kgm_pkmodst = 0
  468 set $kgm_pkmoden = 0
  469 
  470 define showkmodaddrint
  471     showptr $arg0
  472     if ((unsigned long)$arg0 >= (unsigned long)$kgm_pkmodst) && ((unsigned long)$arg0 < (unsigned long)$kgm_pkmoden)
  473         set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_pkmodst)
  474         printf " <%s + 0x%x>", $kgm_pkmod->name, $kgm_off
  475     else
  476         set $kgm_kmodp = (struct kmod_info *)kmod
  477         if ($kgm_mtype == $kgm_mtype_x86_64) && ($arg0 >= (unsigned long)&_mh_execute_header)
  478             # kexts are loaded below the kernel for x86_64
  479             set $kgm_kmodp = 0
  480         end
  481         while $kgm_kmodp
  482             set $kgm_off = ((unsigned long)$arg0 - (unsigned long)$kgm_kmodp->address)
  483             if ($kgm_kmodp->address <= $arg0) && ($kgm_off < $kgm_kmodp->size)
  484                 printf " <%s + 0x%x>", $kgm_kmodp->name, $kgm_off
  485                 set $kgm_pkmod = $kgm_kmodp
  486                 set $kgm_pkmodst = $kgm_kmodp->address
  487                 set $kgm_pkmoden = $kgm_pkmodst + $kgm_kmodp->size
  488                 set $kgm_kmodp = 0
  489             else
  490                 set $kgm_kmodp = $kgm_kmodp->next
  491             end
  492         end
  493     end
  494 end
  495 
  496 define showkmodaddr
  497     showkmodaddrint $arg0
  498 end
  499 document showkmodaddr
  500 Syntax: (gdb) showkmodaddr <addr>
  501 | Given an address, print the offset and name for the kmod containing it
  502 end
  503 
  504 define showkmod
  505     showkmodheader
  506     showkmodint $arg0
  507 end
  508 document showkmod
  509 Syntax: (gdb) showkmod <kmod>
  510 | Routine to print info about a kext
  511 end
  512 
  513 define showkext
  514     showkmod $arg0
  515 end
  516 document showkext
  517 Syntax: (gdb) showkext <kmod_info_address>
  518 | Routine to print info about a kext
  519 end
  520 
  521 define showallkmods
  522     showkmodheader
  523     set $kgm_kmodp = (struct kmod_info *)kmod
  524     while $kgm_kmodp
  525         showkmodint $kgm_kmodp
  526         set $kgm_kmodp = $kgm_kmodp->next
  527     end
  528 end
  529 document showallkmods
  530 Syntax: (gdb) showallkmods
  531 | Routine to print a summary listing of all loaded kexts
  532 end
  533 
  534 define showallkexts
  535     showallkmods
  536 end
  537 document showallkexts
  538 Syntax: (gdb) showallkexts
  539 | Routine to print a summary listing of all loaded kexts
  540 end
  541 
  542 # See OSKextVersion.c for the C code this is based on
  543 #
  544 set $KGM_OSKEXT_VERS_MAJ_MULT   = 100000000
  545 set $KGM_OSKEXT_VERS_MIN_MULT   = 1000000
  546 set $KGM_OSKEXT_VERS_REV_MULT   = 10000
  547 set $KGM_OSKEXT_VERS_STAGE_MULT = 1000
  548 
  549 define printoskextversion
  550     set $vers_scratch = $arg0
  551 
  552     if ($vers_scratch == -1)
  553         printf "(invalid)"
  554     else
  555      
  556         set $vers_major =  $vers_scratch / $KGM_OSKEXT_VERS_MAJ_MULT
  557 
  558         set $vers_scratch = $vers_scratch - ($vers_major * $KGM_OSKEXT_VERS_MAJ_MULT)
  559         set $vers_minor = $vers_scratch / $KGM_OSKEXT_VERS_MIN_MULT
  560 
  561         set $vers_scratch = $vers_scratch - ( $vers_minor * $KGM_OSKEXT_VERS_MIN_MULT)
  562         set $vers_revision =  $vers_scratch / $KGM_OSKEXT_VERS_REV_MULT
  563 
  564         set $vers_scratch = $vers_scratch - ( $vers_revision * $KGM_OSKEXT_VERS_REV_MULT)
  565         set $vers_stage =  $vers_scratch / $KGM_OSKEXT_VERS_STAGE_MULT
  566 
  567         set $vers_scratch = $vers_scratch - ( $vers_stage * $KGM_OSKEXT_VERS_STAGE_MULT)
  568         set $vers_stagelevel =  $vers_scratch
  569 
  570         printf "%d.%d", $vers_major, $vers_minor
  571         if ($vers_revision > 0)
  572             printf ".%d", $vers_revision
  573         end
  574         
  575         if ($vers_stage == 1)
  576             printf "d"
  577         end
  578         if ($vers_stage == 3)
  579             printf "a"
  580         end
  581         if ($vers_stage == 5)
  582             printf "b"
  583         end
  584         if ($vers_stage == 7)
  585             printf "fc"
  586         end
  587         if ($vers_stage == 1 || $vers_stage == 3 || $vers_stage == 5 || $vers_stage == 7)
  588             printf "%d", $vers_stagelevel
  589         end
  590     end
  591 end
  592 
  593 define showallknownkexts
  594    set $kext_count = sKextsByID->count
  595    set $kext_index = 0
  596    printf "%d kexts in sKextsByID:\n", $kext_count
  597 
  598    printf "OSKext *    "
  599    showptrhdrpad
  600    printf "load_addr   "
  601    showptrhdrpad
  602    
  603    printf " id  name (version)\n"
  604 
  605    while $kext_index < $kext_count
  606        set $kext_id = sKextsByID->dictionary[$kext_index].key->string
  607        set $oskext = (OSKext *)sKextsByID->dictionary[$kext_index].value
  608 
  609        showptr $oskext
  610        printf "  "
  611 
  612        if ($oskext->flags.loaded)
  613            showptr $oskext->kmod_info
  614            printf "  "
  615            printf "%3d", $oskext->loadTag
  616        else
  617            showptrhdrpad
  618            printf " -------- "
  619            printf "  "
  620            printf " --"
  621         end
  622         printf "  "
  623 
  624        printf "%.64s (", $kext_id
  625        printoskextversion (uint64_t)$oskext->version
  626        printf ")\n"
  627        set $kext_index = $kext_index + 1
  628    end
  629 end
  630 document showallknownkexts
  631 Syntax: (gdb) showallknownkexts
  632 | Routine to print a summary listing of all kexts, loaded or not
  633 end
  634 
  635 define showactheader
  636     printf "          "
  637     showptrhdrpad
  638     printf "  thread    "
  639     showptrhdrpad
  640     printf "    thread_id "
  641     showptrhdrpad
  642     printf "  processor "
  643     showptrhdrpad
  644     printf "   pri io_policy   state    wait_queue"
  645     showptrhdrpad
  646     printf "  wait_event\n"
  647 end
  648 
  649 
  650 define showactint
  651         printf "            "
  652         showptrhdrpad
  653         set $kgm_thread = *(struct thread *)$arg0
  654         showptr $arg0
  655         if ($kgm_thread.static_param)
  656            printf "[WQ]"
  657         else
  658            printf "    "
  659         end
  660         printf "  0x%llx   ", $kgm_thread.thread_id
  661         showptr $kgm_thread.last_processor
  662         printf "   %3d ", $kgm_thread.sched_pri
  663         if ($kgm_thread.uthread != 0)
  664            set $kgm_printed = 0
  665            set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
  666            if ($kgm_uthread->uu_flag & 0x400)
  667               printf "RAGE "
  668            else
  669               printf "     "
  670            end
  671            set $diskpolicy = 0
  672            if ($kgm_thread->ext_appliedstate.hw_disk != 0)
  673                 set $diskpolicy = $kgm_thread->ext_appliedstate.hw_disk
  674            else 
  675                 if ($kgm_thread->appliedstate.hw_disk != 0)
  676                         set $diskpolicy = $kgm_thread->appliedstate.hw_disk
  677                 end
  678            end
  679            if ($kgm_thread->ext_appliedstate.hw_bg != 0)
  680                 set $diskpolicy = 5
  681            end
  682            if ($kgm_thread->appliedstate.hw_bg != 0)
  683                 set $diskpolicy = 4
  684            end
  685            if ($diskpolicy == 2)
  686               printf "PASS    "
  687               set $kgm_printed = 1
  688            end
  689            if ($diskpolicy == 3)
  690               printf "THROT   "
  691               set $kgm_printed = 1
  692            end
  693            if ($diskpolicy == 4)
  694               printf "BG_THRT "
  695               set $kgm_printed = 1
  696            end
  697            if ($diskpolicy == 5)
  698               printf "EBG_THRT"
  699               set $kgm_printed = 1
  700            end
  701            if ($kgm_printed == 0)
  702               printf "        "
  703            end
  704         end
  705         set $kgm_state = $kgm_thread.state
  706         if $kgm_state & 0x80
  707             printf "I" 
  708         end
  709         if $kgm_state & 0x40
  710             printf "P" 
  711         end
  712         if $kgm_state & 0x20
  713             printf "A" 
  714         end
  715         if $kgm_state & 0x10
  716             printf "H" 
  717         end
  718         if $kgm_state & 0x08
  719             printf "U" 
  720         end
  721         if $kgm_state & 0x04
  722             printf "R" 
  723         end
  724         if $kgm_state & 0x02
  725             printf "S" 
  726         end
  727         if $kgm_state & 0x01
  728             printf "W"
  729             printf "\t    " 
  730             showptr $kgm_thread.wait_queue
  731             printf "  "
  732                 if (((unsigned long)$kgm_thread.wait_event > (unsigned long)&last_kernel_symbol) \
  733                     && ($arg1 != 2) && ($kgm_show_kmod_syms == 0))
  734                         showkmodaddr $kgm_thread.wait_event
  735                 else
  736                         output /a $kgm_thread.wait_event
  737                 end
  738                 if ($kgm_thread.uthread != 0)
  739                     set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
  740                     if ($kgm_uthread->uu_wmesg != 0)
  741                         printf "\t \"%s\"", $kgm_uthread->uu_wmesg
  742                     end
  743                 end
  744         end
  745         if ($kgm_thread.uthread != 0)
  746            set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
  747            if ($kgm_uthread->pth_name && $kgm_uthread->pth_name[0])
  748                    printf "\n\t\tThread Name: %s", $kgm_uthread->pth_name
  749            end
  750         end
  751         if $arg1 != 0
  752             if ($kgm_thread.kernel_stack != 0)
  753                 if ($kgm_thread.uthread != 0)
  754                         printf "\n          "
  755                         set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
  756                         if ($kgm_uthread->uu_kwe.kwe_kwqqueue != 0)
  757                                 set $kwq = (ksyn_wait_queue_t)$kgm_uthread->uu_kwe.kwe_kwqqueue
  758                                 printf "              kwq_lockcount:0x%x; kwq_retval:0x%x", $kgm_uthread->uu_kwe.kwe_lockseq, $kgm_uthread->uu_kwe.kwe_psynchretval
  759                                 printf "\n                "
  760                                 show_kwq $kwq
  761                                 printf "          "
  762                         end
  763                 end
  764                 if ($kgm_thread.reserved_stack != 0)
  765                         printf "\n          "
  766                         showptrhdrpad
  767                         printf "      reserved_stack="
  768                         showptr $kgm_thread.reserved_stack
  769                 end
  770                 printf "\n          "
  771                 showptrhdrpad
  772                 printf "      kernel_stack="
  773                 showptr $kgm_thread.kernel_stack
  774                 if ($kgm_mtype == $kgm_mtype_ppc)
  775                         set $mysp = $kgm_thread.machine.pcb->save_r1
  776                 end
  777                 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
  778                         set $kgm_statep = (struct x86_kernel_state *) \
  779                                 ($kgm_thread->kernel_stack + kernel_stack_size \
  780                                  - sizeof(struct x86_kernel_state))
  781                         if ($kgm_mtype == $kgm_mtype_i386)
  782                                 set $mysp = $kgm_statep->k_ebp
  783                         else
  784                                 set $mysp = $kgm_statep->k_rbp
  785                         end
  786                 end
  787                 if ($kgm_mtype == $kgm_mtype_arm)
  788                         if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
  789                       && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
  790                                 set $mysp = $r7
  791                         else
  792                                 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
  793                                 set $mysp = $kgm_statep->r[7]
  794                         end
  795                 end
  796                 set $prevsp = $mysp - 16
  797                 printf "\n          "
  798                 showptrhdrpad
  799                 printf "      stacktop="
  800                 showptr $mysp
  801                 if ($kgm_mtype == $kgm_mtype_ppc)
  802                         set $stkmask = 0xf
  803                 else
  804                         set $stkmask = 0x3
  805                 end
  806                 set $kgm_return = 0
  807                 set $kgm_actint_framecount = 0
  808                 while ($mysp != 0) && (($mysp & $stkmask) == 0) \
  809                       && ($mysp != $prevsp) \
  810                       && ((((unsigned long) $mysp ^ (unsigned long) $prevsp) < 0x2000) \
  811                       || (((unsigned long)$mysp < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
  812                       && ((unsigned long)$mysp > (unsigned long) ($kgm_thread->kernel_stack)))) \
  813                       && ($kgm_actint_framecount < 128)
  814                         printf "\n          "
  815                         set $kgm_actint_framecount = $kgm_actint_framecount + 1
  816                         showptrhdrpad
  817                         printf "      "
  818                         showptr $mysp
  819                         printf "  "
  820                         if ($kgm_mtype == $kgm_mtype_ppc)
  821                                 set $kgm_return = *($mysp + 8)
  822                         end
  823                         if ($kgm_mtype == $kgm_mtype_i386)
  824                                 set $kgm_return = *($mysp + 4)
  825                         end
  826                         if ($kgm_mtype == $kgm_mtype_x86_64)
  827                                 set $kgm_return = *(unsigned long *)($mysp + 8)
  828                         end
  829                         if ($kgm_mtype == $kgm_mtype_arm)
  830                                 set $kgm_return = *($mysp + 4)
  831                         end
  832                         if (((unsigned long) $kgm_return < (unsigned long) &_mh_execute_header || \
  833                              (unsigned long) $kgm_return >= (unsigned long) &last_kernel_symbol ) \
  834                             && ($kgm_show_kmod_syms == 0))
  835                                 showkmodaddr $kgm_return
  836                         else
  837                                 output /a $kgm_return
  838                         end
  839                         set $prevsp = $mysp
  840                         set $mysp = *(unsigned long *)$mysp
  841                 end
  842                 set $kgm_return = 0
  843                 printf "\n          "
  844                 showptrhdrpad
  845                 printf "      stackbottom="
  846                 showptr $prevsp
  847             else
  848                 printf "\n          "
  849                 showptrhdrpad
  850                 printf "      continuation="
  851                 output /a $kgm_thread.continuation
  852             end
  853             printf "\n"
  854         else
  855             printf "\n"
  856         end
  857 end         
  858 
  859 define showact
  860     showactheader
  861     showactint $arg0 0
  862 end
  863 document showact
  864 Syntax: (gdb) showact <activation> 
  865 | Routine to print out the state of a specific thread.
  866 end
  867 
  868 
  869 define showactstack
  870     showactheader
  871     showactint $arg0 1
  872 end
  873 document showactstack
  874 Syntax: (gdb) showactstack <activation> 
  875 | Routine to print out the stack of a specific thread.
  876 end
  877 
  878 
  879 define showallthreads
  880     set $kgm_head_taskp = &tasks
  881     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
  882     while $kgm_taskp != $kgm_head_taskp
  883         showtaskheader
  884         showtaskint $kgm_taskp
  885         showactheader
  886         set $kgm_head_actp = &($kgm_taskp->threads)
  887         set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
  888         while $kgm_actp != $kgm_head_actp
  889             showactint $kgm_actp 0
  890             set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
  891         end
  892         printf "\n"
  893         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
  894     end
  895 end
  896 document showallthreads
  897 Syntax: (gdb) showallthreads
  898 | Routine to print out info about all threads in the system.
  899 end
  900 
  901 define showprocessorint
  902     set $kgm_processor_int = (struct processor *)$arg0
  903     printf "Processor "
  904     showptr $kgm_processor_int
  905     printf " State %d (cpu_id 0x%x)\n", ($kgm_processor_int)->state, ($kgm_processor_int)->cpu_id
  906 end
  907 
  908 define showcurrentthreads
  909     set $kgm_prp = (struct processor *)processor_list
  910     while $kgm_prp != 0
  911         showprocessorint $kgm_prp
  912         if ($kgm_prp)->active_thread != 0
  913             set $kgm_actp = ($kgm_prp)->active_thread
  914             showtaskheader
  915             showtaskint ($kgm_actp)->task
  916             showactheader
  917             showactint $kgm_actp 0
  918             printf "\n"
  919         end
  920         set $kgm_prp = ($kgm_prp)->processor_list
  921     end
  922 end
  923 document showcurrentthreads
  924 Syntax: (gdb) showcurrentthreads
  925 | Routine to print out info about the thread running on each cpu.
  926 end
  927 
  928 
  929 define _showrunqint
  930         set $kgm_runq = (struct run_queue *)$arg0
  931         
  932         printf "    Priority Run Queue Info: Count %d\n", $kgm_runq->count
  933         set $kgm_runq_queue_i = 0
  934         set $kgm_runq_queue_count = sizeof($kgm_runq->queues)/sizeof($kgm_runq->queues[0])
  935         while $kgm_runq->count && $kgm_runq_queue_i < $kgm_runq_queue_count
  936                 set $kgm_runq_queue_head = &$kgm_runq->queues[$kgm_runq_queue_i]
  937                 set $kgm_runq_queue_p = $kgm_runq_queue_head->next
  938                 if $kgm_runq_queue_p != $kgm_runq_queue_head
  939                         set $kgm_runq_queue_this_count = 0
  940                         while $kgm_runq_queue_p != $kgm_runq_queue_head
  941                                 set $kgm_runq_queue_this_count = $kgm_runq_queue_this_count + 1
  942                                 showtask ((thread_t)$kgm_runq_queue_p)->task
  943                                 showactstack $kgm_runq_queue_p
  944                                 set $kgm_runq_queue_p = $kgm_runq_queue_p->next
  945                         end
  946                         printf "      Queue Priority %3d [", $kgm_runq_queue_i
  947                         showptr $kgm_runq_queue_head
  948                         printf "] Count %d\n", $kgm_runq_queue_this_count
  949                 end
  950                 set $kgm_runq_queue_i = $kgm_runq_queue_i + 1
  951         end
  952 
  953 end
  954 
  955 define _showgrrrint
  956         set $kgm_grrr_runq = $arg0
  957         
  958         printf "    GRRR Info: Count %d Weight %d Current Group ", $kgm_grrr_runq->count, $kgm_grrr_runq->weight
  959         showptr $kgm_grrr_runq->current_group
  960         printf "\n"
  961         set $kgm_grrr_group_i = 0
  962         set $kgm_grrr_group_count = sizeof($kgm_grrr_runq->groups)/sizeof($kgm_grrr_runq->groups[0])
  963         while $kgm_grrr_runq->count && $kgm_grrr_group_i < $kgm_grrr_group_count
  964                 set $kgm_grrr_group = &$kgm_grrr_runq->groups[$kgm_grrr_group_i]
  965                 if $kgm_grrr_group->count > 0
  966                         printf "      Group %3d [", $kgm_grrr_group->index
  967                         showptr $kgm_grrr_group
  968                         printf "] Count %d Weight %d\n", $kgm_grrr_group->count, $kgm_grrr_group->weight
  969                         set $kgm_grrr_group_client_head = &$kgm_grrr_group->clients
  970                         set $kgm_grrr_group_client = $kgm_grrr_group_client_head->next
  971                         while $kgm_grrr_group_client != $kgm_grrr_group_client_head
  972                                 # showtask ((thread_t)$kgm_grrr_group_client)->task
  973                                 # showactstack $kgm_grrr_group_client
  974                                 set $kgm_grrr_group_client = $kgm_grrr_group_client->next
  975                         end
  976                 end
  977                 set $kgm_grrr_group_i = $kgm_grrr_group_i + 1
  978         end
  979 end
  980 
  981 define showallprocessors
  982         set $kgm_pset = &pset0
  983 
  984         set $kgm_show_grrr = 0
  985         set $kgm_show_priority_runq = 0
  986         set $kgm_show_priority_pset_runq = 0
  987         set $kgm_show_fairshare_grrr = 0
  988         set $kgm_show_fairshare_list = 0
  989 
  990         if _sched_enum == 1
  991                 set $kgm_show_priority_runq = 1
  992                 set $kgm_show_fairshare_list = 1
  993         end
  994         if _sched_enum == 2
  995                 set $kgm_show_priority_pset_runq = 1
  996                 set $kgm_show_fairshare_list = 1
  997         end
  998         if _sched_enum == 4
  999                 set $kgm_show_grrr = 1
 1000                 set $kgm_show_fairshare_grrr = 1
 1001         end
 1002         if _sched_enum == 5
 1003                 set $kgm_show_priority_runq = 1
 1004                 set $kgm_show_fairshare_list = 1
 1005         end
 1006         if _sched_enum == 6
 1007                 set $kgm_show_priority_pset_runq = 1
 1008                 set $kgm_show_fairshare_list = 1
 1009         end
 1010 
 1011         while $kgm_pset != 0
 1012                 printf "Processor Set "
 1013                 showptr $kgm_pset
 1014                 printf " Count %d (cpu_id 0x%x-0x%x)\n", ($kgm_pset)->cpu_set_count, ($kgm_pset)->cpu_set_low, ($kgm_pset)->cpu_set_hi
 1015                 printf "  Active Processors:\n"
 1016                 set $kgm_active_queue_head = &($kgm_pset)->active_queue
 1017                 set $kgm_active_elt = $kgm_active_queue_head->next
 1018                 while $kgm_active_elt != $kgm_active_queue_head
 1019                         set $kgm_processor = (processor_t)$kgm_active_elt
 1020                         printf "    "
 1021                         showprocessorint $kgm_processor
 1022 
 1023                         if $kgm_show_priority_runq
 1024                                 set $kgm_runq = &$kgm_processor->runq
 1025                                 _showrunqint $kgm_runq
 1026                         end
 1027                         if $kgm_show_grrr
 1028                                 set $kgm_grrr_runq = &$kgm_processor->grrr_runq
 1029                                 _showgrrrint $kgm_grrr_runq
 1030                         end
 1031                         
 1032                         if $kgm_processor->processor_meta != 0 && $kgm_processor->processor_meta->primary == $kgm_processor
 1033                                 set $kgm_processor_meta_idle_head = &$kgm_processor->processor_meta->idle_queue
 1034                                 set $kgm_processor_meta_idle = $kgm_processor_meta_idle_head->next
 1035                                 while $kgm_processor_meta_idle != $kgm_processor_meta_idle_head
 1036                                         printf "      Idle Meta Processor: "
 1037                                         showprocessorint $kgm_processor_meta_idle
 1038                                         set $kgm_processor_meta_idle = $kgm_processor_meta_idle->next
 1039                                 end
 1040                         end
 1041                         
 1042                         set $kgm_active_elt = $kgm_active_elt->next
 1043                 end
 1044                 printf "  Idle Processors:\n"
 1045                 set $kgm_idle_queue_head = &($kgm_pset)->idle_queue
 1046                 set $kgm_idle_elt = $kgm_idle_queue_head->next
 1047                 while $kgm_idle_elt != $kgm_idle_queue_head
 1048                         set $kgm_processor = (processor_t)$kgm_idle_elt
 1049                         printf "    "
 1050                         showprocessorint $kgm_processor
 1051                         
 1052                         if $kgm_processor->processor_meta != 0 && $kgm_processor->processor_meta->primary == $kgm_processor
 1053                                 set $kgm_processor_meta_idle_head = &$kgm_processor->processor_meta->idle_queue
 1054                                 set $kgm_processor_meta_idle = $kgm_processor_meta_idle_head->next
 1055                                 while $kgm_processor_meta_idle != $kgm_processor_meta_idle_head
 1056                                         printf "      Idle Meta Processor: "
 1057                                         showprocessorint $kgm_processor_meta_idle
 1058                                         set $kgm_processor_meta_idle = $kgm_processor_meta_idle->next
 1059                                 end
 1060                         end
 1061 
 1062                         set $kgm_idle_elt = $kgm_idle_elt->next
 1063                 end
 1064 
 1065                 if $kgm_show_priority_pset_runq
 1066                         set $kgm_runq = &$kgm_pset->pset_runq
 1067                         printf "\n"
 1068                         _showrunqint $kgm_runq
 1069                 end
 1070                 set $kgm_pset = ($kgm_pset)->pset_list
 1071         end
 1072         
 1073         printf "\n"
 1074         printf "Realtime Queue Count %d\n", rt_runq.count
 1075         set $kgm_rt_runq_head = &rt_runq.queue
 1076         set $kgm_rt_runq = $kgm_rt_runq_head->next
 1077         while $kgm_rt_runq != $kgm_rt_runq_head
 1078                 showtask ((thread_t)$kgm_rt_runq)->task
 1079                 showact $kgm_rt_runq
 1080                 set $kgm_rt_runq = $kgm_rt_runq->next
 1081         end
 1082         
 1083         printf "\n"
 1084         if $kgm_show_fairshare_list
 1085                 printf "Fair Share Queue Count %d\n", fs_runq.count
 1086                 set $kgm_fs_runq_head = &fs_runq.queue
 1087                 set $kgm_fs_runq = $kgm_fs_runq_head->next
 1088                 while $kgm_fs_runq != $kgm_fs_runq_head
 1089                         showtask ((thread_t)$kgm_fs_runq)->task
 1090                         showact $kgm_fs_runq
 1091                         set $kgm_fs_runq = $kgm_fs_runq->next
 1092                 end
 1093         end
 1094         if $kgm_show_fairshare_grrr
 1095                 printf "Fair Share Queue Count %d\n", fs_grrr_runq.count
 1096                 set $kgm_fs_grrr = &fs_grrr_runq
 1097                 _showgrrrint $kgm_fs_grrr
 1098         end
 1099 end
 1100 document showallprocessors
 1101 Syntax: (gdb) showallprocessors
 1102 | Routine to print out info about all psets and processors
 1103 end
 1104 
 1105 set $decode_wait_events = 0
 1106 define showallstacks
 1107     set $kgm_head_taskp = &tasks
 1108     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 1109     while $kgm_taskp != $kgm_head_taskp
 1110         showtaskheader
 1111         showtaskint $kgm_taskp
 1112         set $kgm_head_actp = &($kgm_taskp->threads)
 1113         set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 1114         while $kgm_actp != $kgm_head_actp
 1115             showactheader
 1116             if ($decode_wait_events > 0)
 1117                showactint $kgm_actp 1
 1118             else
 1119                showactint $kgm_actp 2
 1120             end
 1121             set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 1122         end
 1123         printf "\n"
 1124         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 1125     end
 1126 
 1127     printf "\nZombie Processes:\n" 
 1128     zombstacks
 1129 end
 1130 
 1131 document showallstacks
 1132 Syntax: (gdb) showallstacks
 1133 | Routine to print out the stack for each thread in the system.
 1134 | If the variable $decode_wait_events is non-zero, the routine attempts to
 1135 | interpret thread wait_events as kernel module offsets, which can add to
 1136 | processing time.
 1137 end
 1138 
 1139 define showcurrentstacks
 1140     set $kgm_prp = processor_list
 1141     while $kgm_prp != 0
 1142         showprocessorint $kgm_prp
 1143         if ($kgm_prp)->active_thread != 0
 1144             set $kgm_actp = ($kgm_prp)->active_thread
 1145             showtaskheader
 1146             showtaskint ($kgm_actp)->task
 1147             showactheader
 1148             showactint $kgm_actp 1
 1149             printf "\n"
 1150         end
 1151         set $kgm_prp = ($kgm_prp)->processor_list
 1152     end
 1153 end
 1154 
 1155 document showcurrentstacks
 1156 Syntax: (gdb) showcurrentstacks
 1157 | Routine to print out the thread running on each cpu (incl. its stack)
 1158 end
 1159 
 1160 define showwaiterheader
 1161     printf "waiters     thread      "
 1162     printf "processor   pri  state  wait_queue  wait_event\n"
 1163 end
 1164 
 1165 define showwaitqwaiters
 1166     set $kgm_w_waitqp = (WaitQueue*)$arg0
 1167     set $kgm_w_linksp = &($kgm_w_waitqp->wq_queue)
 1168     set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_linksp->next
 1169     set $kgm_w_found = 0
 1170     while ( (queue_entry_t)$kgm_w_wqe != (queue_entry_t)$kgm_w_linksp)
 1171         if ($kgm_w_wqe->wqe_type != &_wait_queue_link)
 1172                 if !$kgm_w_found
 1173                         set $kgm_w_found = 1
 1174                         showwaiterheader
 1175                 end
 1176                 set $kgm_w_shuttle = (struct thread *)$kgm_w_wqe
 1177                 showactint $kgm_w_shuttle 0
 1178         end     
 1179         set $kgm_w_wqe = (WaitQueueElement *)$kgm_w_wqe->wqe_links.next
 1180     end
 1181 end
 1182 
 1183 define showwaitqwaitercount
 1184     set $kgm_wc_waitqp = (WaitQueue*)$arg0
 1185     set $kgm_wc_linksp = &($kgm_wc_waitqp->wq_queue)
 1186     set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_linksp->next
 1187     set $kgm_wc_count = 0
 1188     while ( (queue_entry_t)$kgm_wc_wqe != (queue_entry_t)$kgm_wc_linksp)
 1189         if ($kgm_wc_wqe->wqe_type != &_wait_queue_link)
 1190                 set $kgm_wc_count = $kgm_wc_count + 1
 1191         end
 1192         set $kgm_wc_wqe = (WaitQueueElement *)$kgm_wc_wqe->wqe_links.next
 1193     end
 1194     printf "0x%08x  ", $kgm_wc_count
 1195 end
 1196 
 1197 define showwaitqmembercount
 1198     set $kgm_mc_waitqsetp = (WaitQueueSet*)$arg0
 1199     set $kgm_mc_setlinksp = &($kgm_mc_waitqsetp->wqs_setlinks)
 1200     set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_setlinksp->next
 1201     set $kgm_mc_count = 0
 1202     while ( (queue_entry_t)$kgm_mc_wql != (queue_entry_t)$kgm_mc_setlinksp)
 1203         set $kgm_mc_count = $kgm_mc_count + 1
 1204         set $kgm_mc_wql = (WaitQueueLink *)$kgm_mc_wql->wql_setlinks.next
 1205     end
 1206     printf "0x%08x  ", $kgm_mc_count
 1207 end
 1208 
 1209     
 1210 define showwaitqmemberheader
 1211     printf "set-members wait_queue  interlock   "
 1212     printf "pol  type   member_cnt  waiter_cnt\n"
 1213 end
 1214 
 1215 define showwaitqmemberint
 1216     set $kgm_m_waitqp = (WaitQueue*)$arg0
 1217     printf "            0x%08x  ", $kgm_m_waitqp
 1218     printf "0x%08x  ", $kgm_m_waitqp->wq_interlock.lock_data
 1219     if ($kgm_m_waitqp->wq_fifo)
 1220         printf "Fifo "
 1221     else
 1222         printf "Prio "
 1223     end
 1224     if ($kgm_m_waitqp->wq_type == 0xf1d1)
 1225         printf "Set    "
 1226         showwaitqmembercount $kgm_m_waitqp
 1227     else
 1228         printf "Que    0x00000000  "
 1229     end
 1230     showwaitqwaitercount $kgm_m_waitqp
 1231     printf "\n"
 1232 end
 1233 
 1234 
 1235 define showwaitqmemberofheader
 1236     printf "member-of   wait_queue  interlock   "
 1237     printf "pol  type   member_cnt  waiter_cnt\n"
 1238 end
 1239 
 1240 define showwaitqmemberof
 1241     set $kgm_mo_waitqp = (WaitQueue*)$arg0
 1242     set $kgm_mo_linksp = &($kgm_mo_waitqp->wq_queue)
 1243     set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_linksp->next
 1244     set $kgm_mo_found = 0
 1245     while ( (queue_entry_t)$kgm_mo_wqe != (queue_entry_t)$kgm_mo_linksp)
 1246         if ($kgm_mo_wqe->wqe_type == &_wait_queue_link)
 1247                 if !$kgm_mo_found
 1248                         set $kgm_mo_found = 1
 1249                         showwaitqmemberofheader
 1250                 end
 1251                 set $kgm_mo_wqlp = (WaitQueueLink *)$kgm_mo_wqe
 1252                 set $kgm_mo_wqsetp = (WaitQueue*)($kgm_mo_wqlp->wql_setqueue)
 1253                 showwaitqmemberint $kgm_mo_wqsetp
 1254         end     
 1255         set $kgm_mo_wqe = (WaitQueueElement *)$kgm_mo_wqe->wqe_links.next
 1256     end
 1257 end
 1258 
 1259 define showwaitqmembers
 1260     set $kgm_ms_waitqsetp = (WaitQueueSet*)$arg0
 1261     set $kgm_ms_setlinksp = &($kgm_ms_waitqsetp->wqs_setlinks)
 1262     set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_setlinksp->next
 1263     set $kgm_ms_found = 0
 1264     while ( (queue_entry_t)$kgm_ms_wql != (queue_entry_t)$kgm_ms_setlinksp)
 1265         set $kgm_ms_waitqp = $kgm_ms_wql->wql_element.wqe_queue
 1266         if !$kgm_ms_found  
 1267             showwaitqmemberheader
 1268             set $kgm_ms_found = 1
 1269         end
 1270         showwaitqmemberint $kgm_ms_waitqp
 1271         set $kgm_ms_wql = (WaitQueueLink *)$kgm_ms_wql->wql_setlinks.next
 1272     end
 1273 end
 1274 
 1275 define showwaitqheader
 1276     printf "wait_queue  ref_count   interlock   "
 1277     printf "pol  type   member_cnt  waiter_cnt\n"
 1278 end
 1279 
 1280 define showwaitqint
 1281     set $kgm_waitqp = (WaitQueue*)$arg0
 1282     printf "0x%08x  ", $kgm_waitqp
 1283     if ($kgm_waitqp->wq_type == 0xf1d1)
 1284         printf "0x%08x  ", ((WaitQueueSet*)$kgm_waitqp)->wqs_refcount
 1285     else
 1286         printf "0x00000000  "
 1287     end
 1288     printf "0x%08x  ", $kgm_waitqp->wq_interlock.lock_data
 1289     if ($kgm_waitqp->wq_fifo)
 1290         printf "Fifo "
 1291     else
 1292         printf "Prio "
 1293     end
 1294     if ($kgm_waitqp->wq_type == 0xf1d1)
 1295         printf "Set    "
 1296         showwaitqmembercount $kgm_waitqp
 1297     else
 1298         printf "Que    0x00000000  "
 1299     end
 1300     showwaitqwaitercount $kgm_waitqp
 1301     printf "\n"
 1302 end
 1303 
 1304 define showwaitq
 1305     set $kgm_waitq1p = (WaitQueue*)$arg0
 1306     showwaitqheader
 1307     showwaitqint $kgm_waitq1p   
 1308     if ($kgm_waitq1p->wq_type == 0xf1d1)
 1309         showwaitqmembers $kgm_waitq1p
 1310     else
 1311         showwaitqmemberof $kgm_waitq1p
 1312     end
 1313     showwaitqwaiters $kgm_waitq1p
 1314 end
 1315 
 1316 define showmapheader
 1317     printf "vm_map    "
 1318     showptrhdrpad
 1319     printf "  pmap      "
 1320     showptrhdrpad
 1321     printf "  vm_size   "
 1322     showptrhdrpad
 1323     printf " #ents rpage  hint      "
 1324     showptrhdrpad
 1325     printf "  first_free\n"
 1326 end
 1327 
 1328 define showvmeheader
 1329     printf "    entry     "
 1330     showptrhdrpad
 1331     printf "  start               prot  #page  object    "
 1332     showptrhdrpad
 1333     printf "  offset\n"
 1334 end
 1335 
 1336 define showvmint
 1337     set $kgm_mapp = (vm_map_t)$arg0
 1338     set $kgm_map = *$kgm_mapp
 1339     showptr $arg0
 1340     printf "  "
 1341     showptr $kgm_map.pmap
 1342     printf "  "
 1343     showptr $kgm_map.size
 1344     printf "   %3d ", $kgm_map.hdr.nentries
 1345     if $kgm_map.pmap
 1346         printf "%5d  ", $kgm_map.pmap->stats.resident_count
 1347     else
 1348         printf "<n/a>  "
 1349     end
 1350     showptr $kgm_map.hint
 1351     printf "  "
 1352     showptr $kgm_map.first_free
 1353     printf "\n"
 1354     if $arg1 != 0
 1355         showvmeheader   
 1356         set $kgm_head_vmep = &($kgm_mapp->hdr.links)
 1357         set $kgm_vmep = $kgm_map.hdr.links.next
 1358         while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
 1359             set $kgm_vme = *$kgm_vmep
 1360             printf "    "
 1361             showptr $kgm_vmep
 1362             printf "  0x%016llx  ", $kgm_vme.links.start
 1363             printf "%1x", $kgm_vme.protection
 1364             printf "%1x", $kgm_vme.max_protection
 1365             if $kgm_vme.inheritance == 0x0
 1366                 printf "S"
 1367             end
 1368             if $kgm_vme.inheritance == 0x1
 1369                 printf "C"
 1370             end
 1371             if $kgm_vme.inheritance == 0x2
 1372                 printf "-"
 1373             end
 1374             if $kgm_vme.inheritance == 0x3
 1375                 printf "D"
 1376             end
 1377             if $kgm_vme.is_sub_map
 1378                 printf "s "
 1379             else
 1380                 if $kgm_vme.needs_copy
 1381                     printf "n "
 1382                 else
 1383                     printf "  "
 1384                 end
 1385             end
 1386             printf "%6d  ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
 1387             showptr $kgm_vme.object.vm_object
 1388             printf "  0x%016llx\n", $kgm_vme.offset
 1389             set $kgm_vmep = $kgm_vme.links.next
 1390         end
 1391     end
 1392     printf "\n"
 1393 end
 1394 
 1395 
 1396 define showmapwiredp
 1397     set $kgm_mapp = (vm_map_t)$arg0
 1398     set $kgm_map = *$kgm_mapp
 1399     set $kgm_head_vmep = &($kgm_mapp->hdr.links)
 1400     set $kgm_vmep = $kgm_map.hdr.links.next
 1401     set $kgm_objp_prev = (struct vm_object *)0
 1402     if $arg1 == 0
 1403         set $kgm_saw_kernel_obj = 0
 1404         set $kgm_wired_count = 0
 1405         set $kgm_objp_print_space = 1
 1406     else
 1407         set $kgm_objp_print_space = 0
 1408     end
 1409     while (($kgm_vmep != 0) && ($kgm_vmep != $kgm_head_vmep))
 1410         set $kgm_vme = *$kgm_vmep
 1411         set $kgm_objp = $kgm_vme.object.vm_object
 1412         if $kgm_vme.is_sub_map
 1413             if $arg1 == 0
 1414                 set $kgm_mapp_orig = $kgm_mapp
 1415                 set $kgm_vmep_orig = $kgm_vmep
 1416                 set $kgm_vme_orig = $kgm_vme
 1417                 set $kgm_head_vmep_orig = $kgm_head_vmep
 1418                 printf "\n****"
 1419                 showptr $kgm_objp
 1420                 showmapwiredp $kgm_objp 1
 1421                 set $kgm_vme = $kgm_vme_orig
 1422                 set $kgm_vmep = $kgm_vmep_orig
 1423                 set $kgm_mapp = $kgm_mapp_orig
 1424                 set $kgm_head_vmep = $kgm_head_vmep_orig
 1425                 set $kgm_objp = (struct vm_object *)0
 1426             else
 1427                 printf "\n????"     
 1428                 showptr $kgm_mapp
 1429                 printf "    "
 1430                 showptr $kgm_vmep
 1431                 set $kgm_objp = (struct vm_object *)0
 1432                 printf "\n"
 1433             end
 1434         end
 1435         if ($kgm_objp == $kgm_objp_prev)
 1436             set $kgm_objp = (struct vm_object *)0
 1437         end
 1438         if $kgm_objp == kernel_object
 1439            if $kgm_saw_kernel_obj
 1440                set $kgm_objp = (struct vm_object *)0
 1441            end
 1442            set $kgm_saw_kernel_obj = 1
 1443         end
 1444         if $kgm_objp && $kgm_objp->wired_page_count
 1445             if $kgm_objp_print_space == 1
 1446                 printf "    "
 1447                 showptr $kgm_mapp
 1448             end
 1449             set $kgm_objp_print_space = 1
 1450             printf "    "
 1451             showptr $kgm_vmep
 1452             printf "  0x%016llx  ", $kgm_vme.links.start
 1453             printf "%5d", $kgm_vme.alias
 1454             printf "%6d  ",($kgm_vme.links.end - $kgm_vme.links.start) >> 12
 1455             showptr $kgm_objp
 1456             printf "[%3d]", $kgm_objp->ref_count
 1457             printf "%7d\n", $kgm_objp->wired_page_count
 1458             set $kgm_wired_count = $kgm_wired_count + $kgm_objp->wired_page_count
 1459             set $kgm_objp_prev = $kgm_objp
 1460         end
 1461         set $kgm_vmep = $kgm_vme.links.next
 1462     end
 1463     if $arg1 == 0
 1464         printf "total wired count = %d\n", $kgm_wired_count
 1465     end
 1466 end
 1467 
 1468 define showmapwired
 1469     printf "    map       "
 1470     showptrhdrpad
 1471     printf "    entry     "
 1472     showptrhdrpad
 1473     printf "  start               alias  #page  object    "
 1474     showptrhdrpad
 1475     printf "       wired\n"
 1476     showmapwiredp $arg0 0
 1477 end
 1478 document showmapwired
 1479 Syntax: (gdb) showmapwired <vm_map>
 1480 | Routine to print out a summary listing of all the entries with wired pages in a vm_map
 1481 end
 1482 
 1483 define showmapvme
 1484         showmapheader
 1485         showvmint $arg0 1
 1486 end
 1487 document showmapvme
 1488 Syntax: (gdb) showmapvme <vm_map>
 1489 | Routine to print out a summary listing of all the entries in a vm_map
 1490 end
 1491 
 1492 
 1493 define showmap
 1494         showmapheader
 1495         showvmint $arg0 0
 1496 end
 1497 document showmap
 1498 Syntax: (gdb) showmap <vm_map>
 1499 | Routine to print out info about the specified vm_map
 1500 end
 1501 
 1502 define showallvm
 1503     set $kgm_head_taskp = &tasks
 1504     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 1505     while $kgm_taskp != $kgm_head_taskp
 1506         showtaskheader
 1507         showmapheader
 1508         showtaskint $kgm_taskp
 1509         showvmint $kgm_taskp->map 0
 1510         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 1511     end
 1512 end
 1513 document showallvm
 1514 Syntax: (gdb) showallvm
 1515 | Routine to print a summary listing of all the vm maps
 1516 end
 1517 
 1518 
 1519 define showallvme
 1520     set $kgm_head_taskp = &tasks
 1521     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 1522     while $kgm_taskp != $kgm_head_taskp
 1523         showtaskheader
 1524         showmapheader
 1525         showtaskint $kgm_taskp
 1526         showvmint $kgm_taskp->map 1
 1527         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 1528     end
 1529 end
 1530 document showallvme
 1531 Syntax: (gdb) showallvme
 1532 | Routine to print a summary listing of all the vm map entries
 1533 end
 1534 
 1535 
 1536 define showipcheader
 1537     printf "ipc_space "
 1538     showptrhdrpad
 1539     printf "  is_task   "
 1540     showptrhdrpad
 1541     printf "  is_table  "
 1542     showptrhdrpad
 1543     printf " flags ports  table_next  "
 1544     showptrhdrpad
 1545     printf "   low_mod   high_mod\n"
 1546 end
 1547 
 1548 define showipceheader
 1549     printf "            "
 1550     showptrhdrpad
 1551     printf "object      "
 1552     showptrhdrpad
 1553     showptrhdrpad
 1554     printf "name        rite urefs  destname    "
 1555     showptrhdrpad
 1556     printf "destination\n"
 1557 end
 1558 
 1559 define showipceint
 1560     set $kgm_ie = *(ipc_entry_t)$arg0
 1561     printf "            "
 1562     showptrhdrpad
 1563     showptr $kgm_ie.ie_object
 1564     showptrhdrpad
 1565     printf "  0x%08x  ", $arg1
 1566     if $kgm_ie.ie_bits & 0x00100000
 1567         printf "Dead "
 1568         printf "%5d\n", $kgm_ie.ie_bits & 0xffff
 1569     else
 1570         if $kgm_ie.ie_bits & 0x00080000
 1571             printf "SET  "
 1572             printf "%5d\n", $kgm_ie.ie_bits & 0xffff
 1573         else
 1574             if $kgm_ie.ie_bits & 0x00010000
 1575                 if $kgm_ie.ie_bits & 0x00020000
 1576                     printf " SR"
 1577                 else
 1578                     printf "  S"
 1579                 end
 1580             else
 1581                 if $kgm_ie.ie_bits & 0x00020000
 1582                    printf "  R"
 1583                 end
 1584             end
 1585             if $kgm_ie.ie_bits & 0x00040000
 1586                 printf "  O"
 1587             end
 1588             if $kgm_ie.index.request
 1589                 set $kgm_port = (ipc_port_t)$kgm_ie.ie_object
 1590                 set $kgm_requests = $kgm_port->ip_requests
 1591                 set $kgm_req_soright = $kgm_requests[$kgm_ie.index.request].notify.port
 1592                 if $kgm_req_soright
 1593 #                   Armed send-possible notification?
 1594                     if (uintptr_t)$kgm_req_soright & 0x1
 1595                         printf "s"
 1596                     else
 1597 #                       Delayed send-possible notification?
 1598                         if (uintptr_t)$kgm_req_soright & 0x2
 1599                             printf "d"
 1600                         else
 1601 #                           Dead-name notification
 1602                             printf "n"
 1603                         end
 1604                     end     
 1605                 else
 1606                     printf " "
 1607                 end
 1608             else
 1609                 printf " "
 1610             end
 1611 #           Collision (with tree)?
 1612             if $kgm_ie.ie_bits & 0x00800000
 1613                 printf "c"
 1614             else
 1615                 printf " "
 1616             end
 1617             printf "%5d  ", $kgm_ie.ie_bits & 0xffff
 1618             showportdest $kgm_ie.ie_object
 1619         end
 1620     end
 1621 end
 1622 
 1623 define showipcint
 1624     set $kgm_isp = (ipc_space_t)$arg0
 1625     set $kgm_is = *$kgm_isp
 1626     showptr $arg0
 1627     printf "  "
 1628     showptr $kgm_is.is_task
 1629     printf "  "
 1630     showptr $kgm_is.is_table
 1631     printf "  "
 1632     if ($kgm_is.is_bits & 0x40000000) == 0
 1633         printf "A"
 1634     else
 1635         printf " "
 1636     end
 1637     if ($kgm_is.is_bits & 0x20000000) != 0
 1638         printf "G   "
 1639     else
 1640         printf "    "
 1641     end
 1642     printf "%5d  ", $kgm_is.is_table_size 
 1643     showptr $kgm_is.is_table_next
 1644     printf "  "
 1645     printf "%10d ", $kgm_is.is_low_mod
 1646     printf "%10d", $kgm_is.is_high_mod
 1647     printf "\n"
 1648     if $arg1 != 0
 1649         showipceheader
 1650         set $kgm_iindex = 0
 1651         set $kgm_iep = $kgm_is.is_table
 1652         set $kgm_destspacep = (ipc_space_t)0
 1653         while ( $kgm_iindex < $kgm_is.is_table_size )
 1654             set $kgm_ie = *$kgm_iep
 1655             if $kgm_ie.ie_bits & 0x001f0000
 1656                 set $kgm_name = (($kgm_iindex << 8)|($kgm_ie.ie_bits >> 24))
 1657                 showipceint $kgm_iep $kgm_name
 1658                 if $arg2 != 0
 1659                    if $kgm_ie.ie_object != 0 && ($kgm_ie.ie_bits & 0x00070000) && ((ipc_port_t) $kgm_ie.ie_object)->ip_callstack[0] != 0
 1660                         printf "              user bt: "
 1661                         showportbt $kgm_ie.ie_object $kgm_is.is_task
 1662                    end
 1663                 end
 1664             end
 1665             set $kgm_iindex = $kgm_iindex + 1
 1666             set $kgm_iep = &($kgm_is.is_table[$kgm_iindex])
 1667         end
 1668     end
 1669     printf "\n"
 1670 end
 1671 
 1672 
 1673 define showipc
 1674     set $kgm_isp = (ipc_space_t)$arg0
 1675     showipcheader
 1676     showipcint $kgm_isp 0 0
 1677 end
 1678 document showipc
 1679 Syntax: (gdb) showipc <ipc_space>
 1680 | Routine to print the status of the specified ipc space
 1681 end
 1682 
 1683 define showrights
 1684         set $kgm_isp = (ipc_space_t)$arg0
 1685     showipcheader
 1686         showipcint $kgm_isp 1 0
 1687 end
 1688 document showrights
 1689 Syntax: (gdb) showrights <ipc_space>
 1690 | Routine to print a summary list of all the rights in a specified ipc space
 1691 end
 1692 
 1693 
 1694 define showtaskipc
 1695         set $kgm_taskp = (task_t)$arg0
 1696         showtaskheader
 1697         showtaskint $kgm_taskp
 1698         showipcheader
 1699         showipcint $kgm_taskp->itk_space 0 0
 1700 end
 1701 document showtaskipc
 1702 Syntax: (gdb) showtaskipc <task>
 1703 | Routine to print info about the ipc space for a task
 1704 end
 1705 
 1706 
 1707 define showtaskrights
 1708         set $kgm_taskp = (task_t)$arg0
 1709         showtaskheader
 1710         showtaskint $kgm_taskp
 1711         showipcheader
 1712         showipcint $kgm_taskp->itk_space 1 0
 1713 end
 1714 document showtaskrights
 1715 Syntax: (gdb) showtaskrights <task>
 1716 | Routine to print info about the ipc rights for a task
 1717 end
 1718 
 1719 define showtaskrightsbt
 1720         set $kgm_taskp = (task_t)$arg0
 1721         showtaskheader
 1722         showtaskint $kgm_taskp
 1723         showipcheader
 1724         showipcint $kgm_taskp->itk_space 1 1
 1725 end
 1726 document showtaskrightsbt
 1727 Syntax: (gdb) showtaskrightsbt <task>
 1728 | Routine to print info about the ipc rights for a task with backtraces
 1729 end
 1730 
 1731 define showallipc
 1732     set $kgm_head_taskp = &tasks
 1733     set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
 1734     while $kgm_cur_taskp != $kgm_head_taskp
 1735         showtaskheader
 1736         showtaskint $kgm_cur_taskp
 1737         showipcheader
 1738         showipcint $kgm_cur_taskp->itk_space 0 0
 1739         set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
 1740     end
 1741 end
 1742 document showallipc
 1743 Syntax: (gdb) showallipc
 1744 | Routine to print a summary listing of all the ipc spaces
 1745 end
 1746 
 1747 define showipcsumheader
 1748     printf "task         "
 1749     showptrhdrpad
 1750     printf " pid         "
 1751     printf " #acts         "
 1752     printf " tsize "
 1753     printf "command\n"
 1754 end
 1755 
 1756 define showipcsummaryint
 1757     set $kgm_taskp = (struct task *)$arg0
 1758     showptr $arg0
 1759     printf "%7d", ((struct proc *)$kgm_taskp->bsd_info)->p_pid
 1760     printf "%15d", $kgm_taskp->thread_count
 1761     printf "%15d", $kgm_cur_taskp->itk_space.is_table_size      
 1762         printf " %s\n", ((struct proc *)$kgm_taskp->bsd_info)->p_comm
 1763 end
 1764 
 1765 define showipcsummary
 1766     showipcsumheader
 1767     set $kgm_head_taskp = &tasks
 1768     set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
 1769     while $kgm_cur_taskp != $kgm_head_taskp
 1770         showipcsummaryint $kgm_cur_taskp
 1771         set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
 1772     end
 1773 end
 1774 
 1775 document showipcsummary
 1776 Syntax: (gdb) showipcsummary 
 1777 | Summarizes the IPC state of all tasks. This is a convenient way to dump
 1778 | some basic clues about IPC messaging. You can use the output to determine
 1779 | tasks that are candidates for further investigation.
 1780 end
 1781 
 1782 
 1783 define showallrights
 1784     set $kgm_head_taskp = &tasks
 1785     set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
 1786     while $kgm_cur_taskp != $kgm_head_taskp
 1787         showtaskheader
 1788         showtaskint $kgm_cur_taskp
 1789         showipcheader
 1790         showipcint $kgm_cur_taskp->itk_space 1 0
 1791         set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
 1792     end
 1793 end
 1794 document showallrights
 1795 Syntax: (gdb) showallrights
 1796 | Routine to print a summary listing of all the ipc rights
 1797 end
 1798 
 1799 
 1800 define showtaskvm
 1801         set $kgm_taskp = (task_t)$arg0
 1802         showtaskheader
 1803         showmapheader
 1804         showtaskint $kgm_taskp
 1805         showvmint $kgm_taskp->map 0
 1806 end
 1807 document showtaskvm
 1808 Syntax: (gdb) showtaskvm <task>
 1809 | Routine to print out info about a task's vm_map
 1810 end
 1811 
 1812 define showtaskvme
 1813         set $kgm_taskp = (task_t)$arg0
 1814         showtaskheader
 1815         showtaskint $kgm_taskp
 1816         showmapheader
 1817         showvmint $kgm_taskp->map 1
 1818 end
 1819 document showtaskvme
 1820 Syntax: (gdb) showtaskvme <task>
 1821 | Routine to print out info about a task's vm_map_entries
 1822 end
 1823 
 1824 
 1825 define showtaskheader
 1826     printf "task      "
 1827     showptrhdrpad
 1828     printf "  vm_map    "
 1829     showptrhdrpad
 1830     printf "  ipc_space "
 1831     showptrhdrpad
 1832     printf " #acts "
 1833     showprocheader
 1834 end
 1835 
 1836 
 1837 define showtaskint
 1838     set $kgm_taskp = (struct task *)$arg0
 1839     showptr $arg0
 1840     printf "  "
 1841     showptr $kgm_taskp->map
 1842     printf "  "
 1843     showptr $kgm_taskp->itk_space
 1844     printf " %5d ", $kgm_taskp->thread_count
 1845     showprocint $kgm_taskp->bsd_info
 1846 end
 1847 
 1848 define showtask
 1849     showtaskheader
 1850     showtaskint $arg0
 1851 end
 1852 document showtask
 1853 Syntax (gdb) showtask <task>
 1854 | Routine to print out info about a task.
 1855 end
 1856 
 1857 
 1858 define showtaskthreads
 1859     showtaskheader
 1860     set $kgm_taskp = (struct task *)$arg0
 1861     showtaskint $kgm_taskp
 1862     showactheader
 1863     set $kgm_head_actp = &($kgm_taskp->threads)
 1864     set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 1865     while $kgm_actp != $kgm_head_actp
 1866         showactint $kgm_actp 0
 1867         set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 1868     end
 1869 end
 1870 document showtaskthreads
 1871 Syntax: (gdb) showtaskthreads <task>
 1872 | Routine to print info about the threads in a task.
 1873 end
 1874 
 1875 
 1876 define showtaskstacks
 1877     showtaskheader
 1878     set $kgm_taskp = (struct task *)$arg0
 1879     showtaskint $kgm_taskp
 1880     set $kgm_head_actp = &($kgm_taskp->threads)
 1881     set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 1882     while $kgm_actp != $kgm_head_actp
 1883         showactheader
 1884         showactint $kgm_actp 1
 1885         set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 1886     end
 1887 end
 1888 document showtaskstacks
 1889 Syntax: (gdb) showtaskstacks <task>
 1890 | Routine to print out the stack for each thread in a task.
 1891 end
 1892 
 1893 define showqueue_elems
 1894         set $queue_head = (struct queue_entry *)($arg0)
 1895         set $queue = (struct queue_entry *)($queue_head->next)
 1896     while $queue != $queue_head
 1897                 showptr $queue
 1898                 printf " "
 1899                 set $thread = (struct thread *)$queue
 1900                 set $task = (struct task *)$thread->task
 1901                 set $bsd = (struct proc *)$task->bsd_info
 1902                 set $guy = (char *)$bsd->p_comm
 1903                 showptr $thread
 1904                 printf " "
 1905                 showptr $task
 1906                 printf " "
 1907                 showptr $bsd
 1908                 printf " "
 1909                 showptr $guy
 1910                 #printf "  %s\n", $kgm_procp->p_comm
 1911                 printf "\n"
 1912         set $queue = (struct queue_entry *)($queue->next)
 1913     end
 1914 end
 1915 
 1916 define showalltasks
 1917     showtaskheader
 1918     set $kgm_head_taskp = &tasks
 1919     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 1920     while $kgm_taskp != $kgm_head_taskp
 1921         showtaskint $kgm_taskp
 1922         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 1923     end
 1924 end
 1925 document showalltasks
 1926 Syntax: (gdb) showalltasks
 1927 | Routine to print a summary listing of all the tasks
 1928 | wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
 1929 |   if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
 1930 | io_policy -> RAGE  - rapid aging of vnodes requested
 1931 |              NORM  - normal I/O explicitly requested (this is the default)
 1932 |              PASS  - passive I/O requested (i.e. I/Os do not affect throttling decisions)
 1933 |              THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
 1934 end
 1935 
 1936 define showprocheader
 1937     printf "  pid  process     "
 1938     showptrhdrpad
 1939     printf "io_policy    wq_state   command\n"
 1940 end
 1941 
 1942 define showprocint
 1943     set $kgm_procp = (struct proc *)$arg0
 1944     if $kgm_procp != 0
 1945         set $kgm_printed = 0
 1946         printf "%5d  ", $kgm_procp->p_pid
 1947         showptr $kgm_procp
 1948         if ($kgm_procp->p_lflag & 0x400000)
 1949            printf "  RAGE "
 1950         else
 1951            printf "       "
 1952         end
 1953         set $ptask = (struct task *)$kgm_procp->task
 1954         set $diskpolicy = 0
 1955         if ($ptask->ext_appliedstate.hw_disk != 0)
 1956                 set $diskpolicy = $ptask->ext_appliedstate.hw_disk
 1957         else 
 1958                 if ($ptask->appliedstate.hw_disk != 0)
 1959                         set $diskpolicy = $ptask->appliedstate.hw_disk
 1960                 end
 1961         end
 1962         if ($ptask->ext_appliedstate.hw_bg != 0)
 1963                 set $diskpolicy = 5
 1964         end
 1965         if ($ptask->appliedstate.hw_bg != 0)
 1966                 set $diskpolicy = 4
 1967         end
 1968         if ($ptask->ext_appliedstate.apptype == 2)
 1969                 set $diskpolicy = 6
 1970         end
 1971         if ($diskpolicy == 2)
 1972                 printf "PASS    "
 1973                 set $kgm_printed = 1
 1974         end
 1975         if ($diskpolicy == 3)
 1976                 printf "THROT   "
 1977                 set $kgm_printed = 1
 1978         end
 1979         if ($diskpolicy == 4)
 1980                 printf "BG_THRT "
 1981                 set $kgm_printed = 1
 1982         end
 1983         if ($diskpolicy == 5)
 1984                 printf "EBG_THRT"
 1985                 set $kgm_printed = 1
 1986         end
 1987         if ($diskpolicy == 6)
 1988                 printf "APD_THRT"
 1989                 set $kgm_printed = 1
 1990         end
 1991         if ($kgm_printed == 0)
 1992            printf "      "
 1993         end
 1994         set $kgm_wqp = (struct workqueue *)$kgm_procp->p_wqptr
 1995         if $kgm_wqp != 0
 1996            printf "  %2d %2d %2d ", $kgm_wqp->wq_nthreads, $kgm_wqp->wq_thidlecount, $kgm_wqp->wq_reqcount
 1997         else
 1998            printf "           "
 1999         end
 2000         printf "  %s\n", $kgm_procp->p_comm
 2001     else
 2002         printf "  *0*  "
 2003         showptr 0
 2004         printf "  --\n"
 2005     end
 2006 end
 2007 
 2008 define showpid
 2009     showtaskheader
 2010     set $kgm_head_taskp = &tasks
 2011     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 2012     while $kgm_taskp != $kgm_head_taskp
 2013         set $kgm_procp = (struct proc *)$kgm_taskp->bsd_info
 2014         if (($kgm_procp != 0) && ($kgm_procp->p_pid == $arg0))
 2015             showtaskint $kgm_taskp
 2016             set $kgm_taskp = $kgm_head_taskp
 2017         else
 2018             set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 2019         end
 2020     end
 2021 end
 2022 document showpid
 2023 Syntax: (gdb) showpid <pid>
 2024 | Routine to print a single process by pid
 2025 end
 2026 
 2027 define showproc
 2028     showtaskheader
 2029     set $kgm_procp = (struct proc *)$arg0
 2030     showtaskint $kgm_procp->task
 2031 end
 2032 
 2033 
 2034 define kdb
 2035     set switch_debugger=1
 2036     continue
 2037 end
 2038 document kdb
 2039 | kdb - Switch to the inline kernel debugger
 2040 |
 2041 | usage: kdb
 2042 |
 2043 | The kdb macro allows you to invoke the inline kernel debugger.
 2044 end
 2045 
 2046 define showpsetheader
 2047     printf "portset     "
 2048     showptrhdrpad
 2049     printf "waitqueue   "
 2050     showptrhdrpad
 2051     showptrhdrpad
 2052     printf "recvname    flags refs  recvname    "
 2053     showptrhdrpad
 2054     printf "process\n"
 2055 end
 2056 
 2057 define showportheader
 2058     printf "port        "
 2059     showptrhdrpad
 2060     printf "mqueue      "
 2061     showptrhdrpad
 2062     showptrhdrpad
 2063     printf "recvname    flags refs  recvname    "
 2064     showptrhdrpad
 2065     printf "dest\n"
 2066 end
 2067 
 2068 define showportmemberheader
 2069     printf "members     "
 2070     showptrhdrpad
 2071     printf "port        "
 2072     showptrhdrpad
 2073     showptrhdrpad
 2074     printf "recvname    "
 2075     printf "flags refs  mqueue      "
 2076     showptrhdrpad
 2077     printf "msgcount\n"
 2078 end
 2079 
 2080 define showkmsgheader
 2081     printf "dest-port   "
 2082     showptrhdrpad
 2083     printf "kmsg        "
 2084     showptrhdrpad
 2085     showptrhdrpad
 2086     printf "msgid       "
 2087     printf "disp  size  "
 2088     printf "reply-port  "
 2089     showptrhdrpad
 2090     printf "source\n"
 2091 end
 2092 
 2093 define showkmsgsrcint
 2094     set $kgm_kmsgsrchp = ((ipc_kmsg_t)$arg0)->ikm_header
 2095 #    set $kgm_kmsgsrctp = (mach_msg_audit_trailer_t *)((uintptr_t)$kgm_kmsgsrchp + $kgm_kmsgsrchp->msgh_size)
 2096 #    set $kgm_kmsgpid = $kgm_kmsgsrctp->msgh_audit.val[5]
 2097     set $kgm_kmsgpid = (pid_t)((uint *)((uintptr_t)$kgm_kmsgsrchp + $kgm_kmsgsrchp->msgh_size))[10]
 2098 # compare against a well-known or cached value as this may be slow
 2099     if ($kgm_kmsgpid == 0)
 2100        set $kgm_kmsgsrcpid = (pid_t)0
 2101        set $kgm_kmsgsrcprocp = (struct proc *)kernel_task->bsd_info
 2102     else 
 2103        if ($kgm_kmsgpid != $kgm_kmsgsrcpid)
 2104           set $kgm_kmsgsrchead_taskp = &tasks
 2105           set $kgm_kmsgsrctaskp = (struct task *)($kgm_kmsgsrchead_taskp->next)
 2106           while $kgm_kmsgsrctaskp != $kgm_kmsgsrchead_taskp
 2107               set $kgm_kmsgsrcprocp = (struct proc *)$kgm_kmsgsrctaskp->bsd_info
 2108               set $kgm_kmsgsrcpid = $kgm_kmsgsrcprocp->p_pid
 2109               if (($kgm_kmsgsrcprocp != 0) && ($kgm_kmsgsrcprocp->p_pid == $kgm_kmsgpid))
 2110                   set $kgm_kmsgsrctaskp = $kgm_kmsgsrchead_taskp
 2111               else
 2112                   set $kgm_kmsgsrctaskp = (struct task *)($kgm_kmsgsrctaskp->tasks.next)
 2113               end
 2114           end
 2115        end
 2116     end
 2117     if ($kgm_kmsgsrcprocp->p_pid == $kgm_kmsgpid)
 2118         printf "%s(%d)\n", $kgm_kmsgsrcprocp->p_comm, $kgm_kmsgpid
 2119     else
 2120         printf "unknown(%d)\n", $kgm_kmsgpid
 2121     end
 2122 end
 2123 
 2124 define showkmsgint
 2125     set $kgm_kmsghp = ((ipc_kmsg_t)$arg0)->ikm_header
 2126     set $kgm_kmsgh = *$kgm_kmsghp
 2127     if ($arg1 != 0)
 2128         printf "            "
 2129         showptrhdrpad
 2130     else
 2131         showptr $kgm_kmsgh.msgh_remote_port
 2132     end
 2133     showptr $arg0
 2134     showptrhdrpad
 2135     printf "  0x%08x  ", $kgm_kmsgh.msgh_id
 2136     if (($kgm_kmsgh.msgh_bits & 0xff) == 19)
 2137         printf "rC"
 2138     else
 2139         printf "rM"
 2140     end
 2141     if (($kgm_kmsgh.msgh_bits & 0xff00) == (19 << 8))
 2142         printf "lC"
 2143     else
 2144         printf "lM"
 2145     end
 2146     if ($kgm_kmsgh.msgh_bits & 0xf0000000)
 2147         printf "c"
 2148     else
 2149         printf "s"
 2150     end
 2151     printf "%5d  ", $kgm_kmsgh.msgh_size
 2152     showptr $kgm_kmsgh.msgh_local_port
 2153     printf "  "
 2154     set $kgm_kmsgsrcpid = (pid_t)0
 2155     showkmsgsrcint $arg0
 2156 end
 2157 
 2158 define showkmsg
 2159     showkmsgint $arg0 0
 2160 end
 2161 
 2162 define showkobject
 2163     set $kgm_portp = (struct ipc_port *)$arg0
 2164     showptr $kgm_portp->ip_kobject
 2165     printf "  kobject("
 2166     set $kgm_kotype = ($kgm_portp->ip_object.io_bits & 0x00000fff)
 2167     if ($kgm_kotype == 1)
 2168         printf "THREAD"
 2169     end
 2170     if ($kgm_kotype == 2)
 2171         printf "TASK"
 2172     end
 2173     if ($kgm_kotype == 3)
 2174         printf "HOST"
 2175     end
 2176     if ($kgm_kotype == 4)
 2177         printf "HOST_PRIV"
 2178     end
 2179     if ($kgm_kotype == 5)
 2180         printf "PROCESSOR"
 2181     end
 2182     if ($kgm_kotype == 6)
 2183         printf "PSET"
 2184     end
 2185     if ($kgm_kotype == 7)
 2186         printf "PSET_NAME"
 2187     end
 2188     if ($kgm_kotype == 8)
 2189         printf "TIMER"
 2190     end
 2191     if ($kgm_kotype == 9)
 2192         printf "PAGER_REQ"
 2193     end
 2194     if ($kgm_kotype == 10)
 2195         printf "DEVICE"
 2196     end
 2197     if ($kgm_kotype == 11)
 2198         printf "XMM_OBJECT"
 2199     end
 2200     if ($kgm_kotype == 12)
 2201         printf "XMM_PAGER"
 2202     end
 2203     if ($kgm_kotype == 13)
 2204         printf "XMM_KERNEL"
 2205     end
 2206     if ($kgm_kotype == 14)
 2207         printf "XMM_REPLY"
 2208     end
 2209     if ($kgm_kotype == 15)
 2210         printf "NOTDEF 15"
 2211     end
 2212     if ($kgm_kotype == 16)
 2213         printf "NOTDEF 16"
 2214     end
 2215     if ($kgm_kotype == 17)
 2216         printf "HOST_SEC"
 2217     end
 2218     if ($kgm_kotype == 18)
 2219         printf "LEDGER"
 2220     end
 2221     if ($kgm_kotype == 19)
 2222         printf "MASTER_DEV"
 2223     end
 2224     if ($kgm_kotype == 20)
 2225         printf "ACTIVATION"
 2226     end
 2227     if ($kgm_kotype == 21)
 2228         printf "SUBSYSTEM"
 2229     end
 2230     if ($kgm_kotype == 22)
 2231         printf "IO_DONE_QUE"
 2232     end
 2233     if ($kgm_kotype == 23)
 2234         printf "SEMAPHORE"
 2235     end
 2236     if ($kgm_kotype == 24)
 2237         printf "LOCK_SET"
 2238     end
 2239     if ($kgm_kotype == 25)
 2240         printf "CLOCK"
 2241     end
 2242     if ($kgm_kotype == 26)
 2243         printf "CLOCK_CTRL"
 2244     end
 2245     if ($kgm_kotype == 27)
 2246         printf "IOKIT_SPARE"
 2247     end
 2248     if ($kgm_kotype == 28)
 2249         printf "NAMED_MEM"
 2250     end
 2251     if ($kgm_kotype == 29)
 2252         printf "IOKIT_CON"
 2253     end
 2254     if ($kgm_kotype == 30)
 2255         printf "IOKIT_OBJ"
 2256     end
 2257     if ($kgm_kotype == 31)
 2258         printf "UPL"
 2259     end
 2260     if ($kgm_kotype == 34)
 2261         printf "FD"
 2262     end
 2263     printf ")\n"
 2264 end
 2265 
 2266 define showportdestproc
 2267     set $kgm_portp = (struct ipc_port *)$arg0
 2268     set $kgm_spacep = $kgm_portp->data.receiver
 2269 #   check against the previous cached value - this is slow
 2270     if ($kgm_spacep != $kgm_destspacep)
 2271         set $kgm_destprocp = (struct proc *)0
 2272         set $kgm_head_taskp = &tasks
 2273         set $kgm_desttaskp = (struct task *)($kgm_head_taskp->next)
 2274         while (($kgm_destprocp == 0) && ($kgm_desttaskp != $kgm_head_taskp))
 2275             set $kgm_destspacep = $kgm_desttaskp->itk_space
 2276             if ($kgm_destspacep == $kgm_spacep)
 2277                set $kgm_destprocp = (struct proc *)$kgm_desttaskp->bsd_info
 2278             else
 2279                set $kgm_desttaskp = (struct task *)($kgm_desttaskp->tasks.next)
 2280             end
 2281         end
 2282     end
 2283     if $kgm_destprocp != 0
 2284        printf "%s(%d)\n", $kgm_destprocp->p_comm, $kgm_destprocp->p_pid
 2285     else
 2286        printf "task "
 2287        showptr $kgm_desttaskp
 2288        printf "\n"
 2289     end
 2290 end
 2291 
 2292 define showportdest
 2293     set $kgm_portp = (struct ipc_port *)$arg0
 2294     set $kgm_spacep = $kgm_portp->data.receiver
 2295     if ((uintptr_t)$kgm_spacep == (uintptr_t)ipc_space_kernel)
 2296         showkobject $kgm_portp
 2297     else
 2298         if ($kgm_portp->ip_object.io_bits & 0x80000000)
 2299             showptr $kgm_portp->ip_messages.data.port.receiver_name
 2300         printf "  "
 2301             showportdestproc $kgm_portp
 2302         else
 2303         showptr $kgm_portp
 2304             printf "  inactive-port\n"
 2305         end
 2306     end
 2307 end
 2308 
 2309 define showportmember
 2310     printf "            "
 2311     showptrhdrpad
 2312     showptr $arg0
 2313     showptrhdrpad
 2314     set $kgm_portp = (struct ipc_port *)$arg0
 2315     printf "  0x%08x  ", $kgm_portp->ip_messages.data.port.receiver_name
 2316     if ($kgm_portp->ip_object.io_bits & 0x80000000)
 2317         printf "A"
 2318     else
 2319         printf " "
 2320     end
 2321     printf "Port"
 2322     printf "%5d  ", $kgm_portp->ip_object.io_references
 2323     showptr &($kgm_portp->ip_messages)
 2324     printf "  0x%08x\n", $kgm_portp->ip_messages.data.port.msgcount
 2325 end
 2326 
 2327 define showportbt
 2328     set $kgm_iebt = ((ipc_port_t) $arg0)->ip_callstack
 2329     set $kgm_iepid = ((ipc_port_t) $arg0)->ip_spares[0]
 2330     set $kgm_procpid = ((proc_t) (((task_t) $arg1)->bsd_info))->p_pid
 2331     if $kgm_iebt[0] != 0
 2332         showptr $kgm_iebt[0]
 2333         set $kgm_iebt_loop_ctr = 1
 2334         while ($kgm_iebt_loop_ctr < 16 && $kgm_iebt[$kgm_iebt_loop_ctr])
 2335             printf " "
 2336             showptr $kgm_iebt[$kgm_iebt_loop_ctr]
 2337             set $kgm_iebt_loop_ctr = $kgm_iebt_loop_ctr + 1
 2338         end
 2339         if $kgm_iepid != $kgm_procpid
 2340             printf " (%d)", $kgm_iepid
 2341         end
 2342         printf "\n"
 2343     end
 2344 end
 2345 
 2346 define showportint
 2347     showptr $arg0
 2348     printf "  "
 2349     set $kgm_portp = (struct ipc_port *)$arg0
 2350     showptr &($kgm_portp->ip_messages)
 2351     showptrhdrpad
 2352     printf "  0x%08x  ", $kgm_portp->ip_messages.data.port.receiver_name
 2353     if ($kgm_portp->ip_object.io_bits & 0x80000000)
 2354         printf "A"
 2355     else
 2356         printf "D"
 2357     end
 2358     printf "Port"
 2359     printf "%5d  ", $kgm_portp->ip_object.io_references
 2360     set $kgm_destspacep = (struct ipc_space *)0
 2361     showportdest $kgm_portp
 2362     set $kgm_kmsgp = (ipc_kmsg_t)$kgm_portp->ip_messages.data.port.messages.ikmq_base
 2363     if $arg1 && $kgm_kmsgp
 2364         showkmsgheader
 2365         showkmsgint $kgm_kmsgp 1
 2366         set $kgm_kmsgheadp = $kgm_kmsgp
 2367         set $kgm_kmsgp = $kgm_kmsgp->ikm_next
 2368         while $kgm_kmsgp != $kgm_kmsgheadp
 2369             showkmsgint $kgm_kmsgp 1
 2370             set $kgm_kmsgp = $kgm_kmsgp->ikm_next
 2371         end
 2372     end
 2373 end
 2374 
 2375 define showpsetint
 2376     showptr $arg0
 2377     printf "  "
 2378     set $kgm_psetp = (struct ipc_pset *)$arg0
 2379     showptr &($kgm_psetp->ips_messages)
 2380     showptrhdrpad
 2381     printf "  0x%08x  ", $kgm_psetp->ips_messages.data.pset.local_name
 2382     if ($kgm_psetp->ips_object.io_bits & 0x80000000)
 2383         printf "A"
 2384     else
 2385         printf "D"
 2386     end
 2387     printf "Set "
 2388     printf "%5d  ", $kgm_psetp->ips_object.io_references
 2389     showptr $kgm_psetp->ips_messages.data.pset.local_name
 2390     printf "  "
 2391     set $kgm_setlinksp = &($kgm_psetp->ips_messages.data.pset.set_queue.wqs_setlinks)
 2392     set $kgm_wql = (WaitQueueLink *)$kgm_setlinksp->next
 2393     set $kgm_found = 0
 2394     while ( (queue_entry_t)$kgm_wql != (queue_entry_t)$kgm_setlinksp)
 2395         set $kgm_portp = (struct ipc_port *)((uintptr_t)($kgm_wql->wql_element->wqe_queue) - (uintptr_t)$kgm_portoff)
 2396         if !$kgm_found  
 2397             set $kgm_destspacep = (struct ipc_space *)0
 2398             showportdestproc $kgm_portp
 2399             showportmemberheader
 2400             set $kgm_found = 1
 2401         end
 2402         showportmember $kgm_portp 0
 2403         set $kgm_wql = (WaitQueueLink *)$kgm_wql->wql_setlinks.next
 2404     end
 2405     if !$kgm_found
 2406         printf "--n/e--\n"
 2407     end
 2408 end
 2409 
 2410 define showpset
 2411     set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
 2412     showpsetheader
 2413     showpsetint $arg0 1
 2414 end
 2415 
 2416 define showport
 2417     showportheader
 2418     showportint $arg0 1
 2419 end
 2420 
 2421 define showipcobject
 2422     set $kgm_objectp = (ipc_object_t)$arg0
 2423     if ($kgm_objectp->io_bits & 0x7fff0000)
 2424         set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
 2425         showpset $kgm_objectp
 2426     else
 2427         showport $kgm_objectp
 2428     end
 2429 end
 2430 
 2431 define showmqueue
 2432     set $kgm_mqueue = *(struct ipc_mqueue *)$arg0
 2433     if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d1)
 2434         set $kgm_psetoff = &(((struct ipc_pset *)0)->ips_messages)
 2435         set $kgm_pset = (((long)$arg0) - ((long)$kgm_psetoff))
 2436         showpsetheader
 2437         showpsetint $kgm_pset 1
 2438     end
 2439     if ($kgm_mqueue.data.pset.set_queue.wqs_wait_queue.wq_type == 0xf1d0)
 2440         set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
 2441         set $kgm_port = (((long)$arg0) - ((long)$kgm_portoff))
 2442         showportheader
 2443         showportint $kgm_port 1
 2444     end
 2445 end
 2446 
 2447 define zprint_one
 2448     set $kgm_zone = (struct zone *)$arg0
 2449 
 2450     showptr $kgm_zone
 2451     printf "  %8d ",$kgm_zone->count
 2452     printf "%8x ",$kgm_zone->cur_size
 2453     printf "%8x ",$kgm_zone->max_size
 2454     printf "%8d ",$kgm_zone->elem_size
 2455     printf "%8x ",$kgm_zone->alloc_size
 2456     if ($kgm_mtype != $kgm_mtype_arm) 
 2457         printf " %16ld ",$kgm_zone->num_allocs 
 2458         printf "%16ld ",$kgm_zone->num_frees
 2459     end
 2460     printf "%s ",$kgm_zone->zone_name
 2461 
 2462     if ($kgm_zone->exhaustible)
 2463         printf "H"
 2464     end
 2465     if ($kgm_zone->collectable)
 2466         printf "C"
 2467     end
 2468     if ($kgm_zone->expandable)
 2469         printf "X"
 2470     end
 2471     if ($kgm_zone->noencrypt)
 2472         printf "$"
 2473     end
 2474     printf "\n"
 2475 end
 2476 
 2477 
 2478 define zprint
 2479     printf "ZONE      "
 2480     showptrhdrpad
 2481     printf "     COUNT   TOT_SZ   MAX_SZ   ELT_SZ ALLOC_SZ         TOT_ALLOC         TOT_FREE NAME\n"
 2482     set $kgm_zone_ptr = (struct zone *)first_zone
 2483     while ($kgm_zone_ptr != 0)
 2484         zprint_one $kgm_zone_ptr
 2485         set $kgm_zone_ptr = $kgm_zone_ptr->next_zone
 2486     end
 2487     printf "\n"
 2488 end
 2489 document zprint
 2490 Syntax: (gdb) zprint
 2491 | Routine to print a summary listing of all the kernel zones
 2492 end
 2493 
 2494 define showmtxgrp
 2495     set $kgm_mtxgrp = (struct _lck_grp_ *)$arg0
 2496 
 2497     if ($kgm_mtxgrp->lck_grp_mtxcnt)
 2498         showptr $kgm_mtxgrp
 2499         printf " %8d ",$kgm_mtxgrp->lck_grp_mtxcnt
 2500         printf "%12u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_util_cnt
 2501         printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_miss_cnt
 2502         printf "%8u ",$kgm_mtxgrp->lck_grp_stat.lck_grp_mtx_stat.lck_grp_mtx_wait_cnt
 2503         printf "%s ",&$kgm_mtxgrp->lck_grp_name
 2504         printf "\n"
 2505     end
 2506 end
 2507 
 2508 
 2509 define showallmtx
 2510     printf "LCK GROUP "
 2511     showptrhdrpad
 2512     printf "      CNT         UTIL     MISS     WAIT NAME\n"
 2513     set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
 2514     set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
 2515     while ($kgm_mtxgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
 2516         showmtxgrp $kgm_mtxgrp_ptr
 2517         set $kgm_mtxgrp_ptr = (struct _lck_grp_ *)$kgm_mtxgrp_ptr->lck_grp_link.next
 2518     end
 2519     printf "\n"
 2520 end
 2521 document showallmtx
 2522 Syntax: (gdb) showallmtx
 2523 | Routine to print a summary listing of all mutexes
 2524 end
 2525 
 2526 define showrwlckgrp
 2527     set $kgm_rwlckgrp = (struct _lck_grp_ *)$arg0
 2528 
 2529     if ($kgm_rwlckgrp->lck_grp_rwcnt)
 2530         showptr $kgm_rwlckgrp
 2531         printf " %8d ",$kgm_rwlckgrp->lck_grp_rwcnt
 2532         printf "%12u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_util_cnt
 2533         printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_miss_cnt
 2534         printf "%8u ",$kgm_rwlckgrp->lck_grp_stat.lck_grp_rw_stat.lck_grp_rw_wait_cnt
 2535         printf "%s ",&$kgm_rwlckgrp->lck_grp_name
 2536         printf "\n"
 2537     end
 2538 end
 2539 
 2540 
 2541 define showallrwlck
 2542     printf "LCK GROUP "
 2543     showptrhdrpad
 2544     printf "      CNT         UTIL     MISS     WAIT NAME\n"
 2545     set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)&lck_grp_queue
 2546     set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
 2547     while ($kgm_rwlckgrp_ptr != (struct _lck_grp_ *)&lck_grp_queue)
 2548         showrwlckgrp $kgm_rwlckgrp_ptr
 2549         set $kgm_rwlckgrp_ptr = (struct _lck_grp_ *)$kgm_rwlckgrp_ptr->lck_grp_link.next
 2550     end
 2551     printf "\n"
 2552 end
 2553 document showallrwlck
 2554 Syntax: (gdb) showallrwlck
 2555 | Routine to print a summary listing of all read/writer locks
 2556 end
 2557 
 2558 set $kdp_act_counter = 0
 2559 set $kdp_arm_act_counter = 0
 2560 
 2561 set $r0_save    = 0
 2562 set $r1_save    = 0
 2563 set $r2_save    = 0
 2564 set $r3_save    = 0
 2565 set $r4_save    = 0
 2566 set $r5_save    = 0
 2567 set $r6_save    = 0
 2568 set $r7_save    = 0
 2569 set $r8_save    = 0
 2570 set $r9_save    = 0
 2571 set $r10_save   = 0
 2572 set $r11_save   = 0
 2573 set $r12_save   = 0
 2574 set $sp_save    = 0
 2575 set $lr_save    = 0
 2576 set $pc_save    = 0
 2577 
 2578 define showcontext_int
 2579         echo Context switched, current instruction pointer: 
 2580         output/a $pc
 2581         echo \n
 2582 end
 2583 
 2584 define switchtoact
 2585         set $newact = (struct thread *) $arg0
 2586         select 0
 2587         if ($newact->kernel_stack == 0)
 2588                 echo This activation does not have a stack.\n
 2589                 echo continuation:
 2590                 output/a (unsigned) $newact.continuation
 2591                 echo \n
 2592         else
 2593                 if ($kgm_mtype == $kgm_mtype_ppc)
 2594                         if ($kdp_act_counter == 0)
 2595                                 set $kdpstate = (struct savearea *) kdp.saved_state
 2596                         end
 2597                         set $kdp_act_counter = $kdp_act_counter + 1
 2598                         set (struct savearea *) kdp.saved_state=$newact->machine->pcb
 2599                         flushregs
 2600                         flushstack
 2601                         set $pc=$newact->machine->pcb.save_srr0
 2602                         update
 2603                 end
 2604                 if ($kgm_mtype == $kgm_mtype_i386)
 2605                         set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
 2606                         if ($kdp_act_counter == 0)
 2607                            set $kdpstate = *($kdpstatep)
 2608                         end     
 2609                         set $kdp_act_counter = $kdp_act_counter + 1
 2610         
 2611                         set $kgm_statep = (struct x86_kernel_state *) \
 2612                                                 ($newact->kernel_stack + kernel_stack_size \
 2613                                                  - sizeof(struct x86_kernel_state))
 2614                         set $kdpstatep->ebx = $kgm_statep->k_ebx 
 2615                         set $kdpstatep->ebp = $kgm_statep->k_ebp 
 2616                         set $kdpstatep->edi = $kgm_statep->k_edi 
 2617                         set $kdpstatep->esi = $kgm_statep->k_esi 
 2618                         set $kdpstatep->eip = $kgm_statep->k_eip 
 2619                         flushregs
 2620                         flushstack
 2621                         set $pc = $kgm_statep->k_eip
 2622                         update
 2623                 end
 2624                 if ($kgm_mtype == $kgm_mtype_x86_64)
 2625                         set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
 2626                         if ($kdp_act_counter == 0)
 2627                            set $kdpstate = *($kdpstatep)
 2628                         end     
 2629                         set $kdp_act_counter = $kdp_act_counter + 1
 2630         
 2631                         set $kgm_statep = (struct x86_kernel_state *) \
 2632                                                 ($newact->kernel_stack + kernel_stack_size \
 2633                                                  - sizeof(struct x86_kernel_state))
 2634                         set $kdpstatep->rbx = $kgm_statep->k_rbx 
 2635                         set $kdpstatep->rbp = $kgm_statep->k_rbp 
 2636                         set $kdpstatep->r12 = $kgm_statep->k_r12 
 2637                         set $kdpstatep->r13 = $kgm_statep->k_r13 
 2638                         set $kdpstatep->r14 = $kgm_statep->k_r14 
 2639                         set $kdpstatep->r15 = $kgm_statep->k_r15 
 2640                         set $kdpstatep->isf.rsp = $kgm_statep->k_rsp 
 2641                         flushregs
 2642                         flushstack
 2643                         set $pc = $kgm_statep->k_rip
 2644                         update
 2645                 end
 2646                 if ($kgm_mtype == $kgm_mtype_arm)
 2647                         set $kdp_arm_act_counter = $kdp_arm_act_counter + 1
 2648                         if ($kdp_arm_act_counter == 1)
 2649                                 set $r0_save   = $r0
 2650                                 set $r1_save   = $r1
 2651                                 set $r2_save   = $r2
 2652                                 set $r3_save   = $r3
 2653                                 set $r4_save   = $r4
 2654                                 set $r5_save   = $r5
 2655                                 set $r6_save   = $r6
 2656                                 set $r7_save   = $r7
 2657                                 set $r8_save   = $r8
 2658                                 set $r9_save   = $r9
 2659                                 set $r10_save  = $r10
 2660                                 set $r11_save  = $r11
 2661                                 set $r12_save  = $r12
 2662                                 set $sp_save   = $sp
 2663                                 set $lr_save   = $lr
 2664                                 set $pc_save   = $pc
 2665                         end
 2666                         set $pc_ctx = load_reg+8
 2667                         set $kgm_statep = (struct arm_saved_state *)((struct thread*)$arg0)->machine.kstackptr
 2668                         set $r0 =  $kgm_statep->r[0]
 2669                         set $r1 =  $kgm_statep->r[1]
 2670                         set $r2 =  $kgm_statep->r[2]
 2671                         set $r3 =  $kgm_statep->r[3]
 2672                         set $r4 =  $kgm_statep->r[4]
 2673                         set $r5 =  $kgm_statep->r[5]
 2674                         set $r6 =  $kgm_statep->r[6]
 2675                         set $r8 =  $kgm_statep->r[8]
 2676                         set $r9 =  $kgm_statep->r[9]
 2677                         set $r10 = $kgm_statep->r[10]
 2678                         set $r11 = $kgm_statep->r[11]
 2679                         set $r12 = $kgm_statep->r[12]
 2680                         set $sp = $kgm_statep->sp
 2681                         set $lr = $kgm_statep->lr
 2682                         set $pc = $pc_ctx
 2683                         set $r7 =  $kgm_statep->r[7]
 2684                         flushregs
 2685                         flushstack
 2686                 end
 2687         end
 2688         showcontext_int
 2689 end
 2690 
 2691 document switchtoact  
 2692 Syntax: switchtoact <address of activation>
 2693 | This command allows gdb to examine the execution context and call
 2694 | stack for the specified activation. For example, to view the backtrace
 2695 | for an activation issue "switchtoact <address>", followed by "bt".
 2696 | Before resuming execution, issue a "resetctx" command, to
 2697 | return to the original execution context.
 2698 end     
 2699 
 2700 define switchtoctx
 2701         select 0
 2702         if ($kgm_mtype == $kgm_mtype_ppc)
 2703                 if ($kdp_act_counter == 0)
 2704                    set $kdpstate = (struct savearea *) kdp.saved_state
 2705                 end
 2706                 set $kdp_act_counter = $kdp_act_counter + 1
 2707                 set (struct savearea *) kdp.saved_state=(struct savearea *) $arg0
 2708                 flushregs
 2709                 flushstack
 2710                 set $pc=((struct savearea *) $arg0)->save_srr0
 2711                 update
 2712         else
 2713                 if ($kgm_mtype == $kgm_mtype_arm)
 2714                         select 0
 2715                         set $kdp_arm_act_counter = $kdp_arm_act_counter + 1
 2716                         if ($kdp_arm_act_counter == 1)
 2717                                 set $r0_save   = $r0
 2718                                 set $r1_save   = $r1
 2719                                 set $r2_save   = $r2
 2720                                 set $r3_save   = $r3
 2721                                 set $r4_save   = $r4
 2722                                 set $r5_save   = $r5
 2723                                 set $r6_save   = $r6
 2724                                 set $r7_save   = $r7
 2725                                 set $r8_save   = $r8
 2726                                 set $r9_save   = $r9
 2727                                 set $r10_save  = $r10
 2728                                 set $r11_save  = $r11
 2729                                 set $r12_save  = $r12
 2730                                 set $sp_save   = $sp
 2731                                 set $lr_save   = $lr
 2732                                 set $pc_save   = $pc
 2733                         end
 2734                         set $kgm_statep = (struct arm_saved_state *)$arg0
 2735                         set $r0 =  $kgm_statep->r[0]
 2736                         set $r1 =  $kgm_statep->r[1]
 2737                         set $r2 =  $kgm_statep->r[2]
 2738                         set $r3 =  $kgm_statep->r[3]
 2739                         set $r4 =  $kgm_statep->r[4]
 2740                         set $r5 =  $kgm_statep->r[5]
 2741                         set $r6 =  $kgm_statep->r[6]
 2742                         set $r8 =  $kgm_statep->r[8]
 2743                         set $r9 =  $kgm_statep->r[9]
 2744                         set $r10 = $kgm_statep->r[10]
 2745                         set $r11 = $kgm_statep->r[11]
 2746                         set $r12 = $kgm_statep->r[12]
 2747                         set $sp = $kgm_statep->sp
 2748                         set $lr = $kgm_statep->lr
 2749                         set $r7 =  $kgm_statep->r[7]
 2750                         set $pc = $kgm_statep->pc
 2751                         flushregs
 2752                         flushstack
 2753                         update
 2754                 else
 2755                         echo switchtoctx not implemented for this architecture.\n
 2756                 end
 2757         end
 2758 end
 2759 
 2760 
 2761 document switchtoctx  
 2762 Syntax: switchtoctx <address of pcb>
 2763 | This command allows gdb to examine an execution context and dump the
 2764 | backtrace for this execution context.
 2765 | Before resuming execution, issue a "resetctx" command, to
 2766 | return to the original execution context.
 2767 end     
 2768 
 2769 define resetctx
 2770         select 0
 2771         if ($kdp_act_counter != 0)
 2772                 if ($kgm_mtype == $kgm_mtype_ppc)
 2773                         set (struct savearea *)kdp.saved_state=$kdpstate
 2774                         flushregs
 2775                         flushstack
 2776                         set $pc=((struct savearea *) kdp.saved_state)->save_srr0
 2777                         update
 2778                         set $kdp_act_counter = 0
 2779                 end
 2780                 if ($kgm_mtype == $kgm_mtype_i386)
 2781                         set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
 2782                         set *($kdpstatep)=$kdpstate
 2783                         flushregs
 2784                         flushstack
 2785                         set $pc=$kdpstatep->eip
 2786                         update
 2787                         set $kdp_act_counter = 0
 2788                 end
 2789                 if ($kgm_mtype == $kgm_mtype_x86_64)
 2790                         set $kdpstatep = (struct x86_saved_state64 *) kdp.saved_state
 2791                         set *($kdpstatep)=$kdpstate
 2792                         flushregs
 2793                         flushstack
 2794                         set $pc=$kdpstatep->isf.rip
 2795                         update
 2796                         set $kdp_act_counter = 0
 2797                 end
 2798                 showcontext_int
 2799         end
 2800         if ($kgm_mtype == $kgm_mtype_arm && $kdp_arm_act_counter != 0)
 2801                 echo Restoring context\n
 2802                 set $r0  = $r0_save
 2803                 flushregs
 2804                 set $r1  = $r1_save
 2805                 flushregs
 2806                 set $r2  = $r2_save
 2807                 flushregs
 2808                 set $r3  = $r3_save
 2809                 flushregs
 2810                 set $r4  = $r4_save
 2811                 flushregs
 2812                 set $r5  = $r5_save
 2813                 flushregs
 2814                 set $r6  = $r6_save
 2815                 flushregs
 2816                 set $r8  = $r8_save
 2817                 flushregs
 2818                 set $r9  = $r9_save
 2819                 flushregs
 2820                 set $r10 = $r10_save
 2821                 flushregs
 2822                 set $r11 = $r11_save
 2823                 flushregs
 2824                 set $r12 = $r12_save
 2825                 flushregs
 2826                 set $sp  = $sp_save
 2827                 flushregs
 2828                 set $lr  = $lr_save
 2829                 flushregs
 2830                 set $pc  = $pc_save
 2831                 flushregs
 2832                 set $r7  = $r7_save
 2833                 flushregs
 2834                 flushstack
 2835                 update
 2836                 set $kdp_arm_act_counter = 0
 2837         end
 2838 end     
 2839         
 2840 document resetctx
 2841 | Syntax: resetctx
 2842 | Returns to the original execution context. This command should be
 2843 | issued if you wish to resume execution after using the "switchtoact"
 2844 | or "switchtoctx" commands.
 2845 end     
 2846 
 2847 # This is a pre-hook for the continue command, to prevent inadvertent attempts 
 2848 # to resume from the context switched to for examination.
 2849 define hook-continue
 2850        resetctx
 2851 end
 2852 
 2853 # This is a pre-hook for the detach command, to prevent inadvertent attempts 
 2854 # to resume from the context switched to for examination.
 2855 define hook-detach
 2856        resetctx
 2857 end
 2858 
 2859 define resume_on
 2860         set $resume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_RESUME
 2861         dumpinfoint $resume
 2862 end
 2863 
 2864 document resume_on
 2865 | Syntax: resume_on
 2866 | The target system will resume when detaching  or exiting from gdb. 
 2867 | This is the default behavior.
 2868 end
 2869 
 2870 define resume_off
 2871         set $noresume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_NORESUME
 2872         dumpinfoint $noresume
 2873 end
 2874 
 2875 document resume_off
 2876 | Syntax: resume_off
 2877 | The target system  won't resume after detaching from gdb and
 2878 | can be attached with a new gdb session
 2879 end
 2880 
 2881 define paniclog
 2882         set $kgm_panic_bufptr = debug_buf
 2883         set $kgm_panic_bufptr_max = debug_buf_ptr
 2884         while $kgm_panic_bufptr < $kgm_panic_bufptr_max
 2885                 if *(char *)$kgm_panic_bufptr == 10
 2886                         printf "\n"
 2887                 else
 2888                         printf "%c", *(char *)$kgm_panic_bufptr
 2889                 end
 2890                 set $kgm_panic_bufptr= (char *)$kgm_panic_bufptr + 1
 2891         end
 2892 end
 2893 
 2894 document paniclog
 2895 | Syntax: paniclog
 2896 | Display the panic log information
 2897 |
 2898 end
 2899 
 2900 define dumpcallqueue
 2901         set $kgm_callhead = $arg0
 2902         set $kgm_callentry = $kgm_callhead->next
 2903         set $kgm_i = 0
 2904         while $kgm_callentry != $kgm_callhead
 2905                 set $kgm_call = (struct call_entry *)$kgm_callentry
 2906                 showptr $kgm_call
 2907                 printf "0x%lx 0x%lx ", $kgm_call->param0, $kgm_call->param1
 2908                 output $kgm_call->deadline
 2909                 printf "\t"
 2910                 output $kgm_call->func
 2911                 printf "\n"
 2912                 set $kgm_i = $kgm_i + 1
 2913                 set $kgm_callentry = $kgm_callentry->next
 2914         end
 2915         printf "%d entries\n", $kgm_i
 2916 end
 2917 
 2918 document dumpcallqueue
 2919 | Syntax: dumpcallqueue <queue head>
 2920 | Displays the contents of the specified call_entry queue.
 2921 end
 2922 
 2923 define showtaskacts
 2924 showtaskthreads $arg0
 2925 end
 2926 document showtaskacts
 2927 | See help showtaskthreads.
 2928 end
 2929 
 2930 define showallacts
 2931 showallthreads
 2932 end
 2933 document showallacts
 2934 | See help showallthreads.
 2935 end
 2936 
 2937 
 2938 define resetstacks
 2939        _kgm_flush_loop
 2940        set kdp_pmap = 0
 2941        _kgm_flush_loop
 2942        resetctx
 2943        _kgm_flush_loop
 2944        _kgm_update_loop
 2945        resetctx
 2946        _kgm_update_loop
 2947 end
 2948 
 2949 document resetstacks
 2950 | Syntax: resetstacks
 2951 | Internal kgmacro routine used by the "showuserstack" macro 
 2952 | to reset the target pmap to the kernel pmap.
 2953 end
 2954 
 2955 #Barely effective hacks to work around bugs in the "flush" and "update" 
 2956 #gdb commands in Tiger (up to 219); these aren't necessary with Panther
 2957 #gdb, but do no harm.
 2958 define _kgm_flush_loop
 2959        set $kgm_flush_loop_ctr = 0
 2960        while ($kgm_flush_loop_ctr < 30)
 2961              flushregs
 2962              flushstack
 2963              set $kgm_flush_loop_ctr = $kgm_flush_loop_ctr + 1
 2964        end
 2965 end
 2966 
 2967 define _kgm_update_loop
 2968        set $kgm_update_loop_ctr = 0
 2969        while ($kgm_update_loop_ctr < 30)
 2970              update
 2971              set $kgm_update_loop_ctr = $kgm_update_loop_ctr + 1
 2972        end
 2973 end
 2974 # Internal routine used by "_loadfrom" to read from 64-bit addresses
 2975 # on 32-bit kernels
 2976 define _loadk32m64
 2977        # set up the manual KDP packet
 2978        set manual_pkt.input = 0
 2979        set manual_pkt.len = sizeof(kdp_readmem64_req_t)
 2980        set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
 2981        set $kgm_pkt->hdr.request = KDP_READMEM64
 2982        set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
 2983        set $kgm_pkt->hdr.is_reply = 0
 2984        set $kgm_pkt->hdr.seq = 0
 2985        set $kgm_pkt->hdr.key = 0
 2986        set $kgm_pkt->address = (uint64_t)$arg0
 2987        set $kgm_pkt->nbytes = sizeof(uint64_t)
 2988        set manual_pkt.input = 1
 2989        # dummy to make sure manual packet is executed
 2990        set $kgm_dummy = &_mh_execute_header
 2991        set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
 2992        if ($kgm_pkt->error == 0)
 2993                 set $kgm_k32read64 = *(uint64_t *)$kgm_pkt->data
 2994        else
 2995                 set $kgm_k32read64 = 0
 2996        end
 2997 end
 2998 
 2999 # Internal routine used by "showx86backtrace" to abstract possible loads from
 3000 # user space
 3001 define _loadfrom
 3002         if (kdp_pmap == 0)
 3003                 set $kgm_loadval = *(uintptr_t *)$arg0
 3004         else
 3005         if ($kgm_x86_abi == 0xe)
 3006               set $kgm_loadval = *(uint32_t *)$arg0
 3007         else
 3008         if ($kgm_x86_abi == 0xf)
 3009             if ($kgm_mtype == $kgm_mtype_i386)
 3010                     _loadk32m64 $arg0
 3011                     set $kgm_loadval = $kgm_k32read64
 3012             else
 3013                     set $kgm_loadval = *(uint64_t *)$arg0
 3014             end
 3015         end
 3016         end
 3017 end
 3018 end
 3019 
 3020 
 3021 #This is necessary since gdb often doesn't do backtraces on x86 correctly
 3022 #in the absence of symbols.The code below in showuserstack and 
 3023 #showx86backtrace also contains several workarouds for the gdb bug where 
 3024 #gdb stops macro evaluation because of spurious "Cannot read memory"
 3025 #errors on x86. These errors appear on ppc as well, but they don't
 3026 #always stop macro evaluation.
 3027 
 3028 set $kgm_cur_frame = 0
 3029 set $kgm_cur_pc = 0
 3030 set $kgm_x86_abi = 0
 3031 define showx86backtrace
 3032         if ($kgm_mtype == $kgm_mtype_i386)
 3033                 set $kgm_frame_reg = $ebp
 3034                 set $kgm_pc = $eip
 3035                 set $kgm_ret_off = 4
 3036         end
 3037         if ($kgm_mtype == $kgm_mtype_x86_64)
 3038                 set $kgm_frame_reg = $rbp
 3039                 set $kgm_pc = $rip
 3040                 set $kgm_ret_off = 8
 3041         end
 3042 
 3043         if ($kgm_x86_abi == 0xe)
 3044                 set $kgm_ret_off = 4
 3045         end
 3046         if ($kgm_x86_abi == 0xf)
 3047                 set $kgm_ret_off = 8
 3048         end
 3049 
 3050         if ($kgm_cur_frame == 0)
 3051                 set $kgm_cur_frame = $kgm_frame_reg
 3052         end
 3053         if ($kgm_cur_pc == 0)
 3054                 set $kgm_cur_pc = $kgm_pc
 3055         end
 3056         printf "0: Frame: 0x%016llx PC: 0x%016llx\n", $kgm_cur_frame, $kgm_cur_pc
 3057         if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
 3058                 x/i $kgm_cur_pc
 3059         end
 3060         set $kgm_tmp_frame = $kgm_cur_frame
 3061         set $kgm_cur_frame = 0
 3062         set $kgm_cur_pc = 0
 3063         _loadfrom ($kgm_tmp_frame)
 3064         set $kgm_prev_frame = $kgm_loadval
 3065         _loadfrom ($kgm_tmp_frame+$kgm_ret_off)
 3066         set $kgm_prev_pc = $kgm_loadval
 3067         set $kgm_frameno = 1
 3068         while ($kgm_prev_frame != 0) && ($kgm_prev_frame != 0x0000000800000008)
 3069                 printf "%d: Saved frame: 0x%016llx Saved PC: 0x%016llx\n", $kgm_frameno, $kgm_prev_frame, $kgm_prev_pc
 3070                 if (!(($kgm_x86_abi == 0xf) && ($kgm_mtype == $kgm_mtype_i386)))
 3071                    x/i $kgm_prev_pc
 3072                 end
 3073                 _loadfrom ($kgm_prev_frame+$kgm_ret_off)
 3074                 set $kgm_prev_pc = $kgm_loadval
 3075                 _loadfrom ($kgm_prev_frame)
 3076                 set $kgm_prev_frame = $kgm_loadval
 3077                 set $kgm_frameno = $kgm_frameno + 1
 3078         end
 3079         set kdp_pmap = 0
 3080         set $kgm_x86_abi = 0
 3081 end
 3082 
 3083 define showx86backtrace2
 3084         set $kgm_cur_frame = $arg0
 3085         set $kgm_cur_pc = $arg1
 3086         showx86backtrace
 3087 end
 3088 
 3089 define showuserstack
 3090                 select 0
 3091                 if ($kgm_mtype == $kgm_mtype_ppc)       
 3092                    if ($kdp_act_counter == 0)
 3093                       set $kdpstate = (struct savearea *) kdp.saved_state
 3094                    end
 3095                    set $kdp_act_counter = $kdp_act_counter + 1
 3096                    set $newact = (struct thread *) $arg0
 3097                    _kgm_flush_loop
 3098                    set $checkpc = $newact->machine->upcb.save_srr0
 3099                    if ($checkpc == 0)
 3100                       echo This activation does not appear to have
 3101                       echo \20 a valid user context.\n
 3102                    else       
 3103                      set (struct savearea *) kdp.saved_state=$newact->machine->upcb
 3104                      set $pc = $checkpc
 3105 #flush and update seem to be executed lazily by gdb on Tiger, hence the
 3106 #repeated invocations - see 3743135
 3107                     _kgm_flush_loop
 3108 # This works because the new pmap is used only for reads
 3109                      set kdp_pmap = $newact->task->map->pmap
 3110                      _kgm_flush_loop
 3111                      _kgm_update_loop
 3112                      bt
 3113                      resetstacks
 3114                      _kgm_flush_loop
 3115                      _kgm_update_loop
 3116                      resetstacks
 3117                      _kgm_flush_loop
 3118                      _kgm_update_loop
 3119                    end
 3120                 else
 3121                 if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
 3122                         set $newact = (struct thread *) $arg0
 3123                         set $newiss = (x86_saved_state_t *) ($newact->machine->iss)
 3124                         set $kgm_x86_abi = $newiss.flavor
 3125                         if ($newiss.flavor == 0xf) 
 3126                                 set $checkpc = $newiss.uss.ss_64.isf.rip
 3127                                 set $checkframe = $newiss.uss.ss_64.rbp
 3128 
 3129                         else
 3130                                 set $checkpc = $newiss.uss.ss_32.eip
 3131                                 set $checkframe = $newiss.uss.ss_32.ebp
 3132                         end
 3133 
 3134                         if ($checkpc == 0)
 3135                             echo This activation does not appear to have
 3136                             echo \20 a valid user context.\n
 3137                         else
 3138                         set $kgm_cur_frame = $checkframe
 3139                         set $kgm_cur_pc = $checkpc
 3140 # When have more than one argument is present, don't print usage
 3141                         if ( $argc == 1 )
 3142                                 printf "You may now issue the showx86backtrace command to see the user space backtrace for this thread ("
 3143                                 showptr $arg0
 3144                                 printf "); you can also examine memory locations in this address space (pmap "
 3145                                 showptr $newact->task->map->pmap
 3146                                 printf ") before issuing the backtrace. This two-step process is necessary to work around various bugs in x86 gdb, which cause it to stop memory evaluation on spurious memory read errors. Additionally, you may need to issue a set kdp_pmap = 0 command after the showx86backtrace completes, to resume reading from the kernel address space.\n"
 3147                         end
 3148                         set kdp_pmap = $newact->task->map->pmap
 3149                         _kgm_flush_loop
 3150                         _kgm_update_loop
 3151                         end                     
 3152                 else
 3153                 if ($kgm_mtype == $kgm_mtype_arm)
 3154                         if (kdp->is_conn > 0)
 3155                                 set $kgm_threadp = (struct thread *)$arg0
 3156                                 set $kgm_saved_pmap = kdp_pmap
 3157                                 showactheader
 3158                                 showactint $kgm_threadp 0
 3159                                 set $kgm_thread_pmap = $kgm_threadp->task->map->pmap
 3160                                 set $kgm_thread_sp = $kgm_threadp.machine->PcbData.r[7]
 3161                                 showptrhdrpad
 3162                                 printf "                  "
 3163                                 showptr 0
 3164                                 printf "  "
 3165                                 showptr $kgm_threadp.machine->PcbData.pc
 3166                                 printf "\n"
 3167                                 set kdp_pmap = $kgm_thread_pmap
 3168                                 while ($kgm_thread_sp != 0)
 3169                                 set $link_register = *($kgm_thread_sp + 4)
 3170                                 showptrhdrpad
 3171                                         printf "                  "
 3172                                         showptr $kgm_thread_sp
 3173                                         printf "  "
 3174                                 showptr $link_register
 3175                                 printf "\n"
 3176                                 set $kgm_thread_sp = *$kgm_thread_sp
 3177                                 end
 3178                                 set kdp_pmap = $kgm_saved_pmap
 3179                         else
 3180                                 set $kgm_threadp = (struct thread *)$arg0
 3181                                 showactheader
 3182                                 showactint $kgm_threadp 0
 3183                                 set $kgm_thread_sp = $kgm_threadp.machine->PcbData.r[7]
 3184                                 while ($kgm_thread_sp != 0)
 3185                                 _map_user_data_from_task $kgm_threadp->task $kgm_thread_sp 8
 3186                                 set $kgm_thread_sp_window = (int *)$kgm_map_user_window
 3187                                 set $link_register = *($kgm_thread_sp_window + 1)
 3188                                 showptrhdrpad
 3189                                         printf "                  "
 3190                                         showptr $kgm_thread_sp
 3191                                         printf "  "
 3192                                 showptr $link_register
 3193                                 printf "\n"
 3194                                 set $kgm_thread_sp = *$kgm_thread_sp_window
 3195                                 _unmap_user_data_from_task
 3196                                 end
 3197                         end
 3198                 else
 3199                         echo showuserstack not supported on this architecture\n
 3200                 end
 3201                 end
 3202                 end
 3203 end
 3204 document showuserstack
 3205 Syntax: showuserstack <address of thread activation>
 3206 |This command displays a numeric backtrace for the user space stack of
 3207 |the given thread activation. It may, of course, fail to display a
 3208 |complete backtrace if portions of the user stack are not mapped in.
 3209 |Symbolic backtraces can be obtained either by running gdb on the
 3210 |user space binary, or a tool such as "symbolicate".
 3211 |Note that while this command works on Panther's gdb, an issue
 3212 |with Tiger gdb (3743135) appears to hamper the evaluation of this
 3213 |macro in some cases.
 3214 end
 3215 
 3216 define showtaskuserstacks
 3217     set $kgm_taskp = (struct task *)$arg0
 3218     set $kgm_head_actp = &($kgm_taskp->threads)
 3219     set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 3220     while $kgm_actp != $kgm_head_actp
 3221         printf "For thread "
 3222         showptr $kgm_actp
 3223         printf "\n"
 3224         showuserstack $kgm_actp quiet
 3225         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
 3226                 showx86backtrace
 3227         end
 3228         set kdp_pmap=0
 3229         set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 3230         printf "\n"
 3231     end
 3232     showuserlibraries $kgm_taskp
 3233 end
 3234 document showtaskuserstacks
 3235 Syntax: (gdb) showtaskuserstacks <task>
 3236 | Print out the user stack for each thread in a task, followed by the user libraries.
 3237 end
 3238 
 3239 
 3240 define showuserregisters
 3241         set $kgm_threadp = (struct thread *)$arg0
 3242         set $kgm_taskp = $kgm_threadp->task
 3243         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
 3244                 set $newiss = (x86_saved_state_t *) ($kgm_threadp->machine.iss)
 3245                 set $kgm_x86_abi = $newiss.flavor
 3246                 if ($newiss.flavor == 0xf)
 3247                         printf "X86 Thread State (64-bit):\n"
 3248                         set $kgm_ss64 = $newiss.uss.ss_64
 3249 
 3250                         printf "  rax: "
 3251                         showuserptr $kgm_ss64.rax
 3252                         printf "  rbx: "
 3253                         showuserptr $kgm_ss64.rbx
 3254                         printf "  rcx: "
 3255                         showuserptr $kgm_ss64.rcx
 3256                         printf "  rdx: "
 3257                         showuserptr $kgm_ss64.rdx
 3258                         printf "\n"
 3259 
 3260                         printf "  rdi: "
 3261                         showuserptr $kgm_ss64.rdi
 3262                         printf "  rsi: "
 3263                         showuserptr $kgm_ss64.rsi
 3264                         printf "  rbp: "
 3265                         showuserptr $kgm_ss64.rbp
 3266                         printf "  rsp: "
 3267                         showuserptr $kgm_ss64.isf.rsp
 3268                         printf "\n"
 3269 
 3270                         printf "   r8: "
 3271                         showuserptr $kgm_ss64.r8
 3272                         printf "   r9: "
 3273                         showuserptr $kgm_ss64.r9
 3274                         printf "  r10: "
 3275                         showuserptr $kgm_ss64.r10
 3276                         printf "  r11: "
 3277                         showuserptr $kgm_ss64.r11
 3278                         printf "\n"
 3279 
 3280                         printf "  r12: "
 3281                         showuserptr $kgm_ss64.r12
 3282                         printf "  r13: "
 3283                         showuserptr $kgm_ss64.r13
 3284                         printf "  r14: "
 3285                         showuserptr $kgm_ss64.r14
 3286                         printf "  r15: "
 3287                         showuserptr $kgm_ss64.r15
 3288                         printf "\n"
 3289 
 3290                         printf "  rip: "
 3291                         showuserptr $kgm_ss64.isf.rip
 3292                         printf "  rfl: "
 3293                         showuserptr $kgm_ss64.isf.rflags
 3294                         printf "  cr2: "
 3295                         showuserptr $kgm_ss64.cr2
 3296                         printf "\n"
 3297                 else
 3298                         printf "X86 Thread State (32-bit):\n"
 3299                         set $kgm_ss32 = $newiss.uss.ss_32
 3300 
 3301                         printf "  eax: "
 3302                         showuserptr $kgm_ss32.eax
 3303                         printf "  ebx: "
 3304                         showuserptr $kgm_ss32.ebx
 3305                         printf "  ecx: "
 3306                         showuserptr $kgm_ss32.ecx
 3307                         printf "  edx: "
 3308                         showuserptr $kgm_ss32.edx
 3309                         printf "\n"
 3310 
 3311                         printf "  edi: "
 3312                         showuserptr $kgm_ss32.edi
 3313                         printf "  esi: "
 3314                         showuserptr $kgm_ss32.esi
 3315                         printf "  ebp: "
 3316                         showuserptr $kgm_ss32.ebp
 3317                         printf "  esp: "
 3318                         showuserptr $kgm_ss32.uesp
 3319                         printf "\n"
 3320 
 3321                         printf "   ss: "
 3322                         showuserptr $kgm_ss32.ss
 3323                         printf "  efl: "
 3324                         showuserptr $kgm_ss32.efl
 3325                         printf "  eip: "
 3326                         showuserptr $kgm_ss32.eip
 3327                         printf "   cs: "
 3328                         showuserptr $kgm_ss32.cs
 3329                         printf "\n"
 3330 
 3331                         printf "   ds: "
 3332                         showuserptr $kgm_ss32.ds
 3333                         printf "   es: "
 3334                         showuserptr $kgm_ss32.es
 3335                         printf "   fs: "
 3336                         showuserptr $kgm_ss32.fs
 3337                         printf "   gs: "
 3338                         showuserptr $kgm_ss32.gs
 3339                         printf "\n"
 3340 
 3341                         printf "  cr2: "
 3342                         showuserptr $kgm_ss32.cr2
 3343                         printf "\n"
 3344                 end
 3345         else
 3346         if ($kgm_mtype == $kgm_mtype_arm)
 3347                 printf "ARM Thread State:\n"
 3348                 set $kgm_pcb = (arm_saved_state_t *) (&$kgm_threadp->machine.PcbData)
 3349 
 3350                 printf "    r0: "
 3351                 showuserptr $kgm_pcb.r[0]
 3352                 printf "    r1: "
 3353                 showuserptr $kgm_pcb.r[1]
 3354                 printf "    r2: "
 3355                 showuserptr $kgm_pcb.r[2]
 3356                 printf "    r3: "
 3357                 showuserptr $kgm_pcb.r[3]
 3358                 printf "\n"
 3359 
 3360                 printf "    r4: "
 3361                 showuserptr $kgm_pcb.r[4]
 3362                 printf "    r5: "
 3363                 showuserptr $kgm_pcb.r[5]
 3364                 printf "    r6: "
 3365                 showuserptr $kgm_pcb.r[6]
 3366                 printf "    r7: "
 3367                 showuserptr $kgm_pcb.r[7]
 3368                 printf "\n"
 3369 
 3370                 printf "    r8: "
 3371                 showuserptr $kgm_pcb.r[8]
 3372                 printf "    r9: "
 3373                 showuserptr $kgm_pcb.r[9]
 3374                 printf "   r10: "
 3375                 showuserptr $kgm_pcb.r[10]
 3376                 printf "   r11: "
 3377                 showuserptr $kgm_pcb.r[11]
 3378                 printf "\n"
 3379 
 3380                 printf "    ip: "
 3381                 showuserptr $kgm_pcb.r[12]
 3382                 printf "    sp: "
 3383                 showuserptr $kgm_pcb.sp
 3384                 printf "    lr: "
 3385                 showuserptr $kgm_pcb.lr
 3386                 printf "    pc: "
 3387                 showuserptr $kgm_pcb.pc
 3388                 printf "\n"
 3389 
 3390                 printf "  cpsr: "
 3391                 showuserptr $kgm_pcb.cpsr
 3392                 printf "\n"
 3393         else
 3394                 echo showuserregisters not supported on this architecture\n
 3395         end
 3396         end
 3397 end
 3398 document showuserregisters
 3399 Syntax: showuserstack <address of thread>
 3400 |This command displays the last known user register state
 3401 |for the thread. This map not be correct for cases where
 3402 |the thread is currently executing in userspace. However
 3403 |for threads that have entered the kernel (either explicitly
 3404 |with a system call or implicitly with a fault), it should
 3405 |be accurate
 3406 end
 3407 
 3408 define showtaskuserregisters
 3409     set $kgm_taskp = (struct task *)$arg0
 3410     set $kgm_head_actp = &($kgm_taskp->threads)
 3411     set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 3412     while $kgm_actp != $kgm_head_actp
 3413         printf "For thread "
 3414         showptr $kgm_actp
 3415         printf "\n"
 3416         showuserregisters $kgm_actp
 3417         set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 3418         printf "\n"
 3419     end
 3420 end
 3421 document showtaskuserregisters
 3422 Syntax: (gdb) showtaskuserregisters <task>
 3423 | Print out the user registers for each thread in a task
 3424 end
 3425 
 3426 define kdp-reboot
 3427 # Alternatively, set *(*(unsigned **) 0x2498) = 1 
 3428 # (or 0x5498 on PPC, 0xffffff8000002928 on x86_64, 0xffff049c on arm)
 3429        manualhdrint $kgm_kdp_pkt_hostreboot
 3430        detach
 3431 end
 3432 
 3433 document kdp-reboot
 3434 Syntax: kdp-reboot
 3435 |Reboot the remote target machine; not guaranteed to succeed. 
 3436 end
 3437 
 3438 define kdpversionint
 3439        # set up the manual KDP packet
 3440        set manual_pkt.input = 0
 3441        set manual_pkt.len = sizeof(kdp_version_req_t)
 3442        set $kgm_pkt = (kdp_version_req_t *)&manual_pkt.data
 3443        set $kgm_pkt->hdr.request  = KDP_VERSION
 3444        set $kgm_pkt->hdr.len      = sizeof(kdp_version_req_t)
 3445        set $kgm_pkt->hdr.is_reply = 0
 3446        set $kgm_pkt->hdr.seq      = 0
 3447        set $kgm_pkt->hdr.key      = 0
 3448        set manual_pkt.input       = 1
 3449        # dummy to make sure manual packet is executed
 3450        set $kgm_dummy = &_mh_execute_header
 3451        set $kgm_pkt = (kdp_version_reply_t *)&manual_pkt.data
 3452        set $kgm_kdp_version = $kgm_pkt->version
 3453        set $kgm_kdp_feature = $kgm_pkt->feature
 3454 end
 3455 
 3456 define kdp-version
 3457        kdpversionint
 3458        printf "KDP VERSION = %d, FEATURE = 0x%x\n", $kgm_kdp_version, $kgm_kdp_feature
 3459 end
 3460 
 3461 document kdp-version
 3462 Syntax: kdp-version
 3463 |Get the KDP protocol version being used by the kernel.
 3464 end
 3465 
 3466 define dumpinfoint
 3467        # set up the manual KDP packet
 3468        set manual_pkt.input        = 0
 3469 
 3470        set manual_pkt.len          = sizeof(kdp_dumpinfo_req_t)
 3471        set $kgm_pkt                = (kdp_dumpinfo_req_t *)&manual_pkt.data
 3472        set $kgm_pkt->hdr.request  = KDP_DUMPINFO
 3473        set $kgm_pkt->hdr.len      = sizeof(kdp_dumpinfo_req_t)
 3474        set $kgm_pkt->hdr.is_reply = 0
 3475        set $kgm_pkt->hdr.seq      = 0
 3476        set $kgm_pkt->hdr.key      = 0
 3477        set $kgm_pkt->type         = $arg0 
 3478        set $kgm_pkt->name         = ""
 3479        set $kgm_pkt->destip       = ""
 3480        set $kgm_pkt->routerip     = ""
 3481        set $kgm_pkt->port         = 0
 3482 
 3483        if $argc > 1
 3484           set $kgm_pkt->name      = "$arg1"
 3485        end
 3486        if $argc > 2
 3487           set $kgm_pkt->destip    = "$arg2"
 3488        end
 3489        if $argc > 3
 3490           set $kgm_pkt->routerip  = "$arg3"
 3491        end
 3492        if $argc > 4
 3493           set $kgm_pkt->port      = $arg4
 3494        end
 3495 
 3496        set manual_pkt.input       = 1
 3497        # dummy to make sure manual packet is executed
 3498        set $kgm_dummy = &_mh_execute_header
 3499 end
 3500 
 3501 define sendcore
 3502        if $argc > 1
 3503           dumpinfoint KDP_DUMPINFO_CORE $arg1 $arg0
 3504        else
 3505           dumpinfoint KDP_DUMPINFO_CORE \0 $arg0
 3506        end
 3507 end
 3508 
 3509 document sendcore
 3510 Syntax: sendcore <IP address> [filename]
 3511 |Configure the kernel to transmit a kernel coredump to a server (kdumpd) 
 3512 |at the specified IP address. This is useful when the remote target has
 3513 |not been previously configured to transmit coredumps, and you wish to
 3514 |preserve kernel state for later examination. NOTE: You must issue a "continue"
 3515 |command after using this macro to trigger the kernel coredump. The kernel
 3516 |will resume waiting in the debugger after completion of the coredump. You
 3517 |may disable coredumps by executing the "disablecore" macro. You can 
 3518 |optionally specify the filename to be used for the generated core file.
 3519 end
 3520 
 3521 define sendsyslog
 3522        if $argc > 1
 3523           dumpinfoint KDP_DUMPINFO_SYSTEMLOG $arg1 $arg0
 3524        else
 3525           dumpinfoint KDP_DUMPINFO_SYSTEMLOG \0 $arg0
 3526        end
 3527 end
 3528 
 3529 document sendsyslog
 3530 Syntax: sendsyslog <IP address> [filename]
 3531 |Configure the kernel to transmit a kernel system log to a server (kdumpd) 
 3532 |at the specified IP address. NOTE: You must issue a "continue"
 3533 |command after using this macro to trigger the kernel system log. The kernel
 3534 |will resume waiting in the debugger after completion. You can optionally
 3535 |specify the name to be used for the generated system log.
 3536 end
 3537 
 3538 define sendpaniclog
 3539        if panicstr 
 3540           if $argc > 1
 3541              dumpinfoint KDP_DUMPINFO_PANICLOG $arg1 $arg0
 3542           else
 3543              dumpinfoint KDP_DUMPINFO_PANICLOG \0 $arg0
 3544           end
 3545        else
 3546           printf "No panic log available.\n"
 3547        end
 3548 end
 3549 
 3550 document sendpaniclog
 3551 Syntax: sendpaniclog <IP address> [filename]
 3552 |Configure the kernel to transmit a kernel paniclog to a server (kdumpd) 
 3553 |at the specified IP address. NOTE: You must issue a "continue"
 3554 |command after using this macro to trigger the kernel panic log. The kernel
 3555 |will resume waiting in the debugger after completion. You can optionally
 3556 |specify the name to be used for the generated panic log.
 3557 end
 3558 
 3559 define getdumpinfo
 3560        dumpinfoint KDP_DUMPINFO_GETINFO
 3561        set $kgm_dumpinfo = (kdp_dumpinfo_reply_t *) manual_pkt.data
 3562        if $kgm_dumpinfo->type & KDP_DUMPINFO_REBOOT
 3563           printf "System will reboot after kernel info gets dumped.\n"
 3564        else
 3565           printf "System will not reboot after kernel info gets dumped.\n"
 3566        end
 3567        if $kgm_dumpinfo->type & KDP_DUMPINFO_NORESUME
 3568           printf "System will allow a re-attach after a KDP disconnect.\n"
 3569        else
 3570           printf "System will resume after a KDP disconnect.\n"
 3571        end
 3572        set $kgm_dumpinfo_type = $kgm_dumpinfo->type & KDP_DUMPINFO_MASK
 3573        if $kgm_dumpinfo_type == KDP_DUMPINFO_DISABLE
 3574           printf "Kernel not setup for remote dumps.\n"
 3575        else
 3576           printf "Remote dump type: "
 3577           if $kgm_dumpinfo_type == KDP_DUMPINFO_CORE
 3578              printf "Core file\n"
 3579           end
 3580           if $kgm_dumpinfo_type == KDP_DUMPINFO_PANICLOG
 3581              printf "Panic log\n"
 3582           end
 3583           if $kgm_dumpinfo_type == KDP_DUMPINFO_SYSTEMLOG
 3584              printf "System log\n"
 3585           end
 3586 
 3587           printf "Name: "
 3588           if $kgm_dumpinfo->name[0] == '\0'
 3589              printf "(autogenerated)\n"
 3590           else
 3591              printf "%s\n", $kgm_dumpinfo->name
 3592           end             
 3593 
 3594           printf "Network Info: %s[%d] ", $kgm_dumpinfo->destip, $kgm_dumpinfo->port
 3595           if $kgm_dumpinfo->routerip[0] == '\0'
 3596              printf "\n"
 3597           else
 3598              printf "Router: %s\n", $kgm_dumpinfo->routerip
 3599           end
 3600        end
 3601 end
 3602 
 3603 document getdumpinfo
 3604 Syntax: getdumpinfo
 3605 |Retrieve the current remote dump settings. 
 3606 end
 3607 
 3608 define setdumpinfo
 3609        dumpinfoint KDP_DUMPINFO_SETINFO $arg0 $arg1 $arg2 $arg3
 3610 end
 3611 
 3612 document setdumpinfo
 3613 Syntax: setdumpinfo <filename> <ip> <router> <port>
 3614 |Configure the current remote dump settings. Specify \0 if you
 3615 |want to use the defaults (filename) or previously configured
 3616 |settings (ip/router). Specify 0 for the port if you wish to 
 3617 |use the previously configured/default setting for that.
 3618 end
 3619 
 3620 define disablecore
 3621        dumpinfoint KDP_DUMPINFO_DISABLE
 3622 end
 3623 
 3624 document disablecore
 3625 Syntax: disablecore
 3626 |Reconfigures the kernel so that it no longer transmits kernel coredumps. This
 3627 |complements the "sendcore" macro, but it may be used if the kernel has been
 3628 |configured to transmit coredumps through boot-args as well.
 3629 end
 3630 
 3631 define switchtocorethread
 3632         set $newact = (struct thread *) $arg0
 3633         select 0
 3634         if ($newact->kernel_stack == 0)
 3635            echo This thread does not have a stack.\n
 3636            echo continuation:
 3637            output/a (unsigned) $newact.continuation
 3638            echo \n
 3639         else
 3640         if ($kgm_mtype == $kgm_mtype_ppc)
 3641            loadcontext $newact->machine->pcb
 3642            flushstack
 3643            set $pc = $newact->machine->pcb.save_srr0
 3644         else
 3645         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
 3646                 set $kgm_cstatep = (struct x86_kernel_state *) \
 3647                                         ($newact->kernel_stack + kernel_stack_size \
 3648                                          - sizeof(struct x86_kernel_state))
 3649                 loadcontext $kgm_cstatep
 3650                 flushstack
 3651         else
 3652                 echo switchtocorethread not supported on this architecture\n
 3653         end
 3654         end
 3655         showcontext_int
 3656         end
 3657 end
 3658 
 3659 document switchtocorethread
 3660 Syntax: switchtocorethread <address of activation>
 3661 | The corefile equivalent of "switchtoact". When debugging a kernel coredump
 3662 | file, this command can be used to examine the execution context and stack
 3663 | trace for a given thread activation. For example, to view the backtrace
 3664 | for a thread issue "switchtocorethread <address>", followed by "bt".
 3665 | Before resuming execution, issue a "resetcorectx" command, to
 3666 | return to the original execution context. Note that this command
 3667 | requires gdb support, as documented in Radar 3401283.
 3668 end
 3669 
 3670 define loadcontext
 3671         select 0
 3672         if ($kgm_mtype == $kgm_mtype_ppc)
 3673         set $kgm_contextp = (struct savearea *) $arg0
 3674         set $pc = $kgm_contextp.save_srr0
 3675         set $r1 = $kgm_contextp.save_r1
 3676         set $lr = $kgm_contextp.save_lr
 3677 
 3678         set $r2 = $kgm_contextp.save_r2
 3679         set $r3 = $kgm_contextp.save_r3
 3680         set $r4 = $kgm_contextp.save_r4
 3681         set $r5 = $kgm_contextp.save_r5
 3682         set $r6 = $kgm_contextp.save_r6
 3683         set $r7 = $kgm_contextp.save_r7
 3684         set $r8 = $kgm_contextp.save_r8
 3685         set $r9 = $kgm_contextp.save_r9
 3686         set $r10 = $kgm_contextp.save_r10
 3687         set $r11 = $kgm_contextp.save_r11
 3688         set $r12 = $kgm_contextp.save_r12
 3689         set $r13 = $kgm_contextp.save_r13
 3690         set $r14 = $kgm_contextp.save_r14
 3691         set $r15 = $kgm_contextp.save_r15
 3692         set $r16 = $kgm_contextp.save_r16
 3693         set $r17 = $kgm_contextp.save_r17
 3694         set $r18 = $kgm_contextp.save_r18
 3695         set $r19 = $kgm_contextp.save_r19
 3696         set $r20 = $kgm_contextp.save_r20
 3697         set $r21 = $kgm_contextp.save_r21
 3698         set $r22 = $kgm_contextp.save_r22
 3699         set $r23 = $kgm_contextp.save_r23
 3700         set $r24 = $kgm_contextp.save_r24
 3701         set $r25 = $kgm_contextp.save_r25
 3702         set $r26 = $kgm_contextp.save_r26
 3703         set $r27 = $kgm_contextp.save_r27
 3704         set $r28 = $kgm_contextp.save_r28
 3705         set $r29 = $kgm_contextp.save_r29
 3706         set $r30 = $kgm_contextp.save_r30
 3707         set $r31 = $kgm_contextp.save_r31
 3708 
 3709         set $cr = $kgm_contextp.save_cr
 3710         set $ctr = $kgm_contextp.save_ctr
 3711        else
 3712         if ($kgm_mtype == $kgm_mtype_i386)
 3713                 set $kgm_contextp = (struct x86_kernel_state *) $arg0
 3714                 set $ebx = $kgm_contextp->k_ebx 
 3715                 set $ebp = $kgm_contextp->k_ebp 
 3716                 set $edi = $kgm_contextp->k_edi 
 3717                 set $esi = $kgm_contextp->k_esi 
 3718                 set $eip = $kgm_contextp->k_eip 
 3719                 set $pc =  $kgm_contextp->k_eip
 3720         else
 3721         if ($kgm_mtype == $kgm_mtype_x86_64)
 3722                 set $kgm_contextp = (struct x86_kernel_state *) $arg0
 3723                 set $rbx = $kgm_contextp->k_rbx 
 3724                 set $rbp = $kgm_contextp->k_rbp 
 3725                 set $r12 = $kgm_contextp->k_r12 
 3726                 set $r13 = $kgm_contextp->k_r13 
 3727                 set $r14 = $kgm_contextp->k_r14 
 3728                 set $r15 = $kgm_contextp->k_r15 
 3729                 set $rip = $kgm_contextp->k_rip
 3730                 set $pc = $kgm_contextp->k_rip
 3731         else
 3732                 echo loadcontext not supported on this architecture\n
 3733         end
 3734         end
 3735         end
 3736 end
 3737 
 3738 define resetcorectx
 3739         select 0
 3740         if ($kgm_mtype == $kgm_mtype_ppc)
 3741                 set $kgm_corecontext = (struct savearea *) kdp.saved_state
 3742                 loadcontext $kgm_corecontext
 3743         else
 3744         if ($kgm_mtype == $kgm_mtype_i386)
 3745                 set $kdpstatep = (struct x86_saved_state32 *) kdp.saved_state
 3746                 set $ebx = $kdpstatep->ebx
 3747                 set $ebp = $kdpstatep->ebp
 3748                 set $edi = $kdpstatep->edi
 3749                 set $esi = $kdpstatep->esi
 3750                 set $eip = $kdpstatep->eip
 3751                 set $eax = $kdpstatep->eax
 3752                 set $ecx = $kdpstatep->ecx
 3753                 set $edx = $kdpstatep->edx
 3754                 flushregs
 3755                 flushstack
 3756                 set $pc = $kdpstatep->eip
 3757                 update
 3758         else
 3759                 echo resetcorectx not supported on this architecture\n
 3760         end
 3761         end
 3762         showcontext_int
 3763 end
 3764 
 3765 document resetcorectx
 3766 Syntax: resetcorectx
 3767 | The corefile equivalent of "resetctx". Returns to the original
 3768 | execution context (that of the active thread at the time of the NMI or
 3769 | panic). This command should be issued if you wish to resume
 3770 | execution after using the "switchtocorethread" command.
 3771 end
 3772 
 3773 #Helper function for "showallgdbstacks"
 3774 
 3775 define showgdbthread
 3776         printf "            0x%08x  ", $arg0
 3777         set $kgm_thread = *(struct thread *)$arg0
 3778         printf "0x%08x  ", $arg0
 3779         printf "%3d  ", $kgm_thread.sched_pri
 3780         set $kgm_state = $kgm_thread.state
 3781         if $kgm_state & 0x80
 3782             printf "I" 
 3783         end
 3784         if $kgm_state & 0x40
 3785             printf "P" 
 3786         end
 3787         if $kgm_state & 0x20
 3788             printf "A" 
 3789         end
 3790         if $kgm_state & 0x10
 3791             printf "H" 
 3792         end
 3793         if $kgm_state & 0x08
 3794             printf "U" 
 3795         end
 3796         if $kgm_state & 0x04
 3797             printf "R" 
 3798         end
 3799         if $kgm_state & 0x02
 3800             printf "S" 
 3801         end
 3802         if $kgm_state & 0x01
 3803             printf "W\t" 
 3804             printf "0x%08x  ", $kgm_thread.wait_queue
 3805             output /a (unsigned) $kgm_thread.wait_event
 3806                 if ($kgm_thread.uthread != 0)
 3807                         set $kgm_uthread = (struct uthread *)$kgm_thread.uthread
 3808                         if ($kgm_uthread->uu_wmesg != 0)
 3809                                 printf " \"%s\"", $kgm_uthread->uu_wmesg
 3810                         end
 3811             end
 3812         end
 3813         if $arg1 != 0
 3814             if ($kgm_thread.kernel_stack != 0)
 3815                 if ($kgm_thread.reserved_stack != 0)
 3816                         printf "\n\t\treserved_stack=0x%08x", $kgm_thread.reserved_stack
 3817                 end
 3818                 printf "\n\t\tkernel_stack=0x%08x", $kgm_thread.kernel_stack
 3819                 if ($kgm_mtype == $kgm_mtype_ppc)
 3820                         set $mysp = $kgm_thread.machine.pcb->save_r1
 3821                 end
 3822                 if ($kgm_mtype == $kgm_mtype_i386)
 3823                         set $kgm_statep = (struct x86_kernel_state *) \
 3824                                 ($kgm_thread->kernel_stack + kernel_stack_size \
 3825                                  - sizeof(struct x86_kernel_state))
 3826                         set $mysp = $kgm_statep->k_ebp
 3827                 end
 3828                 if ($kgm_mtype == $kgm_mtype_arm)
 3829                         if (((unsigned long)$r7 < ((unsigned long) ($kgm_thread->kernel_stack+kernel_stack_size))) \
 3830                       && ((unsigned long)$r7 > (unsigned long) ($kgm_thread->kernel_stack)))
 3831                                 set $mysp = $r7
 3832                         else
 3833                                 set $kgm_statep = (struct arm_saved_state *)$kgm_thread.machine.kstackptr
 3834                                 set $mysp = $kgm_statep->r[7]
 3835                         end
 3836                 end
 3837                 set $prevsp = 0
 3838                 printf "\n\t\tstacktop=0x%08x", $mysp
 3839                 if ($arg2 == 0)
 3840                         switchtoact $arg0
 3841                 else
 3842                         switchtocorethread $arg0
 3843                 end
 3844                 bt
 3845             else
 3846                 printf "\n\t\t\tcontinuation="
 3847                 output /a (unsigned) $kgm_thread.continuation
 3848             end
 3849             printf "\n"
 3850         else
 3851             printf "\n"
 3852         end
 3853 end         
 3854 
 3855 #Use of this macro is currently (8/04) blocked by the fact that gdb
 3856 #stops evaluating macros when encountering an error, such as a failure
 3857 #to read memory from a certain location. Until this issue (described in
 3858 #3758949) is addressed, evaluation of this macro may stop upon
 3859 #encountering such an error.
 3860 
 3861 define showallgdbstacks
 3862     set $kgm_head_taskp = &tasks
 3863     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 3864     while $kgm_taskp != $kgm_head_taskp
 3865         showtaskheader
 3866         showtaskint $kgm_taskp
 3867         set $kgm_head_actp = &($kgm_taskp->threads)
 3868         set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 3869         while $kgm_actp != $kgm_head_actp
 3870             showactheader
 3871             showgdbthread $kgm_actp 1 0
 3872             set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 3873         end
 3874         printf "\n"
 3875         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 3876     end
 3877     resetctx
 3878 end
 3879 
 3880 document showallgdbstacks
 3881 Syntax: showallgdbstacks
 3882 | An alternative to "showallstacks". Iterates through the task list and
 3883 | displays a gdb generated backtrace for each kernel thread. It is
 3884 | advantageous in that it is much faster than "showallstacks", and
 3885 | decodes function call arguments and displays source level traces, but
 3886 | it has the drawback that it doesn't determine if frames belong to
 3887 | functions from kernel extensions, as with "showallstacks".
 3888 | This command may terminate prematurely because of a gdb bug
 3889 | (Radar 3758949), which stops macro evaluation on memory read
 3890 | errors.
 3891 end
 3892 
 3893 define showallgdbcorestacks
 3894         select 0
 3895         set $kgm_head_taskp = &tasks
 3896         set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
 3897         while $kgm_taskp != $kgm_head_taskp
 3898                 showtaskheader
 3899                 showtaskint $kgm_taskp
 3900                 set $kgm_head_actp = &($kgm_taskp->threads)
 3901                 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 3902                 while $kgm_actp != $kgm_head_actp
 3903                 showactheader
 3904                 showgdbthread $kgm_actp 1 1
 3905                 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 3906                 end
 3907                 printf "\n"
 3908                 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 3909         end
 3910         resetcorectx
 3911 end
 3912 
 3913 
 3914 document showallgdbcorestacks
 3915 Syntax: showallgdbcorestacks
 3916 |Corefile version of "showallgdbstacks"
 3917 end
 3918 
 3919 
 3920 define switchtouserthread
 3921                 select 0
 3922                 if ($kgm_mtype == $kgm_mtype_ppc)       
 3923                    if ($kdp_act_counter == 0)
 3924                       set $kdpstate = (struct savearea *) kdp.saved_state
 3925                    end
 3926                    set $kdp_act_counter = $kdp_act_counter + 1
 3927                    set $newact = (struct thread *) $arg0
 3928                    _kgm_flush_loop
 3929                    set $checkpc = $newact->machine->upcb.save_srr0
 3930                    if ($checkpc == 0)
 3931                       echo This activation does not appear to have
 3932                       echo \20 a valid user context.\n
 3933                    else       
 3934                      set (struct savearea *) kdp.saved_state=$newact->machine->upcb
 3935                      set $pc = $checkpc
 3936 #flush and update seem to be executed lazily by gdb on Tiger, hence the
 3937 #repeated invocations - see 3743135
 3938                     _kgm_flush_loop
 3939 # This works because the new pmap is used only for reads
 3940                      set kdp_pmap = $newact->task->map->pmap
 3941                      _kgm_flush_loop
 3942                      _kgm_update_loop
 3943                    end
 3944                 else
 3945                    echo switchtouserthread not implemented for this architecture.\n
 3946         end
 3947 end
 3948 
 3949 document switchtouserthread
 3950 Syntax: switchtouserthread <address of thread>
 3951 | Analogous to switchtoact, but switches to the user context of a
 3952 | specified thread address. Similar to the "showuserstack"
 3953 | command, but this command does not return gdb to the kernel context
 3954 | immediately. This is to assist with the following (rather risky)
 3955 | manoeuvre - upon switching to the user context and virtual address
 3956 | space, the user may choose to call remove-symbol-file on the
 3957 | mach_kernel symbol file, and then add-symbol-file on the user space
 3958 | binary's symfile. gdb can then generate symbolic backtraces 
 3959 | for the user space thread. To return to the
 3960 | kernel context and virtual address space, the process must be
 3961 | reversed, i.e. call remove-symbol-file on the user space symbols, and
 3962 | then add-symbol-file on the appropriate mach_kernel, and issue the
 3963 | "resetstacks" command. Note that gdb may not react kindly to all these
 3964 | symbol file switches. The same restrictions that apply to "showuserstack"
 3965 | apply here - pages that have been paged out cannot be read while in the
 3966 | debugger context, so backtraces may terminate early.
 3967 | If the virtual addresses in the stack trace do not conflict with those
 3968 | of symbols in the kernel's address space, it may be sufficient to
 3969 | just do an add-symbol-file on the user space binary's symbol file.
 3970 | Note that while this command works on Panther's gdb, an issue
 3971 | with Tiger gdb (3743135) appears to hamper the evaluation of this
 3972 | macro in some cases.
 3973 end
 3974 
 3975 define showmetaclass
 3976     set $kgm_metaclassp = (OSMetaClass *)$arg0
 3977     printf "%-5d", $kgm_metaclassp->instanceCount
 3978     printf "x %5d bytes", $kgm_metaclassp->classSize
 3979     printf " %s\n", $kgm_metaclassp->className->string
 3980 end
 3981 
 3982 define showstring
 3983     printf "\"%s\"", ((OSString *)$arg0)->string
 3984 end
 3985 
 3986 define shownumber
 3987     printf "%lld", ((OSNumber *)$arg0)->value
 3988 end
 3989 
 3990 define showboolean
 3991     if ($arg0 == gOSBooleanFalse)
 3992         printf "No"
 3993     else
 3994         printf "Yes"
 3995     end
 3996 end
 3997 
 3998 define showdatabytes
 3999     set $kgm_data = (OSData *)$arg0
 4000 
 4001     printf "<"
 4002     set $kgm_datap = (const unsigned char *) $kgm_data->data
 4003         set $kgm_idx = 0
 4004         while ( $kgm_idx < $kgm_data->length )
 4005                 printf "%02X", *$kgm_datap
 4006                 set $kgm_datap = $kgm_datap + 1
 4007                 set $kgm_idx = $kgm_idx + 1
 4008         end
 4009         printf ">\n"
 4010 end
 4011 
 4012 define showdata
 4013     set $kgm_data = (OSData *)$arg0
 4014 
 4015     printf "<"
 4016     set $kgm_datap = (const unsigned char *) $kgm_data->data
 4017 
 4018     set $kgm_printstr = 0
 4019     if (0 == (3 & (unsigned int)$kgm_datap) && ($kgm_data->length >= 3))
 4020         set $kgm_bytes = *(unsigned int *) $kgm_datap
 4021         if (0xffff0000 & $kgm_bytes)
 4022             set $kgm_idx = 0
 4023             set $kgm_printstr = 1
 4024             while ($kgm_idx++ < 4)
 4025                 set $kgm_bytes = $kgm_bytes >> 8
 4026                 set $kgm_char = 0xff & $kgm_bytes
 4027                 if ($kgm_char && (($kgm_char < 0x20) || ($kgm_char > 0x7e)))
 4028                     set $kgm_printstr = 0
 4029                 end
 4030             end
 4031         end
 4032     end
 4033     
 4034     set $kgm_idx = 0
 4035     if ($kgm_printstr)
 4036         set $kgm_quoted = 0
 4037         while ($kgm_idx < $kgm_data->length)
 4038             set $kgm_char = $kgm_datap[$kgm_idx++]
 4039             if ($kgm_char)
 4040                 if (0 == $kgm_quoted)
 4041                     set $kgm_quoted = 1
 4042                     if ($kgm_idx > 1)
 4043                         printf ",\""
 4044                     else
 4045                         printf "\""
 4046                     end
 4047                 end
 4048                 printf "%c", $kgm_char
 4049             else
 4050                 if ($kgm_quoted)
 4051                     set $kgm_quoted = 0
 4052                     printf "\""
 4053                 end
 4054             end
 4055         end
 4056         if ($kgm_quoted)
 4057             printf "\""
 4058         end
 4059     else
 4060         if (0 == (3 & (unsigned int)$kgm_datap))
 4061             while (($kgm_idx + 3) <= $kgm_data->length)
 4062                 printf "%08x", *(unsigned int *) &$kgm_datap[$kgm_idx]
 4063                 set $kgm_idx = $kgm_idx + 4
 4064             end
 4065         end
 4066         while ($kgm_idx < $kgm_data->length)
 4067             printf "%02x", $kgm_datap[$kgm_idx++]
 4068         end
 4069     end
 4070     printf ">"
 4071 end
 4072 
 4073 define showdictionaryint
 4074     set $kgm$arg0_dict = (OSDictionary *)$arg1
 4075 
 4076     printf "{"
 4077     set $kgm$arg0_idx = 0
 4078     while ($kgm$arg0_idx < $kgm$arg0_dict->count)
 4079         set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx].key
 4080         showobjectint _$arg0 $kgm_obj
 4081         printf "="
 4082         set $kgm_obj = $kgm$arg0_dict->dictionary[$kgm$arg0_idx++].value
 4083         showobjectint _$arg0 $kgm_obj
 4084         if ($kgm$arg0_idx < $kgm$arg0_dict->count)
 4085             printf ","
 4086         end
 4087     end
 4088     printf "}"
 4089 end
 4090 
 4091 define indent
 4092     set $kgm_idx = 0
 4093     while ($kgm_idx < $arg0)
 4094         if ($arg1 & (1 << $kgm_idx++))
 4095             printf "| "
 4096         else
 4097             printf "  "
 4098         end
 4099     end
 4100 end
 4101 
 4102 define showregdictionary
 4103     indent $kgm_reg_depth+2 $arg1
 4104     printf "{\n"
 4105 
 4106     set $kgm_reg_idx = 0
 4107     while ($kgm_reg_idx < $arg0->count)
 4108         indent $kgm_reg_depth+2 $arg1
 4109         printf "  "
 4110         set $kgm_obj = $arg0->dictionary[$kgm_reg_idx].key
 4111         showobjectint _ $kgm_obj
 4112         printf " = "
 4113 
 4114         set $kgm_obj = $arg0->dictionary[$kgm_reg_idx++].value
 4115         showobjectint _ $kgm_obj
 4116         printf "\n"
 4117     end
 4118     indent $kgm_reg_depth+2 $arg1
 4119     printf "}\n"
 4120 end
 4121 
 4122 
 4123 define showorderedsetarrayint
 4124     set $kgm$arg0_array = (_Element *)$arg1
 4125     set $kgm$arg0_count = $arg2
 4126 
 4127     set $kgm$arg0_idx = 0
 4128     while ($kgm$arg0_idx < $kgm$arg0_count)
 4129         set $kgm_obj = $kgm$arg0_array[$kgm$arg0_idx++]
 4130         showobjectint _$arg0 $kgm_obj
 4131         if ($kgm$arg0_idx < $kgm$arg0_count)
 4132             printf ","
 4133         end
 4134     end
 4135 end
 4136 
 4137 define showorderedsetint
 4138     set $kgm_array = ((OSOrderedSet *)$arg1)->array
 4139     set $count = ((OSOrderedSet *)$arg1)->count
 4140     printf "["
 4141     showorderedsetarrayint $arg0 $kgm_array $count
 4142     printf "]"
 4143 end
 4144 
 4145 define showarraysetint
 4146     set $kgm$arg0_array = (OSArray *)$arg1
 4147 
 4148     set $kgm$arg0_idx = 0
 4149     while ($kgm$arg0_idx < $kgm$arg0_array->count)
 4150         set $kgm_obj = $kgm$arg0_array->array[$kgm$arg0_idx++]
 4151         showobjectint _$arg0 $kgm_obj
 4152         if ($kgm$arg0_idx < $kgm$arg0_array->count)
 4153             printf ","
 4154         end
 4155     end
 4156 end
 4157 
 4158 define showarrayint
 4159     printf "("
 4160     showarraysetint $arg0 $arg1
 4161     printf ")"
 4162 end
 4163 
 4164 define showsetint
 4165     set $kgm_array = ((OSSet *)$arg1)->members
 4166     printf "["
 4167     showarraysetint $arg0 $kgm_array
 4168     printf "]"
 4169 end
 4170 
 4171 
 4172 define showobjectint
 4173     set $kgm_obj = (OSObject *) $arg1
 4174     set $kgm_vt = *((void **) $arg1)
 4175 
 4176     if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
 4177         set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
 4178     end
 4179 
 4180     if ($kgm_show_object_addrs)
 4181         printf "`object "
 4182         showptr $arg1
 4183         printf ", vt "
 4184         output /a (unsigned long) $kgm_vt
 4185         if ($kgm_show_object_retain)
 4186             printf ", retain count %d, container retain %d", (0xffff & $kgm_obj->retainCount), $kgm_obj->retainCount >> 16
 4187         end
 4188         printf "` "
 4189     end
 4190 
 4191     # No multiple-inheritance
 4192     set $kgm_shown = 0
 4193     if ($kgm_vt == &_ZTV8OSString)
 4194         showstring $arg1
 4195         set $kgm_shown = 1
 4196     end
 4197         if ($kgm_vt == &_ZTV8OSSymbol)
 4198             showstring $arg1
 4199         set $kgm_shown = 1
 4200     end
 4201     if ($kgm_vt == &_ZTV8OSNumber)
 4202                 shownumber $arg1
 4203         set $kgm_shown = 1
 4204     end
 4205     if ($kgm_vt == &_ZTV6OSData)
 4206         if $kgm_show_data_alwaysbytes == 1
 4207             showdatabytes $arg1
 4208         else
 4209             showdata $arg1
 4210         end
 4211         set $kgm_shown = 1
 4212     end
 4213     if ($kgm_vt == &_ZTV9OSBoolean)
 4214         showboolean $arg1
 4215         set $kgm_shown = 1
 4216     end
 4217     if ($kgm_vt == &_ZTV12OSDictionary)
 4218         showdictionaryint _$arg0 $arg1
 4219         set $kgm_shown = 1
 4220     end
 4221     if ($kgm_vt == &_ZTV7OSArray)
 4222         showarrayint _$arg0 $arg1
 4223         set $kgm_shown = 1
 4224     end
 4225     if ($kgm_vt == &_ZTV5OSSet)
 4226         showsetint _$arg0 $arg1
 4227         set $kgm_shown = 1
 4228     end
 4229     if ($kgm_vt == &_ZTV12OSOrderedSet)
 4230         showorderedsetint _$arg0 $arg1
 4231         set $kgm_shown = 1
 4232     end
 4233     
 4234     if ($kgm_shown != 1)
 4235         if ($kgm_show_object_addrs == 0)
 4236             printf "`object "
 4237             showptr $arg1
 4238             printf ", vt "
 4239             output /a (unsigned long) $kgm_vt
 4240             printf "`"
 4241         end
 4242     end
 4243 end
 4244 
 4245 define showobject
 4246     set $kgm_save = $kgm_show_object_addrs
 4247     set $kgm_show_object_addrs = 1
 4248     set $kgm_show_object_retain = 1
 4249     showobjectint _ $arg0
 4250     set $kgm_show_object_addrs = $kgm_save
 4251     set $kgm_show_object_retain = 0
 4252     printf "\n"
 4253 end
 4254 document showobject
 4255 Syntax: (gdb) showobject <object address>
 4256 | Show info about an OSObject - its vtable ptr and retain count.
 4257 | If the object is a simple container class, more info will be shown.
 4258 end
 4259 
 4260 define dictget 
 4261     set $kgm_dictp = (OSDictionary *)$arg0
 4262     set $kgm_keyp = (const OSSymbol *)$arg1
 4263     set $kgm_idx = 0
 4264     set $kgm_result = 0
 4265     while (($kgm_idx < $kgm_dictp->count) && ($kgm_result == 0))
 4266         if ($kgm_keyp == $kgm_dictp->dictionary[$kgm_idx].key)
 4267             set $kgm_result = $kgm_dictp->dictionary[$kgm_idx].value
 4268         end
 4269         set $kgm_idx = $kgm_idx + 1
 4270     end
 4271 end
 4272 
 4273 
 4274 define _registryentryrecurseinit
 4275     set $kgm_re         = (IOService *)$arg1
 4276     set $kgm$arg0_stack = (unsigned long long) $arg2
 4277 
 4278     if ($arg3)
 4279         set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
 4280     else
 4281         set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
 4282     end
 4283 
 4284     dictget $kgm_re->fRegistryTable $kgm_childkey
 4285     set $kgm$arg0_child_array = (OSArray *) $kgm_result
 4286 
 4287     if ($kgm$arg0_child_array)
 4288         set $kgm$arg0_child_count = $kgm$arg0_child_array->count
 4289     else
 4290         set $kgm$arg0_child_count = 0
 4291     end
 4292 
 4293     if ($kgm$arg0_child_count)
 4294         set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
 4295     else
 4296         set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
 4297     end
 4298 end
 4299 
 4300 define findregistryentryrecurse
 4301     set $kgm_registry_entry = 0
 4302     _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
 4303 
 4304     dictget $kgm_re->fRegistryTable $kgm_namekey
 4305     if ($kgm_result == 0)
 4306         dictget $kgm_re->fRegistryTable gIONameKey
 4307     end
 4308     if ($kgm_result == 0)
 4309         dictget $kgm_re->fPropertyTable gIOClassKey
 4310     end
 4311 
 4312     if ($kgm_result != 0)
 4313        set $str = ((OSString *) $kgm_result)->string
 4314        strcmp_nomalloc $str $kgm_reg_find_str0 $kgm_reg_find_str1 $kgm_reg_find_str2 $kgm_reg_find_str3 $kgm_reg_find_str4 $kgm_reg_find_str5 $kgm_reg_find_str6 $kgm_reg_find_str7 $kgm_reg_find_str8 
 4315        if $kgm_findregistry_verbose
 4316           echo .
 4317        end
 4318 
 4319        if $kgm_strcmp_result == 0
 4320           if $kgm_findregistry_verbose
 4321              printf "\n%s:\n | ", ((OSString *) $kgm_result)->string
 4322              showobject $kgm_re
 4323              printf " | "
 4324              print $kgm_re
 4325           end
 4326 
 4327           # don't populate $kgm_registry_entry if we want to show everything
 4328           if !$kgm_findregistry_continue
 4329              set $kgm_registry_entry = $kgm_re
 4330           end
 4331        end
 4332     end
 4333 
 4334     # recurse
 4335     if (!$kgm_registry_entry && ($kgm$arg0_child_count != 0))
 4336         set $kgm_reg_depth = $kgm_reg_depth + 1
 4337         set $kgm$arg0_child_idx = 0
 4338 
 4339         while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 4340             set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
 4341             set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 4342             if $kgm_reg_depth >= $kgm_reg_depth_max + 1
 4343                loop_break
 4344             end
 4345             findregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib 
 4346             if $kgm_registry_entry
 4347                loop_break
 4348             end
 4349         end
 4350         set $kgm_reg_depth = $kgm_reg_depth - 1
 4351     end
 4352 end
 4353 
 4354 define findregdictvalue
 4355     set $kgm_registry_value = 0
 4356     set $kgm_reg_idx = 0
 4357     while ($kgm_reg_idx < $arg0->count)
 4358         set $kgm_obj = $arg0->dictionary + $kgm_reg_idx
 4359         set $str = ((OSString *)$kgm_obj->key)->string
 4360         strcmp_nomalloc $str $kgm_reg_find_str0 $kgm_reg_find_str1 $kgm_reg_find_str2 $kgm_reg_find_str3 $kgm_reg_find_str4 $kgm_reg_find_str5 $kgm_reg_find_str6 $kgm_reg_find_str7 $kgm_reg_find_str8 
 4361 
 4362         if $kgm_strcmp_result == 0
 4363            set $kgm_registry_value = $kgm_obj->value
 4364            if $kgm_findregistry_verbose
 4365               showobject $kgm_registry_value
 4366               print $kgm_registry_value
 4367            end
 4368            loop_break
 4369         end
 4370         set $kgm_reg_idx = $kgm_reg_idx + 1
 4371     end
 4372 end
 4373 
 4374 define setfindregistrystr
 4375     set $kgm_reg_find_str0 = 0
 4376     set $kgm_reg_find_str1 = 0
 4377     set $kgm_reg_find_str2 = 0
 4378     set $kgm_reg_find_str3 = 0
 4379     set $kgm_reg_find_str4 = 0
 4380     set $kgm_reg_find_str5 = 0
 4381     set $kgm_reg_find_str6 = 0
 4382     set $kgm_reg_find_str7 = 0
 4383     set $kgm_reg_find_str8 = 0
 4384 
 4385     if $argc > 0
 4386        set $kgm_reg_find_str0 = $arg0
 4387     end
 4388     if $argc > 1
 4389        set $kgm_reg_find_str1 = $arg1
 4390     end
 4391     if $argc > 2
 4392        set $kgm_reg_find_str2 = $arg2
 4393     end
 4394     if $argc > 3
 4395        set $kgm_reg_find_str3 = $arg3
 4396     end
 4397     if $argc > 4
 4398        set $kgm_reg_find_str4 = $arg4
 4399     end
 4400     if $argc > 5
 4401        set $kgm_reg_find_str5 = $arg5
 4402     end
 4403     if $argc > 6
 4404        set $kgm_reg_find_str6 = $arg6
 4405     end
 4406     if $argc > 7
 4407        set $kgm_reg_find_str7 = $arg7
 4408     end
 4409     if $argc > 8
 4410        set $kgm_reg_find_str8 = $arg8
 4411     end
 4412 end
 4413 
 4414 document setfindregistrystr
 4415 Syntax: (gdb) setfindregistrystr [a] [b] [c] [d] [e] [f] [g] [h] [i]
 4416 | Store an encoded string into up to 9 arguments for use by 
 4417 | findregistryprop or findregistryentry. The arguments are created
 4418 | through calls to strcmp_arg_pack64
 4419 end
 4420 
 4421 define _findregistryprop
 4422     set $reg       = (IOService *) $arg0
 4423     set $kgm_props = $reg->fPropertyTable
 4424     set $kgm_findregistry_verbose = 0
 4425 
 4426     findregdictvalue $kgm_props 
 4427 end
 4428 
 4429 define findregistryprop
 4430     set $reg       = (IOService *) $arg0
 4431     set $kgm_props = $reg->fPropertyTable
 4432 
 4433     set $kgm_findregistry_verbose = 1
 4434     findregdictvalue $kgm_props 
 4435 end
 4436 
 4437 document findregistryprop
 4438 Syntax: (gdb) findregistryprop <entry>
 4439 | Given a registry entry, print out the contents for the property that matches
 4440 | the encoded string specified via setfindregistrystr.
 4441 |
 4442 | For example, the following will print out the "intel-pic" property stored in
 4443 | the AppleACPIPlatformExpert registry entry $pe_entry:
 4444 |            strcmp_arg_pack64 'i' 'n' 't' 'e' 'l' '-' 'p' 'i' 
 4445 |            set $intel_pi = $kgm_strcmp_arg
 4446 |            strcmp_arg_pack64 'c' 0 0 0 0 0 0 0
 4447 |            set $c = $kgm_strcmp_arg
 4448 |            setfindregistrystr $intel_pi $c
 4449 |            findregistryprop $pe_entry
 4450 end
 4451 
 4452 define findregistryentryint
 4453     if !$kgm_reg_plane
 4454        set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
 4455     end
 4456 
 4457     if !$kgm_reg_plane
 4458        printf "Please load kgmacros after KDP attaching to the target.\n"
 4459     else
 4460        set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
 4461        set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
 4462        if $kgm_findregistry_verbose
 4463           printf "Searching"
 4464        end
 4465        findregistryentryrecurse _ $arg0 0 0
 4466     end
 4467 end
 4468 
 4469 define _findregistryentry
 4470     set $kgm_findregistry_verbose  = 0
 4471     set $kgm_findregistry_continue = 0
 4472     set $kgm_reg_depth             = 0
 4473 
 4474     findregistryentryint gRegistryRoot
 4475 end
 4476 
 4477 define findregistryentry
 4478     set $kgm_findregistry_verbose  = 1
 4479     set $kgm_findregistry_continue = 0
 4480     set $kgm_reg_depth             = 0
 4481 
 4482     findregistryentryint gRegistryRoot
 4483 end
 4484 
 4485 define findregistryentries
 4486     set $kgm_findregistry_verbose  = 1
 4487     set $kgm_findregistry_continue = 1
 4488     set $kgm_reg_depth             = 0
 4489 
 4490     findregistryentryint gRegistryRoot
 4491 end
 4492 
 4493 document findregistryentry
 4494 Syntax: (gdb) findregistryentry
 4495 | Search for a registry entry that matches the encoded string specified through
 4496 | setfindregistrystr. You can alter the search depth through use of 
 4497 | $kgm_reg_depth_max.
 4498 |
 4499 | For example, the following will pull out the AppleACPIPlatformExpert registry
 4500 | entry:
 4501 |         strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
 4502 |         set $AppleACP = $kgm_strcmp_arg
 4503 |         strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
 4504 |         set $IPlatfor = $kgm_strcmp_arg
 4505 |         strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
 4506 |         set $mExpert = $kgm_strcmp_arg
 4507 |         setfindregistrystr $AppleACP $IPlatfor $mExpert
 4508 |         findregistryentry
 4509 end
 4510 
 4511 document findregistryentries
 4512 Syntax: (gdb) findregistryentries
 4513 | Search for all registry entries that match the encoded string specified through
 4514 | setfindregistrystr. You can alter the search depth through use of 
 4515 | $kgm_reg_depth_max. See findregistryentry for an example of how to encode a string.
 4516 end
 4517 
 4518 
 4519 define showregistryentryrecurse
 4520     _registryentryrecurseinit $arg0 $arg1 $arg2 $arg3
 4521 
 4522     indent $kgm_reg_depth $kgm$arg0_stack
 4523     printf "+-o "
 4524 
 4525     dictget $kgm_re->fRegistryTable $kgm_namekey
 4526     if ($kgm_result == 0)
 4527         dictget $kgm_re->fRegistryTable gIONameKey
 4528     end
 4529     if ($kgm_result == 0)
 4530         dictget $kgm_re->fPropertyTable gIOClassKey
 4531     end
 4532 
 4533     if ($kgm_result != 0)
 4534         printf "%s", ((OSString *)$kgm_result)->string
 4535     else
 4536         if (((IOService*)$kgm_re)->pwrMgt &&  ((IOService*)$kgm_re)->pwrMgt->Name)
 4537             printf "%s", ((IOService*)$kgm_re)->pwrMgt->Name
 4538         else
 4539 #           printf ", guessclass "
 4540 #           guessclass $kgm_re
 4541             printf "??"
 4542         end
 4543     end
 4544 
 4545 
 4546     printf "  <object "
 4547     showptr $kgm_re
 4548     printf ", id 0x%llx, ", $kgm_re->IORegistryEntry::reserved->fRegistryEntryID
 4549     printf "vtable "
 4550     set $kgm_vt = (unsigned long) *(void**) $kgm_re
 4551     if ($kgm_lp64 || $kgm_mtype == $kgm_mtype_arm)
 4552         set $kgm_vt = $kgm_vt - 2 * sizeof(void *)
 4553     end
 4554     output /a $kgm_vt
 4555 
 4556     if ($kgm_vt != &_ZTV15IORegistryEntry)
 4557         printf ", "
 4558         set $kgm_state =  $kgm_re->__state[0]
 4559         # kIOServiceRegisteredState
 4560         if (0 == ($kgm_state & 2))
 4561             printf "!"
 4562         end
 4563         printf "registered, "
 4564         # kIOServiceMatchedState
 4565         if (0 == ($kgm_state & 4))
 4566             printf "!"
 4567         end
 4568         printf "matched, "
 4569         # kIOServiceInactiveState
 4570         if ($kgm_state & 1)
 4571             printf "in"
 4572         end
 4573         printf "active, busy %d, retain count %d", (0xff & $kgm_re->__state[1]), (0xffff & $kgm_re->retainCount)
 4574     end
 4575     printf ">\n"
 4576 
 4577     if ($kgm_show_props)
 4578         set $kgm_props = $kgm_re->fPropertyTable
 4579         showregdictionary $kgm_props $kgm$arg0_stack
 4580     end
 4581 
 4582     # recurse
 4583     if ($kgm$arg0_child_count != 0)
 4584 
 4585         set $kgm_reg_depth = $kgm_reg_depth + 1
 4586         set $kgm$arg0_child_idx = 0
 4587 
 4588         while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 4589             set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
 4590             set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 4591             if $kgm_reg_depth >= $kgm_reg_depth_max + 1
 4592                loop_break
 4593             end
 4594             showregistryentryrecurse _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
 4595         end
 4596 
 4597         set $kgm_reg_depth = $kgm_reg_depth - 1
 4598     end
 4599 end
 4600 
 4601 define showregistryentryint
 4602     if !$kgm_reg_plane
 4603        set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
 4604     end
 4605 
 4606     if !$kgm_reg_plane
 4607        printf "Please load kgmacros after KDP attaching to the target.\n"
 4608     else        
 4609        set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
 4610        set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
 4611        showregistryentryrecurse _ $arg0 0 0
 4612     end
 4613 end
 4614 
 4615 define showregistry
 4616     set $kgm_reg_depth  = 0
 4617     set $kgm_show_props = 0
 4618     showregistryentryint gRegistryRoot
 4619 end
 4620 document showregistry
 4621 Syntax: (gdb) showregistry 
 4622 | Show info about all registry entries in the current plane. You can specify the maximum
 4623 | display depth with $kgm_reg_depth_max.
 4624 end
 4625 
 4626 define showregistryprops
 4627     set $kgm_reg_depth  = 0
 4628     set $kgm_show_props = 1
 4629     showregistryentryint gRegistryRoot
 4630 end
 4631 document showregistryprops
 4632 Syntax: (gdb) showregistryprops 
 4633 | Show info about all registry entries in the current plane, and their properties.
 4634 | set $kgm_show_object_addrs = 1 and/or set $kgm_show_object_retain = 1 will display
 4635 | more verbose information
 4636 end
 4637 
 4638 define showregistryentry
 4639     set $kgm_reg_depth  = 0
 4640     set $kgm_show_props = 1
 4641     showregistryentryint $arg0
 4642 end
 4643 document showregistryentry
 4644 Syntax: (gdb) showregistryentry <object address>
 4645 | Show info about a registry entry; its properties and descendants in the current plane.
 4646 end
 4647 
 4648 define setregistryplane
 4649     if ($arg0 != 0)
 4650         set $kgm_reg_plane = (IORegistryPlane *) $arg0
 4651     else
 4652         showobjectint _ gIORegistryPlanes
 4653         printf "\n"
 4654     end
 4655 end
 4656 document setregistryplane
 4657 Syntax: (gdb) setregistryplane <plane object address>
 4658 | Set the plane to be used for the iokit registry macros. An argument of zero will 
 4659 | display known planes.
 4660 end
 4661 
 4662 define guessclass
 4663     set $kgm_classidx = 0
 4664     set $kgm_lookvt = *((void **) $arg0)
 4665     set $kgm_bestvt = (void *) 0
 4666     set $kgm_bestidx = 0
 4667     
 4668     while $kgm_classidx < sAllClassesDict->count
 4669         set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx].value
 4670 
 4671         set $kgm_vt = *((void **) $kgm_meta)
 4672 
 4673         if (($kgm_vt > $kgm_bestvt) && ($kgm_vt < $kgm_lookvt))
 4674             set $kgm_bestvt  = $kgm_vt
 4675             set $kgm_bestidx = $kgm_classidx
 4676         end
 4677         set $kgm_classidx = $kgm_classidx + 1
 4678     end
 4679     printf "%s", sAllClassesDict->dictionary[$kgm_bestidx].key->string
 4680 end
 4681 
 4682 define showallclasses
 4683     set $kgm_classidx = 0
 4684     while $kgm_classidx < sAllClassesDict->count
 4685         set $kgm_meta = (OSMetaClass *) sAllClassesDict->dictionary[$kgm_classidx++].value
 4686         showmetaclass $kgm_meta
 4687     end
 4688 end
 4689 
 4690 document showallclasses
 4691 Syntax: (gdb) showallclasses
 4692 | Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
 4693 end
 4694 
 4695 define showioalloc
 4696     printf " Instance allocation = 0x%08lx = %4ld K\n", (int) debug_ivars_size, ((int) debug_ivars_size) / 1024
 4697     printf "Container allocation = 0x%08lx = %4ld K\n", (int) debug_container_malloc_size, ((int) debug_container_malloc_size) / 1024
 4698     printf " IOMalloc allocation = 0x%08lx = %4ld K\n", (int) debug_iomalloc_size, ((int) debug_iomalloc_size) / 1024
 4699     printf " Pageable allocation = 0x%08lx = %4ld K\n", (vm_size_t) debug_iomallocpageable_size, ((vm_size_t) debug_iomallocpageable_size) / 1024
 4700 end
 4701 
 4702 document showioalloc
 4703 Syntax: (gdb) showioalloc
 4704 | Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
 4705 end
 4706 
 4707 define showosobjecttracking
 4708     set $kgm_next = (OSObjectTracking *) gOSObjectTrackList.next
 4709     while $kgm_next != &gOSObjectTrackList
 4710         set $obj = (OSObject *) ($kgm_next+1)
 4711         showobject $obj
 4712         set $kgm_idx = 0
 4713         while $kgm_idx < (sizeof($kgm_next->bt) / sizeof($kgm_next->bt[0]))
 4714             if ((unsigned long) $kgm_next->bt[$kgm_idx] > (unsigned long) &last_kernel_symbol)
 4715                 showkmodaddr $kgm_next->bt[$kgm_idx]
 4716                 printf "\n"
 4717             else
 4718                 if ((unsigned long) $kgm_next->bt[$kgm_idx] > 0)
 4719                     output /a $kgm_next->bt[$kgm_idx]
 4720                     printf "\n"
 4721                 end
 4722             end
 4723             set $kgm_idx = $kgm_idx + 1
 4724         end
 4725         printf "\n"
 4726         set $kgm_next = (OSObjectTracking *) $kgm_next->link.next
 4727     end
 4728 end
 4729 
 4730 document showosobjecttracking
 4731 Syntax: (gdb) showosobjecttracking
 4732 | Show the list of tracked OSObject allocations with backtraces.
 4733 | Boot with the kOSTraceObjectAlloc (0x00400000) io debug flag set. 
 4734 | Set gOSObjectTrackThread to 1 or a thread_t to capture new OSObjects allocated by a thread or all threads.
 4735 end
 4736 
 4737 # $kgm_readphys_force_kdp and $kgm_readphys_force_physmap
 4738 # can respectively cause physical memory access to use
 4739 # a KDP manual packet or the physical memory mapping
 4740 # even if the default behavior would be otherwise.
 4741 define readphysint
 4742     set $kgm_readphysint_result = 0xBAD10AD
 4743 
 4744     if ($kgm_readphys_force_kdp != 0)
 4745         set $kgm_readphys_use_kdp = 1
 4746     else
 4747         if ($kgm_readphys_force_physmap)
 4748             set $kgm_readphys_use_kdp = 0
 4749         else
 4750             set $kgm_readphys_use_kdp = ( kdp->is_conn > 0 )
 4751         end
 4752     end
 4753 
 4754     if ($kgm_readphys_use_kdp)
 4755 
 4756         # set up the manual KDP packet
 4757         set manual_pkt.input = 0
 4758         set manual_pkt.len = sizeof(kdp_readphysmem64_req_t)
 4759         set $kgm_pkt = (kdp_readphysmem64_req_t *)&manual_pkt.data
 4760         set $kgm_pkt->hdr.request  = KDP_READPHYSMEM64
 4761         set $kgm_pkt->hdr.len      = sizeof(kdp_readphysmem64_req_t)
 4762         set $kgm_pkt->hdr.is_reply = 0
 4763         set $kgm_pkt->hdr.seq      = 0
 4764         set $kgm_pkt->hdr.key      = 0
 4765         set $kgm_pkt->address      = (uint64_t)$arg0
 4766         set $kgm_pkt->nbytes       = $arg1 >> 3
 4767         set $kgm_pkt->lcpu         = $arg2
 4768         set manual_pkt.input       = 1
 4769         # dummy to make sure manual packet is executed
 4770         set $kgm_dummy = &_mh_execute_header
 4771         set $kgm_pkt = (kdp_readphysmem64_reply_t *)&manual_pkt.data
 4772         if ($kgm_pkt->error == 0)
 4773             if $arg1 == 8
 4774                 set $kgm_readphysint_result = *((uint8_t *)$kgm_pkt->data)
 4775             end
 4776             if $arg1 == 16
 4777                 set $kgm_readphysint_result = *((uint16_t *)$kgm_pkt->data)
 4778             end
 4779             if $arg1 == 32
 4780                 set $kgm_readphysint_result = *((uint32_t *)$kgm_pkt->data)
 4781             end
 4782             if $arg1 == 64
 4783                 set $kgm_readphysint_result = *((uint64_t *)$kgm_pkt->data)
 4784             end
 4785         end
 4786 
 4787     else
 4788         # No KDP. Attempt to use physical memory mapping
 4789 
 4790         if ($kgm_mtype == $kgm_mtype_x86_64)
 4791             set $kgm_readphys_paddr_in_kva = (unsigned long long)$arg0 + physmap_base
 4792         else
 4793             if ($kgm_mtype == $kgm_mtype_arm)
 4794                 set $kgm_readphys_paddr_in_kva = (unsigned long long)$arg0 - gPhysBase + gVirtBase
 4795             else
 4796                 printf "readphys not available for current architecture.\n"
 4797                 set $kgm_readphys_paddr_in_kva = 0
 4798             end
 4799         end
 4800         if $kgm_readphys_paddr_in_kva
 4801             if $arg1 == 8
 4802                 set $kgm_readphysint_result = *((uint8_t *)$kgm_readphys_paddr_in_kva)
 4803             end
 4804             if $arg1 == 16
 4805                 set $kgm_readphysint_result = *((uint16_t *)$kgm_readphys_paddr_in_kva)
 4806             end
 4807             if $arg1 == 32
 4808                 set $kgm_readphysint_result = *((uint32_t *)$kgm_readphys_paddr_in_kva)
 4809             end
 4810             if $arg1 == 64
 4811                 set $kgm_readphysint_result = *((uint64_t *)$kgm_readphys_paddr_in_kva)
 4812             end
 4813         end
 4814     end
 4815 end
 4816 
 4817 define readphys8
 4818        readphysint $arg0 8 $kgm_lcpu_self
 4819        output /a $arg0
 4820        printf ":\t0x%02hhx\n", $kgm_readphysint_result
 4821        set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
 4822 end
 4823 
 4824 define readphys16
 4825        readphysint $arg0 16 $kgm_lcpu_self
 4826        output /a $arg0
 4827        printf ":\t0x%04hx\n", $kgm_readphysint_result
 4828        set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
 4829 end
 4830 
 4831 define readphys32
 4832        readphysint $arg0 32 $kgm_lcpu_self
 4833        output /a $arg0
 4834        printf ":\t0x%08x\n", $kgm_readphysint_result
 4835        set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
 4836 end
 4837 
 4838 define readphys64
 4839        readphysint $arg0 64 $kgm_lcpu_self
 4840        output /a $arg0
 4841        printf ":\t0x%016llx\n", $kgm_readphysint_result
 4842        set $kgm_readphys_result = (uint64_t)$kgm_readphysint_result
 4843 end
 4844 
 4845 define readphys
 4846        readphys32 $arg0
 4847 end
 4848 
 4849 document readphys8
 4850 | See readphys64
 4851 end
 4852 
 4853 document readphys16
 4854 | See readphys64
 4855 end
 4856 
 4857 document readphys32
 4858 | See readphys64
 4859 end
 4860 
 4861 document readphys64
 4862 | The argument is interpreted as a physical address, and the 64-bit word
 4863 | addressed is displayed. Saves 64-bit result in $kgm_readphys_result.
 4864 end
 4865 
 4866 define writephysint
 4867        # set up the manual KDP packet
 4868        set manual_pkt.input = 0
 4869        set manual_pkt.len = sizeof(kdp_writephysmem64_req_t)
 4870        set $kgm_pkt = (kdp_writephysmem64_req_t *)&manual_pkt.data
 4871        set $kgm_pkt->hdr.request  = KDP_WRITEPHYSMEM64
 4872        set $kgm_pkt->hdr.len      = sizeof(kdp_writephysmem64_req_t)
 4873        set $kgm_pkt->hdr.is_reply = 0
 4874        set $kgm_pkt->hdr.seq      = 0
 4875        set $kgm_pkt->hdr.key      = 0
 4876        set $kgm_pkt->address      = (uint64_t)$arg0
 4877        set $kgm_pkt->nbytes       = $arg1 >> 3
 4878        set $kgm_pkt->lcpu         = $arg3
 4879        if $arg1 == 8
 4880           set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
 4881        end
 4882        if $arg1 == 16
 4883           set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
 4884        end
 4885        if $arg1 == 32
 4886           set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
 4887        end
 4888        if $arg1 == 64
 4889           set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg2
 4890        end
 4891        set manual_pkt.input = 1
 4892        # dummy to make sure manual packet is executed
 4893        set $kgm_dummy = &_mh_execute_header
 4894        set $kgm_pkt = (kdp_writephysmem64_reply_t *)&manual_pkt.data
 4895        set $kgm_writephysint_result = $kgm_pkt->error
 4896 end
 4897 
 4898 define writephys8
 4899        writephysint $arg0 8 $arg1 $kgm_lcpu_self
 4900 end
 4901 
 4902 define writephys16
 4903        writephysint $arg0 16 $arg1 $kgm_lcpu_self
 4904 end
 4905 
 4906 define writephys32
 4907        writephysint $arg0 32 $arg1 $kgm_lcpu_self
 4908 end
 4909 
 4910 define writephys64
 4911        writephysint $arg0 64 $arg1 $kgm_lcpu_self
 4912 end
 4913 
 4914 document writephys8
 4915 | See writephys64
 4916 end
 4917 
 4918 document writephys16
 4919 | See writephys64
 4920 end
 4921 
 4922 document writephys32
 4923 | See writephys64
 4924 end
 4925 
 4926 document writephys64
 4927 | The argument is interpreted as a physical address, and the second argument is
 4928 | written to that address as a 64-bit word.
 4929 end
 4930 
 4931 define addkextsyms
 4932         if ($argc <= 1)
 4933                 if ($argc == 0)
 4934                         printf "Adding kext symbols from in-kernel summary data.\n"
 4935                         add-all-kexts
 4936                 else
 4937                         printf "Adding kext symbols from $arg0.\n"
 4938                         shell echo cd `pwd` > /tmp/gdb-cd
 4939                         cd $arg0
 4940                         source kcbmacros
 4941                         source /tmp/gdb-cd
 4942                 end
 4943                 set $kgm_show_kmod_syms = 1
 4944         else
 4945                 printf "| Usage:\n|\n"
 4946                 help addkextsyms
 4947         end
 4948 end
 4949 
 4950 document addkextsyms
 4951 | If specified without an argument, uses gdb's add-all-kexts command to load
 4952 | kext symbols. Otherwise, takes a directory of kext symbols generated with
 4953 | kextcache -y or kcgen and loads them into gdb.
 4954 | (gdb) addkextsyms
 4955 | - or -
 4956 | (gdb) addkextsyms /path/to/symboldir
 4957 end
 4958 
 4959 define showprocfiles
 4960     if ($argc == 1)
 4961         _showprocheader
 4962         _showprocfiles $arg0
 4963     else
 4964         printf "| Usage:\n|\n"
 4965         help showprocfiles
 4966     end
 4967 end
 4968 document showprocfiles
 4969 Syntax: (gdb) showprocfiles <proc_t>
 4970 | Given a proc_t pointer, display the list of open file descriptors for the
 4971 | referenced process.
 4972 end
 4973 
 4974 define _showprocheader
 4975     printf "fd     fileglob  "
 4976     showptrhdrpad
 4977     printf "  fg flags    fg type   fg data   "
 4978     showptrhdrpad
 4979     printf "  info\n"
 4980     printf "-----  ----------"
 4981     if $kgm_lp64
 4982         printf "--------"
 4983     end
 4984     printf "  ----------  --------  ----------"
 4985     if $kgm_lp64
 4986         printf "--------"
 4987     end
 4988     printf "  -------------------\n"
 4989 end
 4990 
 4991 define _showprocfiles
 4992     set $kgm_spf_filedesc = ((proc_t)$arg0)->p_fd
 4993     set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
 4994     set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
 4995     set $kgm_spf_count = 0
 4996     while ($kgm_spf_count <= $kgm_spf_last)
 4997         if ($kgm_spf_ofiles[$kgm_spf_count] == 0)
 4998             # DEBUG: For files that were open, but are now closed
 4999             # printf "%-5d  FILEPROC_NULL\n", $kgm_spf_count
 5000         else
 5001             # display fd #, fileglob address, fileglob flags
 5002             set $kgm_spf_flags = $kgm_spf_ofiles[$kgm_spf_count].f_flags
 5003             set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
 5004             printf "%-5d  ", $kgm_spf_count
 5005             showptr $kgm_spf_fg
 5006             printf "  0x%08x  ", $kgm_spf_flags
 5007             # decode fileglob type
 5008             set $kgm_spf_fgt = $kgm_spf_fg->fg_type
 5009             if ($kgm_spf_fgt == 1)
 5010                 printf "VNODE   "
 5011             end
 5012             if ($kgm_spf_fgt == 2)
 5013                 printf "SOCKET  "
 5014             end
 5015             if ($kgm_spf_fgt == 3)
 5016                 printf "PSXSHM  "
 5017             end
 5018             if ($kgm_spf_fgt == 4)
 5019                 printf "PSXSEM  "
 5020             end
 5021             if ($kgm_spf_fgt == 5)
 5022                 printf "KQUEUE  "
 5023             end
 5024             if ($kgm_spf_fgt == 6)
 5025                 printf "PIPE    "
 5026             end
 5027             if ($kgm_spf_fgt == 7)
 5028                 printf "FSEVENTS"
 5029             end
 5030             if ($kgm_spf_fgt < 1 || $kgm_spf_fgt > 7)
 5031                 printf "?: %-5d", $kgm_spf_fgt
 5032             end
 5033 
 5034             # display fileglob data address and decode interesting fact(s)
 5035             # about data, if we know any
 5036             set $kgm_spf_fgd = $kgm_spf_fg->fg_data
 5037             printf "  "
 5038             showptr $kgm_spf_fgd
 5039             printf "  "
 5040             if ($kgm_spf_fgt == 1)
 5041                 set $kgm_spf_name = ((struct vnode *)$kgm_spf_fgd)->v_name
 5042                 if ($kgm_spf_name == 0)
 5043                     printf "(null)"
 5044                 else
 5045                     printf "%s", $kgm_spf_name
 5046                 end
 5047             end
 5048             printf "\n"
 5049         end
 5050         set $kgm_spf_count = $kgm_spf_count + 1
 5051     end
 5052 end
 5053 
 5054 #
 5055 # Show all the advisory file locks held by a process for each of the vnode
 5056 # type files that it has open; do this by walking the per process open file
 5057 # table and looking at any vnode type fileglob that has a non-NULL lock list
 5058 # associated with it.
 5059 #
 5060 define showproclocks
 5061     if ($argc == 1)
 5062         _showproclocks $arg0
 5063     else
 5064         printf "| Usage:\n|\n"
 5065         help showproclocks
 5066     end
 5067 end
 5068 document showproclocks
 5069 Syntax: (gdb) showproclocks <proc_t>
 5070 | Given a proc_t pointer, display the list of advisory file locks held by the
 5071 | referenced process.
 5072 end
 5073 
 5074 define _showproclocks
 5075     set $kgm_spl_filedesc = ((proc_t)$arg0)->p_fd
 5076     set $kgm_spl_last = $kgm_spl_filedesc->fd_lastfile
 5077     set $kgm_spl_ofiles = $kgm_spl_filedesc->fd_ofiles
 5078     set $kgm_spl_count = 0
 5079     set $kgm_spl_seen = 0
 5080     while ($kgm_spl_count <= $kgm_spl_last)
 5081         if ($kgm_spl_ofiles[$kgm_spl_count] == 0)
 5082             # DEBUG: For files that were open, but are now closed
 5083             # printf "%-5d  FILEPROC_NULL\n", $kgm_spl_count
 5084         else
 5085             set $kgm_spl_fg = $kgm_spl_ofiles[$kgm_spl_count].f_fglob
 5086             # decode fileglob type
 5087             set $kgm_spl_fgt = $kgm_spl_fg->fg_type
 5088             if ($kgm_spl_fgt == 1)
 5089                 set $kgm_spl_fgd = $kgm_spl_fg->fg_data
 5090                 set $kgm_spl_name = ((struct vnode *)$kgm_spl_fgd)->v_name
 5091                 set $kgm_spl_vnode = ((vnode_t)$kgm_spl_fgd)
 5092                 set $kgm_spl_lockiter = $kgm_spl_vnode->v_lockf
 5093                 if ($kgm_spl_lockiter != 0)
 5094                     if ($kgm_spl_seen == 0)
 5095                         _showvnodelockheader
 5096                     end
 5097                     set $kgm_spl_seen = $kgm_spl_seen + 1
 5098                     printf "( fd %d, name ", $kgm_spl_count
 5099                     if ($kgm_spl_name == 0)
 5100                         printf "(null) )"
 5101                     else
 5102                         printf "%s )\n", $kgm_spl_name
 5103                     end
 5104                     _showvnodelocks $kgm_spl_fgd
 5105                 end
 5106             end
 5107         end
 5108         set $kgm_spl_count = $kgm_spf_count + 1
 5109     end
 5110     printf "%d total locks for ", $kgm_spl_seen
 5111     showptr $arg0
 5112     printf "\n"
 5113 end
 5114 
 5115 define showprocinfo
 5116     set $kgm_spi_proc = (proc_t)$arg0
 5117     printf "Process "
 5118     showptr $kgm_spi_proc
 5119     printf "\n"
 5120     printf "   name %s\n", $kgm_spi_proc->p_comm
 5121     printf "   pid:%.8d", $kgm_spi_proc->p_pid
 5122     printf "   task:"
 5123     showptr $kgm_spi_proc->task
 5124     printf "   p_stat:%.1d", $kgm_spi_proc->p_stat
 5125     printf "   parent pid:%.8d", $kgm_spi_proc->p_ppid
 5126     printf "\n"
 5127     # decode part of credential
 5128     set $kgm_spi_cred = $kgm_spi_proc->p_ucred
 5129     if ($kgm_spi_cred != 0)
 5130         printf "Cred: euid %d ruid %d svuid %d\n", $kgm_spi_cred->cr_posix.cr_uid, $kgm_spi_cred->cr_posix.cr_ruid, $kgm_spi_cred->cr_posix.cr_svuid
 5131     else
 5132         printf "Cred: (null)\n"
 5133     end
 5134     # decode flags
 5135     set $kgm_spi_flag = $kgm_spi_proc->p_flag
 5136     printf "Flags: 0x%08x\n", $kgm_spi_flag
 5137     if ($kgm_spi_flag & 0x00000001)
 5138         printf "    0x00000001 - may hold advisory locks\n"
 5139     end
 5140     if ($kgm_spi_flag & 0x00000002)
 5141         printf "    0x00000002 - has a controlling tty\n"
 5142     end
 5143     if ($kgm_spi_flag & 0x00000004)
 5144         printf "    0x00000004 - process is 64 bit\n"
 5145     else
 5146         printf "   !0x00000004 - process is 32 bit\n"
 5147     end
 5148     if ($kgm_spi_flag & 0x00000008)
 5149         printf "    0x00000008 - no SIGCHLD on child stop\n"
 5150     end
 5151     if ($kgm_spi_flag & 0x00000010)
 5152         printf "    0x00000010 - waiting for child exec/exit\n"
 5153     end
 5154     if ($kgm_spi_flag & 0x00000020)
 5155         printf "    0x00000020 - has started profiling\n"
 5156     end
 5157     if ($kgm_spi_flag & 0x00000040)
 5158         printf "    0x00000040 - in select; wakeup/waiting danger\n"
 5159     end
 5160     if ($kgm_spi_flag & 0x00000080)
 5161         printf "    0x00000080 - was stopped and continued\n"
 5162     end
 5163     if ($kgm_spi_flag & 0x00000100)
 5164         printf "    0x00000100 - has set privileges since exec\n"
 5165     end
 5166     if ($kgm_spi_flag & 0x00000200)
 5167         printf "    0x00000200 - system process: no signals, stats, or swap\n"
 5168     end
 5169     if ($kgm_spi_flag & 0x00000400)
 5170         printf "    0x00000400 - timing out during a sleep\n"
 5171     end
 5172     if ($kgm_spi_flag & 0x00000800)
 5173         printf "    0x00000800 - debugged process being traced\n"
 5174     end
 5175     if ($kgm_spi_flag & 0x00001000)
 5176         printf "    0x00001000 - debugging process has waited for child\n"
 5177     end
 5178     if ($kgm_spi_flag & 0x00002000)
 5179         printf "    0x00002000 - exit in progress\n"
 5180     end
 5181     if ($kgm_spi_flag & 0x00004000)
 5182         printf "    0x00004000 - process has called exec\n"
 5183     end
 5184     if ($kgm_spi_flag & 0x00008000)
 5185         printf "    0x00008000 - owe process an addupc() XXX\n"
 5186     end
 5187     if ($kgm_spi_flag & 0x00010000)
 5188         printf "    0x00010000 - affinity for Rosetta children\n"
 5189     end
 5190     if ($kgm_spi_flag & 0x00020000)
 5191         printf "    0x00020000 - wants to run Rosetta\n"
 5192     end
 5193     if ($kgm_spi_flag & 0x00040000)
 5194         printf "    0x00040000 - has wait() in progress\n"
 5195     end
 5196     if ($kgm_spi_flag & 0x00080000)
 5197         printf "    0x00080000 - kdebug tracing on for this process\n"
 5198     end
 5199     if ($kgm_spi_flag & 0x00100000)
 5200         printf "    0x00100000 - blocked due to SIGTTOU or SIGTTIN\n"
 5201     end
 5202     if ($kgm_spi_flag & 0x00200000)
 5203         printf "    0x00200000 - has called reboot()\n"
 5204     end
 5205     if ($kgm_spi_flag & 0x00400000)
 5206         printf "    0x00400000 - is TBE state\n"
 5207     end
 5208     if ($kgm_spi_flag & 0x00800000)
 5209         printf "    0x00800000 - signal exceptions\n"
 5210     end
 5211     if ($kgm_spi_flag & 0x01000000)
 5212         printf "    0x01000000 - has thread cwd\n"
 5213     end
 5214     if ($kgm_spi_flag & 0x02000000)
 5215         printf "    0x02000000 - has vfork() children\n"
 5216     end
 5217     if ($kgm_spi_flag & 0x04000000)
 5218         printf "    0x04000000 - not allowed to attach\n"
 5219     end
 5220     if ($kgm_spi_flag & 0x08000000)
 5221         printf "    0x08000000 - vfork() in progress\n"
 5222     end
 5223     if ($kgm_spi_flag & 0x10000000)
 5224         printf "    0x10000000 - no shared libraries\n"
 5225     end
 5226     if ($kgm_spi_flag & 0x20000000)
 5227         printf "    0x20000000 - force quota for root\n"
 5228     end
 5229     if ($kgm_spi_flag & 0x40000000)
 5230         printf "    0x40000000 - no zombies when children exit\n"
 5231     end
 5232     if ($kgm_spi_flag & 0x80000000)
 5233         printf "    0x80000000 - don't hang on remote FS ops\n"
 5234     end
 5235     # decode state
 5236     set $kgm_spi_state = $kgm_spi_proc->p_stat
 5237     printf "State: "
 5238     if ($kgm_spi_state == 1)
 5239         printf "Idle\n"
 5240     end
 5241     if ($kgm_spi_state == 2)
 5242         printf "Run\n"
 5243     end
 5244     if ($kgm_spi_state == 3)
 5245         printf "Sleep\n"
 5246     end
 5247     if ($kgm_spi_state == 4)
 5248         printf "Stop\n"
 5249     end
 5250     if ($kgm_spi_state == 5)
 5251         printf "Zombie\n"
 5252     end
 5253     if ($kgm_spi_state == 6)
 5254         printf "Reaping\n"
 5255     end
 5256     if ($kgm_spi_state < 1 || $kgm_spi_state > 6)
 5257         printf "(Unknown)\n"
 5258     end
 5259 end
 5260 
 5261 document showprocinfo
 5262 Syntax: (gdb) showprocinfo <proc_t>
 5263 | Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
 5264 end
 5265 
 5266 #
 5267 # dump the zombprocs 
 5268 #
 5269 define zombproc
 5270   set $basep = (struct proc  *)zombproc->lh_first
 5271   set $pp = $basep
 5272   while $pp
 5273         showprocinfo $pp
 5274       set $pp = $pp->p_list.le_next
 5275   end
 5276 end
 5277 
 5278 document zombproc
 5279 Syntax: (gdb) zombproc 
 5280 | Routine to print out all procs in the zombie list
 5281 end
 5282 
 5283 #
 5284 # dump the zombstacks 
 5285 #
 5286 define zombstacks
 5287   set $basep = (struct proc  *)zombproc->lh_first
 5288   set $pp = $basep
 5289   while $pp
 5290         if $pp->p_stat != 5
 5291                 showtaskstacks $pp->task
 5292         end
 5293      set $pp = $pp->p_list.le_next
 5294   end
 5295 end
 5296 
 5297 document zombstacks
 5298 Syntax: (gdb) zombstacks 
 5299 | Routine to print out all stacks of tasks that are exiting
 5300 end
 5301 
 5302 
 5303 #
 5304 # dump the allprocs
 5305 #
 5306 define allproc
 5307   set $basep = (struct proc  *)allproc->lh_first
 5308   set $pp = $basep
 5309   while $pp
 5310         showprocinfo $pp
 5311       set $pp = $pp->p_list.le_next
 5312   end
 5313 end
 5314 
 5315 document allproc
 5316 Syntax: (gdb) allproc 
 5317 | Routine to print out all process in the system 
 5318 | which are not in the zombie list
 5319 end
 5320 define showprocsiblingint
 5321     set $kgm_sibling_ptr = (struct proc *)$arg0
 5322     set $kgm_lx = $arg1 
 5323     while $kgm_lx
 5324         printf "|  " 
 5325         set $kgm_lx = $kgm_lx-3 
 5326     end   
 5327     printf "|--%d    %s    [ 0x%llx ]\n", $kgm_sibling_ptr->p_pid, $kgm_sibling_ptr->p_comm, $kgm_sibling_ptr
 5328 end
 5329 define showproctreeint
 5330 #Initialize all the set variables used in this macro
 5331     set $kgm_basep1 = 0
 5332     set $kgm_sibling_ptr = 0
 5333     set $kgm_lx = 0
 5334     set $kgm_tmp_base = 0
 5335     set $kgm_head_ptr = 0
 5336     set $kgm_search_pid = 0 
 5337     set $kgm_rev = 0
 5338     set $kgm_x = 0
 5339 
 5340     set $kgm_basep1 = (struct proc *)allproc->lh_first
 5341     if ($arg0 == 0)
 5342         set $kgm_head_ptr = (struct proc *)initproc
 5343     end       
 5344     if ($arg0 > 0)
 5345         set $kgm_tmp_base = (struct proc *)allproc->lh_first
 5346         set $kgm_search_pid = $arg0 
 5347         while $kgm_tmp_base
 5348             if ( $kgm_tmp_base->p_pid == $kgm_search_pid)
 5349                if ($kgm_tmp_base->p_childrencnt > 0)
 5350                     set $kgm_head_ptr = $kgm_tmp_base->p_children.lh_first
 5351                else
 5352                     set $kgm_head_ptr = 0
 5353                     printf "No children present for PID=%d", $kgm_search_pid
 5354                end
 5355                loop_break
 5356             end
 5357             set $kgm_tmp_base = $kgm_tmp_base->p_list.le_next
 5358         end
 5359     end
 5360     set $kgm_rev = 0
 5361     set $kgm_x = 0
 5362     if ($kgm_head_ptr)
 5363         printf "PID   PROCESS       POINTER]\n"
 5364         printf "===   =======       =======\n"
 5365         printf "%d    %s      [ 0x%llx ]\n", $kgm_head_ptr->p_ppid, $kgm_head_ptr->p_pptr->p_comm, $kgm_head_ptr
 5366         printf "|--%d    %s      [ 0x%llx ]\n", $kgm_head_ptr->p_pid, $kgm_head_ptr->p_comm, $kgm_head_ptr
 5367     end
 5368     while ($kgm_head_ptr)
 5369        #Is childrencnt = 0?       YES  {=> no children}
 5370         if ($kgm_head_ptr->p_childrencnt == 0)
 5371             # Does it have sibling? 
 5372             if($kgm_head_ptr->p_sibling.le_next == 0)
 5373                 #No, it does not have sibling, so go back to its parent which will go to its sibling
 5374                 if($kgm_head_ptr == $kgm_head_ptr->p_pptr)
 5375                     loop_break
 5376                 end
 5377                 set $kgm_head_ptr = $kgm_head_ptr->p_pptr
 5378                 if ($kgm_head_ptr == $kgm_tmp_base)
 5379                     loop_break
 5380                 end
 5381                 if ($kgm_x > 3)
 5382                     set $kgm_x = $kgm_x - 3
 5383                 end
 5384                 set $kgm_rev = 1
 5385             end
 5386             if($kgm_head_ptr->p_sibling.le_next != 0)
 5387                 # Yes, it has sibling. So print sibling
 5388                 set $kgm_rev = 0
 5389                 showprocsiblingint $kgm_head_ptr->p_sibling.le_next $kgm_x
 5390                 set $kgm_head_ptr = $kgm_head_ptr->p_sibling.le_next
 5391             end
 5392         # childrencnt != 0  {=> it has children}
 5393         else
 5394             if ($kgm_rev == 1)
 5395                 if($kgm_head_ptr->p_sibling.le_next == 0)
 5396                     #No, it does not have sibling, so go back to its parent which will go to its sibling
 5397                     if($kgm_head_ptr == $kgm_head_ptr->p_pptr)
 5398                         loop_break
 5399                     end
 5400                     set $kgm_head_ptr = $kgm_head_ptr->p_pptr
 5401                     if ($kgm_head_ptr == $kgm_tmp_base)
 5402                         loop_break
 5403                     end
 5404 
 5405                     if ($kgm_x > 3)
 5406                         set $kgm_x = $kgm_x - 3
 5407                     end
 5408                     set $kgm_rev = 1
 5409                 end
 5410                 if($kgm_head_ptr->p_sibling.le_next != 0)
 5411                     set $kgm_rev = 0
 5412                     # Yes, it has sibling. So print sibling
 5413                     showprocsiblingint $kgm_head_ptr->p_sibling.le_next $kgm_x
 5414                     set $kgm_head_ptr = $kgm_head_ptr->p_sibling.le_next
 5415                 end
 5416             else
 5417                 set $kgm_head_ptr = $kgm_head_ptr->p_children.lh_first
 5418                 set $kgm_x = $kgm_x + 3
 5419                 set $kgm_lx = $kgm_x
 5420                 while $kgm_lx
 5421                     printf "|  "
 5422                     set $kgm_lx = $kgm_lx-3
 5423                 end
 5424                 printf "|--%d    %s      [ 0x%llx ] \n", $kgm_head_ptr->p_pid, $kgm_head_ptr->p_comm, $kgm_head_ptr
 5425             end
 5426         end
 5427     end
 5428     printf "\n"
 5429 #Unset all the set variables used in this macro
 5430     set $kgm_basep1 = 0
 5431     set $kgm_sibling_ptr = 0
 5432     set $kgm_lx = 0
 5433     set $kgm_tmp_base = 0
 5434     set $kgm_head_ptr = 0
 5435     set $kgm_search_pid = 0
 5436     set $kgm_rev = 0
 5437     set $kgm_x = 0
 5438 end
 5439 define showproctree
 5440     if ($argc > 0)
 5441         showproctreeint $arg0
 5442     else
 5443         showproctreeint 0
 5444     end
 5445 end
 5446 document showproctree
 5447 Syntax: (gdb) showproctree <pid>
 5448 | Routine to print the processes in the system in a hierarchical tree form. This routine does not print zombie processes.
 5449 | If no argument is given, showproctree will print all the processes in the system.  
 5450 | If pid is specified, showproctree prints all the descendants of the indicated process
 5451 end
 5452 
 5453 
 5454 define print_vnode
 5455    set $vp = (struct vnode *)$arg0
 5456    printf "   "
 5457    printf " vp "
 5458    showptr $vp
 5459    printf " use %d", $vp->v_usecount
 5460    printf " io %d", $vp->v_iocount
 5461    printf " kuse %d", $vp->v_kusecount
 5462    printf " type %d", $vp->v_type
 5463    printf " flg 0x%.8x", $vp->v_flag
 5464    printf " lflg 0x%.8x", $vp->v_lflag
 5465    printf " par "
 5466    showptr $vp->v_parent
 5467    set $_name = (char *)$vp->v_name
 5468    if ($_name != 0)
 5469       printf " %s", $_name
 5470    end
 5471   if ($vp->v_type == VREG) && ($vp->v_un.vu_ubcinfo != 0)
 5472        printf " mapped %d", ($vp->v_un.vu_ubcinfo.ui_flags & 0x08) ? 1 : 0
 5473    end
 5474    printf "\n"
 5475 end
 5476 
 5477 document print_vnode
 5478 Syntax: (gdb) print_vnode <vnode>
 5479 | Prints out the fields of a vnode struct
 5480 end
 5481 
 5482 define showprocvnodes
 5483         set $pp = (struct proc *)$arg0
 5484         set $fdp = (struct filedesc *)$pp->p_fd
 5485         set $cvp = $fdp->fd_cdir
 5486         set $rvp = $fdp->fd_rdir
 5487         if $cvp
 5488                 printf "Current Working Directory \n"
 5489                 print_vnode $cvp
 5490                 printf "\n"
 5491         end
 5492         if $rvp
 5493                 printf "Current Root Directory \n"
 5494                 print_vnode $rvp
 5495                 printf "\n"
 5496         end
 5497         set $count = 0
 5498         set $fpp =  (struct fileproc **)($fdp->fd_ofiles)
 5499         set $fpo =  (char)($fdp->fd_ofileflags[0])
 5500         while $count < $fdp->fd_nfiles
 5501                 #printf"fpp %x ", *$fpp
 5502                 if *$fpp
 5503                         set $fg =(struct fileglob *)((**$fpp)->f_fglob)
 5504                         if  $fg && (($fg)->fg_type == 1) 
 5505                                 if $fdp->fd_ofileflags[$count] & 4
 5506                                         printf "U: "
 5507                                 else
 5508                                         printf " "
 5509                                 end
 5510                                 printf "fd = %d ", $count
 5511                                 print_vnode $fg->fg_data
 5512                         end
 5513                 end
 5514                 set $fpp = $fpp + 1
 5515                 set $count = $count + 1         
 5516         end
 5517 end
 5518 
 5519 document showprocvnodes
 5520 Syntax: (gdb) showprocvnodes <proc_address>
 5521 | Routine to print out all the open fds
 5522 | which are vnodes in a process
 5523 end
 5524 
 5525 define showallprocvnodes
 5526   set $basep = (struct proc  *)allproc->lh_first
 5527   set $pp = $basep
 5528   while $pp
 5529         printf "============================================ \n"
 5530         showprocinfo $pp
 5531         showprocvnodes $pp
 5532         set $pp = $pp->p_list.le_next
 5533   end
 5534 end
 5535 
 5536 document showallprocvnodes
 5537 Syntax: (gdb) showallprocvnodes
 5538 | Routine to print out all the open fds
 5539 | which are vnodes 
 5540 end
 5541 
 5542 
 5543 #   
 5544 # dump the childrent of a proc 
 5545 #
 5546 define showinitchild
 5547   set $basep = (struct proc  *)initproc->p_children.lh_first
 5548   set $pp = $basep
 5549   while $pp
 5550         showprocinfo $pp
 5551       set $pp = $pp->p_sibling.le_next
 5552   end
 5553 end
 5554 
 5555 document showinitchild
 5556 Syntax: (gdb) showinitchild 
 5557 | Routine to print out all processes in the system 
 5558 | which are children of init process
 5559 end
 5560 
 5561 
 5562 define showmountallvnodes
 5563   set $mp = (struct mount *)$arg0
 5564   set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
 5565   set $vp = $basevp
 5566   printf "____________________ Vnode list Queue ---------------\n"
 5567   while $vp
 5568       print_vnode $vp
 5569       set $vp = $vp->v_mntvnodes->tqe_next
 5570   end
 5571   set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
 5572   set $vp = $basevp
 5573   printf "____________________ Worker Queue ---------------\n"
 5574   while $vp
 5575       print_vnode $vp
 5576       set $vp = $vp->v_mntvnodes->tqe_next
 5577   end
 5578   set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
 5579   set $vp = $basevp
 5580   printf "____________________ New vnodes  Queue ---------------\n"
 5581   while $vp
 5582       print_vnode $vp
 5583       set $vp = $vp->v_mntvnodes->tqe_next
 5584   end
 5585 end
 5586 document showmountallvnodes
 5587 Syntax: showmountallvnodes <struct mount *>
 5588 | Print the vnode inactive list
 5589 end
 5590 
 5591 
 5592 define showmountvnodes
 5593   set $mp = (struct mount *)$arg0
 5594   set $basevp = (struct vnode *)$mp->mnt_vnodelist.tqh_first
 5595   set $vp = $basevp
 5596   printf "____________________ Vnode list Queue ---------------\n"
 5597   while $vp
 5598       print_vnode $vp
 5599       set $vp = $vp->v_mntvnodes->tqe_next
 5600   end
 5601 end
 5602 document showmountvnodes
 5603 Syntax: showmountvnodes <struct mount *>
 5604 | Print the vnode list
 5605 end
 5606 
 5607 
 5608 
 5609 define showworkqvnodes
 5610   set $mp = (struct mount *)$arg0
 5611   set $basevp = (struct vnode *)$mp->mnt_workerqueue.tqh_first
 5612   set $vp = $basevp
 5613   printf "____________________ Worker Queue ---------------\n"
 5614   while $vp
 5615       print_vnode $vp
 5616       set $vp = $vp->v_mntvnodes->tqe_next
 5617   end
 5618 end
 5619 document showworkqvnodes
 5620 Syntax: showworkqvnodes <struct mount *>
 5621 | Print the vnode worker list
 5622 end
 5623 
 5624 
 5625 define shownewvnodes
 5626   set $mp = (struct mount *)$arg0
 5627   set $basevp = (struct vnode *)$mp->mnt_newvnodes.tqh_first
 5628   set $vp = $basevp
 5629   printf "____________________ New vnodes  Queue ---------------\n"
 5630   while $vp
 5631       print_vnode $vp
 5632       set $vp = $vp->v_mntvnodes->tqe_next
 5633   end
 5634 end
 5635 
 5636 document shownewvnodes
 5637 Syntax: shownewvnodes <struct mount *>
 5638 | Print the new vnode list
 5639 end
 5640 
 5641 
 5642 #
 5643 # print mount point info
 5644 define print_mount 
 5645    set $mp = (struct mount *)$arg0
 5646    printf "   "
 5647    printf " mp "
 5648    showptr $mp
 5649    printf " flag %x", $mp->mnt_flag
 5650    printf " kern_flag %x", $mp->mnt_kern_flag
 5651    printf " lflag %x", $mp->mnt_lflag
 5652    printf " type:  %s", $mp->mnt_vfsstat.f_fstypename
 5653    printf " mnton:  %s", $mp->mnt_vfsstat.f_mntonname
 5654    printf " mntfrom:  %s", $mp->mnt_vfsstat.f_mntfromname
 5655    printf "\n"
 5656 end
 5657 
 5658 define showallmounts
 5659         set $mp=(struct mount *)mountlist.tqh_first
 5660         while $mp
 5661                 print_mount $mp
 5662                 set $mp = $mp->mnt_list.tqe_next
 5663         end
 5664 end
 5665         
 5666 document showallmounts
 5667 Syntax: showallmounts
 5668 | Print all mount points
 5669 end
 5670 
 5671 define pcprint
 5672         if (((unsigned long) $arg0 < (unsigned long) &_mh_execute_header || \
 5673              (unsigned long) $arg0 >= (unsigned long) &last_kernel_symbol ))
 5674                 showkmodaddr $arg0
 5675         else
 5676                 output /a $arg0
 5677         end
 5678 end
 5679 
 5680 define mbuf_walkpkt
 5681         set $mp = (struct mbuf *)$arg0
 5682         set $cnt = 1
 5683         set $tot = 0
 5684         while $mp
 5685                 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
 5686                     $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
 5687                 if mclaudit != 0
 5688                         mbuf_buf2mca $mp
 5689                         printf ", "
 5690                 end
 5691                 set $tot = $tot + $mp->m_hdr.mh_len
 5692                 printf "total %d]\n", $tot
 5693                 set $mp = $mp->m_hdr.mh_nextpkt
 5694                 set $cnt = $cnt + 1
 5695         end
 5696 end
 5697 
 5698 document mbuf_walkpkt
 5699 Syntax: (gdb) mbuf_walkpkt <addr>
 5700 | Given an mbuf address, walk its m_nextpkt pointer
 5701 end
 5702 
 5703 define mbuf_walk
 5704         set $mp = (struct mbuf *)$arg0
 5705         set $cnt = 1
 5706         set $tot = 0
 5707         while $mp
 5708                 printf "%4d: %p [len %4d, type %2d, ", $cnt, $mp, \
 5709                     $mp->m_hdr.mh_len, $mp->m_hdr.mh_type
 5710                 if mclaudit != 0
 5711                         mbuf_buf2mca $mp
 5712                         printf ", "
 5713                 end
 5714                 set $tot = $tot + $mp->m_hdr.mh_len
 5715                 printf "total %d]\n", $tot
 5716                 set $mp = $mp->m_hdr.mh_next
 5717                 set $cnt = $cnt + 1
 5718         end
 5719 end
 5720 
 5721 document mbuf_walk
 5722 Syntax: (gdb) mbuf_walk <addr>
 5723 | Given an mbuf address, walk its m_next pointer
 5724 end
 5725 
 5726 define mbuf_buf2slab
 5727         set $addr = $arg0
 5728         set $gix = ((char *)$addr - (char *)mbutl) >> 20
 5729         set $ix = ((char *)$addr - (char *)slabstbl[$gix].slg_slab[0].sl_base) >> 12
 5730         set $slab = &slabstbl[$gix].slg_slab[$ix]
 5731         if $kgm_lp64
 5732                 printf "0x%-16llx", $slab
 5733         else
 5734                 printf "0x%-8x", $slab
 5735         end
 5736 end
 5737 
 5738 document mbuf_buf2slab
 5739 | Given an mbuf object, find its corresponding slab address.
 5740 end
 5741 
 5742 define mbuf_buf2mca
 5743         set $addr = $arg0
 5744         set $ix = ((char *)$addr - (char *)mbutl) >> 12
 5745         set $clbase = ((union mbigcluster *)mbutl) + $ix
 5746         set $mclidx = (((char *)$addr - (char *)$clbase) >> 8)
 5747         set $mca = mclaudit[$ix].cl_audit[$mclidx]
 5748         if $kgm_lp64
 5749                 printf "mca: 0x%-16llx", $mca
 5750         else
 5751                 printf "mca: 0x%-8x", $mca
 5752         end
 5753 end
 5754 
 5755 document mbuf_buf2mca
 5756 Syntax: (gdb) mbuf_buf2mca <addr>
 5757 | Given an mbuf object, find its buffer audit structure address.
 5758 | This requires mbuf buffer auditing to be turned on, by setting
 5759 | the appropriate flags to the "mbuf_debug" boot-args parameter.
 5760 end
 5761 
 5762 define mbuf_showmca
 5763         set language c
 5764         set $mca = (mcache_audit_t *)$arg0
 5765         set $cp = (mcache_t *)$mca->mca_cache
 5766         printf "object type:\t\t"
 5767         mbuf_mca_ctype $mca 1
 5768         printf "\ncontrolling mcache:\t%p (%s)\n", $mca->mca_cache, $cp->mc_name
 5769         if $mca->mca_uflags & $MB_SCVALID
 5770                 set $ix = ((char *)$mca->mca_addr - (char *)mbutl) >> 12
 5771                 set $clbase = ((union mbigcluster *)mbutl) + $ix
 5772                 set $mclidx = (((char *)$mca->mca_addr - (char *)$clbase) >> 8)
 5773                 printf "mbuf obj:\t\t%p\n", $mca->mca_addr
 5774                 printf "mbuf index:\t\t%d (out of 16) in cluster base %p\n", \
 5775                     $mclidx + 1, $clbase
 5776                 if $mca->mca_uptr != 0
 5777                         set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
 5778                         printf "paired cluster obj:\t%p (mca %p)\n", \
 5779                             $peer_mca->mca_addr, $peer_mca
 5780                 end
 5781                 printf "saved contents:\t\t%p (%d bytes)\n", \
 5782                     $mca->mca_contents, $mca->mca_contents_size
 5783         else
 5784                 printf "cluster obj:\t\t%p\n", $mca->mca_addr
 5785                 if $mca->mca_uptr != 0
 5786                         set $peer_mca = (mcache_audit_t *)$mca->mca_uptr
 5787                         printf "paired mbuf obj:\t%p (mca %p)\n", \
 5788                             $peer_mca->mca_addr, $peer_mca
 5789                 end
 5790         end
 5791         printf "recent transaction for this buffer (thread %p):\n", \
 5792             $mca->mca_thread
 5793         set $cnt = 0
 5794         while $cnt < $mca->mca_depth
 5795                 set $kgm_pc = $mca->mca_stack[$cnt]
 5796                 printf "%4d: ", $cnt + 1
 5797                 pcprint $kgm_pc
 5798                 printf "\n"
 5799                 set $cnt = $cnt + 1
 5800         end
 5801         if $mca->mca_pdepth > 0
 5802                 printf "previous transaction for this buffer (thread %p):\n", \
 5803                     $mca->mca_pthread
 5804         end
 5805         set $cnt = 0
 5806         while $cnt < $mca->mca_pdepth
 5807                 set $kgm_pc = $mca->mca_pstack[$cnt]
 5808                 printf "%4d: ", $cnt + 1
 5809                 pcprint $kgm_pc
 5810                 printf "\n"
 5811                 set $cnt = $cnt + 1
 5812         end
 5813         set language auto
 5814 end
 5815 
 5816 document mbuf_showmca
 5817 Syntax: (gdb) mbuf_showmca <addr>
 5818 | Given an mbuf/cluster buffer audit structure address, print the audit
 5819 | records including the stack trace of the last buffer transaction.
 5820 end
 5821 
 5822 define mbuf_topleak
 5823         set language c
 5824         set $topcnt = 0
 5825         if $arg0 < 5
 5826                 set $maxcnt = $arg0
 5827         else
 5828                 set $maxcnt = 5
 5829         end
 5830         while $topcnt < $maxcnt
 5831                 mbuf_traceleak mleak_top_trace[$topcnt]
 5832                 set $topcnt = $topcnt + 1
 5833         end
 5834         set language auto
 5835 end
 5836 
 5837 document mbuf_topleak
 5838 Syntax: (gdb) mbuf_topleak <num>
 5839 | Prints information about the top <num> suspected mbuf leakers
 5840 | where <num> is a value <= 5
 5841 end
 5842 
 5843 define mbuf_traceleak
 5844         set language c
 5845         set $trace = (struct mtrace *) $arg0
 5846         if $trace->allocs != 0
 5847                 printf "%p:%d outstanding allocs\n", $trace, $trace->allocs
 5848                 printf "backtrace saved %d deep:\n", $trace->depth
 5849                 if $trace->depth != 0
 5850                         set $cnt = 0
 5851                         while $cnt < $trace->depth
 5852                                 printf "%4d: ", $cnt + 1
 5853                                 pcprint $trace->addr[$cnt]
 5854                                 printf "\n"
 5855                                 set $cnt = $cnt + 1
 5856                         end
 5857                 end
 5858         end
 5859         set language auto
 5860 end
 5861 
 5862 document mbuf_traceleak
 5863 Syntax: (gdb) mbuf_traceleak <addr>
 5864 | Given an mbuf leak trace (mtrace) structure address, print out the
 5865 | stored information with that trace
 5866 end
 5867 
 5868 set $MCF_NOCPUCACHE = 0x10
 5869 
 5870 define mcache_stat
 5871         set $head = (mcache_t *)mcache_head
 5872         set $mc = $head
 5873 
 5874     if $kgm_lp64
 5875                 printf "cache                        cache              cache    buf   buf            backing             (# of retries)     bufs\n"
 5876                 printf "name                         state               addr   size align               zone     wait   nowait   failed  incache\n"
 5877                 printf "------------------------- -------- ------------------ ------ ----- ------------------ -------------------------- --------\n"
 5878         else
 5879                 printf "cache                        cache      cache    buf   buf    backing             (# of retries)     bufs\n"
 5880                 printf "name                         state       addr   size align       zone     wait   nowait   failed  incache\n"
 5881                 printf "------------------------- -------- ---------- ------ ----- ---------- -------------------------- --------\n"
 5882         end
 5883         while $mc != 0
 5884                 set $bktsize = $mc->mc_cpu.cc_bktsize
 5885                 printf "%-25s ", $mc->mc_name
 5886                 if ($mc->mc_flags & $MCF_NOCPUCACHE)
 5887                         printf "disabled"
 5888                 else
 5889                         if $mc->mc_purge_cnt > 0
 5890                                 printf " purging"
 5891                         else
 5892                                 if $bktsize == 0
 5893                                         printf " offline"
 5894                                 else
 5895                                         printf "  online"
 5896                                 end
 5897                         end
 5898                 end
 5899                 printf " %p %6d %5d ",$mc, \
 5900                     $mc->mc_bufsize, $mc->mc_align
 5901                 if $mc->mc_slab_zone != 0
 5902                         printf "%p", $mc->mc_slab_zone
 5903                 else
 5904                     if $kgm_lp64
 5905                                 printf "            custom"
 5906                         else
 5907                                 printf "    custom"
 5908                         end
 5909                 end
 5910                 set $tot = 0
 5911                 set $tot += $mc->mc_full.bl_total * $bktsize
 5912                 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
 5913                 set $n = 0
 5914                 while $n < ncpu
 5915                         if $ccp->cc_objs > 0
 5916                                 set $tot += $ccp->cc_objs
 5917                         end
 5918                         if $ccp->cc_pobjs > 0
 5919                                 set $tot += $ccp->cc_pobjs
 5920                         end
 5921                         set $n += 1
 5922                         set $ccp += 1
 5923                 end
 5924                 printf " %8d %8d %8d %8d", $mc->mc_wretry_cnt, \
 5925                     $mc->mc_nwretry_cnt, $mc->mc_nwfail_cnt, $tot
 5926                 printf "\n"
 5927                 set $mc = (mcache_t *)$mc->mc_list.le_next
 5928         end
 5929 end
 5930 
 5931 document mcache_stat
 5932 Syntax: (gdb) mcache_stat
 5933 | Print all mcaches in the system.
 5934 end
 5935 
 5936 define mcache_showzone
 5937         set $mc = (mcache_t *)$arg0
 5938         if $mc->mc_slab_zone != 0
 5939                 printf "%p", $mc->mc_slab_zone
 5940         else
 5941                 printf "   custom"
 5942 end
 5943 
 5944 document mcache_showzone
 5945 Syntax: (gdb) mcache_showzone <mcache_addr>
 5946 | Print the type of backend (custom or zone) of a mcache.
 5947 end
 5948 
 5949 define mcache_walkobj
 5950         set $p = (mcache_obj_t *)$arg0
 5951         set $cnt = 1
 5952         set $tot = 0
 5953         while $p
 5954                 printf "%4d: %p\n", $cnt, $p,
 5955                 set $p = $p->obj_next
 5956                 set $cnt = $cnt + 1
 5957         end
 5958 end
 5959 
 5960 document mcache_walkobj
 5961 Syntax: (gdb) mcache_walkobj <addr>
 5962 | Given a mcache object address, walk its obj_next pointer
 5963 end
 5964 
 5965 define mcache_showcache
 5966         set $cp = (mcache_t *)$arg0
 5967         set $ccp = (mcache_cpu_t *)$cp->mc_cpu
 5968         set $bktsize = $cp->mc_cpu.cc_bktsize
 5969         set $cnt = 0
 5970         set $tot = 0
 5971         printf "Showing cache '%s':\n\n", $cp->mc_name
 5972         printf " CPU  cc_objs cc_pobjs    total\n"
 5973         printf "---- -------- -------- --------\n"
 5974         while $cnt < ncpu
 5975                 set $objs = $ccp->cc_objs
 5976                 if $objs <= 0
 5977                         set $objs = 0
 5978                 end
 5979                 set $pobjs = $ccp->cc_pobjs
 5980                 if $pobjs <= 0
 5981                         set $pobjs = 0
 5982                 end
 5983                 set $tot_cpu = $objs + $pobjs
 5984                 set $tot += $tot_cpu
 5985                 printf "%4d %8d %8d %8d\n", $cnt, $objs, $pobjs, $tot_cpu
 5986                 set $ccp += 1
 5987                 set $cnt += 1
 5988         end
 5989         printf "                       ========\n"
 5990         printf "                       %8d\n", $tot
 5991         printf "\n"
 5992         set $tot += $cp->mc_full.bl_total * $bktsize
 5993         printf "Total # of full buckets (%d objs/bkt):\t%-8d\n", \
 5994             $bktsize, $cp->mc_full.bl_total
 5995         printf "Total # of objects cached:\t\t%-8d\n", $tot
 5996 end
 5997 
 5998 document mcache_showcache
 5999 | Display the number of objects in the cache
 6000 end
 6001 
 6002 set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
 6003 
 6004 define mbuf_slabstbl
 6005         set $x = 0
 6006 
 6007         if $kgm_lp64
 6008                 printf "slot slabg              slabs range\n"
 6009                 printf "---- ------------------ -------------------------------------------\n"
 6010         else
 6011                 printf "slot slabg      slabs range\n"
 6012                 printf "---- ---------- ---------------------------\n"
 6013         end
 6014         while $x < maxslabgrp
 6015                 set $slg = slabstbl[$x]
 6016                 printf "%3d: ", $x
 6017                 if $slg == 0
 6018                         printf "-\n"
 6019                 else
 6020                         if $kgm_lp64
 6021                                 printf "0x%-16llx [ 0x%-16llx - 0x%-16llx ]\n", $slg, &$slg->slg_slab[0], \
 6022                                     &$slg->slg_slab[$NSLABSPMB-1]
 6023                         else
 6024                                 printf "0x%-8x [ 0x%-8x - 0x%-8x ]\n", $slg, &$slg->slg_slab[0], \
 6025                                     &$slg->slg_slab[$NSLABSPMB-1]
 6026                         end
 6027                 end
 6028                 set $x += 1
 6029         end
 6030 end
 6031 
 6032 document mbuf_slabstbl
 6033 | Display the mbuf slabs table
 6034 end
 6035 
 6036 set $SLF_MAPPED=0x0001
 6037 set $SLF_PARTIAL=0x0002
 6038 set $SLF_DETACHED=0x0004
 6039 
 6040 define mbuf_slabs
 6041         set $slg = (mcl_slabg_t *)$arg0
 6042         set $x = 0
 6043 
 6044         if $kgm_lp64
 6045                 printf "slot slab               next               obj                mca                 C  R  N   size flags\n"
 6046                 printf "---- ------------------ ------------------ ------------------ ------------------ -- -- -- ------ -----\n"
 6047         else
 6048                 printf "slot slab       next       obj        mca         C  R  N   size flags\n"
 6049                 printf "---- ---------- ---------- ---------- ---------- -- -- -- ------ -----\n"
 6050         end
 6051         while $x < $NSLABSPMB
 6052                 set $sl = &$slg->slg_slab[$x]
 6053                 set $mca = 0
 6054                 set $obj = $sl->sl_base
 6055 
 6056                 if mclaudit != 0
 6057                         set $ix = ((char *)$obj - (char *)mbutl) >> 12
 6058                         set $clbase = ((union mbigcluster *)mbutl) + $ix
 6059                         set $mclidx = (((char *)$obj - (char *)$clbase) >> 8)
 6060                         set $mca = mclaudit[$ix].cl_audit[$mclidx]
 6061                 end
 6062 
 6063                 if $kgm_lp64
 6064                         printf "%3d: 0x%-16llx 0x%-16llx 0x%-16llx 0x%-16llx %2d %2d %2d %6d 0x%04x ", \
 6065                             $x + 1, $sl, $sl->sl_next, $obj, $mca, $sl->sl_class, \
 6066                             $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
 6067                             $sl->sl_flags
 6068                 else
 6069                         printf "%3d: 0x%-8x 0x%-8x 0x%-8x 0x%-8x %2d %2d %2d %6d 0x%04x ", \
 6070                             $x + 1, $sl, $sl->sl_next, $obj, $mca, $sl->sl_class, \
 6071                             $sl->sl_refcnt, $sl->sl_chunks, $sl->sl_len, \
 6072                             $sl->sl_flags
 6073                 end
 6074                 if $sl->sl_flags != 0
 6075                         printf "<"
 6076                         if $sl->sl_flags & $SLF_MAPPED
 6077                                 printf "mapped"
 6078                         end
 6079                         if $sl->sl_flags & $SLF_PARTIAL
 6080                                 printf ",partial"
 6081                         end
 6082                         if $sl->sl_flags & $SLF_DETACHED
 6083                                 printf ",detached"
 6084                         end
 6085                         printf ">"
 6086                 end
 6087                 printf "\n"
 6088 
 6089                 if $sl->sl_chunks > 1
 6090                         set $z = 1
 6091                         set $c = $sl->sl_len / $sl->sl_chunks
 6092 
 6093                         while $z < $sl->sl_chunks
 6094                                 set $obj = $sl->sl_base + ($c * $z)
 6095                                 set $mca = 0
 6096 
 6097                                 if mclaudit != 0
 6098                                         set $ix = ((char *)$obj - (char *)mbutl) >> 12
 6099                                         set $clbase = ((union mbigcluster *)mbutl) + $ix
 6100                                         set $mclidx = (((char *)$obj - (char *)$clbase) >> 8)
 6101                                         set $mca = mclaudit[$ix].cl_audit[$mclidx]
 6102                                 end
 6103 
 6104                                 if $kgm_lp64
 6105                                         printf "                                           0x%-16llx 0x%-16llx\n", $obj, $mca
 6106                                 else
 6107                                         printf "                           0x%-8x 0x%-8x\n", $obj, $mca
 6108                                 end
 6109                                 set $z += 1
 6110                         end
 6111                 end
 6112 
 6113                 set $x += 1
 6114         end
 6115 end
 6116 
 6117 document mbuf_slabs
 6118 | Display all mbuf slabs in the group
 6119 end
 6120 
 6121 define mbuf_stat
 6122         set $x = 0
 6123 
 6124         printf "class               total   cached     uncached           inuse           failed   waiter notified    purge\n"
 6125         printf "name                 objs     objs     objs / slabs        objs      alloc count    count    count    count\n"
 6126         printf "---------------- -------- -------- ------------------- -------- ---------------- -------- -------- --------\n"
 6127         while $x < (sizeof(mbuf_table) / sizeof(mbuf_table[0]))
 6128                 set $mbt = mbuf_table[$x]
 6129                 set $mcs = (mb_class_stat_t *)mbuf_table[$x].mtbl_stats
 6130                 set $tot = 0
 6131                 set $mc = $mbt->mtbl_cache
 6132                 set $bktsize = $mc->mc_cpu.cc_bktsize
 6133                 set $tot += $mc->mc_full.bl_total * $bktsize
 6134                 set $ccp = (mcache_cpu_t *)$mc->mc_cpu
 6135                 set $n = 0
 6136                 while $n < ncpu
 6137                         if $ccp->cc_objs > 0
 6138                                 set $tot += $ccp->cc_objs
 6139                         end
 6140                         if $ccp->cc_pobjs > 0
 6141                                 set $tot += $ccp->cc_pobjs
 6142                         end
 6143                         set $n += 1
 6144                         set $ccp += 1
 6145                 end
 6146 
 6147                 printf "%-16s %8d %8d %8d / %-8d %8d %16llu %8d %8llu %8llu", \
 6148                     $mcs->mbcl_cname, $mcs->mbcl_total, $tot, \
 6149                     $mcs->mbcl_infree, $mcs->mbcl_slab_cnt, \
 6150                     ($mcs->mbcl_total - $tot - $mcs->mbcl_infree), \
 6151                     $mcs->mbcl_fail_cnt, $mc->mc_waiter_cnt, \
 6152                     $mcs->mbcl_notified, $mcs->mbcl_purge_cnt
 6153                 printf "\n"
 6154                 set $x += 1
 6155         end
 6156 end
 6157 
 6158 document mbuf_stat
 6159 | Print extended mbuf allocator statistics.
 6160 end
 6161 
 6162 set $MB_INUSE = 0x1
 6163 set $MB_COMP_INUSE = 0x2
 6164 set $MB_SCVALID = 0x4
 6165 
 6166 set $MCLBYTES = 2048
 6167 set $MSIZE = 256
 6168 set $NBPG = 4096
 6169 set $M16KCLBYTES = 16384
 6170 
 6171 define mbuf_mca_ctype
 6172         set $mca = (mcache_audit_t *)$arg0
 6173         set $vopt = $arg1
 6174         set $cp = $mca->mca_cache
 6175         set $class = (unsigned int)$cp->mc_private
 6176         set $csize = mbuf_table[$class].mtbl_stats->mbcl_size
 6177         set $done = 0
 6178         if $csize == $MSIZE
 6179                 if $vopt
 6180                         printf "M (mbuf) "
 6181                 else
 6182                         printf "M     "
 6183                 end
 6184                 set $done = 1
 6185         end
 6186         if !$done && $csize == $MCLBYTES
 6187                 if $vopt
 6188                         printf "CL (2K cluster) "
 6189                 else
 6190                         printf "CL    "
 6191                 end
 6192                 set $done = 1
 6193         end
 6194         if !$done && $csize == $NBPG
 6195                 if $vopt
 6196                         printf "BCL (4K cluster) "
 6197                 else
 6198                         printf "BCL   "
 6199                 end
 6200                 set $done = 1
 6201         end
 6202         if !$done && $csize == $M16KCLBYTES
 6203                 if $vopt
 6204                         printf "JCL (16K cluster) "
 6205                 else
 6206                         printf "JCL   "
 6207                 end
 6208                 set $done = 1
 6209         end
 6210         if !$done && $csize == ($MSIZE+$MCLBYTES)
 6211                 if $mca->mca_uflags & $MB_SCVALID
 6212                         if $mca->mca_uptr
 6213                                 printf "M+CL  "
 6214                                 if $vopt
 6215                                         printf "(paired mbuf, 2K cluster)"
 6216                                 end
 6217                         else
 6218                                 printf "M-CL  "
 6219                                 if $vopt
 6220                                         printf "(unpaired mbuf, 2K cluster) "
 6221                                 end
 6222                         end
 6223                 else
 6224                         if $mca->mca_uptr
 6225                                 printf "CL+M  "
 6226                                 if $vopt
 6227                                         printf "(paired 2K cluster, mbuf) "
 6228                                 end
 6229                         else
 6230                                 printf "CL-M  "
 6231                                 if $vopt
 6232                                         printf "(paired 2K cluster, mbuf) "
 6233                                 end
 6234                         end
 6235                 end
 6236                 set $done = 1
 6237         end
 6238         if !$done && $csize == ($MSIZE+$NBPG)
 6239                 if $mca->mca_uflags & $MB_SCVALID
 6240                         if $mca->mca_uptr
 6241                                 printf "M+BCL "
 6242                                 if $vopt
 6243                                         printf "(paired mbuf, 4K cluster) "
 6244                                 end
 6245                         else
 6246                                 printf "M-BCL "
 6247                                 if $vopt
 6248                                         printf "(unpaired mbuf, 4K cluster) "
 6249                                 end
 6250                         end
 6251                 else
 6252                         if $mca->mca_uptr
 6253                                 printf "BCL+M "
 6254                                 if $vopt
 6255                                         printf "(paired 4K cluster, mbuf) "
 6256                                 end
 6257                         else
 6258                                 printf "BCL-M "
 6259                                 if $vopt
 6260                                         printf "(unpaired 4K cluster, mbuf) "
 6261                                 end
 6262                         end
 6263                 end
 6264                 set $done = 1
 6265         end
 6266         if !$done && $csize == ($MSIZE+$M16KCLBYTES)
 6267                 if $mca->mca_uflags & $MB_SCVALID
 6268                         if $mca->mca_uptr
 6269                                 printf "M+JCL "
 6270                                 if $vopt
 6271                                         printf "(paired mbuf, 16K cluster) "
 6272                                 end
 6273                         else
 6274                                 printf "M-JCL "
 6275                                 if $vopt
 6276                                         printf "(unpaired mbuf, 16K cluster) "
 6277                                 end
 6278                         end
 6279                 else
 6280                         if $mca->mca_uptr
 6281                                 printf "JCL+M "
 6282                                 if $vopt
 6283                                         printf "(paired 16K cluster, mbuf) "
 6284                                 end
 6285                         else
 6286                                 printf "JCL-M "
 6287                                 if $vopt
 6288                                         printf "(unpaired 16K cluster, mbuf) "
 6289                                 end
 6290                         end
 6291                 end
 6292                 set $done = 1
 6293         end
 6294         if !$done
 6295                 printf "unknown: %s ", $cp->mc_name
 6296         end
 6297 end
 6298 
 6299 document mbuf_mca_ctype
 6300 | This is a helper macro for mbuf_show{active,inactive,all} that prints
 6301 | out the mbuf object type represented by a given mcache audit structure.
 6302 end
 6303 
 6304 define mbuf_showactive
 6305         if $argc == 0
 6306                 mbuf_walkallslabs 1 0
 6307         else
 6308                 mbuf_walkallslabs 1 0 $arg0
 6309         end
 6310 end
 6311 
 6312 document mbuf_showactive
 6313 Syntax: (gdb) mbuf_showactive
 6314 | Walk the mbuf objects pool and print only the active ones; this
 6315 | requires mbuf debugging to be turned on, by setting the appropriate flags
 6316 | to the "mbuf_debug" boot-args parameter.  Active objects are those that
 6317 | are outstanding (have not returned to the mbuf slab layer) and in use
 6318 | by the client (have not been freed).
 6319 end
 6320 
 6321 define mbuf_showinactive
 6322         mbuf_walkallslabs 0 1
 6323 end
 6324 
 6325 document mbuf_showinactive
 6326 Syntax: (gdb) mbuf_showinactive
 6327 | Walk the mbuf objects pool and print only the inactive ones; this
 6328 | requires mbuf debugging to be turned on, by setting the appropriate flags
 6329 | to the "mbuf_debug" boot-args parameter.  Inactive objects are those that
 6330 | are outstanding (have not returned to the mbuf slab layer) but have been
 6331 | freed by the client, i.e. they still reside in the mcache layer ready to
 6332 | be used for subsequent allocation requests.
 6333 end
 6334 
 6335 define mbuf_showall
 6336         mbuf_walkallslabs 1 1
 6337 end
 6338 
 6339 document mbuf_showall
 6340 Syntax: (gdb) mbuf_showall
 6341 | Walk the mbuf objects pool and print them all; this requires
 6342 | mbuf debugging to be turned on, by setting the appropriate flags to the
 6343 | "mbuf_debug" boot-args parameter.
 6344 end
 6345 
 6346 define mbuf_mcaobjs
 6347 end
 6348 
 6349 define mbuf_walkallslabs
 6350         set $show_a = $arg0
 6351         set $show_f = $arg1
 6352         if $argc == 3
 6353                 set $show_tr = $arg2
 6354         else
 6355                 set $show_tr = 0
 6356         end
 6357         set $x = 0
 6358         set $total = 0
 6359         set $total_a = 0
 6360         set $total_f = 0
 6361 
 6362         printf "("
 6363         if $show_a && !$show_f
 6364                 printf "Searching only for active "
 6365         end
 6366         if !$show_a && $show_f
 6367                 printf "Searching only for inactive "
 6368         end
 6369         if $show_a && $show_f
 6370                 printf "Displaying all "
 6371         end
 6372         printf "objects; this may take a while ...)\n\n"
 6373 
 6374         if $kgm_lp64
 6375                 printf "                        slab                mca                obj        allocation\n"
 6376                 printf "slot idx             address            address            address type        state\n"
 6377                 printf "---- ---- ------------------ ------------------ ------------------ ----- -----------\n"
 6378         else
 6379                 printf "                slab        mca        obj        allocation\n"
 6380                 printf "slot idx     address    address    address type        state\n"
 6381                 printf "---- ---- ---------- ---------- ---------- ----- -----------\n"
 6382         end
 6383         
 6384         while $x < slabgrp
 6385                 set $slg = slabstbl[$x]
 6386                 set $y = 0
 6387                 set $stop = 0
 6388                 while $y < $NSLABSPMB && $stop == 0
 6389                         set $sl = &$slg->slg_slab[$y]
 6390                         set $base = (char *)$sl->sl_base
 6391                         set $ix = ($base - (char *)mbutl) >> 12
 6392                         set $clbase = ((union mbigcluster *)mbutl) + $ix
 6393                         set $mclidx = ($base - (char *)$clbase) >> 8
 6394                         set $mca = mclaudit[$ix].cl_audit[$mclidx]
 6395                         set $first = 1
 6396 
 6397                         while $mca != 0 && $mca->mca_addr != 0
 6398                                 set $printmca = 0
 6399                                 if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
 6400                                         set $total_a = $total_a + 1
 6401                                         set $printmca = $show_a
 6402                                 else
 6403                                         set $total_f = $total_f + 1
 6404                                         set $printmca = $show_f
 6405                                 end
 6406 
 6407                                 if $printmca != 0
 6408                                         if $first == 1
 6409                                                 if $kgm_lp64
 6410                                                         printf "%4d %4d 0x%-16llx ", $x, $y, $sl
 6411                                                 else
 6412                                                         printf "%4d %4d 0x%-8x ", $x, $y, $sl
 6413                                                 end
 6414                                         else
 6415                                             if $kgm_lp64
 6416                                                         printf "                             "
 6417                                             else
 6418                                                         printf "                     "
 6419                                             end
 6420                                         end
 6421 
 6422                                         if $kgm_lp64
 6423                                                 printf "0x%-16llx 0x%-16llx ", $mca, $mca->mca_addr
 6424                                         else
 6425                                                 printf "0x%-8x 0x%-8x ", $mca, $mca->mca_addr
 6426                                         end
 6427 
 6428                                         mbuf_mca_ctype $mca 0
 6429                                         if $mca->mca_uflags & ($MB_INUSE|$MB_COMP_INUSE)
 6430                                                 printf "active      "
 6431                                         else
 6432                                                 printf "      freed "
 6433                                         end
 6434                                         if $first == 1
 6435                                                 set $first = 0
 6436                                         end
 6437                                         printf "\n"
 6438                                         set $total = $total + 1
 6439                                         
 6440                                         if $show_tr != 0
 6441                                                 printf "recent transaction for this buffer (thread %p):\n", \
 6442                                                         $mca->mca_thread
 6443                                                 set $cnt = 0
 6444                                                 while $cnt < $mca->mca_depth
 6445                                                         set $kgm_pc = $mca->mca_stack[$cnt]
 6446                                                         printf "%4d: ", $cnt + 1
 6447                                                         pcprint $kgm_pc
 6448                                                         printf "\n"
 6449                                                         set $cnt = $cnt + 1
 6450                                                 end
 6451                                         end
 6452                                 end
 6453                                 
 6454                                 set $mca = $mca->mca_next
 6455                         end
 6456                         set $y += 1
 6457                         if $slg->slg_slab[$y].sl_base == 0
 6458                                 set $stop = 1
 6459                         end
 6460                 end
 6461                 set $x += 1
 6462         end
 6463         if $total && $show_a && $show_f
 6464                 printf "\ntotal objects:\t%d\n", $total
 6465                 printf "active/unfreed:\t%d\n", $total_a
 6466                 printf "freed/in_cache:\t%d\n", $total_f
 6467         end
 6468 end
 6469 
 6470 document mbuf_walkallslabs
 6471 | Walk the mbuf objects pool; this requires mbuf debugging to be
 6472 | turned on, by setting the appropriate flags to the "mbuf_debug" boot-args
 6473 | parameter.  This is a backend routine for mbuf_show{active,inactive,all}.
 6474 end
 6475 
 6476 define mbuf_countchain
 6477         set $mp = (struct mbuf *)$arg0
 6478         
 6479         set $pkt = 0
 6480         set $nxt = 0
 6481 
 6482         while $mp != 0
 6483                 set $pkt = $pkt + 1
 6484         
 6485                 set $mn = (struct mbuf *)$mp->m_hdr.mh_next
 6486                 while $mn != 0
 6487                         set $nxt = $nxt + 1
 6488                         
 6489                         set $mn = (struct mbuf *)$mn->m_hdr.mh_next
 6490                 end
 6491                 
 6492                 set $mp = $mp->m_hdr.mh_nextpkt
 6493 
 6494                 if (($pkt + $nxt) % 50) == 0
 6495                         printf "... %d\n", $pkt + $nxt
 6496                 end
 6497         end
 6498 
 6499         printf "\ntotal: %d (via m_next: %d)\n", $pkt + $nxt, $nxt
 6500 end
 6501 
 6502 document mbuf_countchain
 6503 Syntax: mbuf_countchain <addr>
 6504 | Count the total number of mbufs chained from the given the address of an mbuf. 
 6505 | The routine follows both the m_next pointers and m_nextpkt pointers.
 6506 end
 6507 
 6508 set $RTF_UP          = 0x1
 6509 set $RTF_GATEWAY     = 0x2
 6510 set $RTF_HOST        = 0x4
 6511 set $RTF_REJECT      = 0x8
 6512 set $RTF_DYNAMIC     = 0x10
 6513 set $RTF_MODIFIED    = 0x20
 6514 set $RTF_DONE        = 0x40
 6515 set $RTF_DELCLONE    = 0x80
 6516 set $RTF_CLONING     = 0x100
 6517 set $RTF_XRESOLVE    = 0x200
 6518 set $RTF_LLINFO      = 0x400
 6519 set $RTF_STATIC      = 0x800
 6520 set $RTF_BLACKHOLE   = 0x1000
 6521 set $RTF_PROTO2      = 0x4000
 6522 set $RTF_PROTO1      = 0x8000
 6523 set $RTF_PRCLONING   = 0x10000
 6524 set $RTF_WASCLONED   = 0x20000
 6525 set $RTF_PROTO3      = 0x40000
 6526 set $RTF_PINNED      = 0x100000
 6527 set $RTF_LOCAL       = 0x200000
 6528 set $RTF_BROADCAST   = 0x400000
 6529 set $RTF_MULTICAST   = 0x800000
 6530 set $RTF_IFSCOPE     = 0x1000000
 6531 set $RTF_CONDEMNED   = 0x2000000
 6532 set $RTF_IFREF       = 0x4000000
 6533 set $RTF_PROXY       = 0x8000000
 6534 set $RTF_ROUTER      = 0x10000000
 6535 
 6536 set $AF_INET = 2
 6537 set $AF_INET6 = 30
 6538 set $AF_LINK = 18
 6539 
 6540 define rtentry_prdetails
 6541         set $rt = (struct rtentry *)$arg0
 6542         set $is_v6 = 0
 6543 
 6544         set $dst = (struct sockaddr *)$rt->rt_nodes->rn_u.rn_leaf.rn_Key
 6545         if $dst->sa_family == $AF_INET
 6546                 showsockaddr_in $dst
 6547                 printf " "
 6548         else
 6549                 if $dst->sa_family == $AF_INET6
 6550                         showsockaddr_in6 $dst
 6551                         printf " "
 6552                         set $is_v6 = 1
 6553                 else
 6554                         if $dst->sa_family == $AF_LINK
 6555                                 showsockaddr_dl $dst
 6556                                 printf " "
 6557                         else
 6558                                 showsockaddr_unspec $dst
 6559                         end
 6560                 end
 6561         end
 6562 
 6563         set $dst = (struct sockaddr *)$rt->rt_gateway
 6564         if $dst->sa_family == $AF_INET
 6565                 showsockaddr_in $dst
 6566                 printf "   "
 6567         else
 6568                 if $dst->sa_family == $AF_INET6
 6569                         set $is_v6 = 1
 6570                         showsockaddr_in6 $dst
 6571                         printf " "
 6572                 else
 6573                         if $dst->sa_family == $AF_LINK
 6574                                 showsockaddr_dl $dst
 6575                                 if $is_v6
 6576                                         printf "                       "
 6577                                 else
 6578                                         printf " "
 6579                                 end
 6580                         else
 6581                                 showsockaddr_unspec $dst
 6582                         end
 6583                 end
 6584         end
 6585 
 6586         if $rt->rt_flags & $RTF_WASCLONED
 6587                 if $kgm_lp64
 6588                         printf "%18p ", $rt->rt_parent
 6589                 else
 6590                         printf "%10p ", $rt->rt_parent
 6591                 end
 6592         else
 6593                 if $kgm_lp64
 6594                         printf "                   "
 6595                 else
 6596                         printf "           "
 6597                 end
 6598         end
 6599 
 6600         printf "%6u %8u ", $rt->rt_refcnt, $rt->rt_rmx.rmx_pksent
 6601 
 6602         if $rt->rt_flags & $RTF_UP
 6603                 printf "U"
 6604         end
 6605         if $rt->rt_flags & $RTF_GATEWAY
 6606                 printf "G"
 6607         end
 6608         if $rt->rt_flags & $RTF_HOST
 6609                 printf "H"
 6610         end
 6611         if $rt->rt_flags & $RTF_REJECT
 6612                 printf "R"
 6613         end
 6614         if $rt->rt_flags & $RTF_DYNAMIC
 6615                 printf "D"
 6616         end
 6617         if $rt->rt_flags & $RTF_MODIFIED
 6618                 printf "M"
 6619         end
 6620         if $rt->rt_flags & $RTF_CLONING
 6621                 printf "C"
 6622         end
 6623         if $rt->rt_flags & $RTF_PRCLONING
 6624                 printf "c"
 6625         end
 6626         if $rt->rt_flags & $RTF_LLINFO
 6627                 printf "L"
 6628         end
 6629         if $rt->rt_flags & $RTF_STATIC
 6630                 printf "S"
 6631         end
 6632         if $rt->rt_flags & $RTF_PROTO1
 6633                 printf "1"
 6634         end
 6635         if $rt->rt_flags & $RTF_PROTO2
 6636                 printf "2"
 6637         end
 6638         if $rt->rt_flags & $RTF_PROTO3
 6639                 printf "3"
 6640         end
 6641         if $rt->rt_flags & $RTF_WASCLONED
 6642                 printf "W"
 6643         end
 6644         if $rt->rt_flags & $RTF_BROADCAST
 6645                 printf "b"
 6646         end
 6647         if $rt->rt_flags & $RTF_MULTICAST
 6648                 printf "m"
 6649         end
 6650         if $rt->rt_flags & $RTF_XRESOLVE
 6651                 printf "X"
 6652         end
 6653         if $rt->rt_flags & $RTF_BLACKHOLE
 6654                 printf "B"
 6655         end
 6656         if $rt->rt_flags & $RTF_IFSCOPE
 6657                 printf "I"
 6658         end
 6659         if $rt->rt_flags & $RTF_CONDEMNED
 6660                 printf "Z"
 6661         end
 6662         if $rt->rt_flags & $RTF_IFREF
 6663                 printf "i"
 6664         end
 6665         if $rt->rt_flags & $RTF_PROXY
 6666                 printf "Y"
 6667         end
 6668         if $rt->rt_flags & $RTF_ROUTER
 6669                 printf "r"
 6670         end
 6671 
 6672         printf "/%s%d", $rt->rt_ifp->if_name, $rt->rt_ifp->if_unit
 6673 end
 6674 
 6675 set $RNF_ROOT   = 2
 6676 
 6677 define _rttable_dump
 6678         set $rnh = $arg0
 6679         set $rn = (struct radix_node *)$rnh->rnh_treetop
 6680         set $rnh_cnt = $rnh->rnh_cnt
 6681                 
 6682         while $rn->rn_bit >= 0
 6683                 set $rn = $rn->rn_u.rn_node.rn_L
 6684         end
 6685         
 6686         while 1
 6687                 set $base = (struct radix_node *)$rn
 6688                 while ($rn->rn_parent->rn_u.rn_node.rn_R == $rn) && ($rn->rn_flags & $RNF_ROOT) == 0
 6689                         set $rn = $rn->rn_parent
 6690                 end
 6691                 set $rn = $rn->rn_parent->rn_u.rn_node.rn_R
 6692                 while $rn->rn_bit >= 0
 6693                         set $rn = $rn->rn_u.rn_node.rn_L
 6694                 end
 6695                 set $next = $rn
 6696                 while $base != 0
 6697                         set $rn = $base
 6698                         set $base = $rn->rn_u.rn_leaf.rn_Dupedkey
 6699                         if ($rn->rn_flags & $RNF_ROOT) == 0
 6700                                 
 6701                                 set $rt = (struct rtentry *)$rn
 6702                                 
 6703                                 if $kgm_lp64
 6704                                         printf "%18p ", $rt
 6705                                 else
 6706                                         printf "%10p ", $rt
 6707                                 end
 6708                                 rtentry_prdetails $rt
 6709                                 printf "\n"
 6710                                 
 6711                         end
 6712                 end
 6713                 set $rn = $next
 6714                 if ($rn->rn_flags & $RNF_ROOT) != 0
 6715                         loop_break
 6716                 end
 6717         end
 6718 end
 6719 
 6720 
 6721 define show_rt_inet
 6722         if $kgm_lp64
 6723                 printf " rtentry           dst             gw                parent             Refs   Use      flags/if\n"
 6724                 printf " ----------------- --------------- ----------------- ------------------ ------ -------- -----------\n"
 6725         else
 6726                 printf " rtentry   dst             gw                parent     Refs   Use      flags/if\n"
 6727                 printf " --------- --------------- ----------------- ---------- ------ -------- -----------\n"
 6728         end
 6729         _rttable_dump rt_tables[2]
 6730 end
 6731 
 6732 document show_rt_inet
 6733 Syntax: (gdb) show_rt_inet
 6734 | Show the entries of the IPv4 routing table.
 6735 end
 6736 
 6737 define show_rt_inet6
 6738         if $kgm_lp64
 6739                 printf " rtentry           dst                                     gw                                      parent             Refs   Use      flags/if\n"
 6740                 printf " ----------------- --------------------------------------- --------------------------------------- ------------------ ------ -------- -----------\n"
 6741         else
 6742                 printf " rtentry   dst                                     gw                                      parent     Refs   Use      flags/if\n"
 6743                 printf " --------- --------------------------------------- --------------------------------------- ---------- ------ -------- -----------\n"
 6744         end
 6745         _rttable_dump rt_tables[30]
 6746 end
 6747 
 6748 document show_rt_inet6
 6749 Syntax: (gdb) show_rt_inet6
 6750 | Show the entries of the IPv6 routing table.
 6751 end
 6752 
 6753 define rtentry_trash
 6754         set $rtd = (struct rtentry_dbg *)rttrash_head.tqh_first
 6755         set $cnt = 0
 6756         while $rtd != 0
 6757                 if $cnt == 0
 6758                     if $kgm_lp64
 6759                                 printf "                rtentry ref   hold   rele             dst    gw             parent flags/if\n"
 6760                                 printf "      ----------------- --- ------ ------ --------------- ----- ------------------ -----------\n"
 6761                         else
 6762                                 printf "        rtentry ref   hold   rele             dst    gw     parent flags/if\n"
 6763                                 printf "      --------- --- ------ ------ --------------- ----- ---------- -----------\n"
 6764                         end
 6765                 end
 6766                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $rtd, \
 6767                     $rtd->rtd_refhold_cnt - $rtd->rtd_refrele_cnt, \
 6768                     $rtd->rtd_refhold_cnt, $rtd->rtd_refrele_cnt
 6769                 rtentry_prdetails $rtd
 6770                 printf "\n"
 6771                 set $rtd = $rtd->rtd_trash_link.tqe_next
 6772                 set $cnt = $cnt + 1
 6773         end
 6774 end
 6775 
 6776 document rtentry_trash
 6777 Syntax: (gdb) rtentry_trash
 6778 | Walk the list of trash route entries; this requires route entry
 6779 | debugging to be turned on, by setting the appropriate flags to the
 6780 | "rte_debug" boot-args parameter.
 6781 end
 6782 
 6783 set $CTRACE_STACK_SIZE = ctrace_stack_size
 6784 set $CTRACE_HIST_SIZE = ctrace_hist_size
 6785 
 6786 define rtentry_showdbg
 6787         set $rtd = (struct rtentry_dbg *)$arg0
 6788         set $cnt = 0
 6789 
 6790         printf "Total holds:\t%d\n", $rtd->rtd_refhold_cnt
 6791         printf "Total releases:\t%d\n", $rtd->rtd_refrele_cnt
 6792 
 6793         set $ix = 0
 6794         while $ix < $CTRACE_STACK_SIZE
 6795                 set $kgm_pc = $rtd->rtd_alloc.pc[$ix]
 6796                 if $kgm_pc != 0
 6797                         if $ix == 0
 6798                                 printf "\nAlloc (thread %p):\n", \
 6799                                     $rtd->rtd_alloc.th
 6800                         end
 6801                         printf "%4d: ", $ix + 1
 6802                         pcprint $kgm_pc
 6803                         printf "\n"
 6804                 end
 6805                 set $ix = $ix + 1
 6806         end
 6807         set $ix = 0
 6808         while $ix < $CTRACE_STACK_SIZE
 6809                 set $kgm_pc = $rtd->rtd_free.pc[$ix]
 6810                 if $kgm_pc != 0
 6811                         if $ix == 0
 6812                                 printf "\nFree: (thread %p)\n", \
 6813                                     $rtd->rtd_free.th
 6814                         end
 6815                         printf "%4d: ", $ix + 1
 6816                         pcprint $kgm_pc
 6817                         printf "\n"
 6818                 end
 6819                 set $ix = $ix + 1
 6820         end
 6821         while $cnt < $CTRACE_HIST_SIZE
 6822                 set $ix = 0
 6823                 while $ix < $CTRACE_STACK_SIZE
 6824                         set $kgm_pc = $rtd->rtd_refhold[$cnt].pc[$ix]
 6825                         if $kgm_pc != 0
 6826                                 if $ix == 0
 6827                                         printf "\nHold [%d] (thread %p):\n", \
 6828                                             $cnt, $rtd->rtd_refhold[$cnt].th
 6829                                 end
 6830                                 printf "%4d: ", $ix + 1
 6831                                 pcprint $kgm_pc
 6832                                 printf "\n"
 6833                         end
 6834                         set $ix = $ix + 1
 6835                 end
 6836                 set $cnt = $cnt + 1
 6837         end
 6838         set $cnt = 0
 6839         while $cnt < $CTRACE_HIST_SIZE
 6840                 set $ix = 0
 6841                 while $ix < $CTRACE_STACK_SIZE
 6842                         set $kgm_pc = $rtd->rtd_refrele[$cnt].pc[$ix]
 6843                         if $kgm_pc != 0
 6844                                 if $ix == 0
 6845                                         printf "\nRelease [%d] (thread %p):\n",\
 6846                                             $cnt, $rtd->rtd_refrele[$cnt].th
 6847                                 end
 6848                                 printf "%4d: ", $ix + 1
 6849                                 pcprint $kgm_pc
 6850                                 printf "\n"
 6851                         end
 6852                         set $ix = $ix + 1
 6853                 end
 6854                 set $cnt = $cnt + 1
 6855         end
 6856 
 6857         printf "\nTotal locks:\t%d\n", $rtd->rtd_lock_cnt
 6858         printf "Total unlocks:\t%d\n", $rtd->rtd_unlock_cnt
 6859 
 6860         set $cnt = 0
 6861         while $cnt < $CTRACE_HIST_SIZE
 6862                 set $ix = 0
 6863                 while $ix < $CTRACE_STACK_SIZE
 6864                         set $kgm_pc = $rtd->rtd_lock[$cnt].pc[$ix]
 6865                         if $kgm_pc != 0
 6866                                 if $ix == 0
 6867                                         printf "\nLock [%d] (thread %p):\n",\
 6868                                             $cnt, $rtd->rtd_lock[$cnt].th
 6869                                 end
 6870                                 printf "%4d: ", $ix + 1
 6871                                 pcprint $kgm_pc
 6872                                 printf "\n"
 6873                         end
 6874                         set $ix = $ix + 1
 6875                 end
 6876                 set $cnt = $cnt + 1
 6877         end
 6878         set $cnt = 0
 6879         while $cnt < $CTRACE_HIST_SIZE
 6880                 set $ix = 0
 6881                 while $ix < $CTRACE_STACK_SIZE
 6882                         set $kgm_pc = $rtd->rtd_unlock[$cnt].pc[$ix]
 6883                         if $kgm_pc != 0
 6884                                 if $ix == 0
 6885                                         printf "\nUnlock [%d] (thread %p):\n",\
 6886                                             $cnt, $rtd->rtd_unlock[$cnt].th
 6887                                 end
 6888                                 printf "%4d: ", $ix + 1
 6889                                 pcprint $kgm_pc
 6890                                 printf "\n"
 6891                         end
 6892                         set $ix = $ix + 1
 6893                 end
 6894                 set $cnt = $cnt + 1
 6895         end
 6896 end
 6897 
 6898 document rtentry_showdbg
 6899 Syntax: (gdb) rtentry_showdbg <addr>
 6900 | Given a route entry structure address, print the debug information
 6901 | related to it.  This requires route entry debugging to be turned
 6902 | on, by setting the appropriate flags to the "rte_debug" boot-args
 6903 | parameter.
 6904 end
 6905 
 6906 set $INIFA_TRACE_HIST_SIZE = inifa_trace_hist_size
 6907 
 6908 define inifa_showdbg
 6909         set $inifa = (struct in_ifaddr_dbg *)$arg0
 6910         set $cnt = 0
 6911 
 6912         printf "Total holds:\t%d\n", $inifa->inifa_refhold_cnt
 6913         printf "Total releases:\t%d\n", $inifa->inifa_refrele_cnt
 6914 
 6915         set $ix = 0
 6916         while $ix < $CTRACE_STACK_SIZE
 6917                 set $kgm_pc = $inifa->inifa_alloc.pc[$ix]
 6918                 if $kgm_pc != 0
 6919                         if $ix == 0
 6920                                 printf "\nAlloc (thread %p):\n", \
 6921                                     $inifa->inifa_alloc.th
 6922                         end
 6923                         printf "%4d: ", $ix + 1
 6924                         pcprint $kgm_pc
 6925                         printf "\n"
 6926                 end
 6927                 set $ix = $ix + 1
 6928         end
 6929         set $ix = 0
 6930         while $ix < $CTRACE_STACK_SIZE
 6931                 set $kgm_pc = $inifa->inifa_free.pc[$ix]
 6932                 if $kgm_pc != 0
 6933                         if $ix == 0
 6934                                 printf "\nFree: (thread %p)\n", \
 6935                                     $inifa->inifa_free.th
 6936                         end
 6937                         printf "%4d: ", $ix + 1
 6938                         pcprint $kgm_pc
 6939                         printf "\n"
 6940                 end
 6941                 set $ix = $ix + 1
 6942         end
 6943         while $cnt < $INIFA_TRACE_HIST_SIZE
 6944                 set $ix = 0
 6945                 while $ix < $CTRACE_STACK_SIZE
 6946                         set $kgm_pc = $inifa->inifa_refhold[$cnt].pc[$ix]
 6947                         if $kgm_pc != 0
 6948                                 if $ix == 0
 6949                                         printf "\nHold [%d] (thread %p):\n", \
 6950                                             $cnt, $inifa->inifa_refhold[$cnt].th
 6951                                 end
 6952                                 printf "%4d: ", $ix + 1
 6953                                 pcprint $kgm_pc
 6954                                 printf "\n"
 6955                         end
 6956                         set $ix = $ix + 1
 6957                 end
 6958                 set $cnt = $cnt + 1
 6959         end
 6960         set $cnt = 0
 6961         while $cnt < $INIFA_TRACE_HIST_SIZE
 6962                 set $ix = 0
 6963                 while $ix < $CTRACE_STACK_SIZE
 6964                         set $kgm_pc = $inifa->inifa_refrele[$cnt].pc[$ix]
 6965                         if $kgm_pc != 0
 6966                                 if $ix == 0
 6967                                         printf "\nRelease [%d] (thread %p):\n",\
 6968                                             $cnt, $inifa->inifa_refrele[$cnt].th
 6969                                 end
 6970                                 printf "%4d: ", $ix + 1
 6971                                 pcprint $kgm_pc
 6972                                 printf "\n"
 6973                         end
 6974                         set $ix = $ix + 1
 6975                 end
 6976                 set $cnt = $cnt + 1
 6977         end
 6978 end
 6979 
 6980 document inifa_showdbg
 6981 Syntax: (gdb) inifa_showdbg <addr>
 6982 | Given an IPv4 interface structure address, print the debug information
 6983 | related to it.  This requires interface address debugging to be turned
 6984 | on, by setting the appropriate flags to the "ifa_debug" boot-args
 6985 | parameter.
 6986 end
 6987 
 6988 set $IN6IFA_TRACE_HIST_SIZE = in6ifa_trace_hist_size
 6989 
 6990 define in6ifa_showdbg
 6991         set $in6ifa = (struct in6_ifaddr_dbg *)$arg0
 6992         set $cnt = 0
 6993 
 6994         printf "Total holds:\t%d\n", $in6ifa->in6ifa_refhold_cnt
 6995         printf "Total releases:\t%d\n", $in6ifa->in6ifa_refrele_cnt
 6996 
 6997         set $ix = 0
 6998         while $ix < $CTRACE_STACK_SIZE
 6999                 set $kgm_pc = $in6ifa->in6ifa_alloc.pc[$ix]
 7000                 if $kgm_pc != 0
 7001                         if $ix == 0
 7002                                 printf "\nAlloc (thread %p):\n", \
 7003                                     $in6ifa->in6ifa_alloc.th
 7004                         end
 7005                         printf "%4d: ", $ix + 1
 7006                         pcprint $kgm_pc
 7007                         printf "\n"
 7008                 end
 7009                 set $ix = $ix + 1
 7010         end
 7011         set $ix = 0
 7012         while $ix < $CTRACE_STACK_SIZE
 7013                 set $kgm_pc = $in6ifa->in6ifa_free.pc[$ix]
 7014                 if $kgm_pc != 0
 7015                         if $ix == 0
 7016                                 printf "\nFree: (thread %p)\n", \
 7017                                     $in6ifa->in6ifa_free.th
 7018                         end
 7019                         printf "%4d: ", $ix + 1
 7020                         pcprint $kgm_pc
 7021                         printf "\n"
 7022                 end
 7023                 set $ix = $ix + 1
 7024         end
 7025         while $cnt < $IN6IFA_TRACE_HIST_SIZE
 7026                 set $ix = 0
 7027                 while $ix < $CTRACE_STACK_SIZE
 7028                         set $kgm_pc = $in6ifa->in6ifa_refhold[$cnt].pc[$ix]
 7029                         if $kgm_pc != 0
 7030                                 if $ix == 0
 7031                                         printf "\nHold [%d] (thread %p):\n", \
 7032                                           $cnt, $in6ifa->in6ifa_refhold[$cnt].th
 7033                                 end
 7034                                 printf "%4d: ", $ix + 1
 7035                                 pcprint $kgm_pc
 7036                                 printf "\n"
 7037                         end
 7038                         set $ix = $ix + 1
 7039                 end
 7040                 set $cnt = $cnt + 1
 7041         end
 7042         set $cnt = 0
 7043         while $cnt < $IN6IFA_TRACE_HIST_SIZE
 7044                 set $ix = 0
 7045                 while $ix < $CTRACE_STACK_SIZE
 7046                         set $kgm_pc = $in6ifa->in6ifa_refrele[$cnt].pc[$ix]
 7047                         if $kgm_pc != 0
 7048                                 if $ix == 0
 7049                                         printf "\nRelease [%d] (thread %p):\n",\
 7050                                           $cnt, $in6ifa->in6ifa_refrele[$cnt].th
 7051                                 end
 7052                                 printf "%4d: ", $ix + 1
 7053                                 pcprint $kgm_pc
 7054                                 printf "\n"
 7055                         end
 7056                         set $ix = $ix + 1
 7057                 end
 7058                 set $cnt = $cnt + 1
 7059         end
 7060 end
 7061 
 7062 document in6ifa_showdbg
 7063 Syntax: (gdb) in6ifa_showdbg <addr>
 7064 | Given an IPv6 interface structure address, print the debug information
 7065 | related to it.  This requires interface address debugging to be turned
 7066 | on, by setting the appropriate flags to the "ifa_debug" boot-args
 7067 | parameter.
 7068 end
 7069 
 7070 set $IFMA_TRACE_HIST_SIZE = ifma_trace_hist_size
 7071 
 7072 define ifma_showdbg
 7073         set $ifma = (struct ifmultiaddr_dbg *)$arg0
 7074         set $cnt = 0
 7075 
 7076         printf "Total holds:\t%d\n", $ifma->ifma_refhold_cnt
 7077         printf "Total releases:\t%d\n", $ifma->ifma_refrele_cnt
 7078 
 7079         while $cnt < $IFMA_TRACE_HIST_SIZE
 7080                 set $ix = 0
 7081                 while $ix < $CTRACE_STACK_SIZE
 7082                         set $kgm_pc = $ifma->ifma_refhold[$cnt].pc[$ix]
 7083                         if $kgm_pc != 0
 7084                                 if $ix == 0
 7085                                         printf "\nHold [%d] (thread %p):\n", \
 7086                                           $cnt, $ifma->ifma_refhold[$cnt].th
 7087                                 end
 7088                                 printf "%4d: ", $ix + 1
 7089                                 pcprint $kgm_pc
 7090                                 printf "\n"
 7091                         end
 7092                         set $ix = $ix + 1
 7093                 end
 7094                 set $cnt = $cnt + 1
 7095         end
 7096         set $cnt = 0
 7097         while $cnt < $IFMA_TRACE_HIST_SIZE
 7098                 set $ix = 0
 7099                 while $ix < $CTRACE_STACK_SIZE
 7100                         set $kgm_pc = $ifma->ifma_refrele[$cnt].pc[$ix]
 7101                         if $kgm_pc != 0
 7102                                 if $ix == 0
 7103                                         printf "\nRelease [%d] (thread %p):\n",\
 7104                                           $cnt, $ifma->ifma_refrele[$cnt].th
 7105                                 end
 7106                                 printf "%4d: ", $ix + 1
 7107                                 pcprint $kgm_pc
 7108                                 printf "\n"
 7109                         end
 7110                         set $ix = $ix + 1
 7111                 end
 7112                 set $cnt = $cnt + 1
 7113         end
 7114 end
 7115 
 7116 document ifma_showdbg
 7117 Syntax: (gdb) ifma_showdbg <addr>
 7118 | Given a link multicast structure address, print the debug information
 7119 | related to it.  This requires interface address debugging to be turned
 7120 | on, by setting the appropriate flags to the "ifa_debug" boot-args
 7121 | parameter.
 7122 end
 7123 
 7124 set $INM_TRACE_HIST_SIZE = inm_trace_hist_size
 7125 
 7126 define inm_showdbg
 7127         set $inm = (struct in_multi_dbg *)$arg0
 7128         set $cnt = 0
 7129 
 7130         printf "Total holds:\t%d\n", $inm->inm_refhold_cnt
 7131         printf "Total releases:\t%d\n", $inm->inm_refrele_cnt
 7132 
 7133         while $cnt < $INM_TRACE_HIST_SIZE
 7134                 set $ix = 0
 7135                 while $ix < $CTRACE_STACK_SIZE
 7136                         set $kgm_pc = $inm->inm_refhold[$cnt].pc[$ix]
 7137                         if $kgm_pc != 0
 7138                                 if $ix == 0
 7139                                         printf "\nHold [%d] (thread %p):\n", \
 7140                                           $cnt, $inm->inm_refhold[$cnt].th
 7141                                 end
 7142                                 printf "%4d: ", $ix + 1
 7143                                 pcprint $kgm_pc
 7144                                 printf "\n"
 7145                         end
 7146                         set $ix = $ix + 1
 7147                 end
 7148                 set $cnt = $cnt + 1
 7149         end
 7150         set $cnt = 0
 7151         while $cnt < $INM_TRACE_HIST_SIZE
 7152                 set $ix = 0
 7153                 while $ix < $CTRACE_STACK_SIZE
 7154                         set $kgm_pc = $inm->inm_refrele[$cnt].pc[$ix]
 7155                         if $kgm_pc != 0
 7156                                 if $ix == 0
 7157                                         printf "\nRelease [%d] (thread %p):\n",\
 7158                                           $cnt, $inm->inm_refrele[$cnt].th
 7159                                 end
 7160                                 printf "%4d: ", $ix + 1
 7161                                 pcprint $kgm_pc
 7162                                 printf "\n"
 7163                         end
 7164                         set $ix = $ix + 1
 7165                 end
 7166                 set $cnt = $cnt + 1
 7167         end
 7168 end
 7169 
 7170 document inm_showdbg
 7171 Syntax: (gdb) inm_showdbg <addr>
 7172 | Given an IPv4 multicast structure address, print the debug information
 7173 | related to it.  This requires interface address debugging to be turned
 7174 | on, by setting the appropriate flags to the "ifa_debug" boot-args
 7175 | parameter.
 7176 end
 7177 
 7178 set $IF_REF_TRACE_HIST_SIZE = if_ref_trace_hist_size
 7179 
 7180 define ifpref_showdbg
 7181         set $dl_if = (struct dlil_ifnet_dbg *)$arg0
 7182         set $cnt = 0
 7183 
 7184         printf "Total references:\t%d\n", $dl_if->dldbg_if_refhold_cnt
 7185         printf "Total releases:\t\t%d\n", $dl_if->dldbg_if_refrele_cnt
 7186 
 7187         while $cnt < $IF_REF_TRACE_HIST_SIZE
 7188                 set $ix = 0
 7189                 while $ix < $CTRACE_STACK_SIZE
 7190                         set $kgm_pc = $dl_if->dldbg_if_refhold[$cnt].pc[$ix]
 7191                         if $kgm_pc != 0
 7192                                 if $ix == 0
 7193                                         printf "\nHold [%d] (thread %p):\n", \
 7194                                             $cnt, \
 7195                                             $dl_if->dldbg_if_refhold[$cnt].th
 7196                                 end
 7197                                 printf "%4d: ", $ix + 1
 7198                                 pcprint $kgm_pc
 7199                                 printf "\n"
 7200                         end
 7201                         set $ix = $ix + 1
 7202                 end
 7203                 set $cnt = $cnt + 1
 7204         end
 7205         set $cnt = 0
 7206         while $cnt < $IF_REF_TRACE_HIST_SIZE
 7207                 set $ix = 0
 7208                 while $ix < $CTRACE_STACK_SIZE
 7209                         set $kgm_pc = $dl_if->dldbg_if_refrele[$cnt].pc[$ix]
 7210                         if $kgm_pc != 0
 7211                                 if $ix == 0
 7212                                         printf "\nRelease [%d] (thread %p):\n",\
 7213                                             $cnt, \
 7214                                             $dl_if->dldbg_if_refrele[$cnt].th
 7215                                 end
 7216                                 printf "%4d: ", $ix + 1
 7217                                 pcprint $kgm_pc
 7218                                 printf "\n"
 7219                         end
 7220                         set $ix = $ix + 1
 7221                 end
 7222                 set $cnt = $cnt + 1
 7223         end
 7224 end
 7225 
 7226 document ifpref_showdbg
 7227 Syntax: (gdb) ifpref_showdbg <addr>
 7228 | Given an ifnet structure address, print the debug information
 7229 | related to its refcnt.  This requires ifnet debugging to be turned
 7230 | on, by setting the appropriate flags to the "ifnet_debug" boot-args
 7231 | parameter.
 7232 end
 7233 
 7234 define in6ifa_trash
 7235         set $ifa = (struct in6_ifaddr_dbg *)in6ifa_trash_head.tqh_first
 7236         set $cnt = 0
 7237         while $ifa != 0
 7238                 if $cnt == 0
 7239                     if $kgm_lp64
 7240                                 printf "                in6_ifa ref   hold   rele\n"
 7241                                 printf "      ----------------- --- ------ ------\n"
 7242                         else
 7243                                 printf "        in6_ifa ref   hold   rele\n"
 7244                                 printf "      --------- --- ------ ------\n"
 7245                         end
 7246                 end
 7247                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifa, \
 7248                     $ifa->in6ifa_refhold_cnt - $ifa->in6ifa_refrele_cnt, \
 7249                     $ifa->in6ifa_refhold_cnt, $ifa->in6ifa_refrele_cnt
 7250                 showsockaddr_in6 $ifa->in6ifa.ia_ifa.ifa_addr
 7251                 printf "\n"
 7252                 set $ifa = $ifa->in6ifa_trash_link.tqe_next
 7253                 set $cnt = $cnt + 1
 7254         end
 7255 end
 7256 
 7257 set $NDPR_TRACE_HIST_SIZE = ndpr_trace_hist_size
 7258 
 7259 define ndpr_showdbg
 7260         set $ndpr = (struct nd_prefix_dbg *)$arg0
 7261         set $cnt = 0
 7262 
 7263         printf "Total references:\t%d\n", $ndpr->ndpr_refhold_cnt
 7264         printf "Total releases:\t\t%d\n", $ndpr->ndpr_refrele_cnt
 7265 
 7266         while $cnt < $NDPR_TRACE_HIST_SIZE
 7267                 set $ix = 0
 7268                 while $ix < $CTRACE_STACK_SIZE
 7269                         set $kgm_pc = $ndpr->ndpr_refhold[$cnt].pc[$ix]
 7270                         if $kgm_pc != 0
 7271                                 if $ix == 0
 7272                                         printf "\nHold [%d] (thread %p):\n", \
 7273                                             $cnt, \
 7274                                             $ndpr->ndpr_refhold[$cnt].th
 7275                                 end
 7276                                 printf "%4d: ", $ix + 1
 7277                                 pcprint $kgm_pc
 7278                                 printf "\n"
 7279                         end
 7280                         set $ix = $ix + 1
 7281                 end
 7282                 set $cnt = $cnt + 1
 7283         end
 7284         set $cnt = 0
 7285         while $cnt < $NDPR_TRACE_HIST_SIZE
 7286                 set $ix = 0
 7287                 while $ix < $CTRACE_STACK_SIZE
 7288                         set $kgm_pc = $ndpr->ndpr_refrele[$cnt].pc[$ix]
 7289                         if $kgm_pc != 0
 7290                                 if $ix == 0
 7291                                         printf "\nRelease [%d] (thread %p):\n",\
 7292                                             $cnt, \
 7293                                             $ndpr->ndpr_refrele[$cnt].th
 7294                                 end
 7295                                 printf "%4d: ", $ix + 1
 7296                                 pcprint $kgm_pc
 7297                                 printf "\n"
 7298                         end
 7299                         set $ix = $ix + 1
 7300                 end
 7301                 set $cnt = $cnt + 1
 7302         end
 7303 end
 7304 
 7305 document ndpr_showdbg
 7306 Syntax: (gdb) ndpr_showdbg <addr>
 7307 | Given a nd_prefix structure address, print the debug information
 7308 | related to its refcnt.  This requires the interface address debugging
 7309 | to be turned on, by setting the appropriate flags to the "ifa_debug"
 7310 | boot-args parameter.
 7311 end
 7312 
 7313 set $NDDR_TRACE_HIST_SIZE = nddr_trace_hist_size
 7314 
 7315 define nddr_showdbg
 7316         set $nddr = (struct nd_defrouter_dbg *)$arg0
 7317         set $cnt = 0
 7318 
 7319         printf "Total references:\t%d\n", $nddr->nddr_refhold_cnt
 7320         printf "Total releases:\t\t%d\n", $nddr->nddr_refrele_cnt
 7321 
 7322         while $cnt < $NDDR_TRACE_HIST_SIZE
 7323                 set $ix = 0
 7324                 while $ix < $CTRACE_STACK_SIZE
 7325                         set $kgm_pc = $nddr->nddr_refhold[$cnt].pc[$ix]
 7326                         if $kgm_pc != 0
 7327                                 if $ix == 0
 7328                                         printf "\nHold [%d] (thread %p):\n", \
 7329                                             $cnt, \
 7330                                             $nddr->nddr_refhold[$cnt].th
 7331                                 end
 7332                                 printf "%4d: ", $ix + 1
 7333                                 pcprint $kgm_pc
 7334                                 printf "\n"
 7335                         end
 7336                         set $ix = $ix + 1
 7337                 end
 7338                 set $cnt = $cnt + 1
 7339         end
 7340         set $cnt = 0
 7341         while $cnt < $NDDR_TRACE_HIST_SIZE
 7342                 set $ix = 0
 7343                 while $ix < $CTRACE_STACK_SIZE
 7344                         set $kgm_pc = $nddr->nddr_refrele[$cnt].pc[$ix]
 7345                         if $kgm_pc != 0
 7346                                 if $ix == 0
 7347                                         printf "\nRelease [%d] (thread %p):\n",\
 7348                                             $cnt, \
 7349                                             $nddr->nddr_refrele[$cnt].th
 7350                                 end
 7351                                 printf "%4d: ", $ix + 1
 7352                                 pcprint $kgm_pc
 7353                                 printf "\n"
 7354                         end
 7355                         set $ix = $ix + 1
 7356                 end
 7357                 set $cnt = $cnt + 1
 7358         end
 7359 end
 7360 
 7361 document nddr_showdbg
 7362 Syntax: (gdb) nddr_showdbg <addr>
 7363 | Given a nd_defrouter structure address, print the debug information
 7364 | related to its refcnt.  This requires the interface address debugging
 7365 | to be turned on, by setting the appropriate flags to the "ifa_debug"
 7366 | boot-args parameter.
 7367 end
 7368 set $IMO_TRACE_HIST_SIZE = imo_trace_hist_size
 7369 
 7370 define imo_showdbg
 7371         set $imo = (struct ip_moptions_dbg *)$arg0
 7372         set $cnt = 0
 7373 
 7374         printf "Total references:\t%d\n", $imo->imo_refhold_cnt
 7375         printf "Total releases:\t\t%d\n", $imo->imo_refrele_cnt
 7376 
 7377         while $cnt < $IMO_TRACE_HIST_SIZE
 7378                 set $ix = 0
 7379                 while $ix < $CTRACE_STACK_SIZE
 7380                         set $kgm_pc = $imo->imo_refhold[$cnt].pc[$ix]
 7381                         if $kgm_pc != 0
 7382                                 if $ix == 0
 7383                                         printf "\nHold [%d] (thread %p):\n", \
 7384                                             $cnt, \
 7385                                             $imo->imo_refhold[$cnt].th
 7386                                 end
 7387                                 printf "%4d: ", $ix + 1
 7388                                 pcprint $kgm_pc
 7389                                 printf "\n"
 7390                         end
 7391                         set $ix = $ix + 1
 7392                 end
 7393                 set $cnt = $cnt + 1
 7394         end
 7395         set $cnt = 0
 7396         while $cnt < $IMO_TRACE_HIST_SIZE
 7397                 set $ix = 0
 7398                 while $ix < $CTRACE_STACK_SIZE
 7399                         set $kgm_pc = $imo->imo_refrele[$cnt].pc[$ix]
 7400                         if $kgm_pc != 0
 7401                                 if $ix == 0
 7402                                         printf "\nRelease [%d] (thread %p):\n",\
 7403                                             $cnt, \
 7404                                             $imo->imo_refrele[$cnt].th
 7405                                 end
 7406                                 printf "%4d: ", $ix + 1
 7407                                 pcprint $kgm_pc
 7408                                 printf "\n"
 7409                         end
 7410                         set $ix = $ix + 1
 7411                 end
 7412                 set $cnt = $cnt + 1
 7413         end
 7414 end
 7415 
 7416 document imo_showdbg
 7417 Syntax: (gdb) imo_showdbg <addr>
 7418 | Given a ip_moptions structure address, print the debug information
 7419 | related to its refcnt.  This requires the interface address debugging
 7420 | to be turned on, by setting the appropriate flags to the "ifa_debug"
 7421 | boot-args parameter.
 7422 end
 7423 
 7424 set $IM6O_TRACE_HIST_SIZE = im6o_trace_hist_size
 7425 
 7426 define im6o_showdbg
 7427         set $im6o = (struct ip6_moptions_dbg *)$arg0
 7428         set $cnt = 0
 7429 
 7430         printf "Total references:\t%d\n", $im6o->im6o_refhold_cnt
 7431         printf "Total releases:\t\t%d\n", $im6o->im6o_refrele_cnt
 7432 
 7433         while $cnt < $IM6O_TRACE_HIST_SIZE
 7434                 set $ix = 0
 7435                 while $ix < $CTRACE_STACK_SIZE
 7436                         set $kgm_pc = $im6o->im6o_refhold[$cnt].pc[$ix]
 7437                         if $kgm_pc != 0
 7438                                 if $ix == 0
 7439                                         printf "\nHold [%d] (thread %p):\n", \
 7440                                             $cnt, \
 7441                                             $im6o->im6o_refhold[$cnt].th
 7442                                 end
 7443                                 printf "%4d: ", $ix + 1
 7444                                 pcprint $kgm_pc
 7445                                 printf "\n"
 7446                         end
 7447                         set $ix = $ix + 1
 7448                 end
 7449                 set $cnt = $cnt + 1
 7450         end
 7451         set $cnt = 0
 7452         while $cnt < $IM6O_TRACE_HIST_SIZE
 7453                 set $ix = 0
 7454                 while $ix < $CTRACE_STACK_SIZE
 7455                         set $kgm_pc = $im6o->im6o_refrele[$cnt].pc[$ix]
 7456                         if $kgm_pc != 0
 7457                                 if $ix == 0
 7458                                         printf "\nRelease [%d] (thread %p):\n",\
 7459                                             $cnt, \
 7460                                             $im6o->im6o_refrele[$cnt].th
 7461                                 end
 7462                                 printf "%4d: ", $ix + 1
 7463                                 pcprint $kgm_pc
 7464                                 printf "\n"
 7465                         end
 7466                         set $ix = $ix + 1
 7467                 end
 7468                 set $cnt = $cnt + 1
 7469         end
 7470 end
 7471 
 7472 document im6o_showdbg
 7473 Syntax: (gdb) im6o_showdbg <addr>
 7474 | Given a ip6_moptions structure address, print the debug information
 7475 | related to its refcnt.  This requires the interface address debugging
 7476 | to be turned on, by setting the appropriate flags to the "ifa_debug"
 7477 | boot-args parameter.
 7478 end
 7479 
 7480 document in6ifa_trash
 7481 Syntax: (gdb) in6ifa_trash
 7482 | Walk the list of trash in6_ifaddr entries; this requires interface
 7483 | address debugging to be turned on, by setting the appropriate flags
 7484 | to the "ifa_debug" boot-args parameter.
 7485 end
 7486 
 7487 define inifa_trash
 7488         set $ifa = (struct in_ifaddr_dbg *)inifa_trash_head.tqh_first
 7489         set $cnt = 0
 7490         while $ifa != 0
 7491                 if $cnt == 0
 7492                     if $kgm_lp64
 7493                                 printf "                 in_ifa ref   hold   rele\n"
 7494                                 printf "      ----------------- --- ------ ------\n"
 7495                         else
 7496                                 printf "         in_ifa ref   hold   rele\n"
 7497                                 printf "      --------- --- ------ ------\n"
 7498                         end
 7499                 end
 7500                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifa, \
 7501                     $ifa->inifa_refhold_cnt - $ifa->inifa_refrele_cnt, \
 7502                     $ifa->inifa_refhold_cnt, $ifa->inifa_refrele_cnt
 7503                 showsockaddr_in $ifa->inifa.ia_ifa.ifa_addr
 7504                 printf "\n"
 7505                 set $ifa = $ifa->inifa_trash_link.tqe_next
 7506                 set $cnt = $cnt + 1
 7507         end
 7508 end
 7509 
 7510 document inifa_trash
 7511 Syntax: (gdb) inifa_trash
 7512 | Walk the list of trash in_ifaddr entries; this requires interface
 7513 | address debugging to be turned on, by setting the appropriate flags
 7514 | to the "ifa_debug" boot-args parameter.
 7515 end
 7516 
 7517 define ifma_trash
 7518         set $ifma = (struct ifmultiaddr_dbg *)ifma_trash_head.tqh_first
 7519         set $cnt = 0
 7520         while $ifma != 0
 7521                 if $cnt == 0
 7522                     if $kgm_lp64
 7523                                 printf "                   ifma ref   hold   rele\n"
 7524                                 printf "      ----------------- --- ------ ------\n"
 7525                         else
 7526                                 printf "          ifma  ref   hold   rele\n"
 7527                                 printf "      --------- --- ------ ------\n"
 7528                         end
 7529                 end
 7530                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $ifma, \
 7531                     $ifma->ifma_refhold_cnt - $ifma->ifma_refrele_cnt, \
 7532                     $ifma->ifma_refhold_cnt, $ifma->ifma_refrele_cnt
 7533                 showsockaddr $ifma->ifma.ifma_addr
 7534                 printf " @ %s%d", $ifma->ifma.ifma_ifp->if_name, \
 7535                     $ifma->ifma.ifma_ifp->if_unit
 7536                 printf "\n"
 7537                 set $ifma = $ifma->ifma_trash_link.tqe_next
 7538                 set $cnt = $cnt + 1
 7539         end
 7540 end
 7541 
 7542 document ifma_trash
 7543 Syntax: (gdb) ifma_trash
 7544 | Walk the list of trash ifmultiaddr entries; this requires interface
 7545 | address debugging to be turned on, by setting the appropriate flags
 7546 | to the "ifa_debug" boot-args parameter.
 7547 end
 7548 
 7549 define inm_trash
 7550         set $inm = (struct in_multi_dbg *)inm_trash_head.tqh_first
 7551         set $cnt = 0
 7552         while $inm != 0
 7553                 if $cnt == 0
 7554                     if $kgm_lp64
 7555                                 printf "                    inm ref   hold   rele\n"
 7556                                 printf "      ----------------- --- ------ ------\n"
 7557                         else
 7558                                 printf "            inm ref   hold   rele\n"
 7559                                 printf "      --------- --- ------ ------\n"
 7560                         end
 7561                 end
 7562                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $inm, \
 7563                     $inm->inm_refhold_cnt - $inm->inm_refrele_cnt, \
 7564                     $inm->inm_refhold_cnt, $inm->inm_refrele_cnt
 7565                 show_in_addr &($inm->inm.inm_addr)
 7566                 printf "\n"
 7567                 set $inm = $inm->inm_trash_link.tqe_next
 7568                 set $cnt = $cnt + 1
 7569         end
 7570 end
 7571 
 7572 document inm_trash
 7573 Syntax: (gdb) inm_trash
 7574 | Walk the list of trash in_multi entries; this requires interface
 7575 | address debugging to be turned on, by setting the appropriate flags
 7576 | to the "ifa_debug" boot-args parameter.
 7577 end
 7578 
 7579 define in6m_trash
 7580         set $in6m = (struct in6_multi_dbg *)in6m_trash_head.tqh_first
 7581         set $cnt = 0
 7582         while $in6m != 0
 7583                 if $cnt == 0
 7584                     if $kgm_lp64
 7585                                 printf "                   in6m ref   hold   rele\n"
 7586                                 printf "      ----------------- --- ------ ------\n"
 7587                         else
 7588                                 printf "           in6m ref   hold   rele\n"
 7589                                 printf "      --------- --- ------ ------\n"
 7590                         end
 7591                 end
 7592                 printf "%4d: %p %3d %6d %6d ", $cnt + 1, $in6m, \
 7593                     $in6m->in6m_refhold_cnt - $in6m->in6m_refrele_cnt, \
 7594                     $in6m->in6m_refhold_cnt, $in6m->in6m_refrele_cnt
 7595                 show_in_addr &($in6m->in6m.in6m_addr)
 7596                 printf "\n"
 7597                 set $in6m = $in6m->in6m_trash_link.tqe_next
 7598                 set $cnt = $cnt + 1
 7599         end
 7600 end
 7601 
 7602 document in6m_trash
 7603 Syntax: (gdb) in6m_trash
 7604 | Walk the list of trash in6_multi entries; this requires interface
 7605 | address debugging to be turned on, by setting the appropriate flags
 7606 | to the "ifa_debug" boot-args parameter.
 7607 end
 7608 
 7609 #
 7610 # print all OSMalloc stats 
 7611 
 7612 define ostag_print
 7613 set $kgm_tagp = (OSMallocTag)$arg0
 7614 printf "0x%08x: ", $kgm_tagp
 7615 printf "%8d ",$kgm_tagp->OSMT_refcnt
 7616 printf "%8x ",$kgm_tagp->OSMT_state
 7617 printf "%8x ",$kgm_tagp->OSMT_attr
 7618 printf "%s ",$kgm_tagp->OSMT_name
 7619 printf "\n"
 7620 end
 7621 
 7622 
 7623 define showosmalloc 
 7624 printf "TAG          COUNT     STATE     ATTR     NAME\n"
 7625 set $kgm_tagheadp = (struct _OSMallocTag_ *)&OSMalloc_tag_list
 7626     set $kgm_tagptr = (struct _OSMallocTag_ * )($kgm_tagheadp->OSMT_link.next)
 7627     while $kgm_tagptr != $kgm_tagheadp
 7628         ostag_print $kgm_tagptr
 7629         set $kgm_tagptr = (struct _OSMallocTag_ *)$kgm_tagptr->OSMT_link.next
 7630     end
 7631         printf "\n"
 7632 end
 7633 document showosmalloc
 7634 Syntax: (gdb) showosmalloc
 7635 | Print the outstanding allocation count by OSMallocTags.
 7636 end
 7637 
 7638 
 7639 define systemlog
 7640     if msgbufp->msg_bufc[msgbufp->msg_bufx] == 0 \
 7641        && msgbufp->msg_bufc[0] != 0
 7642         # The buffer hasn't wrapped, so take the easy (and fast!) path
 7643         printf "%s", msgbufp->msg_bufc
 7644     else
 7645         set $kgm_msgbuf = *msgbufp
 7646         set $kgm_syslog_bufsize = $kgm_msgbuf.msg_size
 7647         set $kgm_syslog_bufend = $kgm_msgbuf.msg_bufx
 7648         if $kgm_syslog_bufend >= $kgm_syslog_bufsize
 7649             set $kgm_syslog_bufend = 0
 7650         end
 7651     
 7652         # print older messages from msg_bufx to end of buffer
 7653         set $kgm_i = $kgm_syslog_bufend
 7654         while $kgm_i < $kgm_syslog_bufsize
 7655             set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
 7656             if $kgm_syslog_char == 0
 7657                 # break out of loop
 7658                 set $kgm_i = $kgm_syslog_bufsize
 7659             else
 7660                 printf "%c", $kgm_syslog_char
 7661             end
 7662             set $kgm_i = $kgm_i + 1
 7663         end
 7664         
 7665         # print newer messages from start of buffer to msg_bufx
 7666         set $kgm_i = 0
 7667         while $kgm_i < $kgm_syslog_bufend
 7668             set $kgm_syslog_char = $kgm_msgbuf.msg_bufc[$kgm_i]
 7669             if $kgm_syslog_char != 0
 7670                 printf "%c", $kgm_syslog_char
 7671             end
 7672             set $kgm_i = $kgm_i + 1
 7673         end
 7674     end
 7675     printf "\n"
 7676 end
 7677 document systemlog
 7678 | Syntax: systemlog
 7679 | Display the kernel's printf ring buffer
 7680 end
 7681 
 7682 
 7683 define hexdump
 7684         set $kgm_addr = (unsigned char *)$arg0
 7685         set $kgm_len = $arg1
 7686         while $kgm_len > 0
 7687                 showptr $kgm_addr
 7688                 printf ": "
 7689                 set $kgm_i = 0
 7690                 while $kgm_i < 16
 7691                         printf "%02x ", *($kgm_addr+$kgm_i)
 7692                         set $kgm_i += 1
 7693                 end
 7694                 printf " |"
 7695                 set $kgm_i = 0
 7696                 while $kgm_i < 16
 7697                         set $kgm_temp = *($kgm_addr+$kgm_i)
 7698                         if $kgm_temp < 32 || $kgm_temp >= 127
 7699                                 printf "."
 7700                         else
 7701                                 printf "%c", $kgm_temp
 7702                         end
 7703                         set $kgm_i += 1
 7704                 end
 7705                 printf "|\n"
 7706                 set $kgm_addr += 16
 7707                 set $kgm_len -= 16
 7708         end
 7709 end
 7710 document hexdump
 7711 | Show the contents of memory as a hex/ASCII dump
 7712 | The following is the syntax:
 7713 | (gdb) hexdump <address> <length>
 7714 end
 7715 
 7716 
 7717 define printcolonhex
 7718     if ($argc == 2) 
 7719         set $addr = $arg0
 7720         set $count = $arg1
 7721         set $li = 0
 7722         while ($li < $count)
 7723             if ($li == 0)
 7724                         printf "%02x", (u_char)$addr[$li]
 7725             end
 7726             if ($li != 0)
 7727                         printf ":%02x", (u_char)$addr[$li]
 7728             end
 7729             set $li = $li + 1
 7730         end
 7731     end
 7732 end
 7733 
 7734 define showsockaddr_dl
 7735     set $sdl = (struct sockaddr_dl *)$arg0
 7736     if ($sdl == 0)
 7737                 printf "(null)           "
 7738     else
 7739             if $sdl->sdl_nlen == 0 && $sdl->sdl_alen == 0 && $sdl->sdl_slen == 0
 7740                 printf "link#%3d         ", $sdl->sdl_index
 7741             else
 7742                         set $addr = $sdl->sdl_data + $sdl->sdl_nlen
 7743                         set $count = $sdl->sdl_alen
 7744                         printcolonhex $addr $count
 7745                 end
 7746     end
 7747 end
 7748 
 7749 define showsockaddr_unspec
 7750     set $sockaddr = (struct sockaddr *)$arg0
 7751     set $addr = $sockaddr->sa_data
 7752     set $count = $sockaddr->sa_len - 2
 7753     printcolonhex $addr $count
 7754 end
 7755 
 7756 define showsockaddr_at
 7757     set $sockaddr = (struct sockaddr *)$arg0
 7758     set $addr = $sockaddr->sa_data
 7759     set $count = $sockaddr->sa_len - 2
 7760     printcolonhex $addr $count
 7761 end
 7762 
 7763 define show_in_addr
 7764     set $ia = (unsigned char *)$arg0
 7765     printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
 7766 end
 7767 
 7768 define showsockaddr_in
 7769     set $sin = (struct sockaddr_in *)$arg0
 7770     set $sa_bytes = (unsigned char *)&($sin->sin_addr)
 7771     show_in_addr $sa_bytes
 7772 end
 7773 
 7774 define show_in6_addr
 7775     set $ia = (unsigned char *)$arg0
 7776     printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
 7777         $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
 7778 end
 7779 
 7780 define showsockaddr_in6
 7781     set $sin6 = (struct sockaddr_in6 *)$arg0
 7782     set $sa_bytes = $sin6->sin6_addr.__u6_addr.__u6_addr8
 7783     show_in6_addr $sa_bytes
 7784 end
 7785 
 7786 define showsockaddr_un
 7787         set $sun = (struct sockaddr_un *)$arg0
 7788         if $sun == 0
 7789                 printf "(null)"
 7790         else
 7791                 if $sun->sun_path[0] == 0
 7792                         printf "\"\""
 7793                 else
 7794                         printf "%s", $sun->sun_path
 7795                 end
 7796         end
 7797 end
 7798 
 7799 define showifmultiaddrs
 7800    set $ifp = (struct ifnet *)$arg0
 7801    set $if_multi = (struct ifmultiaddr *)$ifp->if_multiaddrs->lh_first
 7802    set $mymulti = $if_multi
 7803    set $myi = 0
 7804    while ($mymulti != 0)
 7805         printf "%2d. %p ", $myi, $mymulti
 7806         set $sa_family = $mymulti->ifma_addr.sa_family
 7807         if ($sa_family == 2)
 7808             if ($mymulti->ifma_ll != 0)
 7809                 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
 7810                 printf " "
 7811             end
 7812             showsockaddr_in $mymulti->ifma_addr
 7813         end
 7814         if ($sa_family == 30)
 7815             if ($mymulti->ifma_ll != 0)
 7816                 showsockaddr_dl $mymulti->ifma_ll->ifma_addr
 7817                 printf " "
 7818             end
 7819             showsockaddr_in6 $mymulti->ifma_addr
 7820         end
 7821         if ($sa_family == 18)
 7822             showsockaddr_dl $mymulti->ifma_addr
 7823         end
 7824         if ($sa_family == 0)
 7825             showsockaddr_unspec $mymulti->ifma_addr 6
 7826         end
 7827         printf " [%d]", $mymulti->ifma_refcount
 7828         printf "\n"
 7829         set $mymulti = $mymulti->ifma_link.le_next
 7830         set $myi = $myi + 1
 7831    end
 7832 end
 7833 
 7834 document showifmultiaddrs
 7835 Syntax showifmultiaddrs <ifp>
 7836 | show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
 7837 end
 7838 
 7839 define showinmultiaddrs
 7840    set $in_multi = (struct in_multi *)(in_multihead->lh_first)
 7841    set $mymulti = $in_multi
 7842    set $myi = 0
 7843    while ($mymulti != 0)
 7844         set $ifp = (struct ifnet *)$mymulti->inm_ifp
 7845         printf "%2d. %p ", $myi, $mymulti
 7846         show_in_addr &($mymulti->inm_addr)
 7847         printf " (ifp %p [%s%d] ifma %p) ", $ifp, $ifp->if_name, \
 7848             $ifp->if_unit, $mymulti->inm_ifma
 7849         printf "\n"
 7850         set $mymulti = $mymulti->inm_link.le_next
 7851         set $myi = $myi + 1
 7852    end
 7853 end
 7854 
 7855 document showinmultiaddrs
 7856 Syntax showinmultiaddrs
 7857 | show the contents of IPv4 multicast address records
 7858 end
 7859 
 7860 define showin6multiaddrs
 7861    set $in6_multi = (struct in6_multi *)(in6_multihead->lh_first)
 7862    set $mymulti = $in6_multi
 7863    set $myi = 0
 7864    while ($mymulti != 0)
 7865         set $ifp = (struct ifnet *)$mymulti->in6m_ifp
 7866         printf "%2d. %p ", $myi, $mymulti
 7867         show_in6_addr &($mymulti->in6m_addr)
 7868         printf " (ifp %p [%s%d] ifma %p) ", $ifp, $ifp->if_name, \
 7869             $ifp->if_unit, $mymulti->in6m_ifma
 7870         printf "\n"
 7871         set $mymulti = $mymulti->in6m_entry.le_next
 7872         set $myi = $myi + 1
 7873    end
 7874 end
 7875 
 7876 document showin6multiaddrs
 7877 Syntax showin6multiaddrs
 7878 | show the contents of IPv6 multicast address records
 7879 end
 7880 
 7881 define showsockaddr
 7882     set $mysock = (struct sockaddr *)$arg0
 7883     set $showsockaddr_handled = 0
 7884     if ($mysock == 0)
 7885         printf "(null)"
 7886     else
 7887         if ($mysock->sa_family == 0)
 7888                 printf "UNSPC"
 7889             showsockaddr_unspec $mysock
 7890             set $showsockaddr_handled = 1
 7891         end
 7892         if ($mysock->sa_family == 1)
 7893                 printf "UNIX "
 7894             showsockaddr_un $mysock
 7895             set $showsockaddr_handled = 1
 7896         end
 7897         if ($mysock->sa_family == 2)
 7898                 printf "INET "
 7899             showsockaddr_in $mysock
 7900             set $showsockaddr_handled = 1
 7901         end
 7902         if ($mysock->sa_family == 30)
 7903                 printf "INET6 "
 7904             showsockaddr_in6 $mysock
 7905             set $showsockaddr_handled = 1
 7906         end
 7907         if ($mysock->sa_family == 18)
 7908                 printf "LINK "
 7909             showsockaddr_dl $mysock
 7910             set $showsockaddr_handled = 1
 7911         end
 7912         if ($mysock->sa_family == 16)
 7913                 printf "ATLK "
 7914             showsockaddr_at $mysock
 7915             set $showsockaddr_handled = 1
 7916         end
 7917         if ($showsockaddr_handled == 0)
 7918             printf "FAM %d ", $mysock->sa_family
 7919             set $addr = $mysock->sa_data
 7920             set $count = $mysock->sa_len
 7921             printcolonhex $addr $count
 7922         end
 7923     end
 7924 end
 7925 
 7926 define showifflags
 7927         set $flags = (u_short)$arg0
 7928         set $first = 1
 7929         printf "<"
 7930         if ($flags & 0x1)
 7931             printf "UP"
 7932             set $first = 0
 7933         end
 7934         if ($flags & 0x2)
 7935             if ($first == 1)
 7936                 set $first = 0
 7937             else
 7938                 printf ","
 7939             end
 7940             printf "BROADCAST"
 7941         end
 7942         if ($flags & 0x4)
 7943             printf "DEBUG"
 7944         end
 7945         if ($flags & 0x8)
 7946             if ($first == 1)
 7947                 set $first = 0
 7948             else
 7949                 printf ","
 7950             end
 7951             printf "LOOPBACK"
 7952         end
 7953         if ($flags & 0x10)
 7954             if ($first == 1)
 7955                 set $first = 0
 7956             else
 7957                 printf ","
 7958             end
 7959             printf "POINTTOPOINT"
 7960         end
 7961 ##      if ($flags & 0x20)
 7962 ##          if ($first == 1)
 7963 #               set $first = 0
 7964 ##          else
 7965 #               printf ","
 7966 #           end
 7967 #           printf "NOTRAILERS"
 7968 #       end
 7969         if ($flags & 0x40)
 7970             if ($first == 1)
 7971                 set $first = 0
 7972             else
 7973                 printf ","
 7974             end
 7975             printf "RUNNING"
 7976         end
 7977         if ($flags & 0x80)
 7978             if ($first == 1)
 7979                 set $first = 0
 7980             else
 7981                 printf ","
 7982             end
 7983             printf "NOARP"
 7984         end
 7985         if ($flags & 0x100)
 7986             if ($first == 1)
 7987                 set $first = 0
 7988             else
 7989                 printf ","
 7990             end
 7991             printf "PROMISC"
 7992         end
 7993         if ($flags & 0x200)
 7994             if ($first == 1)
 7995                 set $first = 0
 7996             else
 7997                 printf ","
 7998             end
 7999             printf "ALLMULTI"
 8000         end
 8001         if ($flags & 0x400)
 8002             if ($first == 1)
 8003                 set $first = 0
 8004             else
 8005                 printf ","
 8006             end
 8007             printf "OACTIVE"
 8008         end
 8009         if ($flags & 0x800)
 8010             if ($first == 1)
 8011                 set $first = 0
 8012             else
 8013                 printf ","
 8014             end
 8015             printf "SIMPLEX"
 8016         end
 8017         if ($flags & 0x1000)
 8018             if ($first == 1)
 8019                 set $first = 0
 8020             else
 8021                 printf ","
 8022             end
 8023             printf "LINK0"
 8024         end
 8025         if ($flags & 0x2000)
 8026             if ($first == 1)
 8027                 set $first = 0
 8028             else
 8029                 printf ","
 8030             end
 8031             printf "LINK1"
 8032         end
 8033         if ($flags & 0x4000)
 8034             if ($first == 1)
 8035                 set $first = 0
 8036             else
 8037                 printf ","
 8038             end
 8039             printf "LINK2-ALTPHYS"
 8040         end
 8041         if ($flags & 0x8000)
 8042             if ($first == 1)
 8043                 set $first = 0
 8044             else
 8045                 printf ","
 8046             end
 8047             printf "MULTICAST"
 8048         end
 8049         printf ">"
 8050 end
 8051 
 8052 define showifaddrs
 8053    set $ifp = (struct ifnet *)$arg0
 8054    set $myifaddr = (struct ifaddr *)$ifp->if_addrhead->tqh_first
 8055    set $myi = 0
 8056    while ($myifaddr != 0)
 8057         printf "\t%d. %p ", $myi, $myifaddr
 8058         showsockaddr $myifaddr->ifa_addr
 8059         printf " [%d]\n", $myifaddr->ifa_refcnt
 8060         set $myifaddr = $myifaddr->ifa_link->tqe_next
 8061         set $myi = $myi + 1
 8062    end
 8063 end
 8064 
 8065 document showifaddrs
 8066 Syntax: showifaddrs <ifp>
 8067 | show the (struct ifnet).if_addrhead list of addresses for the given ifp
 8068 end
 8069 
 8070 define ifconfig
 8071    set $ifconfig_all = 0
 8072    if ($argc == 1)
 8073         set $ifconfig_all = 1
 8074    end
 8075    set $ifp = (struct ifnet *)(ifnet_head->tqh_first)
 8076    while ($ifp != 0)
 8077         printf "%s%d: flags=%hx", $ifp->if_name, $ifp->if_unit, (u_short)$ifp->if_flags
 8078         showifflags $ifp->if_flags
 8079         printf " index %d", $ifp->if_index
 8080         printf " mtu %d\n", $ifp->if_data.ifi_mtu
 8081         printf "\t(struct ifnet *)"
 8082     showptr $ifp
 8083     printf "\n"
 8084         if ($ifconfig_all == 1) 
 8085            showifaddrs $ifp
 8086     end
 8087         set $ifp = $ifp->if_link->tqe_next
 8088    end
 8089 end
 8090 document ifconfig
 8091 Syntax: (gdb) ifconfig
 8092 | display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
 8093 end
 8094 
 8095 set $DLIF_INUSE = 0x1
 8096 set $DLIF_REUSE = 0x2
 8097 
 8098 define showifnets
 8099         set $all = 0
 8100         if ($argc == 1)
 8101                 set $all = 1
 8102         end
 8103         set $dlifp = (struct dlil_ifnet *)(dlil_ifnet_head->tqh_first)
 8104         while ($dlifp != 0)
 8105                 set $ifp = (struct ifnet *)$dlifp
 8106                 if ($dlifp->dl_if_flags & $DLIF_REUSE)
 8107                         printf "*"
 8108                 end
 8109                 if ($dlifp->dl_if_flags & $DLIF_INUSE)
 8110                         printf "%s%d: ", $ifp->if_name, $ifp->if_unit
 8111                 else
 8112                         printf "[%s%d]: ", $ifp->if_name, $ifp->if_unit
 8113                 end
 8114                 printf "flags=%hx", (u_short)$ifp->if_flags
 8115                 showifflags $ifp->if_flags
 8116                 printf " index %d", $ifp->if_index
 8117                 printf " mtu %d\n", $ifp->if_data.ifi_mtu
 8118                 printf "\t(struct ifnet *)"
 8119                 showptr $ifp
 8120                 printf "\n"
 8121                 if ($all == 1) 
 8122                         showifaddrs $ifp
 8123                 end
 8124                 set $dlifp = $dlifp->dl_if_link->tqe_next
 8125         end
 8126 end
 8127 
 8128 document showifnets
 8129 Syntax: (gdb) showifnets
 8130 | Display ifconfig-like output for all attached and detached interfaces
 8131 end
 8132 
 8133 define _show_unix_domain_socket
 8134         set $so = (struct socket *)$arg0
 8135         set $pcb = (struct unpcb *)$so->so_pcb
 8136         if $pcb == 0
 8137                 printf "unpcb: (null) "
 8138         else
 8139                 printf "unpcb: %p ", $pcb
 8140                 printf "unp_vnode: %p ", $pcb->unp_vnode
 8141                 printf "unp_conn: %p ", $pcb->unp_conn
 8142                 printf "unp_addr: "
 8143                 showsockaddr_un $pcb->unp_addr
 8144         end
 8145 end
 8146 
 8147 define _show_in_port
 8148         set $str = (unsigned char *)$arg0
 8149         set $port = *(unsigned short *)$arg0
 8150         
 8151         if (((($port & 0xff00) >> 8) == $str[0])) && ((($port & 0x00ff) == $str[1]))
 8152                 #printf "big endian "
 8153                 printf ":%d ", $port
 8154         else
 8155                 #printf "little endian "
 8156                 printf ":%d ", (($port & 0xff00) >> 8) | (($port & 0x00ff) << 8)
 8157         end
 8158 end
 8159 
 8160 define _show_in_addr_4in6
 8161         set $ia = (unsigned char *)$arg0
 8162         if $ia
 8163             printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
 8164         end
 8165 end
 8166 
 8167 define _show_in6_addr
 8168         set $ia = (unsigned char *)$arg0
 8169         if $ia
 8170                 printf "%2x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", \
 8171                         $ia[0], $ia[1], $ia[2], $ia[3], $ia[4], $ia[5], $ia[6], $ia[7], \
 8172                         $ia[8], $ia[9], $ia[10], $ia[11], $ia[12], $ia[13], $ia[14], $ia[15]
 8173         end
 8174 end
 8175 
 8176 define _showtcpstate
 8177         set $tp = (struct tcpcb *)$arg0
 8178         if $tp
 8179                 if $tp->t_state == 0
 8180                         printf "CLOSED      "
 8181                 end
 8182                 if $tp->t_state == 1
 8183                         printf "LISTEN      "
 8184                 end
 8185                 if $tp->t_state == 2
 8186                         printf "SYN_SENT    "
 8187                 end
 8188                 if $tp->t_state == 3
 8189                         printf "SYN_RCVD    "
 8190                 end
 8191                 if $tp->t_state == 4
 8192                         printf "ESTABLISHED "
 8193                 end
 8194                 if $tp->t_state == 5
 8195                         printf "CLOSE_WAIT   "
 8196                 end
 8197                 if $tp->t_state == 6
 8198                         printf "FIN_WAIT_1   "
 8199                 end
 8200                 if $tp->t_state == 7
 8201                         printf "CLOSING      "
 8202                 end
 8203                 if $tp->t_state == 8
 8204                         printf "LAST_ACK     "
 8205                 end
 8206                 if $tp->t_state == 9
 8207                         printf "FIN_WAIT_2   "
 8208                 end
 8209                 if $tp->t_state == 10
 8210                         printf "TIME_WAIT    "
 8211                 end
 8212         end
 8213 end
 8214 
 8215 define _showsockprotocol
 8216         set $so = (struct socket *)$arg0
 8217         set $inpcb = (struct inpcb *)$so->so_pcb
 8218 
 8219         if $so->so_proto->pr_protocol == 6
 8220                 printf "TCP "
 8221                 _showtcpstate $inpcb->inp_ppcb
 8222         end
 8223         if $so->so_proto->pr_protocol == 17
 8224                 printf "UDP "
 8225         end
 8226         if $so->so_proto->pr_protocol == 1
 8227                 printf "ICMP "
 8228         end
 8229         if $so->so_proto->pr_protocol == 254
 8230                 printf "DIVERT "
 8231         end
 8232         if $so->so_proto->pr_protocol == 255
 8233                 printf "RAW "
 8234         end
 8235 end
 8236 
 8237 define _show_ipv4_socket
 8238         set $so = (struct socket *)$arg0
 8239         set $inpcb = (struct inpcb *)$so->so_pcb
 8240         if $inpcb == 0
 8241                 printf "inpcb: (null) "
 8242         else
 8243                 printf "inpcb: %p ", $inpcb
 8244                 
 8245                 _showsockprotocol $so
 8246 
 8247                 _show_in_addr_4in6  &$inpcb->inp_dependladdr.inp46_local
 8248                 _show_in_port  &$inpcb->inp_lport
 8249                 printf "-> "
 8250                 _show_in_addr_4in6  &$inpcb->inp_dependfaddr.inp46_foreign
 8251                 _show_in_port &$inpcb->inp_fport
 8252         end
 8253 end
 8254 
 8255 define _show_ipv6_socket
 8256         set $so = (struct socket *)$arg0
 8257         set $pcb = (struct inpcb *)$so->so_pcb
 8258         if $pcb == 0
 8259                 printf "inpcb: (null) "
 8260         else
 8261                 printf "inpcb: %p ", $pcb
 8262 
 8263                 _showsockprotocol $so
 8264 
 8265                 _show_in6_addr  &$pcb->inp_dependladdr.inp6_local
 8266                 _show_in_port  &$pcb->inp_lport
 8267                 printf "-> "
 8268                 _show_in6_addr  &$pcb->inp_dependfaddr.inp6_foreign
 8269                 _show_in_port &$pcb->inp_fport
 8270         end
 8271 end
 8272 
 8273 
 8274 define showsocket
 8275         set $so = (struct socket *)$arg0
 8276         if $so == 0
 8277                 printf "so: (null) "
 8278         else
 8279                 printf "so: %p ", $so
 8280                 if $so && $so->so_proto && $so->so_proto->pr_domain
 8281                         set $domain = (struct  domain *) $so->so_proto->pr_domain
 8282 
 8283                         printf "%s ", $domain->dom_name
 8284                         if  $domain->dom_family == 1
 8285                                 _show_unix_domain_socket $so
 8286                         end
 8287                         if  $domain->dom_family == 2
 8288                                 _show_ipv4_socket $so
 8289                         end
 8290                         if  $domain->dom_family == 30
 8291                                 _show_ipv6_socket $so
 8292                         end
 8293                 end
 8294         end
 8295         printf "\n"
 8296 end
 8297 document showsocket
 8298 Syntax: (gdb) showsocket <socket_address>
 8299 | Routine to print out a socket
 8300 end
 8301 
 8302 define showprocsockets
 8303         set $pp = (struct proc *)$arg0
 8304         set $fdp = (struct filedesc *)$pp->p_fd
 8305 
 8306         set $count = 0
 8307         set $fpp =  (struct fileproc **)($fdp->fd_ofiles)
 8308         set $fpo =  (char)($fdp->fd_ofileflags[0])
 8309         while $count < $fdp->fd_nfiles
 8310                 if *$fpp
 8311                         set $fg =(struct fileglob *)((**$fpp)->f_fglob)
 8312                         if  $fg && (($fg)->fg_type == 2) 
 8313                                 if $fdp->fd_ofileflags[$count] & 4
 8314                                         printf "U: "
 8315                                 else
 8316                                         printf " "
 8317                                 end
 8318                                 printf "fd = %d ", $count
 8319                                 if  $fg->fg_data
 8320                                         showsocket  $fg->fg_data
 8321                                 else
 8322                                         printf "\n"
 8323                                 end
 8324                         end
 8325                 end
 8326                 set $fpp = $fpp + 1
 8327                 set $count = $count + 1         
 8328         end
 8329 end
 8330 document showprocsockets
 8331 Syntax: (gdb) showprocsockets <proc_address>
 8332 | Routine to print out all the open fds
 8333 | which are sockets in a process
 8334 end
 8335 
 8336 define showallprocsockets
 8337   set $basep = (struct proc  *)allproc->lh_first
 8338   set $pp = $basep
 8339   while $pp
 8340         printf "============================================ \n"
 8341         showproc $pp
 8342         showprocsockets $pp
 8343         set $pp = $pp->p_list.le_next
 8344   end
 8345 end
 8346 document showallprocsockets
 8347 Syntax: (gdb) showallprocsockets
 8348 | Routine to print out all the open fds
 8349 | which are sockets 
 8350 end
 8351 
 8352 define _print_ntohs
 8353         set $port = (unsigned short)$arg0
 8354         set $port = (unsigned short)((($arg0 & 0xff00) >> 8) & 0xff)
 8355         set $port |= (unsigned short)(($arg0 & 0xff) << 8)
 8356         printf "%5d", $port
 8357 end
 8358 
 8359 set $INPCB_STATE_INUSE=0x1
 8360 set $INPCB_STATE_CACHED=0x2
 8361 set $INPCB_STATE_DEAD=0x3
 8362 
 8363 set $INP_RECVOPTS=0x01
 8364 set $INP_RECVRETOPTS=0x02
 8365 set $INP_RECVDSTADDR=0x04
 8366 set $INP_HDRINCL=0x08
 8367 set $INP_HIGHPORT=0x10
 8368 set $INP_LOWPORT=0x20
 8369 set $INP_ANONPORT=0x40
 8370 set $INP_RECVIF=0x80
 8371 set $INP_MTUDISC=0x100
 8372 set $INP_STRIPHDR=0x200
 8373 set $INP_RECV_ANYIF=0x400
 8374 set $INP_INADDR_ANY=0x800
 8375 set $INP_RECVTTL=0x1000
 8376 set $INP_UDP_NOCKSUM=0x2000
 8377 set $IN6P_IPV6_V6ONLY=0x008000
 8378 set $IN6P_PKTINFO=0x010000
 8379 set $IN6P_HOPLIMIT=0x020000
 8380 set $IN6P_HOPOPTS=0x040000
 8381 set $IN6P_DSTOPTS=0x080000
 8382 set $IN6P_RTHDR=0x100000
 8383 set $IN6P_RTHDRDSTOPTS=0x200000
 8384 set $IN6P_AUTOFLOWLABEL=0x800000
 8385 set $IN6P_BINDV6ONLY=0x10000000
 8386 
 8387 set $INP_IPV4=0x1
 8388 set $INP_IPV6=0x2
 8389 
 8390 set $IPPROTO_TCP=6
 8391 set $IPPROTO_UDP=17
 8392 
 8393 define _dump_inpcb
 8394         set $pcb = (struct inpcb *)$arg0
 8395         if $kgm_lp64
 8396                 printf "%18p", $pcb
 8397         else
 8398                 printf "%10p ", $pcb
 8399         end
 8400         if $arg1 == $IPPROTO_TCP
 8401                 printf "tcp"
 8402         else
 8403                 if $arg1 == $IPPROTO_UDP
 8404                         printf "udp"
 8405                 else
 8406                         printf "%2d.", $arg1
 8407                 end
 8408         end
 8409         if ($pcb->inp_vflag & $INP_IPV4)
 8410                 printf "4 "
 8411         end
 8412         if ($pcb->inp_vflag & $INP_IPV6)
 8413                 printf "6 "
 8414         end
 8415 
 8416         if ($pcb->inp_vflag & $INP_IPV4)
 8417                 printf "                        "
 8418                 _show_in_addr &$pcb->inp_dependladdr.inp46_local.ia46_addr4
 8419         else
 8420                 _show_in6_addr &$pcb->inp_dependladdr.inp6_local
 8421         end
 8422         printf " "
 8423         _print_ntohs $pcb->inp_lport
 8424         printf " "
 8425         if ($pcb->inp_vflag & $INP_IPV4)
 8426                 printf "                        "
 8427                 _show_in_addr &($pcb->inp_dependfaddr.inp46_foreign.ia46_addr4)
 8428         else
 8429                 _show_in6_addr &($pcb->inp_dependfaddr.inp6_foreign)
 8430         end
 8431         printf " "
 8432         _print_ntohs $pcb->inp_fport
 8433         printf " "
 8434 
 8435         if $arg1 == $IPPROTO_TCP
 8436                 _showtcpstate $pcb->inp_ppcb
 8437         end
 8438 
 8439 #       printf "phd "
 8440 #       set $phd = $pcb->inp_phd
 8441 #       while $phd != 0
 8442 #               printf " "
 8443 #               _print_ntohs $phd->phd_port
 8444 #               set $phd = $phd->phd_hash.le_next
 8445 #       end
 8446 #       printf ", "
 8447         if ($pcb->inp_flags & $INP_RECVOPTS)
 8448                 printf "recvopts "
 8449         end
 8450         if ($pcb->inp_flags & $INP_RECVRETOPTS)
 8451                 printf "recvretopts "
 8452         end
 8453         if ($pcb->inp_flags & $INP_RECVDSTADDR)
 8454                 printf "recvdstaddr "
 8455         end
 8456         if ($pcb->inp_flags & $INP_HDRINCL)
 8457                 printf "hdrincl "
 8458         end
 8459         if ($pcb->inp_flags & $INP_HIGHPORT)
 8460                 printf "highport "
 8461         end
 8462         if ($pcb->inp_flags & $INP_LOWPORT)
 8463                 printf "lowport "
 8464         end
 8465         if ($pcb->inp_flags & $INP_ANONPORT)
 8466                 printf "anonport "
 8467         end
 8468         if ($pcb->inp_flags & $INP_RECVIF)
 8469                 printf "recvif "
 8470         end
 8471         if ($pcb->inp_flags & $INP_MTUDISC)
 8472                 printf "mtudisc "
 8473         end
 8474         if ($pcb->inp_flags & $INP_STRIPHDR)
 8475                 printf "striphdr "
 8476         end
 8477         if ($pcb->inp_flags & $INP_RECV_ANYIF)
 8478                 printf "recv_anyif "
 8479         end
 8480         if ($pcb->inp_flags & $INP_INADDR_ANY)
 8481                 printf "inaddr_any "
 8482         end
 8483         if ($pcb->inp_flags & $INP_RECVTTL)
 8484                 printf "recvttl "
 8485         end
 8486         if ($pcb->inp_flags & $INP_UDP_NOCKSUM)
 8487                 printf "nocksum "
 8488         end
 8489         if ($pcb->inp_flags & $IN6P_IPV6_V6ONLY)
 8490                 printf "v6only "
 8491         end
 8492         if ($pcb->inp_flags & $IN6P_PKTINFO)
 8493                 printf "pktinfo "
 8494         end
 8495         if ($pcb->inp_flags & $IN6P_HOPLIMIT)
 8496                 printf "hoplimit "
 8497         end
 8498         if ($pcb->inp_flags & $IN6P_HOPOPTS)
 8499                 printf "hopopts "
 8500         end
 8501         if ($pcb->inp_flags & $IN6P_DSTOPTS)
 8502                 printf "dstopts "
 8503         end
 8504         if ($pcb->inp_flags & $IN6P_RTHDR)
 8505                 printf "rthdr "
 8506         end
 8507         if ($pcb->inp_flags & $IN6P_RTHDRDSTOPTS)
 8508                 printf "rthdrdstopts "
 8509         end
 8510         if ($pcb->inp_flags & $IN6P_AUTOFLOWLABEL)
 8511                 printf "autoflowlabel "
 8512         end
 8513         if ($pcb->inp_flags & $IN6P_BINDV6ONLY)
 8514                 printf "bindv6only "
 8515         end
 8516         set $so = (struct socket *)$pcb->inp_socket
 8517         if $so != 0
 8518                 printf "[so=%p s=%ld r=%ld usecnt=%ld] ", $so, $so->so_snd.sb_cc, \
 8519                     $so->so_rcv.sb_cc, $so->so_usecount
 8520         end
 8521         if ($pcb->inp_state == 0 || $pcb->inp_state == $INPCB_STATE_INUSE)
 8522                 printf "inuse, "
 8523         else
 8524                 if ($pcb->inp_state == $INPCB_STATE_CACHED)
 8525                         printf "cached, "
 8526                 else
 8527                         if ($pcb->inp_state == $INPCB_STATE_DEAD)
 8528                                 printf "dead, "
 8529                         else
 8530                                 printf "unknown (%d), ", $pcb->inp_state
 8531                         end
 8532                 end
 8533         end
 8534 end
 8535 
 8536 define _dump_inpcbport
 8537         set $ppcb = (struct inpcbport *)$arg0
 8538         printf "%p: lport ", $ppcb
 8539         _print_ntohs $ppcb->phd_port
 8540 end
 8541 
 8542 set $UDBHASHSIZE=16
 8543 
 8544 define _dump_pcbinfo
 8545         set $snd_cc = 0
 8546         set $snd_buf = (unsigned int)0
 8547         set $rcv_cc = 0
 8548         set $rcv_buf = (unsigned int)0
 8549         set $pcbseen = 0
 8550         set $pcbi = (struct inpcbinfo *)$arg0
 8551         printf "lastport %d lastlow %d lasthi %d\n", \
 8552             $pcbi->lastport, $pcbi->lastlow, $pcbi->lasthi
 8553         printf "active pcb count is %d\n", $pcbi->ipi_count
 8554         set $hashsize = $pcbi->hashmask + 1
 8555         printf "hash size is %d\n", $hashsize
 8556         printf "hash base %p has the following inpcb(s):\n", $pcbi->hashbase
 8557         if $kgm_lp64
 8558                 printf "pcb                prot source                          address port  destination                     address port\n"
 8559                 printf "------------------ ---- --------------------------------------- ----- --------------------------------------- -----\n"
 8560         else
 8561                 printf "pcb        prot source                          address port  destination                     address port\n"
 8562                 printf "---------- ---- --------------------------------------- ----- --------------------------------------- -----\n"
 8563         end
 8564         set $i = 0
 8565         set $hashbase = $pcbi->hashbase
 8566         set $head = *(uintptr_t *)$hashbase
 8567         while $i < $hashsize
 8568                 if $head != 0
 8569                         set $pcb0 = (struct inpcb *)$head
 8570                         while $pcb0  != 0
 8571                                 set $pcbseen += 1
 8572                                 _dump_inpcb $pcb0 $arg1
 8573                                 set $so = (struct socket *)$pcb->inp_socket
 8574                                 if $so != 0
 8575                                         set $snd_cc += $so->so_snd.sb_cc
 8576                                         set $mp = $so->so_snd.sb_mb
 8577                                         while $mp
 8578                                                 set $snd_buf += 256
 8579                                                 if ($mp->m_hdr.mh_flags & 0x01)
 8580                                                         set $snd_buf += $mp->M_dat.MH.MH_dat.MH_ext.ext_size
 8581                                                 end
 8582                                                 set $mp = $mp->m_hdr.mh_next
 8583                                         end
 8584                                         set $rcv_cc += $so->so_rcv.sb_cc
 8585                                         set $mp = $so->so_rcv.sb_mb
 8586                                         while $mp
 8587                                                 set $rcv_buf += 256
 8588                                                 if ($mp->m_hdr.mh_flags & 0x01)
 8589                                                         set $rcv_buf += $mp->M_dat.MH.MH_dat.MH_ext.ext_size
 8590                                                 end
 8591                                                 set $mp = $mp->m_hdr.mh_next
 8592                                         end
 8593                                 end
 8594                                 set $pcb0 = $pcb0->inp_hash.le_next
 8595                                 printf "\n"
 8596                         end
 8597                 end
 8598                 set $i += 1
 8599                 set $hashbase += 1
 8600                 set $head = *(uintptr_t *)$hashbase
 8601         end
 8602         printf "total seen %ld snd_cc %ld rcv_cc %ld\n", $pcbseen, $snd_cc, $rcv_cc
 8603         printf "total snd_buf %u rcv_buf %u \n", (unsigned int)$snd_buf, (unsigned int)$rcv_buf
 8604         printf "port hash base is %p\n", $pcbi->porthashbase
 8605         set $i = 0
 8606         set $hashbase = $pcbi->porthashbase
 8607         set $head = *(uintptr_t *)$hashbase
 8608         while $i < $hashsize
 8609                 if $head != 0
 8610                         set $pcb0 = (struct inpcbport *)$head
 8611                         while $pcb0  != 0
 8612                                 printf "\t"
 8613                                 _dump_inpcbport $pcb0
 8614                                 printf "\n"
 8615                                 set $pcb0 = $pcb0->phd_hash.le_next
 8616                         end
 8617                 end
 8618                 set $i += 1
 8619                 set $hashbase += 1
 8620                 set $head = *(uintptr_t *)$hashbase
 8621         end
 8622 end
 8623 
 8624 set $N_TIME_WAIT_SLOTS=128
 8625 
 8626 define show_tcp_timewaitslots
 8627         set $slot = -1
 8628         set $all = 0
 8629         if $argc == 1
 8630                 if (int)$arg0 == -1
 8631                         set $all = 1
 8632                 else
 8633                         set $slot = (int)$arg0
 8634                 end
 8635         end
 8636         printf "time wait slot size %d cur_tw_slot %ld\n", $N_TIME_WAIT_SLOTS, cur_tw_slot
 8637         set $i = 0
 8638         while $i < $N_TIME_WAIT_SLOTS
 8639                 set $perslot = 0
 8640                 set $head = (uintptr_t *)time_wait_slots[$i]
 8641                 if $i == $slot || $slot == -1
 8642                         if $head != 0
 8643                                 set $pcb0 = (struct inpcb *)$head
 8644                                 while $pcb0  != 0
 8645                                         set $perslot += 1
 8646                                         set $pcb0 = $pcb0->inp_list.le_next
 8647                                 end
 8648                         end
 8649                         printf "  slot %ld count %ld\n", $i, $perslot
 8650                 end
 8651                 if $all ||  $i == $slot
 8652                         if $head != 0
 8653                                 set $pcb0 = (struct inpcb *)$head
 8654                                 while $pcb0  != 0
 8655                                         printf "\t"
 8656                                         _dump_inpcb $pcb0 $IPPROTO_TCP
 8657                                         printf "\n"
 8658                                         set $pcb0 = $pcb0->inp_list.le_next
 8659                                 end
 8660                         end
 8661                 end
 8662                 set $i += 1
 8663         end
 8664 end
 8665 document show_tcp_timewaitslots
 8666 Syntax: (gdb) show_tcp_timewaitslots
 8667 | Print the list of TCP protocol control block in the TIMEWAIT state
 8668 | Pass -1 to see the list of PCB for each slot
 8669 | Pass a slot number to see information for that slot with the list of PCB
 8670 end
 8671 
 8672 define show_tcp_pcbinfo
 8673         _dump_pcbinfo &tcbinfo $IPPROTO_TCP
 8674 end
 8675 document show_tcp_pcbinfo
 8676 Syntax: (gdb) show_tcp_pcbinfo
 8677 | Print the list of TCP protocol control block information
 8678 end
 8679 
 8680 
 8681 define show_udp_pcbinfo
 8682         _dump_pcbinfo &udbinfo $IPPROTO_UDP
 8683 end
 8684 document show_udp_pcbinfo
 8685 Syntax: (gdb) show_udp_pcbinfo
 8686 | Print the list of UDP protocol control block information
 8687 end
 8688 
 8689 define showbpfdtab
 8690     set $myi = 0
 8691     while ($myi < bpf_dtab_size)
 8692         if (bpf_dtab[$myi] != 0)
 8693                 printf "Address 0x%x, bd_next 0x%x\n", bpf_dtab[$myi], bpf_dtab[$myi]->bd_next
 8694                 print *bpf_dtab[$myi]
 8695         end
 8696         set $myi = $myi + 1
 8697     end
 8698 end
 8699 
 8700 define printvnodepathint_recur
 8701         if $arg0 != 0
 8702                 if ($arg0->v_flag & 0x000001) && ($arg0->v_mount != 0)
 8703                         if $arg0->v_mount->mnt_vnodecovered != 0
 8704                                 printvnodepathint_recur  $arg0->v_mount->mnt_vnodecovered $arg0->v_mount->mnt_vnodecovered->v_name
 8705                         end
 8706                 else
 8707                         printvnodepathint_recur $arg0->v_parent $arg0->v_parent->v_name
 8708                         printf "/%s", $arg1
 8709                 end
 8710         end
 8711 end
 8712 
 8713 define showvnodepath
 8714         set $vp = (struct vnode *)$arg0
 8715         if $vp != 0
 8716                 if ($vp->v_flag & 0x000001) && ($vp->v_mount != 0) && ($vp->v_mount->mnt_flag & 0x00004000)
 8717                         printf "/"
 8718                 else
 8719                         printvnodepathint_recur $vp $vp->v_name
 8720                 end
 8721         end
 8722         printf "\n"
 8723 end
 8724 
 8725 document showvnodepath
 8726 Syntax: (gdb) showvnodepath <vnode>
 8727 | Prints the path for a vnode
 8728 end
 8729 
 8730 define showallvols
 8731         printf "volume    "
 8732     showptrhdrpad
 8733     printf "  mnt_data  "
 8734     showptrhdrpad
 8735     printf "  mnt_devvp "
 8736     showptrhdrpad
 8737     printf "  typename    mountpoint\n"
 8738         set $kgm_vol = (mount_t) mountlist.tqh_first
 8739         while $kgm_vol
 8740         showptr $kgm_vol
 8741         printf "  "
 8742         showptr $kgm_vol->mnt_data
 8743         printf "  "
 8744         showptr $kgm_vol->mnt_devvp
 8745         printf "  "
 8746                 if  ($kgm_vol->mnt_vtable->vfc_name[0] == 'h') && \
 8747                     ($kgm_vol->mnt_vtable->vfc_name[1] == 'f') && \
 8748                     ($kgm_vol->mnt_vtable->vfc_name[2] == 's') && \
 8749                     ($kgm_vol->mnt_vtable->vfc_name[3] == '\0')
 8750                         set $kgm_hfsmount = \
 8751                             (struct hfsmount *) $kgm_vol->mnt_data
 8752                         if $kgm_hfsmount->hfs_freezing_proc != 0
 8753                                 printf "FROZEN hfs  "
 8754                         else
 8755                                 printf "hfs         "
 8756                         end
 8757                 else
 8758                         printf "%-10s  ", $kgm_vol->mnt_vtable->vfc_name
 8759                 end
 8760                 printf "%s\n", $kgm_vol->mnt_vfsstat.f_mntonname
 8761                 
 8762                 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
 8763         end
 8764 end
 8765 
 8766 document showallvols
 8767 Syntax: (gdb) showallvols
 8768 | Display a summary of mounted volumes
 8769 end
 8770 
 8771 define showvnodeheader
 8772         printf "vnode     "
 8773     showptrhdrpad
 8774     printf "  usecount  iocount  v_data    "
 8775     showptrhdrpad
 8776     printf "  vtype  parent    "
 8777     showptrhdrpad    
 8778     printf "  name\n"
 8779 end
 8780 
 8781 define showvnodeint
 8782         set $kgm_vnode = (vnode_t) $arg0
 8783         showptr $kgm_vnode
 8784         printf "  %8d  ", $kgm_vnode->v_usecount
 8785         printf "%7d  ", $kgm_vnode->v_iocount
 8786 # print information about clean/dirty blocks?
 8787         showptr $kgm_vnode->v_data
 8788     printf "  "
 8789         # print the vtype, using the enum tag
 8790         set $kgm_vtype = $kgm_vnode->v_type
 8791         if $kgm_vtype == VNON
 8792                 printf "VNON   "
 8793         end
 8794         if $kgm_vtype == VREG
 8795                 printf "VREG   "
 8796         end
 8797         if $kgm_vtype == VDIR
 8798                 printf "VDIR   "
 8799         end
 8800         if $kgm_vtype == VBLK
 8801                 printf "VBLK   "
 8802         end
 8803         if $kgm_vtype == VCHR
 8804                 printf "VCHR   "
 8805         end
 8806         if $kgm_vtype == VLNK
 8807                 printf "VLNK   "
 8808         end
 8809         if $kgm_vtype == VSOCK
 8810                 printf "VSOCK  "
 8811         end
 8812         if $kgm_vtype == VFIFO
 8813                 printf "VFIFO  "
 8814         end
 8815         if $kgm_vtype == VBAD
 8816                 printf "VBAD   "
 8817         end
 8818         if ($kgm_vtype < VNON) || ($kgm_vtype > VBAD)
 8819                 printf "%5d  ", $kgm_vtype
 8820         end
 8821 
 8822         showptr $kgm_vnode->v_parent
 8823     printf "  "
 8824         if ($kgm_vnode->v_name != 0)
 8825                 printf "%s\n", $kgm_vnode->v_name
 8826         else 
 8827                 # If this is HFS vnode, get name from the cnode
 8828                 if ($kgm_vnode->v_tag == 16) 
 8829                         set $kgm_cnode = (struct cnode *)$kgm_vnode->v_data
 8830                         printf "hfs: %s\n", (char *)$kgm_cnode->c_desc->cd_nameptr
 8831                 else 
 8832                         printf "\n"
 8833                 end
 8834         end
 8835 end
 8836 
 8837 define showvnode
 8838         showvnodeheader
 8839         showvnodeint $arg0
 8840 end
 8841 
 8842 document showvnode
 8843 Syntax: (gdb) showvnode <vnode>
 8844 | Display info about one vnode
 8845 end
 8846 
 8847 define showvolvnodes
 8848         showvnodeheader
 8849         set $kgm_vol = (mount_t) $arg0
 8850         set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
 8851         while $kgm_vnode
 8852                 showvnodeint $kgm_vnode
 8853                 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
 8854         end
 8855 end
 8856 
 8857 document showvolvnodes
 8858 Syntax: (gdb) showvolvnodes <mouont_t>
 8859 | Display info about all vnodes of a given mount_t
 8860 end
 8861 
 8862 define showvolbusyvnodes
 8863         showvnodeheader
 8864         set $kgm_vol = (mount_t) $arg0
 8865         set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
 8866         while $kgm_vnode
 8867                 if $kgm_vnode->v_iocount != 0
 8868                         showvnodeint $kgm_vnode
 8869                 end
 8870                 set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
 8871         end
 8872 end
 8873 
 8874 document showvolbusyvnodes
 8875 Syntax: (gdb) showvolbusyvnodes <mount_t>
 8876 | Display info about busy (iocount!=0) vnodes of a given mount_t
 8877 end
 8878 
 8879 define showallbusyvnodes
 8880         showvnodeheader
 8881         set $kgm_vol = (mount_t) mountlist.tqh_first
 8882         while $kgm_vol
 8883                 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
 8884                 while $kgm_vnode
 8885                         if $kgm_vnode->v_iocount != 0
 8886                                 showvnodeint $kgm_vnode
 8887                         end
 8888                         set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
 8889                 end
 8890                 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
 8891         end
 8892 end
 8893 
 8894 document showallbusyvnodes
 8895 Syntax: (gdb) showallbusyvnodes <vnode>
 8896 | Display info about all busy (iocount!=0) vnodes
 8897 end
 8898 
 8899 define showallvnodes
 8900         showvnodeheader
 8901         set $kgm_vol = (mount_t) mountlist.tqh_first
 8902         while $kgm_vol
 8903                 set $kgm_vnode = (vnode_t) $kgm_vol.mnt_vnodelist.tqh_first
 8904                 while $kgm_vnode
 8905                         showvnodeint $kgm_vnode
 8906                         set $kgm_vnode = (vnode_t) $kgm_vnode->v_mntvnodes.tqe_next
 8907                 end
 8908                 set $kgm_vol = (mount_t) $kgm_vol->mnt_list.tqe_next
 8909         end
 8910 end
 8911 
 8912 document showallvnodes
 8913 Syntax: (gdb) showallvnodes
 8914 | Display info about all vnodes
 8915 end
 8916 
 8917 define _showvnodelockheader
 8918     printf "*  type   W  held by        lock type  start               end\n"
 8919     printf "-  -----  -  -------------  ---------  ------------------  ------------------\n"
 8920 end
 8921 
 8922 define _showvnodelock
 8923     set $kgm_svl_lock = ((struct lockf *)$arg0)
 8924 
 8925     # decode flags
 8926     set $kgm_svl_flags = $kgm_svl_lock->lf_flags
 8927     set $kgm_svl_type = $kgm_svl_lock->lf_type
 8928     if ($kgm_svl_flags & 0x20)
 8929         printf "flock"
 8930     end
 8931     if ($kgm_svl_flags & 0x40)
 8932         printf "posix"
 8933     end
 8934     if ($kgm_svl_flags & 0x80)
 8935         printf "prov "
 8936     end
 8937     if ($kgm_svl_flags & 0x10)
 8938         printf "  W  "
 8939     else
 8940         printf "  .  "
 8941     end
 8942 
 8943     # POSIX file vs. advisory range locks
 8944     if ($kgm_svl_flags & 0x40)
 8945         set $kgm_svl_proc = (proc_t)$kgm_svl_lock->lf_id
 8946         printf "PID %8d   ", $kgm_svl_proc->p_pid
 8947     else
 8948         printf "ID 0x%08x  ", $kgm_svl_lock->lf_id
 8949     end
 8950 
 8951     # lock type
 8952     if ($kgm_svl_type == 1)
 8953                 printf "shared     "
 8954     else
 8955         if ($kgm_svl_type == 3)
 8956                 printf "exclusive  "
 8957         else
 8958             if ($kgm_svl_type == 2)
 8959                 printf "unlock     "
 8960             else
 8961                 printf "unknown    "
 8962             end
 8963         end
 8964     end
 8965 
 8966     # start and stop
 8967     printf "0x%016x..", $kgm_svl_lock->lf_start
 8968     printf "0x%016x  ", $kgm_svl_lock->lf_end
 8969     printf "\n"
 8970 end
 8971 # Body of showvnodelocks, not including header
 8972 define _showvnodelocks
 8973     set $kgm_svl_vnode = ((vnode_t)$arg0)
 8974     set $kgm_svl_lockiter = $kgm_svl_vnode->v_lockf
 8975     while ($kgm_svl_lockiter != 0)
 8976         # locks that are held
 8977         printf "H  "
 8978         _showvnodelock $kgm_svl_lockiter
 8979 
 8980         # and any locks blocked by them
 8981         set $kgm_svl_blocker = $kgm_svl_lockiter->lf_blkhd.tqh_first
 8982         while ($kgm_svl_blocker != 0)
 8983             printf ">  "
 8984             _showvnodelock $kgm_svl_blocker
 8985             set $kgm_svl_blocker = $kgm_svl_blocker->lf_block.tqe_next
 8986         end
 8987 
 8988         # and on to the next one...
 8989         set $kgm_svl_lockiter = $kgm_svl_lockiter->lf_next
 8990     end
 8991 end
 8992 
 8993 
 8994 define showvnodelocks
 8995     if ($argc == 1)
 8996         _showvnodelockheader
 8997         _showvnodelocks $arg0
 8998     else
 8999         printf "| Usage:\n|\n"
 9000         help showvnodelocks
 9001     end
 9002 end
 9003 
 9004 document showvnodelocks
 9005 Syntax: (gdb) showvnodelocks <vnode_t>
 9006 | Given a vnodet pointer, display the list of advisory record locks for the
 9007 | referenced pvnodes
 9008 end
 9009 
 9010 define showbootargs
 9011         printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
 9012 end
 9013 
 9014 document showbootargs
 9015 Syntax: showbootargs
 9016 | Display boot arguments passed to the target kernel
 9017 end
 9018 
 9019 define showbootermemorymap
 9020         if ($kgm_mtype == $kgm_mtype_i386)
 9021             set $kgm_voffset = 0
 9022         else
 9023             if ($kgm_mtype == $kgm_mtype_x86_64)
 9024                 set $kgm_voffset = 0xFFFFFF8000000000ULL
 9025             else
 9026                 echo showbootermemorymap not supported on this architecture
 9027             end
 9028         end
 9029 
 9030         set $kgm_boot_args = kernelBootArgs
 9031         set $kgm_msize = kernelBootArgs->MemoryMapDescriptorSize
 9032         set $kgm_mcount = kernelBootArgs->MemoryMapSize / $kgm_msize
 9033         set $kgm_i = 0
 9034        
 9035         printf "Type       Physical Start   Number of Pages  Virtual Start    Attributes\n"
 9036         while $kgm_i < $kgm_mcount
 9037              set $kgm_mptr = (EfiMemoryRange *)((unsigned long)kernelBootArgs->MemoryMap + $kgm_voffset + $kgm_i * $kgm_msize)
 9038 #            p/x *$kgm_mptr
 9039              if $kgm_mptr->Type == 0
 9040                printf "Reserved  "
 9041              end
 9042              if $kgm_mptr->Type == 1
 9043                printf "LoaderCode"
 9044              end
 9045              if $kgm_mptr->Type == 2
 9046                printf "LoaderData"
 9047              end
 9048              if $kgm_mptr->Type == 3
 9049                printf "BS_code   "
 9050              end
 9051              if $kgm_mptr->Type == 4
 9052                printf "BS_data   "
 9053              end
 9054              if $kgm_mptr->Type == 5
 9055                printf "RT_code   "
 9056              end
 9057              if $kgm_mptr->Type == 6
 9058                printf "RT_data   "
 9059              end
 9060              if $kgm_mptr->Type == 7
 9061                printf "Convention"
 9062              end
 9063              if $kgm_mptr->Type == 8
 9064                printf "Unusable  "
 9065              end
 9066              if $kgm_mptr->Type == 9
 9067                printf "ACPI_recl "
 9068              end
 9069              if $kgm_mptr->Type == 10
 9070                printf "ACPI_NVS  "
 9071              end
 9072              if $kgm_mptr->Type == 11
 9073                printf "MemMapIO  "
 9074              end
 9075              if $kgm_mptr->Type == 12
 9076                printf "MemPortIO "
 9077              end
 9078              if $kgm_mptr->Type == 13
 9079                printf "PAL_code  "
 9080              end
 9081              if $kgm_mptr->Type > 13
 9082                printf "UNKNOWN   "
 9083              end
 9084 
 9085              printf " %016llx %016llx", $kgm_mptr->PhysicalStart, $kgm_mptr->NumberOfPages
 9086              if $kgm_mptr->VirtualStart != 0
 9087                printf " %016llx", $kgm_mptr->VirtualStart
 9088              else
 9089                printf "                 "
 9090              end
 9091              printf " %016llx\n", $kgm_mptr->Attribute
 9092              set $kgm_i = $kgm_i + 1
 9093        end
 9094 end
 9095 
 9096 document showbootermemorymap
 9097 Syntax: (gdb) showbootermemorymap
 9098 | Prints out the phys memory map from kernelBootArgs
 9099 end
 9100 
 9101 
 9102 define showstacksaftertask
 9103     set $kgm_head_taskp = &tasks
 9104     set $kgm_taskp = (struct task *)$arg0
 9105     set $kgm_taskp = (struct task *)$kgm_taskp->tasks.next
 9106     while $kgm_taskp != $kgm_head_taskp
 9107         showtaskheader
 9108         showtaskint $kgm_taskp
 9109         set $kgm_head_actp = &($kgm_taskp->threads)
 9110         set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 9111         while $kgm_actp != $kgm_head_actp
 9112             showactheader
 9113             if ($decode_wait_events > 0)
 9114                showactint $kgm_actp 1
 9115             else
 9116                showactint $kgm_actp 2
 9117             end
 9118             set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 9119         end
 9120         printf "\n"
 9121         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 9122     end
 9123 end
 9124 document showstacksaftertask
 9125 Syntax: (gdb) showstacksaftertask <task>
 9126 | Routine to print out all stacks (as in showallstacks) starting after a given task
 9127 | Useful if that gdb refuses to print a certain task's stack.
 9128 end
 9129 
 9130 define showpmworkqueueint
 9131     set $kgm_pm_workqueue = (IOPMWorkQueue *)$arg0
 9132     set $kgm_pm_wq = &($kgm_pm_workqueue->fWorkQueue)
 9133     set $kgm_pm_wqe = (IOServicePM *)$kgm_pm_wq->next
 9134     while ((queue_entry_t) $kgm_pm_wqe != (queue_entry_t) $kgm_pm_wq)
 9135         printf "service   "
 9136         showptrhdrpad
 9137         printf "  ps  ms  wr  name\n"
 9138         showptr $kgm_pm_wqe->Owner
 9139         printf "  "
 9140         printf "%02d  ", $kgm_pm_wqe->CurrentPowerState
 9141         printf "%02d  ", $kgm_pm_wqe->MachineState
 9142         printf "%02d  ", $kgm_pm_wqe->WaitReason
 9143         printf "%s\n", $kgm_pm_wqe->Name
 9144         printf "request   "
 9145         showptrhdrpad
 9146         printf "  type  next      "
 9147         showptrhdrpad
 9148         printf "  root      "
 9149         showptrhdrpad
 9150         printf "  work_wait   free_wait\n"
 9151         set $kgm_pm_rq = &($kgm_pm_wqe->RequestHead)
 9152         set $kgm_pm_rqe = (IOPMRequest *)$kgm_pm_rq->next
 9153         while ((queue_entry_t) $kgm_pm_rqe != (queue_entry_t) $kgm_pm_rq)
 9154             showptr $kgm_pm_rqe
 9155             printf "  0x%02x  ", $kgm_pm_rqe->fType
 9156             showptr $kgm_pm_rqe->fRequestNext
 9157             printf "  "
 9158             showptr $kgm_pm_rqe->fRequestRoot
 9159             printf "  0x%08x  0x%08x\n", $kgm_pm_rqe->fWorkWaitCount, $kgm_pm_rqe->fFreeWaitCount
 9160             showptrhdrpad
 9161             printf "            args  "
 9162             showptr $kgm_pm_rqe->fArg0
 9163             printf "  "
 9164             showptr $kgm_pm_rqe->fArg1
 9165             printf "  "
 9166             showptr $kgm_pm_rqe->fArg2
 9167             printf "\n"
 9168             set $kgm_pm_rqe = (IOPMRequest *)$kgm_pm_rqe->fCommandChain.next
 9169         end
 9170         printf "\n"
 9171         set $kgm_pm_wqe = (IOServicePM *)$kgm_pm_wqe->WorkChain.next
 9172     end
 9173 end
 9174 
 9175 define showpmworkqueue
 9176     printf "IOPMWorkQueue "
 9177     showptr gIOPMWorkQueue
 9178     printf " length "
 9179     printf "%u", gIOPMWorkQueue->fQueueLength
 9180     printf "\n"
 9181     if (gIOPMWorkQueue->fQueueLength > 0)
 9182         showpmworkqueueint gIOPMWorkQueue
 9183     end
 9184 end
 9185 
 9186 document showpmworkqueue
 9187 Syntax: (gdb) showpmworkqueue
 9188 | Display the IOPMWorkQueue object
 9189 end
 9190 
 9191 define showioservicepm
 9192     set $kgm_iopmpriv = (IOServicePM *)$arg0
 9193     printf "{ "
 9194     printf "MachineState = %d (", $kgm_iopmpriv->MachineState
 9195     if ( $kgm_iopmpriv->MachineState == 0 )
 9196         printf "kIOPM_Finished"
 9197     else
 9198     if ( $kgm_iopmpriv->MachineState == 1 )
 9199         printf "kIOPM_OurChangeTellClientsPowerDown"
 9200     else
 9201     if ( $kgm_iopmpriv->MachineState == 2 )
 9202         printf "kIOPM_OurChangeTellPriorityClientsPowerDown"
 9203     else
 9204     if ( $kgm_iopmpriv->MachineState == 3 )
 9205         printf "kIOPM_OurChangeNotifyInterestedDriversWillChange"
 9206     else
 9207     if ( $kgm_iopmpriv->MachineState == 4 )
 9208         printf "kIOPM_OurChangeSetPowerState"
 9209     else
 9210     if ( $kgm_iopmpriv->MachineState == 5 )
 9211         printf "kIOPM_OurChangeWaitForPowerSettle"
 9212     else
 9213     if ( $kgm_iopmpriv->MachineState == 6 )
 9214         printf "kIOPM_OurChangeNotifyInterestedDriversDidChange"
 9215     else
 9216     if ( $kgm_iopmpriv->MachineState == 7 )
 9217         printf "kIOPM_OurChangeTellCapabilityDidChange"
 9218     else
 9219     if ( $kgm_iopmpriv->MachineState == 8 )
 9220         printf "kIOPM_OurChangeFinish"
 9221     else
 9222     if ( $kgm_iopmpriv->MachineState == 9 )
 9223         printf "Unused_MachineState_9"
 9224     else
 9225     if ( $kgm_iopmpriv->MachineState == 10 )
 9226         printf "kIOPM_ParentChangeTellPriorityClientsPowerDown"
 9227     else
 9228     if ( $kgm_iopmpriv->MachineState == 11 )
 9229         printf "kIOPM_ParentChangeNotifyInterestedDriversWillChange"
 9230     else
 9231     if ( $kgm_iopmpriv->MachineState == 12 )
 9232         printf "kIOPM_ParentChangeSetPowerState"
 9233     else
 9234     if ( $kgm_iopmpriv->MachineState == 13 )
 9235         printf "kIOPM_ParentChangeWaitForPowerSettle"
 9236     else
 9237     if ( $kgm_iopmpriv->MachineState == 14)
 9238         printf "kIOPM_ParentChangeNotifyInterestedDriversDidChange"
 9239     else
 9240     if ( $kgm_iopmpriv->MachineState == 15)
 9241         printf "kIOPM_ParentChangeTellCapabilityDidChange"
 9242     else
 9243     if ( $kgm_iopmpriv->MachineState == 16)
 9244         printf "kIOPM_ParentChangeAcknowledgePowerChange"
 9245     else
 9246     if ( $kgm_iopmpriv->MachineState == 17)
 9247         printf "kIOPM_NotifyChildrenStart"
 9248     else
 9249     if ( $kgm_iopmpriv->MachineState == 18)
 9250         printf "kIOPM_NotifyChildrenOrdered"
 9251     else
 9252     if ( $kgm_iopmpriv->MachineState == 19)
 9253         printf "kIOPM_NotifyChildrenDelayed"
 9254     else
 9255     if ( $kgm_iopmpriv->MachineState == 20)
 9256         printf "kIOPM_SyncTellClientsPowerDown"
 9257     else
 9258     if ( $kgm_iopmpriv->MachineState == 21)
 9259         printf "kIOPM_SyncTellPriorityClientsPowerDown"
 9260     else
 9261     if ( $kgm_iopmpriv->MachineState == 22)
 9262         printf "kIOPM_SyncNotifyWillChange"
 9263     else
 9264     if ( $kgm_iopmpriv->MachineState == 23)
 9265         printf "kIOPM_SyncNotifyDidChange"
 9266     else
 9267     if ( $kgm_iopmpriv->MachineState == 24)
 9268         printf "kIOPM_SyncTellCapabilityDidChange"
 9269     else
 9270     if ( $kgm_iopmpriv->MachineState == 25)
 9271         printf "kIOPM_SyncFinish"
 9272     else
 9273     if ( $kgm_iopmpriv->MachineState == 26)
 9274         printf "kIOPM_TellCapabilityChangeDone"
 9275     else
 9276     if ( $kgm_iopmpriv->MachineState == 27)
 9277         printf "kIOPM_DriverThreadCallDone"
 9278     else
 9279         printf "Unknown_MachineState"
 9280     end
 9281     end
 9282     end
 9283     end
 9284     end
 9285     end
 9286     end
 9287     end
 9288     end
 9289     end
 9290     end
 9291     end
 9292     end
 9293     end
 9294     end
 9295     end
 9296     end
 9297     end
 9298     end
 9299     end
 9300     end
 9301     end
 9302     end
 9303     end
 9304     end
 9305     end
 9306     end
 9307         end
 9308         printf "), "
 9309         
 9310         if ( $kgm_iopmpriv->MachineState != 20 )
 9311         printf "DriverTimer = %d, ",(unsigned int)$kgm_iopmpriv->DriverTimer
 9312         printf "SettleTime  = %d, ",(unsigned int)$kgm_iopmpriv->SettleTimeUS
 9313         printf "HeadNoteFlags = %08x, ",(unsigned int)$kgm_iopmpriv->HeadNoteChangeFlags
 9314         printf "HeadNotePendingAcks = %x, ",(unsigned int)$kgm_iopmpriv->HeadNotePendingAcks
 9315         end
 9316 
 9317     if ( $kgm_iopmpriv->DeviceOverrideEnabled != 0 )
 9318         printf"DeviceOverrides, "
 9319     end
 9320         
 9321     printf "DeviceDesire = %d, ",(unsigned int)$kgm_iopmpriv->DeviceDesire
 9322     printf "DesiredPowerState = %d, ",(unsigned int)$kgm_iopmpriv->DesiredPowerState
 9323     printf "PreviousRequest = %d }\n",(unsigned int)$kgm_iopmpriv->PreviousRequestPowerFlags
 9324 end
 9325 
 9326 document showioservicepm
 9327 Syntax: (gdb) showioservicepm <IOServicePM pointer>
 9328 | Routine to dump the IOServicePM object
 9329 end
 9330 
 9331 define showregistryentryrecursepmstate
 9332     set $kgm_re         = (IOService *)$arg1
 9333     set $kgm$arg0_stack = (unsigned long long) $arg2
 9334 
 9335     if ($arg3)
 9336         set $kgm$arg0_stack = $kgm$arg0_stack | (1ULL << $kgm_reg_depth)
 9337     else
 9338         set $kgm$arg0_stack = $kgm$arg0_stack & ~(1ULL << $kgm_reg_depth)
 9339     end
 9340 
 9341     dictget $kgm_re->fRegistryTable $kgm_childkey
 9342     set $kgm$arg0_child_array = (OSArray *) $kgm_result
 9343 
 9344     if ($kgm$arg0_child_array)
 9345         set $kgm$arg0_child_count = $kgm$arg0_child_array->count
 9346     else
 9347         set $kgm$arg0_child_count = 0
 9348     end
 9349 
 9350     if ($kgm$arg0_child_count)
 9351         set $kgm$arg0_stack = $kgm$arg0_stack | (2ULL << $kgm_reg_depth)
 9352     else
 9353         set $kgm$arg0_stack = $kgm$arg0_stack & ~(2ULL << $kgm_reg_depth)
 9354     end
 9355 
 9356     indent $kgm_reg_depth $kgm$arg0_stack
 9357     printf "+-o "
 9358 
 9359     dictget $kgm_re->fRegistryTable $kgm_namekey
 9360     if ($kgm_result == 0)
 9361         dictget $kgm_re->fRegistryTable gIONameKey
 9362     end
 9363     if ($kgm_result == 0)
 9364         dictget $kgm_re->fPropertyTable gIOClassKey
 9365     end
 9366 
 9367     if ($kgm_result != 0)
 9368         printf "%s <%p>", ((OSString *)$kgm_result)->string, $kgm_re
 9369     else
 9370         if (((IOService*)$kgm_re)->pwrMgt &&  ((IOService*)$kgm_re)->pwrMgt->Name)
 9371             printf "%s <", ((IOService*)$kgm_re)->pwrMgt->Name
 9372             showptr $kgm_re
 9373             printf ">"
 9374         else
 9375             printf "?? <"
 9376             showptr $kgm_re
 9377             printf ">"
 9378         end
 9379     end
 9380 
 9381     if (((IOService*)$kgm_re)->pwrMgt )
 9382         printf " Current Power State: %ld ", ((IOService*)$kgm_re)->pwrMgt->CurrentPowerState
 9383         #printf " Mach State %ld", ((IOService*)$kgm_re)->pwrMgt->MachineState
 9384         showioservicepm ((IOService*)$kgm_re)->pwrMgt
 9385     end
 9386     printf "\n"
 9387    
 9388 
 9389     # recurse
 9390     if ($kgm$arg0_child_count != 0)
 9391 
 9392         set $kgm_reg_depth = $kgm_reg_depth + 1
 9393         set $kgm$arg0_child_idx = 0
 9394 
 9395         while ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 9396             set $kgm_re = $kgm$arg0_child_array->array[$kgm$arg0_child_idx++]
 9397             set $kgm_more_sib = ($kgm$arg0_child_idx < $kgm$arg0_child_count)
 9398             if $kgm_reg_depth >= $kgm_reg_depth_max + 1
 9399                loop_break
 9400             end
 9401             showregistryentryrecursepmstate _$arg0 $kgm_re $kgm$arg0_stack $kgm_more_sib
 9402         end
 9403 
 9404         set $kgm_reg_depth = $kgm_reg_depth - 1
 9405     end
 9406 end
 9407 
 9408 define showregistryentryintpmstate
 9409     if !$kgm_reg_plane
 9410        set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
 9411     end
 9412 
 9413     if !$kgm_reg_plane
 9414        printf "Please load kgmacros after KDP attaching to the target.\n"
 9415     else
 9416        set $kgm_namekey   = (OSSymbol *) $kgm_reg_plane->nameKey
 9417        set $kgm_childkey  = (OSSymbol *) $kgm_reg_plane->keys[1]
 9418        showregistryentryrecursepmstate _ $arg0 0 0
 9419     end
 9420 end
 9421 
 9422 define showregistrypmstate
 9423 #    setregistryplane gIOPowerPlane
 9424     set $kgm_reg_depth  = 0
 9425     set $kgm_show_props = 1
 9426     showregistryentryintpmstate gRegistryRoot
 9427 end
 9428 
 9429 document showregistrypmstate
 9430 Syntax: (gdb) showregistrypmstate
 9431 | Routine to dump the PM state of each IOPower registry entry
 9432 end
 9433 
 9434 define showstacksafterthread
 9435     set $kgm_head_taskp = &tasks
 9436     set $kgm_actp = (struct thread *)$arg0
 9437     set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 9438     set $kgm_taskp = (struct task *)$kgm_actp->task
 9439     while $kgm_taskp != $kgm_head_taskp
 9440         showtaskheader
 9441         showtaskint $kgm_taskp
 9442         set $kgm_head_actp = &($kgm_taskp->threads)
 9443         if $kgm_actp == 0
 9444             set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
 9445         end
 9446         while $kgm_actp != $kgm_head_actp
 9447             showactheader
 9448             if ($decode_wait_events > 0)
 9449                showactint $kgm_actp 1
 9450             else
 9451                showactint $kgm_actp 2
 9452             end
 9453             set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
 9454         end
 9455         printf "\n"
 9456         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
 9457         set $kgm_actp = 0
 9458     end
 9459 end
 9460 
 9461 document showstacksafterthread
 9462 Syntax: (gdb) showstacksafterthread <thread>
 9463 | Routine to print out all stacks (as in showallstacks) starting after a given thread
 9464 | Useful if that gdb refuses to print a certain task's stack.
 9465 end
 9466 
 9467 define kdp-reenter
 9468        set kdp_reentry_deadline = ((unsigned) $arg0)*1000
 9469        continue
 9470 end
 9471 
 9472 document kdp-reenter
 9473 Syntax: (gdb) kdp-reenter <seconds>
 9474 | Schedules reentry into the debugger after <seconds> seconds, and resumes
 9475 | the target system.
 9476 end
 9477 
 9478 define _if_present
 9479     if (!$arg0)
 9480         printf " not"
 9481     end
 9482     printf " present"
 9483 end
 9484 
 9485 define showMCAstate
 9486     if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
 9487         printf "Not available for current architecture.\n"
 9488     else
 9489         printf "MCA"
 9490         _if_present mca_MCA_present
 9491         printf ", control MSR"
 9492         _if_present mca_control_MSR_present
 9493         printf ", threshold status"
 9494         _if_present mca_threshold_status_present
 9495         printf "\n%d error banks, ", mca_error_bank_count
 9496         printf "family code 0x%x, ", mca_family
 9497         printf "machine-check dump state: %d\n", mca_dump_state
 9498         set $kgm_cpu = 0
 9499         while cpu_data_ptr[$kgm_cpu] != 0
 9500             set $kgm_mcp = cpu_data_ptr[$kgm_cpu]->cpu_mca_state
 9501             if $kgm_mcp
 9502                 printf "CPU %d:", $kgm_cpu
 9503                 printf " mca_mcg_ctl: 0x%016llx", $kgm_mcp->mca_mcg_ctl
 9504                 printf " mca_mcg_status: 0x%016llx\n", $kgm_mcp->mca_mcg_status.u64
 9505                 printf "bank   "
 9506                 printf "mca_mci_ctl        "
 9507                 printf "mca_mci_status     "
 9508                 printf "mca_mci_addr       "
 9509                 printf "mca_mci_misc\n"
 9510                 set $kgm_bank = 0
 9511                 while $kgm_bank < mca_error_bank_count
 9512                     set $kgm_bp = &$kgm_mcp->mca_error_bank[$kgm_bank]
 9513                     printf " %2d:", $kgm_bank
 9514                     printf " 0x%016llx", $kgm_bp->mca_mci_ctl
 9515                     printf " 0x%016llx", $kgm_bp->mca_mci_status.u64
 9516                     printf " 0x%016llx", $kgm_bp->mca_mci_addr
 9517                     printf " 0x%016llx\n", $kgm_bp->mca_mci_misc
 9518                     set $kgm_bank = $kgm_bank + 1
 9519                 end
 9520             end
 9521             set $kgm_cpu = $kgm_cpu + 1
 9522         end
 9523     end
 9524 end
 9525 
 9526 document showMCAstate
 9527 Syntax: showMCAstate
 9528 | Print machine-check register state after MC exception.
 9529 end
 9530 
 9531 define _pt_step
 9532     #
 9533     # Step to lower-level page table and print attributes
 9534     #   $kgm_pt_paddr: current page table entry physical address
 9535     #   $kgm_pt_index: current page table entry index (0..511)
 9536     # returns
 9537     #   $kgm_pt_paddr: next level page table entry physical address
 9538     #                  or null if invalid
 9539     #   $kgm_pt_valid: 1 if $kgm_pt_paddr is valid, 0 if the walk
 9540     #                  should be aborted
 9541     #   $kgm_pt_large: 1 if kgm_pt_paddr is a page frame address
 9542     #                  of a large page and not another page table entry
 9543     # For $kgm_pt_verbose = 0: print nothing
 9544     #                       1: print basic information
 9545     #                       2: print basic information and hex table dump
 9546     #
 9547     set $kgm_entryp = $kgm_pt_paddr + 8*$kgm_pt_index
 9548     readphysint $kgm_entryp 64 $kgm_lcpu_self
 9549     set $entry = $kgm_readphysint_result
 9550     if $kgm_pt_verbose >= 3
 9551         set $kgm_pte_loop = 0
 9552         while $kgm_pte_loop < 512
 9553             set $kgm_pt_paddr_tmp = $kgm_pt_paddr + $kgm_pte_loop*8
 9554             readphys64 $kgm_pt_paddr_tmp
 9555             set $kgm_pte_loop = $kgm_pte_loop + 1
 9556         end
 9557     end
 9558     set $kgm_paddr_mask = ~((0xfffULL<<52) | 0xfffULL)
 9559     set $kgm_paddr_largemask = ~((0xfffULL<<52) | 0x1fffffULL)
 9560     if $kgm_pt_verbose < 2
 9561         if $entry & (0x1 << 0)
 9562             set $kgm_pt_valid = 1
 9563             if $entry & (0x1 << 7)
 9564                 set $kgm_pt_large = 1
 9565                 set $kgm_pt_paddr = $entry & $kgm_paddr_largemask
 9566             else
 9567                 set $kgm_pt_large = 0
 9568                 set $kgm_pt_paddr = $entry & $kgm_paddr_mask
 9569             end     
 9570         else
 9571             set $kgm_pt_valid = 0
 9572             set $kgm_pt_large = 0
 9573             set $kgm_pt_paddr = 0
 9574         end
 9575     else
 9576         printf "0x%016llx:\n\t0x%016llx\n\t", $kgm_entryp, $entry
 9577         if $entry & (0x1 << 0)
 9578             printf "valid"      
 9579             set $kgm_pt_paddr = $entry & $kgm_paddr_mask
 9580             set $kgm_pt_valid = 1
 9581         else
 9582             printf "invalid"
 9583             set $kgm_pt_paddr = 0
 9584             set $kgm_pt_valid = 0
 9585             # stop decoding other bits
 9586             set $entry = 0
 9587         end
 9588         if $entry & (0x1 << 1)
 9589             printf " writeable" 
 9590         else
 9591             printf " read-only" 
 9592         end
 9593         if $entry & (0x1 << 2)
 9594             printf " user" 
 9595         else
 9596             printf " supervisor" 
 9597         end
 9598         if $entry & (0x1 << 3)
 9599             printf " PWT" 
 9600         end
 9601         if $entry & (0x1 << 4)
 9602             printf " PCD" 
 9603         end
 9604         if $entry & (0x1 << 5)
 9605             printf " accessed" 
 9606         end
 9607         if $entry & (0x1 << 6)
 9608             printf " dirty" 
 9609         end
 9610         if $entry & (0x1 << 7)
 9611             printf " large" 
 9612             set $kgm_pt_large = 1
 9613         else
 9614             set $kgm_pt_large = 0
 9615         end
 9616         if $entry & (0x1 << 8)
 9617             printf " global" 
 9618         end
 9619         if $entry & (0x3 << 9)
 9620             printf " avail:0x%x", ($entry >> 9) & 0x3
 9621         end
 9622         if $entry & (0x1ULL << 63)
 9623             printf " noexec" 
 9624         end
 9625         printf "\n"
 9626     end
 9627 end
 9628 
 9629 define _pml4_walk
 9630     set $kgm_pt_paddr = $arg0
 9631     set $kgm_vaddr = $arg1
 9632     set $kgm_pt_valid = $kgm_pt_paddr != 0
 9633     set $kgm_pt_large = 0
 9634     set $kgm_pframe_offset = 0
 9635     if $kgm_pt_valid && cpu_64bit
 9636         # Look up bits 47:39 of the linear address in PML4T
 9637         set $kgm_pt_index = ($kgm_vaddr >> 39) & 0x1ffULL
 9638         set $kgm_pframe_offset = $kgm_vaddr & 0x7fffffffffULL
 9639         if $kgm_pt_verbose >= 2
 9640             printf "pml4 (index %d):\n", $kgm_pt_index
 9641         end
 9642         _pt_step
 9643     end
 9644     if $kgm_pt_valid
 9645         # Look up bits 38:30 of the linear address in PDPT
 9646         set $kgm_pt_index = ($kgm_vaddr >> 30) & 0x1ffULL
 9647         set $kgm_pframe_offset = $kgm_vaddr & 0x3fffffffULL
 9648         if $kgm_pt_verbose >= 2
 9649             printf "pdpt (index %d):\n", $kgm_pt_index
 9650         end
 9651         _pt_step
 9652     end
 9653     if $kgm_pt_valid && !$kgm_pt_large
 9654         # Look up bits 29:21 of the linear address in PDT
 9655         set $kgm_pt_index = ($kgm_vaddr >> 21) & 0x1ffULL
 9656         set $kgm_pframe_offset = $kgm_vaddr & 0x1fffffULL
 9657         if $kgm_pt_verbose >= 2
 9658             printf "pdt (index %d):\n", $kgm_pt_index
 9659         end
 9660         _pt_step
 9661     end
 9662     if $kgm_pt_valid && !$kgm_pt_large
 9663         # Look up bits 20:21 of the linear address in PT
 9664         set $kgm_pt_index = ($kgm_vaddr >> 12) & 0x1ffULL
 9665         set $kgm_pframe_offset = $kgm_vaddr & 0xfffULL
 9666         if $kgm_pt_verbose >= 2
 9667             printf "pt (index %d):\n", $kgm_pt_index
 9668         end
 9669         _pt_step
 9670     end
 9671 
 9672     if $kgm_pt_valid
 9673         set $kgm_paddr = $kgm_pt_paddr + $kgm_pframe_offset
 9674         set $kgm_paddr_isvalid = 1
 9675     else
 9676         set $kgm_paddr = 0
 9677         set $kgm_paddr_isvalid = 0
 9678     end
 9679 
 9680     if $kgm_pt_verbose >= 1
 9681         if $kgm_paddr_isvalid
 9682             readphysint $kgm_paddr 32 $kgm_lcpu_self
 9683             set $kgm_value = $kgm_readphysint_result
 9684             printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value
 9685         else
 9686             printf "(no translation)\n"
 9687         end
 9688     end
 9689 end
 9690 
 9691 define _pmap_walk_x86
 9692     set $kgm_pmap = (pmap_t) $arg0
 9693     _pml4_walk $kgm_pmap->pm_cr3 $arg1
 9694 end
 9695 
 9696 define _pmap_walk_arm_level1_section
 9697     set $kgm_tte_p = $arg0
 9698     set $kgm_tte = *$kgm_tte_p
 9699     set $kgm_vaddr = $arg1
 9700 
 9701         # Supersection or just section?
 9702     if (($kgm_tte & 0x00040000) == 0x00040000)
 9703         set $kgm_paddr = ($kgm_tte & 0xFF000000) | ($kgm_vaddr & 0x00FFFFFF)
 9704         set $kgm_paddr_isvalid = 1
 9705     else
 9706         set $kgm_paddr = ($kgm_tte & 0xFFF00000) | ($kgm_vaddr & 0x000FFFFF)
 9707         set $kgm_paddr_isvalid = 1
 9708     end
 9709 
 9710     if $kgm_pt_verbose >= 2
 9711         printf "0x%08x\n\t0x%08x\n\t", (unsigned long)$kgm_tte_p, $kgm_tte
 9712 
 9713         # bit [1:0] evaluated in _pmap_walk_arm
 9714 
 9715         # B bit 2
 9716         set $kgm_b_bit = (($kgm_tte & 0x00000004) >> 2)
 9717 
 9718         # C bit 3
 9719         set $kgm_c_bit = (($kgm_tte & 0x00000008) >> 3)
 9720 
 9721         # XN bit 4
 9722         if ($kgm_tte & 0x00000010)
 9723             printf "no-execute" 
 9724         else
 9725             printf "execute" 
 9726         end
 9727 
 9728         # Domain bit [8:5] if not supersection
 9729         if (($kgm_tte & 0x00040000) == 0x00000000)
 9730             printf " domain(%d)", (($kgm_tte & 0x000001e0) >> 5)
 9731         end
 9732 
 9733         # IMP bit 9
 9734         printf " imp(%d)", (($kgm_tte & 0x00000200) >> 9) 
 9735 
 9736         # AP bit 15 and [11:10], merged to a single 3-bit value
 9737         set $kgm_access = (($kgm_tte & 0x00000c00) >> 10) | (($kgm_tte & 0x00008000) >> 13)
 9738         if ($kgm_access == 0x0)
 9739             printf " noaccess"
 9740         end
 9741         if ($kgm_access == 0x1)
 9742             printf " supervisor(readwrite) user(noaccess)"
 9743         end
 9744         if ($kgm_access == 0x2)
 9745             printf " supervisor(readwrite) user(readonly)"
 9746         end
 9747         if ($kgm_access == 0x3)
 9748             printf " supervisor(readwrite) user(readwrite)"
 9749         end
 9750         if ($kgm_access == 0x4)
 9751             printf " noaccess(reserved)"
 9752         end
 9753         if ($kgm_access == 0x5)
 9754             printf " supervisor(readonly) user(noaccess)"
 9755         end
 9756         if ($kgm_access == 0x6)
 9757             printf " supervisor(readonly) user(readonly)"
 9758         end
 9759         if ($kgm_access == 0x7)
 9760             printf " supervisor(readonly) user(readonly)"
 9761         end
 9762 
 9763         # TEX bit [14:12]
 9764         set $kgm_tex_bits = (($kgm_tte & 0x00007000) >> 12)
 9765 
 9766         # Print TEX, C, B all together
 9767         printf " TEX:C:B(%d%d%d:%d:%d)", ($kgm_tex_bits & 0x4 ? 1 : 0), ($kgm_tex_bits & 0x2 ? 1 : 0), ($kgm_tex_bits & 0x1 ? 1 : 0), $kgm_c_bit, $kgm_b_bit
 9768 
 9769         # S bit 16
 9770         if ($kgm_tte & 0x00010000)
 9771             printf " shareable" 
 9772         else
 9773             printf " not-shareable" 
 9774         end
 9775 
 9776         # nG bit 17
 9777         if ($kgm_tte & 0x00020000)
 9778             printf " not-global"
 9779         else
 9780             printf " global" 
 9781         end
 9782 
 9783         # Supersection bit 18
 9784         if ($kgm_tte & 0x00040000)
 9785             printf " supersection"
 9786         else
 9787             printf " section" 
 9788         end
 9789 
 9790         # NS bit 19
 9791         if ($kgm_tte & 0x00080000)
 9792             printf " no-secure"
 9793         else
 9794             printf " secure" 
 9795         end
 9796 
 9797         printf "\n"
 9798     end
 9799 end
 9800 
 9801 define _pmap_walk_arm_level2
 9802     set $kgm_tte_p = $arg0
 9803     set $kgm_tte = *$kgm_tte_p
 9804     set $kgm_vaddr = $arg1
 9805 
 9806     set $kgm_pte_pbase = (($kgm_tte & 0xFFFFFC00) - gPhysBase + gVirtBase)
 9807     set $kgm_pte_index = ($kgm_vaddr >> 12) & 0x000000FF
 9808     set $kgm_pte_p = &((pt_entry_t *)$kgm_pte_pbase)[$kgm_pte_index]
 9809     set $kgm_pte = *$kgm_pte_p
 9810 
 9811     # Print first level symbolically
 9812     if $kgm_pt_verbose >= 2
 9813         printf "0x%08x\n\t0x%08x\n\t", (unsigned long)$kgm_tte_p, $kgm_tte
 9814 
 9815         # bit [1:0] evaluated in _pmap_walk_arm
 9816 
 9817         # NS bit 3
 9818         if ($kgm_tte & 0x00000008)
 9819             printf "no-secure"
 9820         else
 9821             printf "secure" 
 9822         end
 9823 
 9824         # Domain bit [8:5]
 9825         printf " domain(%d)", (($kgm_tte & 0x000001e0) >> 5)
 9826 
 9827         # IMP bit 9
 9828         printf " imp(%d)", (($kgm_tte & 0x00000200) >> 9) 
 9829 
 9830         printf "\n"
 9831     end
 9832 
 9833     if $kgm_pt_verbose >= 2
 9834         printf "second-level table (index %d):\n", $kgm_pte_index
 9835     end
 9836     if $kgm_pt_verbose >= 3
 9837         set $kgm_pte_loop = 0
 9838         while $kgm_pte_loop < 256
 9839             set $kgm_pte_p_tmp = &((pt_entry_t *)$kgm_pte_pbase)[$kgm_pte_loop]
 9840             printf "0x%08x:\t0x%08x\n", (unsigned long)$kgm_pte_p_tmp, *$kgm_pte_p_tmp
 9841             set $kgm_pte_loop = $kgm_pte_loop + 1
 9842         end
 9843     end
 9844 
 9845     if ($kgm_pte & 0x00000003)
 9846         set $kgm_pve_p = (pv_entry_t *)($kgm_pte_pbase + 0x100*sizeof(pt_entry_t) + $kgm_pte_index*sizeof(pv_entry_t))
 9847         if ($kgm_pve_p->shadow != 0)
 9848             set $kgm_spte = $kgm_pve_p->shadow ^ ($kgm_vaddr & ~0xFFF)
 9849             set $kgm_paddr = ($kgm_spte & 0xFFFFF000) | ($kgm_vaddr & 0xFFF)
 9850             set $kgm_paddr_isvalid = 1
 9851         else
 9852             set $kgm_paddr = (*$kgm_pte_p & 0xFFFFF000) | ($kgm_vaddr & 0xFFF)
 9853             set $kgm_paddr_isvalid = 1
 9854         end
 9855     else
 9856         set $kgm_paddr = 0
 9857         set $kgm_paddr_isvalid = 0
 9858     end
 9859 
 9860     if $kgm_pt_verbose >= 2
 9861         printf "0x%08x\n\t0x%08x\n\t", (unsigned long)$kgm_pte_p, $kgm_pte
 9862         if (($kgm_pte & 0x00000003) == 0x00000000)
 9863             printf "invalid" 
 9864         else
 9865             if (($kgm_pte & 0x00000003) == 0x00000001)
 9866                 printf "large"
 9867 
 9868                 # XN bit 15
 9869                 if ($kgm_pte & 0x00008000) == 0x00008000
 9870                     printf " no-execute"
 9871                 else
 9872                     printf " execute"
 9873                 end
 9874             else
 9875                 printf "small"
 9876 
 9877                 # XN bit 0
 9878                 if ($kgm_pte & 0x00000001) == 0x00000001
 9879                     printf " no-execute"
 9880                 else
 9881                     printf " execute"
 9882                 end
 9883             end
 9884 
 9885             # B bit 2
 9886             set $kgm_b_bit = (($kgm_pte & 0x00000004) >> 2)
 9887 
 9888             # C bit 3
 9889             set $kgm_c_bit = (($kgm_pte & 0x00000008) >> 3)
 9890 
 9891             # AP bit 9 and [5:4], merged to a single 3-bit value
 9892             set $kgm_access = (($kgm_pte & 0x00000030) >> 4) | (($kgm_pte & 0x00000200) >> 7)
 9893             if ($kgm_access == 0x0)
 9894                 printf " noaccess"
 9895             end
 9896             if ($kgm_access == 0x1)
 9897                 printf " supervisor(readwrite) user(noaccess)"
 9898             end
 9899             if ($kgm_access == 0x2)
 9900                 printf " supervisor(readwrite) user(readonly)"
 9901             end
 9902             if ($kgm_access == 0x3)
 9903                 printf " supervisor(readwrite) user(readwrite)"
 9904             end
 9905             if ($kgm_access == 0x4)
 9906                 printf " noaccess(reserved)"
 9907             end
 9908             if ($kgm_access == 0x5)
 9909                 printf " supervisor(readonly) user(noaccess)"
 9910             end
 9911             if ($kgm_access == 0x6)
 9912                 printf " supervisor(readonly) user(readonly)"
 9913             end
 9914             if ($kgm_access == 0x7)
 9915                 printf " supervisor(readonly) user(readonly)"
 9916             end
 9917 
 9918             # TEX bit [14:12] for large, [8:6] for small
 9919             if (($kgm_pte & 0x00000003) == 0x00000001)
 9920                 set $kgm_tex_bits = (($kgm_pte & 0x00007000) >> 12)
 9921             else
 9922                 set $kgm_tex_bits = (($kgm_pte & 0x000001c0) >> 6)
 9923             end
 9924 
 9925             # Print TEX, C, B all together
 9926             printf " TEX:C:B(%d%d%d:%d:%d)", ($kgm_tex_bits & 0x4 ? 1 : 0), ($kgm_tex_bits & 0x2 ? 1 : 0), ($kgm_tex_bits & 0x1 ? 1 : 0), $kgm_c_bit, $kgm_b_bit
 9927 
 9928             # S bit 10
 9929             if ($kgm_pte & 0x00000400)
 9930                 printf " shareable" 
 9931             else
 9932                 printf " not-shareable" 
 9933             end
 9934 
 9935             # nG bit 11
 9936             if ($kgm_pte & 0x00000800)
 9937                 printf " not-global"
 9938             else
 9939                 printf " global" 
 9940             end
 9941 
 9942         end
 9943         printf "\n"
 9944     end
 9945 end
 9946 
 9947 # See ARM ARM Section B3.3
 9948 define _pmap_walk_arm
 9949     set $kgm_pmap = (pmap_t) $arg0
 9950     set $kgm_vaddr = $arg1
 9951     set $kgm_paddr = 0
 9952     set $kgm_paddr_isvalid = 0
 9953 
 9954     # Shift by TTESHIFT (20) to get tte index
 9955     set $kgm_tte_index = (($kgm_vaddr - $kgm_pmap->min) >> 20)
 9956     set $kgm_tte_p = &$kgm_pmap->tte[$kgm_tte_index]
 9957     set $kgm_tte = *$kgm_tte_p
 9958     if $kgm_pt_verbose >= 2
 9959         printf "first-level table (index %d):\n", $kgm_tte_index
 9960     end
 9961     if $kgm_pt_verbose >= 3
 9962         set $kgm_tte_loop = 0
 9963         while $kgm_tte_loop < 4096
 9964             set $kgm_tte_p_tmp = &$kgm_pmap->tte[$kgm_tte_loop]
 9965             printf "0x%08x:\t0x%08x\n", (unsigned long)$kgm_tte_p_tmp, *$kgm_tte_p_tmp
 9966             set $kgm_tte_loop = $kgm_tte_loop + 1
 9967         end
 9968     end
 9969 
 9970     if (($kgm_tte & 0x00000003) == 0x00000001)
 9971         _pmap_walk_arm_level2 $kgm_tte_p $kgm_vaddr
 9972     else
 9973         if (($kgm_tte & 0x00000003) == 0x00000002)
 9974             _pmap_walk_arm_level1_section $kgm_tte_p $kgm_vaddr
 9975         else
 9976             set $kgm_paddr = 0
 9977             set $kgm_paddr_isvalid = 0
 9978             if $kgm_pt_verbose >= 2
 9979                 printf "Invalid First-Level Translation Table Entry: 0x%08x\n", $kgm_tte
 9980             end
 9981         end
 9982     end
 9983 
 9984     if $kgm_pt_verbose >= 1
 9985         if $kgm_paddr_isvalid
 9986             readphysint $kgm_paddr 32 $kgm_lcpu_self
 9987             set $kgm_value = $kgm_readphysint_result
 9988             printf "phys 0x%016llx: 0x%08x\n", $kgm_paddr, $kgm_value
 9989         else
 9990             printf "(no translation)\n"
 9991         end
 9992     end
 9993 end
 9994 
 9995 define pmap_walk
 9996     if $argc != 2
 9997         printf "pmap_walk <pmap> <vaddr>\n"
 9998     else
 9999         if !$kgm_pt_verbose
10000             set $kgm_pt_verbose = 2
10001         else
10002             if $kgm_pt_verbose > 3
10003                 set $kgm_pt_verbose = 2
10004             end
10005         end
10006         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
10007             _pmap_walk_x86 $arg0 $arg1
10008         else
10009             if ($kgm_mtype == $kgm_mtype_arm)
10010                 _pmap_walk_arm $arg0 $arg1
10011             else
10012                 printf "Not available for current architecture.\n"
10013             end
10014         end
10015     end
10016 end
10017 
10018 document pmap_walk
10019 Syntax: (gdb) pmap_walk <pmap> <virtual_address>
10020 | Perform a page-table walk in <pmap> for <virtual_address>.
10021 | Set:
10022 |     $kgm_pt_verbose=0 for no output, $kgm_paddr will be set
10023 |                       if $kgm_paddr_isvalid is 1
10024 |     $kgm_pt_verbose=1 for final physical address
10025 |     $kgm_pt_verbose=2 for dump of page table entry.
10026 |     $kgm_pt_verbose=3 for full hex dump of page tables.
10027 end
10028 
10029 define pmap_vtop
10030     if $argc != 2
10031         printf "pmap_vtop <pamp> <vaddr>\n"
10032     else
10033         set $kgm_pt_verbose = 1
10034         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
10035             _pmap_walk_x86 $arg0 $arg1
10036         else
10037             if ($kgm_mtype == $kgm_mtype_arm)
10038                 _pmap_walk_arm $arg0 $arg1
10039             else
10040                 printf "Not available for current architecture.\n"
10041             end
10042         end
10043     end
10044 end
10045 
10046 document pmap_vtop
10047 Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
10048 | For page-tables in <pmap> translate <virtual_address> to physical address.
10049 end
10050 
10051 define zstack
10052         set $index = $arg0
10053 
10054         if (log_records == 0)
10055                 set $count = 0
10056                 printf "Zone logging not enabled.  Add 'zlog=<zone name>' to boot-args.\n"
10057         else 
10058                 if ($argc == 2)
10059                         set $count = $arg1
10060                 else
10061                         set $count = 1
10062                 end
10063         end
10064 
10065         while ($count)
10066                 printf "\n--------------- "
10067 
10068                 if (zrecords[$index].z_opcode == 1)
10069                         printf "ALLOC  "
10070                 else
10071                         printf "FREE  "
10072                 end
10073                 showptr zrecords[$index].z_element
10074                 printf " : index %d  :  ztime %d -------------\n", $index, zrecords[$index].z_time
10075 
10076                 set $frame = 0
10077 
10078                 while ($frame < 15)
10079                         set $frame_pc = zrecords[$index].z_pc[$frame]
10080 
10081                         if ($frame_pc == 0)
10082                                 loop_break
10083                         end
10084 
10085                         x/i $frame_pc
10086                         set $frame = $frame + 1
10087                 end
10088 
10089                 set $index = $index + 1
10090                 set $count = $count - 1
10091         end
10092 end
10093 
10094 document zstack
10095 Syntax: (gdb) zstack <index> [<count>]
10096 | Zone leak debugging: print the stack trace of log element at <index>.
10097 | If a <count> is supplied, it prints <count> log elements starting at <index>.
10098 |
10099 | The suggested usage is to look at indexes below zcurrent and look for common stack traces.
10100 | The stack trace that occurs the most is probably the cause of the leak.  Find the pc of the
10101 | function calling into zalloc and use the countpcs kgmacro to find out how often that pc occurs in the log.
10102 | The pc occuring in a high percentage of records is most likely the source of the leak.
10103 |
10104 | The findoldest kgmacro is also useful for leak debugging since it identifies the oldest record
10105 | in the log, which may indicate the leaker.
10106 end
10107 
10108 define findoldest
10109         set $index = 0
10110         set $count = log_records
10111         set $cur_min = 2000000000
10112         set $cur_index = 0
10113 
10114         if (log_records == 0)
10115                 printf "Zone logging not enabled.  Add 'zlog=<zone name>' to boot-args.\n"
10116         else
10117 
10118                 while ($count)
10119                         if (zrecords[$index].z_element && zrecords[$index].z_time < $cur_min)
10120                                 set $cur_index = $index
10121                                 set $cur_min = zrecords[$index].z_time
10122                         end
10123         
10124                         set $count = $count - 1
10125                         set $index = $index + 1
10126                 end
10127         
10128                 printf "oldest record is at log index %d:\n", $cur_index
10129                 zstack $cur_index
10130         end
10131 end
10132 
10133 document findoldest
10134 Syntax: (gdb) findoldest
10135 | Zone leak debugging: find and print the oldest record in the log.  Note that this command
10136 | can take several minutes to run since it uses linear search.
10137 |
10138 | Once it prints a stack trace, find the pc of the caller above all the zalloc, kalloc and
10139 | IOKit layers.  Then use the countpcs kgmacro to see how often this caller has allocated
10140 | memory.  A caller with a high percentage of records in the log is probably the leaker.
10141 end
10142 
10143 define countpcs
10144         set $target_pc = $arg0
10145         set $index = 0
10146         set $count = log_records
10147         set $found = 0
10148 
10149         if (log_records == 0)
10150                 printf "Zone logging not enabled.  Add 'zlog=<zone name>' to boot-args.\n"
10151         else
10152 
10153                 while ($count)
10154                         set $frame = 0
10155         
10156                         if (zrecords[$index].z_element != 0)
10157                                 while ($frame < 15)
10158                                         if (zrecords[$index].z_pc[$frame] == $target_pc)
10159                                                 set $found = $found + 1
10160                                                 set $frame = 15
10161                                         end
10162                 
10163                                         set $frame = $frame + 1
10164                                 end
10165                         end
10166         
10167                         set $index = $index + 1
10168                         set $count = $count - 1
10169                 end
10170         
10171                 printf "occurred %d times in log (%d%c of records)\n", $found, ($found * 100) / zrecorded, '%'
10172         end
10173 end
10174 
10175 document countpcs
10176 Syntax: (gdb) countpcs <pc>
10177 | Zone leak debugging: search the log and print a count of all log entries that contain the given <pc>
10178 | in the stack trace.  This is useful for verifying a suspected <pc> as being the source of
10179 | the leak.  If a high percentage of the log entries contain the given <pc>, then it's most
10180 | likely the source of the leak.  Note that this command can take several minutes to run.
10181 end
10182 
10183 define findelem
10184         set $fe_index = zcurrent
10185         set $fe_count = log_records
10186         set $fe_elem = $arg0
10187         set $fe_prev_op = -1
10188 
10189         if (log_records == 0)
10190                 printf "Zone logging not enabled.  Add 'zlog=<zone name>' to boot-args.\n"
10191         end
10192 
10193         while ($fe_count)
10194                 if (zrecords[$fe_index].z_element == $fe_elem)
10195                         zstack $fe_index
10196 
10197                         if (zrecords[$fe_index].z_opcode == $fe_prev_op)
10198                                 printf "***************   DOUBLE OP!   *********************\n"
10199                         end
10200 
10201                         set $fe_prev_op = zrecords[$fe_index].z_opcode
10202                 end
10203 
10204                 set $fe_count = $fe_count - 1
10205                 set $fe_index = $fe_index + 1
10206 
10207                 if ($fe_index >= log_records)
10208                         set $fe_index = 0
10209                 end
10210         end
10211 end
10212 
10213 document findelem
10214 Syntax: (gdb) findelem <elem addr>
10215 | Zone corruption debugging: search the log and print out the stack traces for all log entries that
10216 | refer to the given zone element.  When the kernel panics due to a corrupted zone element, get the
10217 | element address and use this macro.  This will show you the stack traces of all logged zalloc and
10218 | zfree operations which tells you who touched the element in the recent past.  This also makes
10219 | double-frees readily apparent.
10220 end
10221 
10222 
10223 # This implements a shadowing scheme in kgmacros. If the
10224 # current user data can be accessed by simply changing kdp_pmap,
10225 # that is used. Otherwise, we copy data into a temporary buffer
10226 # in the kernel's address space and use that instead. Don't rely on
10227 # kdp_pmap between invocations of map/unmap. Since the shadow
10228 # codepath uses a manual KDP packet, request no more than 128 bytes.
10229 # Uses $kgm_lp64 for kernel address space size, and
10230 # $kgm_readphys_use_kdp/$kgm_readphys_force_physmap to override
10231 # how the user pages are accessed ($kgm_readphys_force_physmap
10232 # implies walking the user task's pagetables to get a physical
10233 # address and then shadowing data from there using the
10234 # physical mapping of memory).
10235 define _map_user_data_from_task
10236     set $kgm_map_user_taskp = (task_t)$arg0
10237     set $kgm_map_user_map = $kgm_map_user_taskp->map
10238     set $kgm_map_user_pmap = $kgm_map_user_map->pmap
10239     set $kgm_map_user_task_64 = ( $kgm_map_user_taskp->taskFeatures[0] & 0x80000000)
10240     set $kgm_map_user_window = 0
10241     set $kgm_map_switch_map = 0
10242     
10243     if ($kgm_readphys_force_kdp != 0)
10244         set $kgm_readphys_use_kdp = 1
10245     else
10246         if ($kgm_readphys_force_physmap)
10247             set $kgm_readphys_use_kdp = 0
10248         else
10249             set $kgm_readphys_use_kdp = ( kdp->is_conn > 0 )
10250         end
10251     end
10252 
10253     if ($kgm_readphys_use_kdp)
10254 
10255         if $kgm_lp64
10256             set $kgm_map_switch_map = 1
10257         else
10258             if !$kgm_map_user_task_64
10259                 set $kgm_map_switch_map = 1
10260             end
10261         end
10262     
10263         if ($kgm_map_switch_map)
10264             # switch the map safely
10265             set $kgm_map_user_window = $arg1
10266             set kdp_pmap = $kgm_map_user_pmap
10267         else
10268             # requires shadowing/copying
10269 
10270             # set up the manual KDP packet
10271             set manual_pkt.input = 0
10272             set manual_pkt.len = sizeof(kdp_readmem64_req_t)
10273             set $kgm_pkt = (kdp_readmem64_req_t *)&manual_pkt.data
10274             set $kgm_pkt->hdr.request = KDP_READMEM64
10275             set $kgm_pkt->hdr.len = sizeof(kdp_readmem64_req_t)
10276             set $kgm_pkt->hdr.is_reply = 0
10277             set $kgm_pkt->hdr.seq = 0
10278             set $kgm_pkt->hdr.key = 0
10279             set $kgm_pkt->address = (uint64_t)$arg1
10280             set $kgm_pkt->nbytes = (uint32_t)$arg2
10281 
10282             set kdp_pmap = $kgm_map_user_pmap
10283             set manual_pkt.input = 1
10284             # dummy to make sure manual packet is executed
10285             set $kgm_dummy = &_mh_execute_header
10286             # Go back to kernel map so that we can access buffer directly
10287             set kdp_pmap = 0
10288 
10289             set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
10290             if ($kgm_pkt->error == 0)
10291                 set $kgm_map_user_window = $kgm_pkt->data
10292             else
10293                 set $kgm_map_user_window = 0
10294             end
10295         end
10296 
10297     else
10298         # without the benefit of a KDP stub on the target, try to
10299         # find the user task's physical mapping and memcpy the data.
10300         # If it straddles a page boundary, copy in two passes
10301         set $kgm_vaddr_range1_start = (unsigned long long)$arg1
10302         set $kgm_vaddr_range1_count = (unsigned long long)$arg2
10303         if (($kgm_vaddr_range1_start + $kgm_vaddr_range1_count) & 0xFFF) < $kgm_vaddr_range1_count
10304             set $kgm_vaddr_range2_start = ($kgm_vaddr_range1_start + $kgm_vaddr_range1_count) & ~((unsigned long long)0xFFF)
10305             set $kgm_vaddr_range2_count = $kgm_vaddr_range1_start + $kgm_vaddr_range1_count - $kgm_vaddr_range2_start
10306             set $kgm_vaddr_range1_count = $kgm_vaddr_range2_start - $kgm_vaddr_range1_start
10307         else
10308             set $kgm_vaddr_range2_start = 0
10309             set $kgm_vaddr_range2_count = 0
10310         end
10311         set $kgm_paddr_range1_in_kva = 0
10312         set $kgm_paddr_range2_in_kva = 0
10313 
10314         if ($kgm_mtype == $kgm_mtype_x86_64)
10315             set $kgm_pt_verbose = 0
10316             _pmap_walk_x86 $kgm_map_user_pmap $kgm_vaddr_range1_start
10317             if $kgm_paddr_isvalid
10318                 set $kgm_paddr_range1_in_kva = $kgm_paddr + physmap_base
10319             end
10320             if $kgm_vaddr_range2_start
10321                 _pmap_walk_x86 $kgm_map_user_pmap $kgm_vaddr_range2_start
10322                 if $kgm_paddr_isvalid
10323                     set $kgm_paddr_range2_in_kva = $kgm_paddr + physmap_base
10324                 end
10325             end
10326         else
10327             if ($kgm_mtype == $kgm_mtype_arm)
10328                 set $kgm_pt_verbose = 0
10329                 _pmap_walk_arm $kgm_map_user_pmap $kgm_vaddr_range1_start
10330                 if $kgm_paddr_isvalid
10331                    set $kgm_paddr_range1_in_kva = $kgm_paddr - gPhysBase + gVirtBase
10332                 end
10333                 if $kgm_vaddr_range2_start
10334                     _pmap_walk_arm $kgm_map_user_pmap $kgm_vaddr_range2_start
10335                     if $kgm_paddr_isvalid
10336                         set $kgm_paddr_range2_in_kva = $kgm_paddr - gPhysBase + gVirtBase
10337                     end
10338                 end
10339             else
10340                 printf "Not available for current architecture.\n"
10341                 set $kgm_paddr_isvalid = 0
10342             end
10343         end
10344         if $kgm_paddr_range1_in_kva
10345             set $kgm_pkt = (kdp_readmem64_reply_t *)&manual_pkt.data
10346             memcpy $kgm_pkt->data $kgm_paddr_range1_in_kva $kgm_vaddr_range1_count
10347             if $kgm_paddr_range2_in_kva
10348                 memcpy &$kgm_pkt->data[$kgm_vaddr_range1_count] $kgm_paddr_range2_in_kva $kgm_vaddr_range2_count
10349             end
10350             set $kgm_map_user_window  = $kgm_pkt->data
10351         else
10352             set $kgm_map_user_window  = 0
10353         end
10354     end
10355 end
10356 
10357 define _unmap_user_data_from_task
10358     set kdp_pmap = 0
10359 end
10360 
10361 # uses $kgm_taskp. Maps 32 bytes at a time and prints it
10362 define _print_path_for_image
10363     set $kgm_print_path_address = (unsigned long long)$arg0
10364     set $kgm_path_str_notdone = 1
10365 
10366     if ($kgm_print_path_address == 0)
10367        set $kgm_path_str_notdone = 0
10368     end
10369     
10370     while $kgm_path_str_notdone
10371         _map_user_data_from_task $kgm_taskp $kgm_print_path_address 32
10372 
10373         set $kgm_print_path_ptr = (char *)$kgm_map_user_window
10374         set $kgm_path_i = 0
10375         while ($kgm_path_i < 32 && $kgm_print_path_ptr[$kgm_path_i] != '\0')
10376             set $kgm_path_i = $kgm_path_i + 1
10377         end
10378         printf "%.32s", $kgm_print_path_ptr
10379         
10380         _unmap_user_data_from_task $kgm_taskp
10381         
10382         # break out if we terminated on NUL
10383         if $kgm_path_i < 32
10384             set $kgm_path_str_notdone = 0
10385         else
10386             set $kgm_print_path_address = $kgm_print_path_address + 32
10387         end
10388     end
10389 end
10390 
10391 # uses $kgm_taskp and $kgm_task_64. May modify $kgm_dyld_load_path
10392 define _print_image_info
10393     set $kgm_mh_image_address = (unsigned long long)$arg0
10394     set $kgm_mh_path_address = (unsigned long long)$arg1
10395 
10396     # 32 bytes enough for mach_header/mach_header_64
10397     _map_user_data_from_task $kgm_taskp $kgm_mh_image_address 32
10398 
10399     set $kgm_mh_ptr = (unsigned int*)$kgm_map_user_window
10400     set $kgm_mh_magic = $kgm_mh_ptr[0]
10401     set $kgm_mh_cputype = $kgm_mh_ptr[1]
10402     set $kgm_mh_cpusubtype = $kgm_mh_ptr[2]
10403     set $kgm_mh_filetype = $kgm_mh_ptr[3]
10404     set $kgm_mh_ncmds = $kgm_mh_ptr[4]
10405     set $kgm_mh_sizeofcmds = $kgm_mh_ptr[5]
10406     set $kgm_mh_flags = $kgm_mh_ptr[6]
10407 
10408     _unmap_user_data_from_task $kgm_taskp
10409 
10410     if $kgm_mh_magic == 0xfeedfacf
10411         set $kgm_mh_64 = 1
10412         set $kgm_lc_address = $kgm_mh_image_address + 32
10413     else
10414         set $kgm_mh_64 = 0
10415         set $kgm_lc_address = $kgm_mh_image_address + 28
10416     end
10417     
10418     set $kgm_lc_idx = 0
10419     set $kgm_uuid_data = 0
10420     while $kgm_lc_idx < $kgm_mh_ncmds
10421         
10422         # 24 bytes is size of uuid_command
10423         _map_user_data_from_task $kgm_taskp $kgm_lc_address 24
10424     
10425         set $kgm_lc_ptr = (unsigned int *)$kgm_map_user_window
10426         set $kgm_lc_cmd = $kgm_lc_ptr[0]
10427         set $kgm_lc_cmd_size = $kgm_lc_ptr[1]
10428         set $kgm_lc_data = (unsigned char *)$kgm_lc_ptr + 8
10429 
10430         if $kgm_lc_cmd == 0x1b
10431             set $kgm_uuid_data = $kgm_lc_data
10432             if $kgm_mh_64
10433                 printf "0x%016llx  ", $kgm_mh_image_address
10434             else
10435                 printf "0x%08x  ", $kgm_mh_image_address                                
10436             end
10437             
10438             set $kgm_printed_type = 0
10439             if $kgm_mh_filetype == 0x2
10440                 printf "MH_EXECUTE   "
10441                 set $kgm_printed_type = 1
10442             end
10443             if $kgm_mh_filetype == 0x6
10444                 printf "MH_DYLIB     "
10445                 set $kgm_printed_type = 1
10446             end
10447             if $kgm_mh_filetype == 0x7
10448                 printf "MH_DYLINKER  "
10449                 set $kgm_printed_type = 1
10450             end
10451             if $kgm_mh_filetype == 0x8
10452                 printf "MH_BUNDLE    "
10453                 set $kgm_printed_type = 1
10454             end
10455             if !$kgm_printed_type
10456                 printf "UNKNOWN      "            
10457             end
10458             printf "%02.2X%02.2X%02.2X%02.2X-", $kgm_uuid_data[0], $kgm_uuid_data[1], $kgm_uuid_data[2], $kgm_uuid_data[3]
10459             printf "%02.2X%02.2X-", $kgm_uuid_data[4], $kgm_uuid_data[5]
10460             printf "%02.2X%02.2X-", $kgm_uuid_data[6], $kgm_uuid_data[7]
10461             printf "%02.2X%02.2X-", $kgm_uuid_data[8], $kgm_uuid_data[9]
10462             printf "%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X", $kgm_uuid_data[10], $kgm_uuid_data[11], $kgm_uuid_data[12], $kgm_uuid_data[13], $kgm_uuid_data[14], $kgm_uuid_data[15]
10463 
10464             _unmap_user_data_from_task $kgm_taskp
10465 
10466             printf "  "
10467             _print_path_for_image $kgm_mh_path_address
10468             printf "\n"
10469 
10470             loop_break
10471         else
10472             if $kgm_lc_cmd == 0xe
10473                 set $kgm_load_dylinker_data = $kgm_lc_data
10474                 set $kgm_dyld_load_path = $kgm_lc_address + *((unsigned int *)$kgm_load_dylinker_data)
10475             end
10476             _unmap_user_data_from_task $kgm_taskp
10477         end
10478 
10479         set $kgm_lc_address = $kgm_lc_address + $kgm_lc_cmd_size
10480         set $kgm_lc_idx = $kgm_lc_idx + 1
10481     end
10482     
10483     if (!$kgm_uuid_data)
10484             # didn't find LC_UUID, for a dylib, just print out basic info
10485             if $kgm_mh_64
10486                 printf "0x%016llx  ", $kgm_mh_image_address
10487             else
10488                 printf "0x%08x  ", $kgm_mh_image_address                          
10489             end
10490             set $kgm_printed_type = 0
10491             if $kgm_mh_filetype == 0x2
10492                 printf "MH_EXECUTE   "
10493                 set $kgm_printed_type = 1
10494             end
10495             if $kgm_mh_filetype == 0x6
10496                 printf "MH_DYLIB     "
10497                 set $kgm_printed_type = 1
10498             end
10499             if $kgm_mh_filetype == 0x7
10500                 printf "MH_DYLINKER  "
10501                 set $kgm_printed_type = 1
10502             end
10503             if $kgm_mh_filetype == 0x8
10504                 printf "MH_BUNDLE    "
10505                 set $kgm_printed_type = 1
10506             end
10507             if !$kgm_printed_type
10508                 printf "UNKNOWN      "            
10509             end
10510         printf "                                    ",
10511 
10512         printf "  "
10513         _print_path_for_image $kgm_mh_path_address
10514         printf "\n"
10515 
10516     end
10517     
10518 end
10519 
10520 define _print_images_for_dyld_image_info
10521     set $kgm_taskp = $arg0
10522     set $kgm_task_64 = $arg1
10523     set $kgm_dyld_all_image_infos_address = (unsigned long long)$arg2
10524 
10525     _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 112
10526 
10527     set $kgm_dyld_all_image_infos = (unsigned int *)$kgm_map_user_window    
10528     set $kgm_dyld_all_image_infos_version = $kgm_dyld_all_image_infos[0]
10529     if ($kgm_dyld_all_image_infos_version > 12)
10530         printf "Unknown dyld all_image_infos version number %d\n", $kgm_dyld_all_image_infos_version
10531     end
10532     set $kgm_image_info_count = $kgm_dyld_all_image_infos[1]
10533 
10534     set $kgm_dyld_load_path = 0    
10535     if $kgm_task_64
10536         set $kgm_image_info_size = 24
10537         set $kgm_image_info_array_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[1]
10538         set $kgm_dyld_load_address = ((unsigned long long *)$kgm_dyld_all_image_infos)[4]
10539         set $kgm_dyld_all_image_infos_address_from_struct = ((unsigned long long *)$kgm_dyld_all_image_infos)[13]
10540     else
10541         set $kgm_image_info_size = 12
10542         set $kgm_image_info_array_address = ((unsigned int *)$kgm_dyld_all_image_infos)[2]
10543         set $kgm_dyld_load_address = ((unsigned int *)$kgm_dyld_all_image_infos)[5]
10544         set $kgm_dyld_all_image_infos_address_from_struct = ((unsigned int *)$kgm_dyld_all_image_infos)[14]
10545     end
10546 
10547     _unmap_user_data_from_task $kgm_taskp
10548 
10549     # Account for ASLR slide before dyld can fix the structure
10550     set $kgm_dyld_load_address = $kgm_dyld_load_address + ($kgm_dyld_all_image_infos_address - $kgm_dyld_all_image_infos_address_from_struct)
10551 
10552     set $kgm_image_info_i = 0
10553     while $kgm_image_info_i < $kgm_image_info_count
10554 
10555         set $kgm_image_info_address = $kgm_image_info_array_address + $kgm_image_info_size*$kgm_image_info_i
10556 
10557         _map_user_data_from_task $kgm_taskp $kgm_image_info_address $kgm_image_info_size
10558         if $kgm_task_64
10559             set $kgm_image_info_addr = ((unsigned long long *)$kgm_map_user_window)[0]
10560             set $kgm_image_info_path = ((unsigned long long *)$kgm_map_user_window)[1]
10561         else
10562             set $kgm_image_info_addr = ((unsigned int *)$kgm_map_user_window)[0]
10563             set $kgm_image_info_path = ((unsigned int *)$kgm_map_user_window)[1]
10564         end
10565         _unmap_user_data_from_task $kgm_taskp
10566  
10567         # printf "[%d] = image address %llx path address %llx\n", $kgm_image_info_i, $kgm_image_info_addr, $kgm_image_info_path
10568         _print_image_info $kgm_image_info_addr $kgm_image_info_path
10569 
10570         set $kgm_image_info_i = $kgm_image_info_i + 1
10571     end
10572 
10573     # $kgm_dyld_load_path may get set when the main executable is processed
10574     # printf "[dyld] = image address %llx path address %llx\n", $kgm_dyld_load_address, $kgm_dyld_load_path
10575     _print_image_info $kgm_dyld_load_address $kgm_dyld_load_path
10576 
10577 end
10578 
10579 define showuserlibraries
10580         set $kgm_taskp = (task_t)$arg0
10581         set $kgm_dyld_image_info = $kgm_taskp->all_image_info_addr
10582 
10583         set $kgm_map = $kgm_taskp->map
10584         set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
10585 
10586         if ($kgm_dyld_image_info != 0)
10587                 printf "address   "
10588                 if $kgm_task_64
10589                         printf "        "
10590                 end
10591                 printf "  type       "
10592                 printf "  uuid                                  "
10593                 printf "path\n"
10594 
10595                 _print_images_for_dyld_image_info $kgm_taskp $kgm_task_64 $kgm_dyld_image_info
10596         else
10597                 printf "No dyld shared library information available for task\n"
10598         end
10599 end
10600 document showuserlibraries
10601 Syntax: (gdb) showuserlibraries <task_t>
10602 | For a given user task, inspect the dyld shared library state and print 
10603 | information about all Mach-O images.
10604 end
10605 
10606 define showuserdyldinfo
10607         set $kgm_taskp = (task_t)$arg0
10608         set $kgm_dyld_all_image_infos_address = (unsigned long long)$kgm_taskp->all_image_info_addr
10609 
10610         set $kgm_map = $kgm_taskp->map
10611         set $kgm_task_64 = ( $kgm_taskp->taskFeatures[0] & 0x80000000)
10612 
10613         if ($kgm_dyld_all_image_infos_address != 0)
10614 
10615            _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 112
10616 
10617            set $kgm_dyld_all_image_infos = (unsigned char *)$kgm_map_user_window
10618            set $kgm_dyld_all_image_infos_version = ((unsigned int *)$kgm_dyld_all_image_infos)[0]
10619            if ($kgm_dyld_all_image_infos_version > 12)
10620                   printf "Unknown dyld all_image_infos version number %d\n", $kgm_dyld_all_image_infos_version
10621            end
10622 
10623            # Find fields by byte offset. We assume at least version 9 is supported
10624            if $kgm_task_64
10625                   set $kgm_dyld_all_image_infos_infoArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[4])
10626                   set $kgm_dyld_all_image_infos_infoArray = *(unsigned long long *)(&$kgm_dyld_all_image_infos[8])
10627                   set $kgm_dyld_all_image_infos_notification = *(unsigned long long *)(&$kgm_dyld_all_image_infos[16])
10628                   set $kgm_dyld_all_image_infos_processDetachedFromSharedRegion = *(unsigned char *)(&$kgm_dyld_all_image_infos[24])
10629                   set $kgm_dyld_all_image_infos_libSystemInitialized = *(unsigned char *)(&$kgm_dyld_all_image_infos[25])
10630                   set $kgm_dyld_all_image_infos_dyldImageLoadAddress = *(unsigned long long *)(&$kgm_dyld_all_image_infos[32])
10631                   set $kgm_dyld_all_image_infos_jitInfo = *(unsigned long long *)(&$kgm_dyld_all_image_infos[40])
10632                   set $kgm_dyld_all_image_infos_dyldVersion = *(unsigned long long *)(&$kgm_dyld_all_image_infos[48])
10633                   set $kgm_dyld_all_image_infos_errorMessage = *(unsigned long long *)(&$kgm_dyld_all_image_infos[56])
10634                   set $kgm_dyld_all_image_infos_terminationFlags = *(unsigned long long *)(&$kgm_dyld_all_image_infos[64])
10635                   set $kgm_dyld_all_image_infos_coreSymbolicationShmPage = *(unsigned long long *)(&$kgm_dyld_all_image_infos[72])
10636                   set $kgm_dyld_all_image_infos_systemOrderFlag = *(unsigned long long *)(&$kgm_dyld_all_image_infos[80])
10637                   set $kgm_dyld_all_image_infos_uuidArrayCount = *(unsigned long long *)(&$kgm_dyld_all_image_infos[88])
10638                   set $kgm_dyld_all_image_infos_uuidArray = *(unsigned long long *)(&$kgm_dyld_all_image_infos[96])
10639                   set $kgm_dyld_all_image_infos_dyldAllImageInfosAddress = *(unsigned long long *)(&$kgm_dyld_all_image_infos[104])
10640            else
10641                   set $kgm_dyld_all_image_infos_infoArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[4])
10642                   set $kgm_dyld_all_image_infos_infoArray = *(unsigned int *)(&$kgm_dyld_all_image_infos[8])
10643                   set $kgm_dyld_all_image_infos_notification = *(unsigned int *)(&$kgm_dyld_all_image_infos[12])
10644                   set $kgm_dyld_all_image_infos_processDetachedFromSharedRegion = *(unsigned char *)(&$kgm_dyld_all_image_infos[16])
10645                   set $kgm_dyld_all_image_infos_libSystemInitialized = *(unsigned char *)(&$kgm_dyld_all_image_infos[17])
10646                   set $kgm_dyld_all_image_infos_dyldImageLoadAddress = *(unsigned int *)(&$kgm_dyld_all_image_infos[20])
10647                   set $kgm_dyld_all_image_infos_jitInfo = *(unsigned int *)(&$kgm_dyld_all_image_infos[24])
10648                   set $kgm_dyld_all_image_infos_dyldVersion = *(unsigned int *)(&$kgm_dyld_all_image_infos[28])
10649                   set $kgm_dyld_all_image_infos_errorMessage = *(unsigned int *)(&$kgm_dyld_all_image_infos[32])
10650                   set $kgm_dyld_all_image_infos_terminationFlags = *(unsigned int *)(&$kgm_dyld_all_image_infos[36])
10651                   set $kgm_dyld_all_image_infos_coreSymbolicationShmPage = *(unsigned int *)(&$kgm_dyld_all_image_infos[40])
10652                   set $kgm_dyld_all_image_infos_systemOrderFlag = *(unsigned int *)(&$kgm_dyld_all_image_infos[44])
10653                   set $kgm_dyld_all_image_infos_uuidArrayCount = *(unsigned int *)(&$kgm_dyld_all_image_infos[48])
10654                   set $kgm_dyld_all_image_infos_uuidArray = *(unsigned int *)(&$kgm_dyld_all_image_infos[52])
10655                   set $kgm_dyld_all_image_infos_dyldAllImageInfosAddress = *(unsigned int *)(&$kgm_dyld_all_image_infos[56])
10656            end
10657 
10658            _unmap_user_data_from_task $kgm_taskp
10659 
10660            set $kgm_dyld_all_imfo_infos_slide = ( $kgm_dyld_all_image_infos_address - $kgm_dyld_all_image_infos_dyldAllImageInfosAddress )
10661            set $kgm_dyld_all_image_infos_dyldVersion_postslide = ( $kgm_dyld_all_image_infos_dyldVersion + $kgm_dyld_all_imfo_infos_slide )
10662 
10663            printf "                        version %u\n", $kgm_dyld_all_image_infos_version
10664            printf "                 infoArrayCount %u\n", $kgm_dyld_all_image_infos_infoArrayCount
10665            printf "                      infoArray "
10666            showuserptr $kgm_dyld_all_image_infos_infoArray
10667            printf "\n"
10668            printf "                   notification "
10669            showuserptr $kgm_dyld_all_image_infos_notification
10670            printf "\n"
10671            printf "processDetachedFromSharedRegion %d\n", $kgm_dyld_all_image_infos_processDetachedFromSharedRegion
10672            printf "           libSystemInitialized %d\n", $kgm_dyld_all_image_infos_libSystemInitialized
10673            printf "           dyldImageLoadAddress "
10674            showuserptr $kgm_dyld_all_image_infos_dyldImageLoadAddress
10675            printf "\n"
10676            printf "                        jitInfo "
10677            showuserptr $kgm_dyld_all_image_infos_jitInfo
10678            printf "\n"
10679            printf "                    dyldVersion "
10680            showuserptr $kgm_dyld_all_image_infos_dyldVersion
10681            printf "\n"
10682            printf "                                "
10683            _print_path_for_image $kgm_dyld_all_image_infos_dyldVersion_postslide
10684            if ($kgm_dyld_all_imfo_infos_slide != 0)
10685                   printf " (currently "
10686                   showuserptr $kgm_dyld_all_image_infos_dyldVersion_postslide
10687                   printf ")"
10688            end
10689            printf "\n"
10690 
10691            printf "                   errorMessage "
10692            showuserptr $kgm_dyld_all_image_infos_errorMessage
10693            printf "\n"
10694            if $kgm_dyld_all_image_infos_errorMessage != 0
10695                   printf "                                "
10696                   _print_path_for_image $kgm_dyld_all_image_infos_errorMessage
10697                   printf "\n"
10698            end
10699 
10700            printf "               terminationFlags "
10701            showuserptr $kgm_dyld_all_image_infos_terminationFlags
10702            printf "\n"
10703            printf "       coreSymbolicationShmPage "
10704            showuserptr $kgm_dyld_all_image_infos_coreSymbolicationShmPage
10705            printf "\n"
10706            printf "                systemOrderFlag "
10707            showuserptr $kgm_dyld_all_image_infos_systemOrderFlag
10708            printf "\n"
10709            printf "                 uuidArrayCount "
10710            showuserptr $kgm_dyld_all_image_infos_uuidArrayCount
10711            printf "\n"
10712            printf "                      uuidArray "
10713            showuserptr $kgm_dyld_all_image_infos_uuidArray
10714            printf "\n"
10715            printf "       dyldAllImageInfosAddress "
10716            showuserptr $kgm_dyld_all_image_infos_dyldAllImageInfosAddress
10717            printf "\n"
10718            printf "                                (currently "
10719            showuserptr $kgm_dyld_all_image_infos_address
10720            printf ")\n"
10721 
10722            if $kgm_task_64
10723                   set $kgm_dyld_all_image_infos_address = $kgm_dyld_all_image_infos_address + 112
10724                   _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 64
10725                   set $kgm_dyld_all_image_infos_v10 = (unsigned char *)$kgm_map_user_window
10726                   set $kgm_dyld_all_image_infos_initialImageCount = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[112-112])
10727                   set $kgm_dyld_all_image_infos_errorKind = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[120-112])
10728                   set $kgm_dyld_all_image_infos_errorClientOfDylibPath = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[128-112])
10729                   set $kgm_dyld_all_image_infos_errorTargetDylibPath = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[136-112])
10730                   set $kgm_dyld_all_image_infos_errorSymbol = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[144-112])
10731                   set $kgm_dyld_all_image_infos_sharedCacheSlide = *(unsigned long long *)(&$kgm_dyld_all_image_infos_v10[152-112])
10732 
10733                   _unmap_user_data_from_task $kgm_taskp
10734            else
10735                   set $kgm_dyld_all_image_infos_address = $kgm_dyld_all_image_infos_address + 60
10736                   _map_user_data_from_task $kgm_taskp $kgm_dyld_all_image_infos_address 64
10737                   set $kgm_dyld_all_image_infos_v10 = (unsigned char *)$kgm_map_user_window
10738                   set $kgm_dyld_all_image_infos_initialImageCount = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[60-60])
10739                   set $kgm_dyld_all_image_infos_errorKind = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[64-60])
10740                   set $kgm_dyld_all_image_infos_errorClientOfDylibPath = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[68-60])
10741                   set $kgm_dyld_all_image_infos_errorTargetDylibPath = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[72-60])
10742                   set $kgm_dyld_all_image_infos_errorSymbol = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[76-60])
10743                   set $kgm_dyld_all_image_infos_sharedCacheSlide = *(unsigned int *)(&$kgm_dyld_all_image_infos_v10[80-60])
10744                   _unmap_user_data_from_task $kgm_taskp
10745            end
10746 
10747            if $kgm_dyld_all_image_infos_version >= 10
10748                   printf "              initialImageCount "
10749                   showuserptr $kgm_dyld_all_image_infos_initialImageCount
10750                   printf "\n"
10751            end
10752 
10753            if $kgm_dyld_all_image_infos_version >= 11
10754                   printf "                      errorKind "
10755                   showuserptr $kgm_dyld_all_image_infos_errorKind
10756                   printf "\n"
10757                   printf "         errorClientOfDylibPath "
10758                   showuserptr $kgm_dyld_all_image_infos_errorClientOfDylibPath
10759                   printf "\n"
10760                   if $kgm_dyld_all_image_infos_errorClientOfDylibPath != 0
10761                          printf "                                "
10762                          _print_path_for_image $kgm_dyld_all_image_infos_errorClientOfDylibPath
10763                          printf "\n"
10764                   end
10765                   printf "           errorTargetDylibPath "
10766                   showuserptr $kgm_dyld_all_image_infos_errorTargetDylibPath
10767                   printf "\n"
10768                   if $kgm_dyld_all_image_infos_errorTargetDylibPath != 0
10769                          printf "                                "
10770                          _print_path_for_image $kgm_dyld_all_image_infos_errorTargetDylibPath
10771                          printf "\n"
10772                   end
10773                   printf "                    errorSymbol "
10774                   showuserptr $kgm_dyld_all_image_infos_errorSymbol
10775                   printf "\n"
10776                   if $kgm_dyld_all_image_infos_errorSymbol != 0
10777                          printf "                                "
10778                          _print_path_for_image $kgm_dyld_all_image_infos_errorSymbol
10779                          printf "\n"
10780                   end
10781            end
10782 
10783            if $kgm_dyld_all_image_infos_version >= 12
10784                   printf "               sharedCacheSlide "
10785                   showuserptr $kgm_dyld_all_image_infos_sharedCacheSlide
10786                   printf "\n"
10787            end
10788 
10789         else
10790                 printf "No dyld information available for task\n"
10791         end
10792 end
10793 document showuserdyldinfo
10794 Syntax: (gdb) showuserdyldinfo <task_t>
10795 | For a given user task, inspect the dyld global info and print
10796 | out all fields, including error messages.
10797 end
10798 
10799 define showkerneldebugheader
10800         printf "kd_buf     "
10801         showptrhdrpad
10802         printf "CPU  Thread     "
10803         showptrhdrpad
10804         printf "Timestamp         S/E Class Sub   Code   Code Specific Info\n"
10805 end
10806 
10807 define _printevflags
10808         if $arg0 & 1
10809                 printf "EV_RE "
10810         end
10811         if $arg0 & 2
10812                 printf "EV_WR "
10813         end
10814         if $arg0 & 4
10815                 printf "EV_EX "
10816         end
10817         if $arg0 & 8
10818                 printf "EV_RM "
10819         end
10820 
10821         if $arg0 & 0x00100
10822                 printf "EV_RBYTES "
10823         end
10824         if $arg0 & 0x00200
10825                 printf "EV_WBYTES "
10826         end
10827         if $arg0 & 0x00400
10828                 printf "EV_RCLOSED "
10829         end
10830         if $arg0 & 0x00800
10831                 printf "EV_RCONN "
10832         end
10833         if $arg0 & 0x01000
10834                 printf "EV_WCLOSED "
10835         end
10836         if $arg0 & 0x02000
10837                 printf "EV_WCONN "
10838         end
10839         if $arg0 & 0x04000
10840                 printf "EV_OOB "
10841         end
10842         if $arg0 & 0x08000
10843                 printf "EV_FIN "
10844         end
10845         if $arg0 & 0x10000
10846                 printf "EV_RESET "
10847         end
10848         if $arg0 & 0x20000
10849                 printf "EV_TIMEOUT "
10850         end
10851 end
10852 
10853 define showkerneldebugbufferentry
10854         set $kgm_kdebug_entry = (kd_buf *) $arg0
10855         
10856         set $kgm_debugid     = $kgm_kdebug_entry->debugid
10857         set $kgm_kdebug_arg1 = $kgm_kdebug_entry->arg1
10858         set $kgm_kdebug_arg2 = $kgm_kdebug_entry->arg2
10859         set $kgm_kdebug_arg3 = $kgm_kdebug_entry->arg3
10860         set $kgm_kdebug_arg4 = $kgm_kdebug_entry->arg4
10861         
10862         if $kgm_lp64
10863                 set $kgm_kdebug_cpu      = $kgm_kdebug_entry->cpuid
10864                 set $kgm_ts_hi       = ($kgm_kdebug_entry->timestamp >> 32) & 0xFFFFFFFF
10865                 set $kgm_ts_lo       = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
10866         else
10867                 set $kgm_kdebug_cpu      = ($kgm_kdebug_entry->timestamp >> 56)
10868                 set $kgm_ts_hi       = ($kgm_kdebug_entry->timestamp >> 32) & 0x00FFFFFF
10869                 set $kgm_ts_lo       = $kgm_kdebug_entry->timestamp & 0xFFFFFFFF
10870         end
10871         
10872         set $kgm_kdebug_class    = ($kgm_debugid >> 24) & 0x000FF
10873         set $kgm_kdebug_subclass = ($kgm_debugid >> 16) & 0x000FF
10874         set $kgm_kdebug_code     = ($kgm_debugid >>  2) & 0x03FFF
10875         set $kgm_kdebug_qual     = ($kgm_debugid      ) & 0x00003
10876         
10877         if $kgm_kdebug_qual == 0
10878                 set $kgm_kdebug_qual = '-'
10879         else
10880                 if $kgm_kdebug_qual == 1
10881                         set $kgm_kdebug_qual = 'S'
10882                 else
10883                         if $kgm_kdebug_qual == 2
10884                                 set $kgm_kdebug_qual = 'E'
10885                         else
10886                                 if $kgm_kdebug_qual == 3
10887                                         set $kgm_kdebug_qual = '?'
10888                                 end
10889                         end
10890                 end
10891         end
10892 
10893         # preamble and qual
10894         
10895         showptr $kgm_kdebug_entry
10896         printf "  %d   ", $kgm_kdebug_cpu
10897         showptr $kgm_kdebug_entry->arg5
10898         printf " 0x%08X%08X %c  ", $kgm_ts_hi, $kgm_ts_lo, $kgm_kdebug_qual
10899         
10900         # class
10901         
10902         if $kgm_kdebug_class == 1
10903                 printf "MACH"
10904         else
10905         if $kgm_kdebug_class == 2
10906                 printf "NET "
10907         else
10908         if $kgm_kdebug_class == 3
10909                 printf "FS  "
10910         else
10911         if $kgm_kdebug_class == 4
10912                 printf "BSD "
10913         else
10914         if $kgm_kdebug_class == 5
10915                 printf "IOK "
10916         else
10917         if $kgm_kdebug_class == 6
10918                 printf "DRVR"
10919         else
10920         if $kgm_kdebug_class == 7
10921                 printf "TRAC"
10922         else
10923         if $kgm_kdebug_class == 8
10924                 printf "DLIL"
10925         else
10926         if $kgm_kdebug_class == 8
10927                 printf "SEC "
10928         else
10929         if $kgm_kdebug_class == 20
10930                 printf "MISC"
10931         else
10932         if $kgm_kdebug_class == 31
10933                 printf "DYLD"
10934         else
10935         if $kgm_kdebug_class == 32
10936                 printf "QT  "
10937         else
10938         if $kgm_kdebug_class == 33
10939                 printf "APPS"
10940         else
10941         if $kgm_kdebug_class == 255
10942                 printf "MIG "
10943         else
10944                 printf "0x%02X", $kgm_kdebug_class
10945         end
10946         end
10947         end
10948         end
10949         end
10950         end
10951         end
10952         end
10953         end
10954         end
10955         end
10956         end
10957         end
10958         end
10959         
10960         # subclass and code
10961         
10962         printf "  0x%02X %5d   ", $kgm_kdebug_subclass, $kgm_kdebug_code
10963 
10964         # space for debugid-specific processing
10965         
10966         # EVPROC from bsd/kern/sys_generic.c
10967         
10968         # MISCDBG_CODE(DBG_EVENT,DBG_WAIT)
10969         if $kgm_debugid == 0x14100048
10970                 printf "waitevent "
10971                 if $kgm_kdebug_arg1 == 1
10972                         printf "before sleep"
10973                 else
10974                 if $kgm_kdebug_arg1 == 2
10975                         printf "after  sleep"
10976                 else
10977                         printf "????????????"
10978                 end
10979                 end
10980                 printf " chan=0x%08X ", $kgm_kdebug_arg2
10981         else
10982         # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_START)
10983         if $kgm_debugid == 0x14100049
10984                 printf "waitevent "
10985         else
10986         # MISCDBG_CODE(DBG_EVENT,DBG_WAIT|DBG_FUNC_END)
10987         if $kgm_debugid == 0x1410004a
10988                 printf "waitevent error=%d ", $kgm_kdebug_arg1
10989                 printf "eqp=0x%08X ", $kgm_kdebug_arg4
10990                 _printevflags $kgm_kdebug_arg3
10991                 printf "er_handle=%d ", $kgm_kdebug_arg2
10992         else
10993         # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_START)
10994         if $kgm_debugid == 0x14100059
10995                 printf "evprocdeque proc=0x%08X ", $kgm_kdebug_arg1
10996                 if $kgm_kdebug_arg2 == 0
10997                         printf "remove first "
10998                 else
10999                         printf "remove 0x%08X ", $kgm_kdebug_arg2
11000                 end
11001         else
11002         # MISCDBG_CODE(DBG_EVENT,DBG_DEQUEUE|DBG_FUNC_END)
11003         if $kgm_debugid == 0x1410005a
11004                 printf "evprocdeque "
11005                 if $kgm_kdebug_arg1 == 0
11006                         printf "result=NULL "
11007                 else
11008                         printf "result=0x%08X ", $kgm_kdebug_arg1
11009                 end
11010         else
11011         # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_START)
11012         if $kgm_debugid == 0x14100041
11013                 printf "postevent "
11014                 _printevflags $kgm_kdebug_arg1
11015         else
11016         # MISCDBG_CODE(DBG_EVENT,DBG_POST)
11017         if $kgm_debugid == 0x14100040
11018                 printf "postevent "
11019                 printf "evq=0x%08X ", $kgm_kdebug_arg1
11020                 printf "er_eventbits="
11021                 _printevflags $kgm_kdebug_arg2
11022                 printf "mask="
11023                 _printevflags $kgm_kdebug_arg3
11024         else
11025         # MISCDBG_CODE(DBG_EVENT,DBG_POST|DBG_FUNC_END)
11026         if $kgm_debugid == 0x14100042
11027                 printf "postevent "
11028         else
11029         # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_START)
11030         if $kgm_debugid == 0x14100055
11031                 printf "evprocenque eqp=0x%08d ", $kgm_kdebug_arg1
11032                 if $kgm_kdebug_arg2 & 1
11033                         printf "EV_QUEUED "
11034                 end
11035                 _printevflags $kgm_kdebug_arg3
11036         else
11037         
11038         # MISCDBG_CODE(DBG_EVENT,DBG_EWAKEUP)
11039         if $kgm_debugid == 0x14100050
11040                 printf "evprocenque before wakeup eqp=0x%08d ", $kgm_kdebug_arg4
11041         else
11042         # MISCDBG_CODE(DBG_EVENT,DBG_ENQUEUE|DBG_FUNC_END)
11043         if $kgm_debugid == 0x14100056
11044                 printf "evprocenque "
11045         else
11046         # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_START)
11047         if $kgm_debugid == 0x1410004d
11048                 printf "modwatch "
11049         else
11050         # MISCDBG_CODE(DBG_EVENT,DBG_MOD)
11051         if $kgm_debugid == 0x1410004c
11052                 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
11053                 _printevflags $kgm_kdebug_arg2
11054                 printf "evq=0x%08X ", $kgm_kdebug_arg3
11055         else
11056         # MISCDBG_CODE(DBG_EVENT,DBG_MOD|DBG_FUNC_END)
11057         if $kgm_debugid == 0x1410004e
11058                 printf "modwatch er_handle=%d ", $kgm_kdebug_arg1
11059                 printf "ee_eventmask="
11060                 _printevflags $kgm_kdebug_arg2
11061                 printf "sp=0x%08X ", $kgm_kdebug_arg3
11062                 printf "flag="
11063                 _printevflags $kgm_kdebug_arg4
11064         else
11065                 printf "arg1=0x%08X ", $kgm_kdebug_arg1
11066                 printf "arg2=0x%08X ", $kgm_kdebug_arg2
11067                 printf "arg3=0x%08X ", $kgm_kdebug_arg3
11068                 printf "arg4=0x%08X ", $kgm_kdebug_arg4
11069         end
11070         end
11071         end
11072         end
11073         end
11074         end
11075         end
11076         end
11077         end
11078         end
11079         end
11080         end
11081         end
11082         end
11083         
11084         # finish up
11085         
11086         printf "\n"
11087 end
11088 
11089 define showkerneldebugbuffercpu
11090         set $kgm_cpu_number = (int) $arg0
11091         set $kgm_entry_count = (int) $arg1
11092         set $kgm_debugentriesfound = 0
11093         # 0x80000000 == KDBG_BFINIT
11094         if (kd_ctrl_page.kdebug_flags & 0x80000000)     
11095                 showkerneldebugheader
11096                 
11097                 if $kgm_entry_count == 0
11098                         printf "<count> is 0, dumping 50 entries\n"
11099                         set $kgm_entry_count = 50
11100                 end
11101         
11102                 if $kgm_cpu_number >= kd_cpus
11103                         printf "cpu number too big\n"
11104                 else
11105                         set $kgm_kdbp = &kdbip[$kgm_cpu_number]
11106                         set $kgm_kdsp = $kgm_kdbp->kd_list_head
11107                         while (($kgm_kdsp.raw != 0) && ($kgm_entry_count > 0))
11108                                 set $kgm_kdsp_actual = &kd_bufs[$kgm_kdsp.buffer_index].kdsb_addr[$kgm_kdsp.offset]
11109                                 if $kgm_kdsp_actual->kds_readlast != $kgm_kdsp_actual->kds_bufindx
11110                                         set $kgm_kds_bufptr = &$kgm_kdsp_actual->kds_records[$kgm_kdsp_actual->kds_bufindx]
11111                                         while (($kgm_kds_bufptr > &$kgm_kdsp_actual->kds_records[$kgm_kdsp_actual->kds_readlast]) && ($kgm_entry_count > 0))
11112                                                 set $kgm_kds_bufptr = $kgm_kds_bufptr - 1
11113                                                 set $kgm_entry_count = $kgm_entry_count - 1
11114                                                 showkerneldebugbufferentry $kgm_kds_bufptr
11115                                         end
11116                                 end
11117                                 set $kgm_kdsp = $kgm_kdsp_actual->kds_next
11118                         end
11119                 end
11120         else
11121                 printf "Trace buffer not enabled\n"
11122         end
11123 end
11124 
11125 document showkerneldebugbuffercpu
11126 Syntax:  showkerneldebugbuffercpu <cpu> <count>
11127 | Prints the last N entries in the kernel debug buffer for CPU x.
11128 end
11129 
11130 define showkerneldebugbuffer
11131         # 0x80000000 == KDBG_BFINIT
11132         if (kd_ctrl_page.kdebug_flags & 0x80000000)     
11133         
11134                 set $kgm_entrycount = (int) $arg0
11135         
11136                 if $kgm_entrycount == 0
11137                         printf "<count> is 0, dumping 50 entries per cpu\n"
11138                         set $kgm_entrycount = 50
11139                 end
11140         
11141                 set $kgm_cpu = (int) 0
11142         
11143                 while $kgm_cpu < kd_cpus
11144                         showkerneldebugbuffercpu $kgm_cpu $kgm_entrycount
11145                         set $kgm_cpu = $kgm_cpu + 1
11146                 end
11147         else
11148                 printf "Trace buffer not enabled\n"
11149         end
11150 end
11151 
11152 document showkerneldebugbuffer
11153 Syntax: showkerneldebugbuffer <count>
11154 | Prints the last N entries in the kernel debug buffer per cpu. i.e. showkerneldebugbuffer 50 will
11155 | display the last 50 entries in each CPU's debug buffer.
11156 end
11157 
11158 define showallvmstats
11159   printf "     pid           command    #ents           wired           vsize   rsize       max rsize\n"
11160   printf "                                            (pages)         (pages)   (pages)         (pages)\n"
11161   set $kgm_head_taskp = &tasks
11162   set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
11163   while $kgm_taskp != $kgm_head_taskp
11164     set $kgm_procp = (struct proc *)($kgm_taskp->bsd_info)
11165     set $kgm_mapp = (struct _vm_map *)($kgm_taskp->map)
11166     printf "%8d %17s %8d %15d %15d %15d %15d\n", $kgm_procp->p_pid, $kgm_procp->p_comm, $kgm_mapp->hdr.nentries, $kgm_mapp->pmap->stats.wired_count, $kgm_mapp->size >> 12, $kgm_mapp->pmap->stats.resident_count, $kgm_mapp->pmap->stats.resident_max
11167     set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
11168   end
11169 end
11170 
11171 document showallvmstats
11172 Syntax: showallvmstats
11173 | prints a summary of vm statistics in a table format
11174 end
11175 
11176 define memstats
11177         if ($kgm_mtype == $kgm_mtype_arm)
11178                 printf "kern_memorystatus_level:  %8d\n", kern_memorystatus_level
11179         end     
11180         printf "vm_page_throttled_count:  %8d\n", vm_page_throttled_count 
11181         printf "vm_page_active_count:     %8d\n", vm_page_active_count
11182         printf "vm_page_inactive_count:   %8d\n", vm_page_inactive_count
11183         printf "vm_page_wire_count:       %8d\n", vm_page_wire_count
11184         printf "vm_page_free_count:       %8d\n", vm_page_free_count
11185         printf "vm_page_purgeable_count:  %8d\n", vm_page_purgeable_count
11186         printf "vm_page_inactive_target:  %8d\n", vm_page_inactive_target
11187         printf "vm_page_free_target:      %8d\n", vm_page_free_target
11188         printf "inuse_ptepages_count:     %8d\n", inuse_ptepages_count
11189         printf "vm_page_free_reserved:    %8d\n", vm_page_free_reserved
11190 end
11191 
11192 document memstats
11193 Syntax: (gdb) memstats 
11194 | Prints out a summary of various memory statistics. In particular vm_page_wire_count should
11195 | be greater than 2K or you are under memory pressure.
11196 end
11197 
11198 define show_user_registers
11199        showuserregisters $arg0
11200 end
11201 
11202 document show_user_registers
11203 Syntax: show_user_registers <thread_address>
11204 | Display user registers associated with a kernel thread
11205 | properly displays the 32 bit or 64 bit registers for intel architecture
11206 end
11207 
11208 define _cmp
11209        set $cmp0 = $arg0
11210        set $cmp1 = $arg1
11211 
11212        # check for end of string. cmp0 can be longer than cmp1. it
11213        # can't be shorter.
11214        if $cmp1 == '\0'
11215           set $kgm_strcmp_result = 0
11216           set $kgm_strcmp_done   = 1
11217        end
11218 
11219        if !$kgm_strcmp_done && $cmp0 == '\0'
11220           set $kgm_strcmp_result = -1
11221           set $kgm_strcmp_done   =  1
11222        end
11223 
11224        # do they match?
11225        if !$kgm_strcmp_done 
11226           set $kgm_strcmp_result = (uint8_t) $cmp0 - (uint8_t) $cmp1
11227           if $kgm_strcmp_result != 0
11228              set $kgm_strcmp_done = 1
11229           end
11230        end
11231 end
11232 
11233 define _cmp_arg64
11234        set $cmp = $arg1
11235        set $masked = $cmp & 0xFF
11236        _cmp $arg0[0] $masked
11237 
11238        if !$kgm_strcmp_done
11239           set $cmp = $cmp >> 8
11240           set $masked  = $cmp & 0xFF
11241           _cmp $arg0[1] $masked
11242        end
11243        if !$kgm_strcmp_done
11244           set $cmp = $cmp >> 8
11245           set $masked  = $cmp & 0xFF
11246           _cmp $arg0[2] $masked
11247        end
11248        if !$kgm_strcmp_done
11249           set $cmp = $cmp >> 8
11250           set $masked  = $cmp & 0xFF
11251           _cmp $arg0[3] $masked
11252        end
11253        if !$kgm_strcmp_done
11254           set $cmp = $cmp >> 8
11255           set $masked  = $cmp & 0xFF
11256           _cmp $arg0[4] $masked
11257        end
11258        if !$kgm_strcmp_done
11259           set $cmp = $cmp >> 8
11260           set $masked  = $cmp & 0xFF
11261           _cmp $arg0[5] $masked
11262        end
11263        if !$kgm_strcmp_done
11264           set $cmp = $cmp >> 8
11265           set $masked  = $cmp & 0xFF
11266           _cmp $arg0[6] $masked
11267        end
11268        if !$kgm_strcmp_done
11269           set $cmp = $cmp >> 8
11270           set $masked  = $cmp & 0xFF
11271           _cmp $arg0[7] $masked
11272        end
11273 end
11274 
11275 define strcmp_arg_pack64
11276        set $kgm_strcmp_arg = ((((((((((((((uint64_t) $arg7 << 8) | $arg6) << 8) | $arg5) << 8) | $arg4) << 8) | $arg3) << 8) | $arg2) << 8) | $arg1) << 8) | $arg0
11277 end
11278 
11279 document strcmp_arg_pack64
11280 Syntax: strcmp_arg_pack64 <a> <b> <c> <d> <e <f> <g> <h>
11281 | Packs a string given as 8 character arguments into a 64-bit int stored in 
11282 | $kgm_strcmp_arg. Use 0 or '\0' for unused arguments. The encoded string
11283 | is suitable for use by strcmp_nomalloc and setfindregistrystr.
11284 | e.g., strcmp_arg_pack64 'H' 'e' 'l' 'l' 'o' 0 0 0 
11285 |       packs "Hello" into $kgm_strcmp_arg.
11286 | 
11287 end
11288 
11289 define strcmp_nomalloc
11290        set $str   = $arg0
11291        set $count = $argc - 1
11292 
11293        set $kgm_strcmp_result = 0
11294        set $kgm_strcmp_done   = 0
11295 
11296        if $count > 0 
11297           _cmp_arg64 $str $arg1
11298        end
11299        if !$kgm_strcmp_done && $count > 1
11300           set $str = $str + 8
11301           _cmp_arg64 $str $arg2
11302        end
11303        if !$kgm_strcmp_done && $count > 2
11304           set $str = $str + 8
11305           _cmp_arg64 $str $arg3
11306        end
11307        if !$kgm_strcmp_done && $count > 3
11308           set $str = $str + 8
11309           _cmp_arg64 $str $arg4
11310        end
11311        if !$kgm_strcmp_done && $count > 4
11312           set $str = $str + 8
11313           _cmp_arg64 $str $arg5
11314        end
11315        if !$kgm_strcmp_done && $count > 5
11316           set $str = $str + 8
11317           _cmp_arg64 $str $arg6
11318        end
11319        if !$kgm_strcmp_done && $count > 6
11320           set $str = $str + 8
11321           _cmp_arg64 $str $arg7
11322        end
11323        if !$kgm_strcmp_done && $count > 7
11324           set $str = $str + 8
11325           _cmp_arg64 $str $arg8
11326        end
11327        if !$kgm_strcmp_done && $count > 8
11328           set $str = $str + 8
11329           _cmp_arg64 $str $arg9
11330        end
11331 end
11332 
11333 document strcmp_nomalloc
11334 Syntax: strcmp_nomalloc <string> <a> [b] [c] [d] [e] [f] [g] [h] [i]
11335 | Given a pre-allocated <string>, perform a string compare with the 
11336 | encoded string stored in arguments a - i. The result is stored in
11337 | $kgm_strcmp_result.
11338 |
11339 | For example, the following will result in $kgm_strcmp_result == 0:
11340 | strcmp_arg_pack64 'D' 'a' 'r' 'w' 'i' 'n' ' ' 'K' 
11341 | strcmp_nomalloc version $kgm_strcmp_arg
11342 end
11343 
11344 define memcpy
11345     set $kgm_dst = (unsigned char *)$arg0
11346     set $kgm_src = (unsigned char *)$arg1
11347     set $kgm_count = $arg2
11348 
11349     # printf "src %p dst %p len %d\n", $kgm_src, $kgm_dst, $kgm_count
11350 
11351     while ($kgm_count >= 8)
11352         set *(unsigned long long *)$kgm_dst = *(unsigned long long *)$kgm_src
11353 
11354         set $kgm_dst = $kgm_dst + 8
11355         set $kgm_src = $kgm_src + 8
11356         set $kgm_count = $kgm_count - 8
11357     end
11358     while ($kgm_count > 0)
11359         set *$kgm_dst = *$kgm_src
11360 
11361         set $kgm_dst = $kgm_dst + 1
11362         set $kgm_src = $kgm_src + 1
11363         set $kgm_count = $kgm_count - 1
11364     end
11365 end
11366 
11367 document memcpy
11368 Syntax: memcpy <dst> <src> <n>
11369 | Given two addresses that are accessible by the debugger, perform
11370 | a memory copy of <n> bytes from <src> to <dst>
11371 end
11372 
11373 # _pci_cfg_addr_value $addr $size
11374 define _pci_cfg_addr_value
11375    readphysint $arg0 $arg1 $kgm_lcpu_self
11376    set $kgm_pci_cfg_value = $kgm_readphysint_result
11377 end
11378 
11379 
11380 set $kgm_pci_cfg_init = 0
11381 define _pci_cfg_init
11382        # get this from the registry if it exists there
11383        if $kgm_pci_cfg_init == 0
11384           strcmp_arg_pack64 'A' 'p' 'p' 'l' 'e' 'A' 'C' 'P'
11385           set $AppleACP = $kgm_strcmp_arg
11386           strcmp_arg_pack64 'I' 'P' 'l' 'a' 't' 'f' 'o' 'r'
11387           set $IPlatfor = $kgm_strcmp_arg
11388           strcmp_arg_pack64 'm' 'E' 'x' 'p' 'e' 'r' 't' 0
11389           set $mExpert = $kgm_strcmp_arg
11390           setfindregistrystr $AppleACP $IPlatfor $mExpert
11391 
11392           set $olddepth = $kgm_reg_depth_max
11393           set $kgm_reg_depth_max = 2
11394           _findregistryentry 
11395           set $kgm_reg_depth_max = $olddepth
11396 
11397           if $kgm_registry_entry
11398              strcmp_arg_pack64 'a' 'c' 'p' 'i' '-' 'm' 'm' 'c' 
11399              set $acpi_mmc = $kgm_strcmp_arg
11400              strcmp_arg_pack64 'f' 'g' '-' 's' 'e' 'g' '0' 0
11401              set $fg_seg0 = $kgm_strcmp_arg
11402              setfindregistrystr $acpi_mmc $fg_seg0
11403 
11404              _findregistryprop $kgm_registry_entry
11405              if $kgm_registry_value
11406                 set $kgm_pci_cfg_base = ((OSNumber *) $kgm_registry_value)->value
11407                 set $kgm_pci_cfg_init = 1
11408              end
11409           end
11410        end
11411 
11412        # search for 0:0:0 in likely places if the above fails
11413        if $kgm_pci_cfg_init == 0
11414           set $kgm_pci_cfg_base = 0xF0000000
11415           while $kgm_pci_cfg_init == 0 && $kgm_pci_cfg_base > 0xA0000000
11416               _pci_cfg_addr_value $kgm_pci_cfg_base 8
11417               if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xFF
11418                  set $kgm_pci_cfg_init = 1
11419               else
11420                  set $kgm_pci_cfg_base = $kgm_pci_cfg_base - 0x10000000
11421               end
11422           end
11423        end
11424 end
11425 
11426 # _pci_cfg_addr $bus $dev $fcn $off
11427 define _pci_cfg_addr
11428        set $bus = $arg0
11429        set $dev = $arg1
11430        set $fcn = $arg2
11431        set $off = $arg3
11432 
11433        _pci_cfg_init
11434        set $kgm_pci_cfg_addr = $kgm_pci_cfg_base | ($bus << 20) | ($dev << 15) | ($fcn << 12) | $off
11435 end
11436 
11437 define _pci_cfg_value
11438        _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11439        _pci_cfg_addr_value $kgm_pci_cfg_addr $arg4
11440 end
11441 
11442 define pci_cfg_read8
11443        _pci_cfg_value $arg0 $arg1 $arg2 $arg3 8
11444        printf "%08X: %02X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11445 end
11446 
11447 define pci_cfg_read16
11448        _pci_cfg_value $arg0 $arg1 $arg2 $arg3 16
11449        printf "%08X: %04X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11450 end
11451 
11452 define pci_cfg_read32
11453        _pci_cfg_value $arg0 $arg1 $arg2 $arg3 32
11454        printf "%08X: %08X\n", $kgm_pci_cfg_addr, $kgm_pci_cfg_value
11455 end
11456 
11457 document pci_cfg_read8
11458 Syntax: (gdb) pci_cfg_read8 <bus> <dev> <fcn> <off>
11459 | read 8 bits for the given <off> of the pci device located at
11460 | <bus>:<dev>:<fcn>. 
11461 end
11462 
11463 document pci_cfg_read16
11464 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
11465 | read 16 bits for the given <off> of the pci device located at
11466 | <bus>:<dev>:<fcn>.
11467 end
11468 
11469 document pci_cfg_read32
11470 Syntax: (gdb) pci_cfg_read <bus> <dev> <fcn> <off>
11471 | read 32 bits for the given <off> of the pci device located at
11472 | <bus>:<dev>:<fcn>.
11473 end
11474 
11475 define pci_cfg_write8
11476        _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11477        writephysint $kgm_pci_cfg_addr 8 $arg4 $kgm_lcpu_self
11478 end
11479 
11480 define pci_cfg_write16
11481        _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11482        writephysint $kgm_pci_cfg_addr 16 $arg4 $kgm_lcpu_self
11483 end
11484 
11485 define pci_cfg_write32
11486        _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11487        writephysint $kgm_pci_cfg_addr 32 $arg4 $kgm_lcpu_self
11488 end
11489 
11490 document pci_cfg_write8
11491 Syntax: (gdb) pci_cfg_write8 <bus> <dev> <fcn> <off> <value>
11492 | write an 8-bit <value> into the given <off> of the pci device located at
11493 | <bus>:<dev>:<fcn>. 
11494 end
11495 
11496 document pci_cfg_write16
11497 Syntax: (gdb) pci_cfg_write16 <bus> <dev> <fcn> <off> <value>
11498 | write a 16-bit <value> into the given <off> of the pci device located at
11499 | <bus>:<dev>:<fcn>. 
11500 end
11501 
11502 document pci_cfg_write32
11503 Syntax: (gdb) pci_cfg_write32 <bus> <dev> <fcn> <off> <value>
11504 | write a 32-bit <value> into the given <off> of the pci device located at
11505 | <bus>:<dev>:<fcn>.
11506 end
11507 
11508 
11509 define pci_cfg_dump
11510        set $bus  = $arg0
11511        set $dev  = $arg1
11512        set $fcn  = $arg2
11513        set $off  = 0
11514 
11515        # check for a valid pci device
11516        _pci_cfg_value $bus $dev $fcn $off 8
11517        if $kgm_pci_cfg_value > 0x0 && $kgm_pci_cfg_value < 0xff
11518               printf " address: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"
11519               printf "---------------------------------------------------------"
11520 
11521               while $off < 256
11522                   _pci_cfg_value $bus $dev $fcn $off 32
11523                   if ($off & 0xF) == 0
11524                      printf "\n%08X: ", $kgm_pci_cfg_addr
11525                   end
11526                   printf "%02X %02X %02X %02X ", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF
11527                   set $off = $off + 4
11528               end
11529               printf "\n"
11530 
11531               # check for pcie extended capability config space
11532               _pci_cfg_value $bus $dev $fcn $off 8
11533               if $kgm_pci_cfg_value < 0xff
11534                  while $off < 4096
11535                        _pci_cfg_value $bus $dev $fcn $off 32
11536                        if ($off & 0xF) == 0
11537                           printf "\n%08X: ", $kgm_pci_cfg_addr
11538                        end
11539                        printf "%02X %02X %02X %02X ", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF
11540                        set $off = $off + 4
11541                  end
11542                  printf "\n"
11543              end
11544        end      
11545 end
11546 
11547 document pci_cfg_dump
11548 Syntax: (gdb) pci_cfg_dump <bus> <dev> <fcn> 
11549 | dump config space for the pci device located at <bus>:<dev>:<fcn>
11550 | if you specify an invalid/inaccessible pci device, nothing will be 
11551 | printed out.
11552 end
11553 
11554 set $kgm_pci_cfg_bus_start    = 0
11555 set $kgm_pci_cfg_bus_max      = 8
11556 set $kgm_pci_cfg_device_max   = 32
11557 set $kgm_pci_cfg_function_max = 8
11558 define _pci_cfg_scan
11559        set $dump = $arg0
11560 
11561        set $bus = $kgm_pci_cfg_bus_start
11562        while $bus < $kgm_pci_cfg_bus_max
11563              # check for bus:0:0 to see if we should
11564              # probe this bus further
11565              _pci_cfg_value $bus 0x0 0x0 0x0 32
11566              if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
11567 
11568                 set $dev = 0
11569                 while $dev < $kgm_pci_cfg_device_max
11570 
11571                    set $fcn = 0
11572                    while $fcn < $kgm_pci_cfg_function_max
11573                          _pci_cfg_value $bus $dev $fcn 0x0 32
11574                          if $kgm_pci_cfg_value > 0 && $kgm_pci_cfg_value < 0xFFFFFFFF
11575                             if $dump == 0
11576                                printf "%03X:%03X:%03X: %02X%02X   %02X%02X", $bus, $dev, $fcn, ($kgm_pci_cfg_value >> 8) & 0xFF, $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF 
11577                                _pci_cfg_value $bus $dev $fcn 0x8 32
11578                                printf "    %02X | %02X%02X%02X\n", $kgm_pci_cfg_value & 0xFF, ($kgm_pci_cfg_value >> 24) & 0xFF, ($kgm_pci_cfg_value >> 16) & 0xFF, ($kgm_pci_cfg_value >> 8) & 0xFF
11579                             else
11580                                printf "  device: %03X:%03X:%03X\n", $bus, $dev, $fcn                           
11581                                pci_cfg_dump $bus $dev $fcn      
11582                                printf "\n"
11583                             end
11584                          end
11585                          set $fcn = $fcn + 1
11586                    end
11587                    set $dev = $dev + 1
11588                 end
11589              end
11590              set $bus = $bus + 1
11591        end
11592 end
11593 
11594 define pci_cfg_dump_all
11595        _pci_cfg_scan 1
11596 end
11597 
11598 document pci_cfg_dump_all
11599 Syntax: (gdb) pci_cfg_dump_all
11600 | dump config spaces for scanned pci devices. the number of busses to scan 
11601 | is stored in $kgm_pci_cfg_bus_max. the default for that is 8. you can also 
11602 | specify the starting bus with $kgm_pci_cfg_bus_start. 
11603 end
11604 
11605 define pci_cfg_scan
11606        printf "bus:dev:fcn: vendor device rev | class\n"
11607        printf "---------------------------------------\n"
11608        _pci_cfg_scan 0
11609 end
11610 
11611 document pci_cfg_scan
11612 Syntax: (gdb) pci_cfg_scan
11613 | scan for pci devices. the number of busses to scan is stored in
11614 | $kgm_pci_cfg_bus_max. the default for that is 8. you can also specify the
11615 | starting bus with $kgm_pci_cfg_bus_start. 
11616 end
11617 
11618 define readioportint
11619        set $kgm_readioportint_result = 0xBAD10AD
11620        # set up the manual KDP packet
11621        set manual_pkt.input = 0
11622        set manual_pkt.len = sizeof(kdp_readioport_req_t)
11623        set $kgm_pkt = (kdp_readioport_req_t *)&manual_pkt.data
11624        set $kgm_pkt->hdr.request  = KDP_READIOPORT
11625        set $kgm_pkt->hdr.len      = sizeof(kdp_readioport_req_t)
11626        set $kgm_pkt->hdr.is_reply = 0
11627        set $kgm_pkt->hdr.seq      = 0
11628        set $kgm_pkt->hdr.key      = 0
11629        set $kgm_pkt->address      = (uint16_t)$arg0
11630        set $kgm_pkt->nbytes       = $arg1 >> 3
11631        set $kgm_pkt->lcpu         = (uint16_t)$arg2
11632        set manual_pkt.input       = 1
11633        # dummy to make sure manual packet is executed
11634        set $kgm_dummy = &_mh_execute_header
11635        set $kgm_pkt = (kdp_readioport_reply_t *)&manual_pkt.data
11636        if ($kgm_pkt->error == 0)
11637           if $arg1 == 8
11638              set $kgm_readioportint_result = *((uint8_t *) $kgm_pkt->data)
11639           end
11640           if $arg1 == 16
11641              set $kgm_readioportint_result = *((uint16_t *) $kgm_pkt->data)
11642           end
11643           if $arg1 == 32
11644              set $kgm_readioportint_result = *((uint32_t *) $kgm_pkt->data)
11645           end
11646        end
11647 end
11648 
11649 define readioport8
11650        set $lcpu = $kgm_lcpu_self
11651        if $argc > 1
11652           set $lcpu = $arg1
11653        end
11654        readioportint $arg0 8 $lcpu
11655        output /a $arg0
11656        printf ":\t0x%02hhx\n", $kgm_readioportint_result
11657 end
11658 
11659 define readioport16
11660        set $lcpu = $kgm_lcpu_self
11661        if $argc > 1
11662           set $lcpu = $arg1
11663        end
11664        readioportint $arg0 16 $lcpu
11665        output /a $arg0
11666        printf ":\t0x%04hx\n", $kgm_readioportint_result
11667 end
11668 
11669 define readioport32
11670        set $lcpu = $kgm_lcpu_self
11671        if $argc > 1
11672           set $lcpu = $arg1
11673        end
11674        readioportint $arg0 32 $lcpu
11675        output /a $arg0
11676        printf ":\t0x%08x\n", $kgm_readioportint_result
11677 end
11678 
11679 document readioport8
11680 | See readioport32.
11681 end
11682 
11683 document readioport16
11684 | See readioport32.
11685 end
11686 
11687 document readioport32
11688 Syntax: (gdb) readioport32 <port> [lcpu (kernel's numbering convention)]
11689 | Read value stored in the specified IO port. The CPU can be optionally
11690 | specified as well.
11691 end
11692 
11693 define writeioportint
11694        # set up the manual KDP packet
11695        set manual_pkt.input = 0
11696        set manual_pkt.len = sizeof(kdp_writeioport_req_t)
11697        set $kgm_pkt = (kdp_writeioport_req_t *)&manual_pkt.data
11698        set $kgm_pkt->hdr.request  = KDP_WRITEIOPORT
11699        set $kgm_pkt->hdr.len      = sizeof(kdp_writeioport_req_t)
11700        set $kgm_pkt->hdr.is_reply = 0
11701        set $kgm_pkt->hdr.seq      = 0
11702        set $kgm_pkt->hdr.key      = 0
11703        set $kgm_pkt->address      = (uint16_t)$arg0
11704        set $kgm_pkt->nbytes       = $arg1 >> 3
11705        set $kgm_pkt->lcpu         = (uint16_t)$arg3
11706        if $arg1 == 8
11707           set *(uint8_t *)$kgm_pkt->data = (uint8_t)$arg2
11708        end
11709        if $arg1 == 16
11710           set *(uint16_t *)$kgm_pkt->data = (uint16_t)$arg2
11711        end
11712        if $arg1 == 32
11713           set *(uint32_t *)$kgm_pkt->data = (uint32_t)$arg2
11714        end
11715        set manual_pkt.input = 1
11716        # dummy to make sure manual packet is executed
11717        set $kgm_dummy = &_mh_execute_header
11718        set $kgm_pkt = (kdp_writeioport_reply_t *)&manual_pkt.data
11719        set $kgm_writeioportint_result = $kgm_pkt->error
11720 end
11721 
11722 define writeioport8
11723        set $lcpu = $kgm_lcpu_self
11724        if $argc > 2
11725           set $lcpu = $arg2
11726        end
11727        writeioportint $arg0 8 $arg1 $lcpu
11728 end
11729 
11730 define writeioport16
11731        set $lcpu = $kgm_lcpu_self
11732        if $argc > 2
11733           set $lcpu = $arg2
11734        end
11735        writeioportint $arg0 16 $arg1 $lcpu
11736 end
11737 
11738 define writeioport32
11739        set $lcpu = $kgm_lcpu_self
11740        if $argc > 2
11741           set $lcpu = $arg2
11742        end
11743        writeioportint $arg0 32 $arg1 $lcpu
11744 end
11745 
11746 document writeioport8
11747 | See writeioport32.
11748 end
11749 
11750 document writeioport16
11751 | See writeioport32.
11752 end
11753 
11754 document writeioport32
11755 Syntax: (gdb) writeioport32 <port> <value> [lcpu (kernel's numbering convention)]
11756 | Write the value to the specified IO port. The size of the value is
11757 | determined by the name of the command. The CPU used can be optionally
11758 | specified.
11759 end
11760 
11761 define readmsr64int
11762        set $kgm_readmsr64int_result = 0xBAD10AD
11763        # set up the manual KDP packet
11764        set manual_pkt.input = 0
11765        set manual_pkt.len = sizeof(kdp_readmsr64_req_t)
11766        set $kgm_pkt = (kdp_readmsr64_req_t *)&manual_pkt.data
11767        set $kgm_pkt->hdr.request  = KDP_READMSR64
11768        set $kgm_pkt->hdr.len      = sizeof(kdp_readmsr64_req_t)
11769        set $kgm_pkt->hdr.is_reply = 0
11770        set $kgm_pkt->hdr.seq      = 0
11771        set $kgm_pkt->hdr.key      = 0
11772        set $kgm_pkt->address      = (uint32_t)$arg0
11773        set $kgm_pkt->lcpu         = (uint16_t)$arg1
11774        set manual_pkt.input       = 1
11775        # dummy to make sure manual packet is executed
11776        set $kgm_dummy = &_mh_execute_header
11777        set $kgm_pkt = (kdp_readmsr64_reply_t *)&manual_pkt.data
11778        if ($kgm_pkt->error == 0)
11779            set $kgm_readmsr64int_result = *((uint64_t *) $kgm_pkt->data)
11780        end
11781 end
11782 
11783 define readmsr64
11784        set $lcpu = $kgm_lcpu_self
11785        if $argc > 1
11786           set $lcpu = $arg1
11787        end
11788        readmsr64int $arg0 $lcpu
11789        output /a $arg0
11790        printf ":\t0x%016llx\n", $kgm_readmsr64int_result
11791 end
11792 
11793 define writemsr64int
11794        # set up the manual KDP packet
11795        set manual_pkt.input = 0
11796        set manual_pkt.len = sizeof(kdp_writemsr64_req_t)
11797        set $kgm_pkt = (kdp_writemsr64_req_t *)&manual_pkt.data
11798        set $kgm_pkt->hdr.request       = KDP_WRITEMSR64
11799        set $kgm_pkt->hdr.len           = sizeof(kdp_writemsr64_req_t)
11800        set $kgm_pkt->hdr.is_reply      = 0
11801        set $kgm_pkt->hdr.seq           = 0
11802        set $kgm_pkt->hdr.key           = 0
11803        set $kgm_pkt->address           = (uint32_t)$arg0
11804        set $kgm_pkt->lcpu              = (uint16_t)$arg2
11805        set *(uint64_t *)$kgm_pkt->data = (uint64_t)$arg1
11806        set manual_pkt.input            = 1
11807        # dummy to make sure manual packet is executed
11808        set $kgm_dummy = &_mh_execute_header
11809        set $kgm_pkt = (kdp_writemsr64_reply_t *)&manual_pkt.data
11810        set $kgm_writemsr64int_result = $kgm_pkt->error
11811 end
11812 
11813 define writemsr64
11814        set $lcpu = $kgm_lcpu_self
11815        if $argc > 2
11816           set $lcpu = $arg2
11817        end
11818        writemsr64int $arg0 $arg1 $lcpu
11819 end
11820 
11821 document writemsr64
11822 Syntax: (gdb) writemsr64 <msr> <value> [lcpu (kernel's numbering convention)]
11823 | Write <value> to the specified MSR. The CPU can be optionally specified.
11824 end
11825 
11826 document readmsr64
11827 Syntax: (gdb) readmsr64 <msr> [lcpu (kernel's numbering convention)]
11828 | Read the specified MSR. The CPU can be optionally specified.
11829 end
11830 
11831 # default if we can't find a registry entry
11832 set $kgm_ioapic_addr           = 0xFEC00000
11833 set $kgm_ioapic_init           = 0
11834 
11835 set $_ioapic_index_off         = 0x00
11836 set $_ioapic_data_off          = 0x10
11837 set $_ioapic_eoi_off           = 0x40
11838 
11839 set $_ioapic_index_id          = 0x00
11840 set $_ioapic_index_ver         = 0x01
11841 set $_ioapic_index_redir_base  = 0x10
11842 
11843 set $_apic_vector_mask         = 0xFF
11844 set $_apic_timer_tsc_deadline  = 0x40000
11845 set $_apic_timer_periodic      = 0x20000
11846 set $_apic_masked              = 0x10000
11847 set $_apic_trigger_level       = 0x08000
11848 set $_apic_polarity_high       = 0x02000
11849 set $_apic_pending             = 0x01000
11850 
11851 define _ioapic_init
11852        if $kgm_ioapic_init == 0
11853           strcmp_arg_pack64 'i' 'o' '-' 'a' 'p' 'i' 'c' 0
11854           setfindregistrystr $kgm_strcmp_arg
11855 
11856           set $olddepth = $kgm_reg_depth_max
11857           set $kgm_reg_depth_max = 3
11858           _findregistryentry 
11859           set $kgm_reg_depth_max = $olddepth
11860 
11861           if $kgm_registry_entry
11862              strcmp_arg_pack64 'P' 'h' 'y' 's' 'i' 'c' 'a' 'l'
11863              set $Physical = $kgm_strcmp_arg
11864              strcmp_arg_pack64 ' ' 'A' 'd' 'd' 'r' 'e' 's' 's'
11865              set $_Address = $kgm_strcmp_arg
11866              setfindregistrystr $Physical $_Address
11867 
11868              _findregistryprop $kgm_registry_entry 
11869              if $kgm_registry_value
11870                 set $kgm_ioapic_addr = ((OSNumber *) $kgm_registry_value)->value
11871              end
11872           end
11873           set $kgm_ioapic_index_addr = $kgm_ioapic_addr + $_ioapic_index_off
11874           set $kgm_ioapic_data_addr  = $kgm_ioapic_addr + $_ioapic_data_off
11875           set $kgm_ioapic_init  = 1
11876        end
11877 end
11878 
11879 define _ioapic_addr_value
11880        _ioapic_init
11881        writephysint $kgm_ioapic_index_addr 8 $arg0 $kgm_lcpu_self
11882        if $argc > 1
11883           writephysint $kgm_ioapic_data_addr 32 $arg1 $kgm_lcpu_self
11884        else
11885           readphysint $kgm_ioapic_data_addr 32 $kgm_lcpu_self
11886           set $kgm_ioapic_value = $kgm_readphysint_result
11887        end
11888 end
11889 
11890 define _apic_print
11891        set $value = $arg0
11892 
11893        printf "[VEC=%3d", $value & $_apic_vector_mask
11894        if $value & $_apic_masked
11895           printf " MASK=yes"
11896        else
11897           printf " MASK=no "
11898        end       
11899 
11900        if $value & $_apic_trigger_level
11901           printf " TRIG=level"
11902        else
11903           printf " TRIG=edge "
11904        end
11905 
11906        if $value & $_apic_polarity_high
11907           printf " POL=high"
11908        else
11909           printf " POL=low "
11910        end
11911 
11912        if $value & $_apic_pending
11913           printf " PEND=yes"
11914        else
11915           printf " PEND=no "
11916        end
11917 
11918        if $value & $_apic_timer_periodic
11919           printf " PERIODIC"
11920        end
11921        if $value & $_apic_timer_tsc_deadline
11922           printf " TSC_DEADLINE"
11923        end
11924 
11925        printf "]\n"
11926 end
11927 
11928 define ioapic_read32
11929    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11930        printf "ioapic_read32 not supported on this architecture.\n"
11931    else
11932        _ioapic_addr_value $arg0       
11933        printf "IOAPIC[0x%02X]: 0x%08X\n", $arg0, $kgm_ioapic_value
11934    end
11935 end
11936 
11937 document ioapic_read32
11938 Syntax: (gdb) ioapic_read <offset>
11939 | Read the IOAPIC register at the offset specified. 
11940 end
11941 
11942 define ioapic_write32
11943    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11944        printf "ioapic_write32 not supported on this architecture.\n"
11945    else
11946        _ioapic_addr_value $arg0 $arg1
11947    end
11948 end
11949 
11950 document ioapic_write32
11951 Syntax: (gdb) ioapic_write32 <offset> <value>
11952 | Write the IOAPIC register at the offset specified. 
11953 end
11954 
11955 define ioapic_dump
11956    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
11957        printf "ioapic_dump not supported on this architecture.\n"
11958    else
11959        # id
11960        _ioapic_addr_value $_ioapic_index_id
11961        printf "IOAPIC[0x%02X] ID:        0x%08X\n", $_ioapic_index_id, $kgm_ioapic_value
11962 
11963        # version
11964        _ioapic_addr_value $_ioapic_index_ver
11965        set $maxredir = (($kgm_ioapic_value & 0xFF0000) >> 16) + 1
11966 
11967        printf "IOAPIC[0x%02X] VERSION:   0x%08X         [", $_ioapic_index_ver, $kgm_ioapic_value
11968        printf "MAXREDIR=%02d PRQ=%d VERSION=0x%02X]\n", $maxredir, ($kgm_ioapic_value >> 15) & 0x1, $kgm_ioapic_value & 0xFF
11969        
11970        # all the redir entries
11971        set $i = 0
11972        while $i < $maxredir
11973              set $addr0 = $_ioapic_index_redir_base + ($i << 1)
11974              set $addr1 = $addr0 + 1
11975              _ioapic_addr_value $addr1
11976              printf "IOAPIC[0x%02X] IOREDIR%02d: 0x%08X", $addr0, $i, $kgm_ioapic_value
11977 
11978              _ioapic_addr_value $addr0
11979              printf "%08X ", $kgm_ioapic_value
11980              _apic_print $kgm_ioapic_value
11981              set $i = $i + 1
11982        end
11983    end
11984 end
11985 
11986 document ioapic_dump
11987 Syntax: (gdb) ioapic_dump
11988 | Dump all the IOAPIC entries.
11989 end
11990 
11991 
11992 set $_lapic_base_addr         = 0xFEE00000
11993 set $_lapic_id                = 0x20
11994 set $_lapic_version           = 0x30
11995 set $_lapic_tpr               = 0x80
11996 set $_lapic_apr               = 0x90
11997 set $_lapic_ppr               = 0xA0
11998 set $_lapic_eoi               = 0xB0
11999 set $_lapic_ldr               = 0xD0
12000 set $_lapic_dfr               = 0xE0
12001 set $_lapic_sivr              = 0xF0
12002 
12003 set $_lapic_isr_size          = 0x10
12004 set $_lapic_isr_num           = 8
12005 set $_lapic_isr0              = 0x100
12006 set $_lapic_tmr0              = 0x180
12007 set $_lapic_irr0              = 0x200
12008 
12009 set $_lapic_esr               = 0x280
12010 set $_lapic_esr_register      = 0x80
12011 set $_lapic_esr_recv_vect     = 0x40
12012 set $_lapic_esr_send_vect     = 0x20
12013 
12014 set $_lapic_icr0              = 0x300
12015 set $_lapic_icr1              = 0x310
12016 
12017 set $_lapic_lvt_timer         = 0x320
12018 set $_lapic_lvt_thermal       = 0x330
12019 set $_lapic_lvt_pmcr          = 0x340
12020 set $_lapic_lvt_lint0         = 0x350
12021 set $_lapic_lvt_lint1         = 0x360
12022 set $_lapic_lvt_error         = 0x370
12023 
12024 set $_lapic_icr               = 0x380
12025 set $_lapic_ccr               = 0x390
12026 set $_lapic_dcr               = 0x3E0
12027 
12028 set $_apic_cfg_msr          = 0x1B
12029 set $_apic_cfg_msr_x2EN     = 0x00000C00
12030 set $_x2apic_enabled         = -1
12031 
12032 # _lapic_addr $offset returns the actual address to use
12033 define _lapic_addr
12034        if $_x2apic_enabled < 0
12035           readmsr64int $_apic_cfg_msr $kgm_lcpu_self
12036           if ($kgm_readmsr64int_result & $_apic_cfg_msr_x2EN) == $_apic_cfg_msr_x2EN
12037              set $_x2apic_enabled = 1
12038           else
12039              set $_x2apic_enabled = 0
12040           end
12041        end
12042 
12043        if $_x2apic_enabled 
12044           # x2APIC addresses are MSRs that use xAPIC offsets that
12045           # are 4-bit shifted
12046           set $kgm_lapic_addr = $arg0 >> 4
12047        else
12048           set $kgm_lapic_addr = $_lapic_base_addr + $arg0
12049        end
12050 end
12051 
12052 # _lapic_addr_value $offset $lcpu
12053 define _lapic_addr_value
12054        _lapic_addr $arg0
12055        if $_x2apic_enabled
12056           readmsr64int $kgm_lapic_addr $arg1
12057           set $kgm_lapic_value = $kgm_readmsr64int_result                 
12058        else
12059           readphysint $kgm_lapic_addr 32 $arg1
12060           set $kgm_lapic_value = $kgm_readphysint_result
12061        end
12062 end
12063 
12064 # lapic_read32 $offset [$lcpu]
12065 define lapic_read32
12066    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
12067        printf "lapic_read32 not supported on this architecture.\n"
12068    else
12069        set $lcpu = $kgm_lcpu_self
12070        if $argc > 1
12071           set $lcpu = $arg1
12072        end
12073        _lapic_addr_value $arg0 $lcpu
12074        printf "LAPIC[0x%03X]: 0x%08X\n", $arg0, $kgm_lapic_value
12075    end
12076 end
12077 
12078 document lapic_read32
12079 Syntax: (gdb) apic_read32_cpu <offset> [lcpu (kernel's numbering convention)]
12080 | Read the LAPIC register at the offset specified. The CPU can be optionally
12081 | specified.
12082 end
12083 
12084 # lapic_write32 $offset $value [$lcpu]
12085 define lapic_write32
12086    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
12087        printf "lapic_write32_cpu not supported on this architecture.\n"
12088    else
12089        set $lcpu = $kgm_lcpu_self
12090        if $argc > 2
12091           set $lcpu = $arg2
12092        end
12093 
12094        _lapic_addr $arg0
12095        if $_x2apic_enabled
12096           writemsr64int $kgm_lapic_addr $arg1 $lcpu
12097        else
12098           writephysint $kgm_lapic_addr 32 $arg1 $lcpu
12099        end
12100    end
12101 end
12102 
12103 document lapic_write32
12104 Syntax: (gdb) lapic_write32 <offset> <value> [lcpu (kernel's numbering convention)]
12105 | Write the LAPIC register at the offset specified. The CPU can be optionally
12106 | specified.
12107 end
12108 
12109 # lapic_dump [lcpu]
12110 define lapic_dump
12111    if (($kgm_mtype & $kgm_mtype_x86_mask) != $kgm_mtype_x86_any)
12112        printf "lapic_dump not supported on this architecture.\n"
12113    else
12114        set $lcpu = $kgm_lcpu_self
12115        if $argc > 0
12116           set $lcpu = $arg0
12117        end
12118 
12119        _lapic_addr_value $_lapic_id $lcpu
12120 
12121        # the above also figures out if we're using an xAPIC or an x2APIC
12122        printf "LAPIC operating mode: "
12123        if $_x2apic_enabled
12124           printf "           x2APIC\n"
12125        else
12126           printf "           xAPIC\n"
12127        end
12128 
12129        printf "LAPIC[0x%03X] ID:                 0x%08X\n", $_lapic_id, $kgm_lapic_value
12130 
12131        _lapic_addr_value $_lapic_version $lcpu
12132        set $lvt_num = ($kgm_lapic_value >> 16) + 1
12133        printf "LAPIC[0x%03X] VERSION:            0x%08X [VERSION=%d MaxLVT=%d]\n", $_lapic_version, $kgm_lapic_value, $kgm_lapic_value & 0xFF, $lvt_num
12134        
12135        _lapic_addr_value $_lapic_tpr $lcpu
12136        printf "LAPIC[0x%03X] TASK PRIORITY:      0x%08X\n", $_lapic_tpr, $kgm_lapic_value
12137 
12138        _lapic_addr_value $_lapic_ppr $lcpu
12139        printf "LAPIC[0x%03X] PROCESSOR PRIORITY: 0x%08X\n", $_lapic_ppr, $kgm_lapic_value
12140 
12141        _lapic_addr_value $_lapic_ldr $lcpu
12142        printf "LAPIC[0x%03X] LOGICAL DEST:       0x%08X\n", $_lapic_ldr, $kgm_lapic_value
12143 
12144        _lapic_addr_value $_lapic_dfr $lcpu
12145        printf "LAPIC[0x%03X] DEST FORMAT:        0x%08X\n", $_lapic_dfr, $kgm_lapic_value
12146 
12147        _lapic_addr_value $_lapic_sivr $lcpu
12148        printf "LAPIC[0x%03X] SPURIOUS VECTOR:    0x%08X [VEC=%3d ENABLED=%d]\n", $_lapic_sivr, $kgm_lapic_value, $kgm_lapic_value & $_apic_vector_mask, ($kgm_lapic_value & 0x100) >> 8, 
12149 
12150        set $i = 0
12151        while $i < $_lapic_isr_num
12152              set $addr = $_lapic_isr0 + $i * $_lapic_isr_size
12153              _lapic_addr_value $addr $lcpu
12154              printf "LAPIC[0x%03X] ISR[%03d:%03d]:       0x%08X\n", $addr, 32*($i + 1) - 1,  32*$i, $kgm_lapic_value
12155              set $i = $i + 1
12156        end
12157 
12158        set $i = 0
12159        while $i < $_lapic_isr_num
12160              set $addr = $_lapic_tmr0 + $i * $_lapic_isr_size
12161              _lapic_addr_value $addr $lcpu
12162              printf "LAPIC[0x%03X] TMR[%03d:%03d]:       0x%08X\n", $addr, 32*($i + 1) - 1,  32*$i, $kgm_lapic_value
12163              set $i = $i + 1
12164        end
12165 
12166        set $i = 0
12167        while $i < $_lapic_isr_num
12168              set $addr = $_lapic_irr0 + $i * $_lapic_isr_size
12169              _lapic_addr_value $addr $lcpu
12170              printf "LAPIC[0x%03X] IRR[%03d:%03d]:       0x%08X\n", $addr, 32*($i + 1) - 1,  32*$i, $kgm_lapic_value
12171              set $i = $i + 1
12172        end
12173 
12174        _lapic_addr_value $_lapic_esr $lcpu
12175        printf "LAPIC[0x%03X] ERROR STATUS:       0x%08X ", $_lapic_esr, $kgm_lapic_value
12176        if $kgm_lapic_value
12177           printf "["
12178        end
12179        if $kgm_lapic_value & $_lapic_esr_register
12180           printf "Register  "
12181        end
12182        if $kgm_lapic_value & $_lapic_esr_recv_vect
12183           printf "Received Vector  "
12184        end
12185        if $kgm_lapic_value & $_lapic_esr_send_vect
12186           printf "Send Vector"
12187        end
12188        if $kgm_lapic_value
12189           printf "]"
12190        end
12191        printf "\n"
12192 
12193        _lapic_addr_value $_lapic_icr1 $lcpu
12194        printf "LAPIC[0x%03X] Interrupt Command:  0x%08X [DEST=%d]\n", $_lapic_icr0, $kgm_lapic_value, $kgm_lapic_value >> 24
12195        _lapic_addr_value $_lapic_icr0 $lcpu
12196        printf "                                 0x%08X ", $kgm_lapic_value
12197        _apic_print $kgm_lapic_value
12198 
12199        if $lvt_num > 0
12200           _lapic_addr_value $_lapic_lvt_timer $lcpu
12201           printf "LAPIC[0x%03X] LVT Timer:          0x%08X ", $_lapic_lvt_timer, $kgm_lapic_value
12202           _apic_print $kgm_lapic_value
12203        end
12204 
12205        if $lvt_num > 1
12206           _lapic_addr_value $_lapic_lvt_lint0 $lcpu
12207           printf "LAPIC[0x%03X] LVT LINT0:          0x%08X ", $_lapic_lvt_lint0, $kgm_lapic_value
12208           _apic_print $kgm_lapic_value
12209        end
12210 
12211        if $lvt_num > 2
12212           _lapic_addr_value $_lapic_lvt_lint1 $lcpu
12213           printf "LAPIC[0x%03X] LVT LINT1:          0x%08X ", $_lapic_lvt_lint1, $kgm_lapic_value
12214           _apic_print $kgm_lapic_value
12215        end
12216 
12217        if $lvt_num > 3
12218           _lapic_addr_value $_lapic_lvt_error $lcpu
12219           printf "LAPIC[0x%03X] LVT Error:          0x%08X ", $_lapic_lvt_error, $kgm_lapic_value
12220           _apic_print $kgm_lapic_value
12221        end
12222 
12223        if $lvt_num > 4
12224           _lapic_addr_value $_lapic_lvt_pmcr $lcpu
12225           printf "LAPIC[0x%03X] LVT PerfMon:        0x%08X ", $_lapic_lvt_pmcr, $kgm_lapic_value
12226           _apic_print $kgm_lapic_value
12227        end
12228 
12229        if $lvt_num > 5
12230           _lapic_addr_value $_lapic_lvt_thermal $lcpu
12231           printf "LAPIC[0x%03X] LVT Thermal:        0x%08X ", $_lapic_lvt_thermal, $kgm_lapic_value
12232           _apic_print $kgm_lapic_value
12233        end
12234 
12235        _lapic_addr_value $_lapic_dcr $lcpu
12236        printf "LAPIC[0x%03X] Timer Divide:       0x%08X [Divide by ", $_lapic_dcr, $kgm_lapic_value
12237        set $kgm_lapic_value = ($kgm_lapic_value & 0x8) >> 1 | $kgm_lapic_value & 0x3
12238        if $kgm_lapic_value == 0x7
12239           printf "1]\n"
12240        else
12241           printf "%d]\n", 2 << $kgm_lapic_value
12242        end
12243 
12244        _lapic_addr_value $_lapic_icr $lcpu
12245        printf "LAPIC[0x%03X] Timer Init Count:   0x%08X\n", $_lapic_icr, $kgm_lapic_value
12246 
12247        _lapic_addr_value $_lapic_ccr $lcpu
12248        printf "LAPIC[0x%03X] Timer Cur Count:    0x%08X\n", $_lapic_ccr, $kgm_lapic_value
12249    end
12250 end
12251 
12252 document lapic_dump
12253 Syntax: (gdb) lapic_dump [lcpu (kernel's numbering convention)]
12254 | Dump all the LAPIC entries. The CPU can be optionally specified. 
12255 end
12256  
12257 define showknoteheader
12258    printf "            knote       filter           ident  kn_ptr      status\n"
12259 end
12260 
12261 define showknoteint
12262     set $kgm_knotep = ((struct knote *) $arg0)
12263     printf "            "
12264     showptr $kgm_knotep
12265     printf "  "
12266     set $kgm_filt = -$kgm_knotep->kn_kevent.filter
12267     if ($kgm_filt == 1)
12268         printf "EVFILT_READ    "
12269     end
12270     if ($kgm_filt == 2)
12271         printf "EVFILT_WRITE   "
12272     end
12273     if ($kgm_filt == 3)
12274         printf "EVFILT_AIO     "
12275     end
12276     if ($kgm_filt == 4)
12277         printf "EVFILT_VNODE   "
12278     end
12279     if ($kgm_filt == 5)
12280         printf "EVFILT_PROC    "
12281     end
12282     if ($kgm_filt == 6)
12283         printf "EVFILT_SIGNAL  "
12284     end
12285     if ($kgm_filt == 7)
12286         printf "EVFILT_TIMER   "
12287     end
12288     if ($kgm_filt == 8)
12289         printf "EVFILT_MACHPORT"
12290     end
12291     if ($kgm_filt == 9)
12292         printf "EVFILT_FS      "
12293     end
12294     if ($kgm_filt == 10)
12295         printf "EVFILT_USER    "
12296     end
12297     if ($kgm_filt == 11)
12298         printf "EVFILT_SESSION "
12299     end
12300     printf "%7d  ", $kgm_knotep->kn_kevent.ident
12301     showptr $kgm_knotep->kn_ptr.p_fp
12302     printf "  "
12303     if ($kgm_knotep->kn_status == 0)
12304         printf "-"
12305     else
12306         if ($kgm_knotep->kn_status & 0x01)
12307             printf "A"
12308         end
12309         if ($kgm_knotep->kn_status & 0x02)
12310             printf "Q"
12311         end
12312         if ($kgm_knotep->kn_status & 0x04)
12313             printf "Dis"
12314         end
12315         if ($kgm_knotep->kn_status & 0x08)
12316             printf "Dr"
12317         end
12318         if ($kgm_knotep->kn_status & 0x10)
12319             printf "Uw"
12320         end
12321         if ($kgm_knotep->kn_status & 0x20)
12322             printf "Att"
12323         end
12324         if ($kgm_knotep->kn_status & 0x40)
12325             printf "Stq"
12326         end
12327     end
12328     printf "\n"
12329 end
12330 
12331 define showprocknotes
12332     showknoteheader
12333     set $kgm_fdp = ((proc_t)$arg0)->p_fd
12334     set $kgm_knlist = $kgm_fdp->fd_knlist
12335     set $i = 0
12336     while (($i < $kgm_fdp->fd_knlistsize) && ($kgm_knlist != 0))
12337         set $kgm_kn = ((struct knote *)$kgm_knlist[$i].slh_first)
12338         while ($kgm_kn != 0)
12339             showknoteint $kgm_kn
12340             set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
12341         end
12342         set $i = $i + 1
12343     end
12344     set $kgm_knhash = $kgm_fdp->fd_knhash
12345     set $i = 0
12346     while (($i < $kgm_fdp->fd_knhashmask + 1) && ($kgm_knhash != 0))
12347         set $kgm_kn = ((struct knote *)$kgm_knhash[$i].slh_first)
12348         while ($kgm_kn != 0)
12349             showknoteint $kgm_kn
12350             set $kgm_kn = ((struct knote *)$kgm_kn->kn_link.sle_next)
12351         end
12352         set $i = $i + 1
12353     end
12354 end
12355 
12356 define showallknotes
12357     set $kgm_head_taskp = &tasks
12358     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12359     while $kgm_taskp != $kgm_head_taskp
12360         showtaskheader
12361         showtaskint $kgm_taskp
12362         showprocknotes $kgm_taskp->bsd_info
12363         set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
12364     end
12365 end
12366 document showprocknotes 
12367 Syntax: showprocknotes <proc>
12368 | Displays filter and status information for every kevent registered for
12369 | the process.
12370 end
12371 
12372 #
12373 # Device node related debug macros
12374 #
12375 
12376 define _showtty
12377         set $kgm_tty = (struct tty *) $arg0
12378         printf "tty struct at "
12379         showptr $kgm_tty
12380         printf "\n"
12381         printf "-last input to raw queue:\n"
12382         p $kgm_tty->t_rawq->c_cs
12383         printf "-last input to canonical queue:\n"
12384         p $kgm_tty->t_canq->c_cs
12385         printf "-last output data:\n"
12386         p $kgm_tty->t_outq->c_cs
12387         printf "state:\n"
12388         if ($kgm_tty->t_state & 0x00000001)
12389                 printf "    TS_SO_OLOWAT (Wake up when output <= low water)\n"
12390         end
12391         if ($kgm_tty->t_state & 0x00000002)
12392                 printf "    TS_ASYNC (async I/O mode)\n"
12393         else
12394                 printf "    - (synchronous I/O mode)\n"
12395         end
12396         if ($kgm_tty->t_state & 0x00000004)
12397                 printf "    TS_BUSY (Draining output)\n"
12398         end
12399         if ($kgm_tty->t_state & 0x00000008)
12400                 printf "    TS_CARR_ON (Carrier is present)\n"
12401         else
12402                 printf "    - (Carrier is NOT present)\n"
12403         end
12404         if ($kgm_tty->t_state & 0x00000010)
12405                 printf "    TS_FLUSH (Outq has been flushed during DMA)\n"
12406         end
12407         if ($kgm_tty->t_state & 0x00000020)
12408                 printf "    TS_ISOPEN (Open has completed)\n"
12409         else
12410                 printf "    - (Open has NOT completed)\n"
12411         end
12412         if ($kgm_tty->t_state & 0x00000040)
12413                 printf "    TS_TBLOCK (Further input blocked)\n"
12414         end
12415         if ($kgm_tty->t_state & 0x00000080)
12416                 printf "    TS_TIMEOUT (Wait for output char processing)\n"
12417         end
12418         if ($kgm_tty->t_state & 0x00000100)
12419                 printf "    TS_TTSTOP (Output paused)\n"
12420         end
12421         if ($kgm_tty->t_state & 0x00000200)
12422                 printf "    TS_WOPEN (Open in progress)\n"
12423         end
12424         if ($kgm_tty->t_state & 0x00000400)
12425                 printf "    TS_XCLUDE (Tty requires exclusivity)\n"
12426         end
12427         if ($kgm_tty->t_state & 0x00000800)
12428                 printf "    TS_BKSL (State for lowercase \\ work)\n"
12429         end
12430         if ($kgm_tty->t_state & 0x00001000)
12431                 printf "    TS_CNTTB (Counting tab width, ignore FLUSHO)\n"
12432         end
12433         if ($kgm_tty->t_state & 0x00002000)
12434                 printf "    TS_ERASE (Within a \\.../ for PRTRUB)\n"
12435         end
12436         if ($kgm_tty->t_state & 0x00004000)
12437                 printf "    TS_LNCH (Next character is literal)\n"
12438         end
12439         if ($kgm_tty->t_state & 0x00008000)
12440                 printf "    TS_TYPEN (Retyping suspended input (PENDIN))\n"
12441         end
12442         if ($kgm_tty->t_state & 0x00010000)
12443                 printf "    TS_CAN_BYPASS_L_RINT (Device in "raw" mode)\n"
12444         end
12445         if ($kgm_tty->t_state & 0x00020000)
12446                 printf "    TS_CONNECTED (Connection open)\n"
12447         else
12448                 printf "    - (Connection NOT open)\n"
12449         end
12450         if ($kgm_tty->t_state & 0x00040000)
12451                 printf "    TS_SNOOP (Device is being snooped on)\n"
12452         end
12453         if ($kgm_tty->t_state & 0x80000)
12454                 printf "    TS_SO_OCOMPLETE (Wake up when output completes)\n"
12455         end
12456         if ($kgm_tty->t_state & 0x00100000)
12457                 printf "    TS_ZOMBIE (Connection lost)\n"
12458         end
12459         if ($kgm_tty->t_state & 0x00200000)
12460                 printf "    TS_CAR_OFLOW (For MDMBUF - handle in driver)\n"
12461         end
12462         if ($kgm_tty->t_state & 0x00400000)
12463                 printf "    TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)\n"
12464         end
12465         if ($kgm_tty->t_state & 0x00800000)
12466                 printf "    TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)\n"
12467         end
12468         # xxx todo: do we care about decoding flags?
12469         printf "flags:                    0x%08x\n", $kgm_tty->t_flags
12470         printf "foreground process group: "
12471         showptr $kgm_tty->t_pgrp
12472         printf "\n"
12473         printf "enclosing session:        "
12474         showptr $kgm_tty->t_session
12475         printf "\n"
12476         printf "Termios:\n"
12477         # XXX todo: decode these flags, someday
12478         printf "    Input flags:   0x%08x\n", $kgm_tty->t_termios.c_iflag
12479         printf "    Output flags:  0x%08x\n", $kgm_tty->t_termios.c_oflag
12480         printf "    Control flags: 0x%08x\n", $kgm_tty->t_termios.c_cflag
12481         printf "    Local flags:   0x%08x\n", $kgm_tty->t_termios.c_lflag
12482         printf "    Input speed:   %d\n",  $kgm_tty->t_termios.c_ispeed
12483         printf "    Output speed:  %d\n",  $kgm_tty->t_termios.c_ospeed
12484         # XXX todo: useful to decode t_winsize? t_iokit? c_cc? anything else?
12485         printf "high watermark: %d bytes\n", $kgm_tty->t_hiwat
12486         printf "low watermark: %d bytes\n", $kgm_tty->t_lowat
12487 end
12488 
12489 define _showwhohas
12490         # _showwhohas <major> <minor>
12491         printf "fd     "
12492         printf "fileglob    "
12493 showptrhdrpad
12494         printf "vnode       "
12495 showptrhdrpad
12496         printf "process     "
12497 showptrhdrpad
12498         printf "name\n"
12499 
12500         set $kgm_swh_devnode_dev = (((int) $arg0) << 24) | (int) $arg1
12501         # iterate all tasks to iterate all processes to iterate all
12502         # open files in each process to see who has a given major/minor
12503         # device open
12504         set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12505         while $kgm_taskp != $kgm_head_taskp
12506                 set $kgm_procp = (proc_t) $kgm_taskp->bsd_info
12507                 set $kgm_spf_filedesc = $kgm_procp->p_fd
12508                 set $kgm_spf_last = $kgm_spf_filedesc->fd_lastfile
12509                 set $kgm_spf_ofiles = $kgm_spf_filedesc->fd_ofiles
12510                 set $kgm_spf_count = 0
12511                 while (($kgm_spf_ofiles != 0) && ($kgm_spf_count <= $kgm_spf_last))
12512                     # only files currently open
12513                     if ($kgm_spf_ofiles[$kgm_spf_count] != 0)
12514                         set $kgm_spf_fg = $kgm_spf_ofiles[$kgm_spf_count].f_fglob
12515                         if ($kgm_spf_fg->fg_type == 1)
12516                             # display fd #, fileglob & vnode address, proc name
12517                             set $kgm_swh_m_vnode = (vnode_t) $kgm_spf_fg->fg_data
12518                             set $kgm_swh_m_vtype = (enum vtype) $kgm_swh_m_vnode->v_type
12519                             if (($kgm_swh_m_vtype == VBLK) || ($kgm_swh_m_vtype == VCHR)) && ((((devnode_t *)$kgm_swh_m_vnode->v_data)->dn_typeinfo.dev) == $kgm_swh_devnode_dev)
12520                                 printf "%-5d  ", $kgm_spf_count
12521                                 showptr  $kgm_spf_fg
12522                                 printf "  "
12523                                 showptr $kgm_swh_m_vnode
12524                                 printf "  "
12525                                 showptr $kgm_procp
12526                                 printf "  %s\n", $kgm_procp->p_comm
12527                             end
12528                         end
12529                     end
12530                     set $kgm_spf_count = $kgm_spf_count + 1
12531                 end
12532 
12533                 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
12534         end
12535 end
12536 
12537 define _showvnodedev_cpty
12538         set $kgm_ptmx_major = (int) $arg0
12539         set $kgm_ptmx_minor = (int) $arg1
12540         set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
12541         set $kgm_ptmx_ioctl = _state.pis_ioctl_list[$kgm_ptmx_minor]
12542         printf "    ptmx_ioctl struct at "
12543         showptr $kgm_ptmx_ioctl
12544         printf "\n"
12545         printf "    flags:\n"
12546         if ($kgm_ptmx_ioctl->pt_flags & 0x0008)
12547                 printf "        PF_PKT (packet mode)\n"
12548         end
12549         if ($kgm_ptmx_ioctl->pt_flags & 0x0010)
12550                 printf "        PF_STOPPED (user told stopped)\n"
12551         end
12552         if ($kgm_ptmx_ioctl->pt_flags & 0x0020)
12553                 printf "        PF_REMOTE (remote and flow controlled input)\n"
12554         end
12555         if ($kgm_ptmx_ioctl->pt_flags & 0x0040)
12556                 printf "        PF_NOSTOP"
12557         end
12558         if ($kgm_ptmx_ioctl->pt_flags & 0x0080)
12559                 printf "        PF_UCNTL (user control mode)\n"
12560         end
12561         if ($kgm_ptmx_ioctl->pt_flags & 0x0100)
12562                 printf "        PF_UNLOCKED (slave unlock - master open resets)\n"
12563         end
12564         if ($kgm_ptmx_ioctl->pt_flags & 0x0200)
12565                 printf "        PF_OPEN_M (master is open)\n"
12566                 # XXX we should search for who has the master open, but
12567                 # XXX each master gets the same minor, even though it
12568                 # XXX gets a different vnode.  we chold probably change
12569                 # XXX this, but to do it we would need some way of
12570                 # XXX expressing the information in the vnode structure
12571                 # XXX somewhere.  If we *did* change it, it would buy us
12572                 # XXX the ability to determine who has the corresponding
12573                 # XXX master end of the pty open
12574         else
12575                 printf "        PF_OPEN_M (master is closed)\n"
12576         end
12577         if ($kgm_ptmx_ioctl->pt_flags & 0x0400)
12578                 printf "        PF_OPEN_S (slave is open)\n"
12579                 printf "---vvvvv--- fds open on this device ---vvvvv---\n"
12580                 _showwhohas  ($kgm_ptmx_major) ($kgm_ptmx_minor)
12581                 printf "---^^^^^--- fds open on this device ---^^^^^---\n"
12582         else
12583                 printf "        - (slave is closed)\n"
12584         end
12585         printf "TTY Specific Information\n"
12586         _showtty $kgm_ptmx_ioctl->pt_tty
12587 end
12588 
12589 define showvnodedev
12590     if ($argc == 1)
12591         set $kgm_vnode = (vnode_t) $arg0
12592         set $kgm_vtype = (enum vtype) $kgm_vnode->v_type
12593         if (($kgm_vtype == VBLK) || ($kgm_vtype == VCHR))
12594                 set $kgm_devnode = (devnode_t *) $kgm_vnode->v_data
12595                 set $kgm_devnode_dev = $kgm_devnode->dn_typeinfo.dev
12596                 set $kgm_devnode_major = ($kgm_devnode_dev >> 24) & 0xff
12597                 set $kgm_devnode_minor = $kgm_devnode_dev & 0x00ffffff
12598 
12599                 # boilerplate device information for a vnode 
12600                 printf "Device Info:\n"
12601                 printf "    vnode:        "
12602                 showptr $kgm_vnode
12603                 printf "\n"
12604                 printf "    type:         "
12605                 if ($kgm_vtype == VBLK)
12606                         printf "VBLK "
12607                 end
12608                 if ($kgm_vtype == VCHR)
12609                         printf "VCHR"
12610                 end
12611                 printf "\n"
12612                 printf "    name:         %s\n", $kgm_vnode->v_name
12613                 printf "    major, minor: %d, %d\n", $kgm_devnode_major, $kgm_devnode_minor
12614                 printf "    mode          0%o\n", $kgm_devnode->dn_mode
12615                 printf "    owner (u,g):  %d %d", $kgm_devnode->dn_uid, $kgm_devnode->dn_gid
12616                 printf "\n"
12617 
12618                 # decode device specific data
12619                 printf "Device Specific Information:  "
12620                 if ($kgm_vtype == VBLK)
12621                         printf "    Sorry, I do not know how to decode block devices yet!\n"
12622                         printf "    Maybe you can write me!"
12623                 end
12624                 if ($kgm_vtype == VCHR)
12625                         # Device information; this is scanty
12626                         # range check
12627                         if ($kgm_devnode_major > 42) || ($kgm_devnode_major < 0)
12628                                 printf "Invalid major #\n"
12629                         else
12630                         # static assignments in conf
12631                         if ($kgm_devnode_major == 0)
12632                                 printf "Console mux device\n"
12633                         else
12634                         if ($kgm_devnode_major == 2)
12635                                 printf "Current tty alias\n"
12636                         else
12637                         if ($kgm_devnode_major == 3)
12638                                 printf "NULL device\n"
12639                         else
12640                         if ($kgm_devnode_major == 4)
12641                                 printf "Old pty slave\n"
12642                         else
12643                         if ($kgm_devnode_major == 5)
12644                                 printf "Old pty master\n"
12645                         else
12646                         if ($kgm_devnode_major == 6)
12647                                 printf "Kernel log\n"
12648                         else
12649                         if ($kgm_devnode_major == 12)
12650                                 printf "Memory devices\n"
12651                         else
12652                         # Statically linked dynamic assignments
12653                         if cdevsw[$kgm_devnode_major].d_open == ptmx_open
12654                                 printf "Cloning pty master\n"
12655                                 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
12656                         else
12657                         if cdevsw[$kgm_devnode_major].d_open == ptsd_open
12658                                 printf "Cloning pty slave\n"
12659                                 _showvnodedev_cpty ($kgm_devnode_major) ($kgm_devnode_minor)
12660                         else
12661                                 printf "RESERVED SLOT\n"
12662                         end
12663                         end
12664                         end
12665                         end
12666                         end
12667                         end
12668                         end
12669                         end
12670                         end
12671                         end
12672                 end
12673         else
12674                 showptr $kgm_vnode
12675                 printf " is not a device\n"
12676         end
12677     else
12678         printf "| Usage:\n|\n"
12679         help showvnodedev
12680     end
12681 end
12682 document showvnodedev
12683 Syntax: (gdb) showvnodedev <vnode>
12684 |     showvnodedev       Display information about a device vnode
12685 end
12686 
12687 define showtty
12688     if ($argc == 1)
12689         _showtty $arg0
12690     else
12691         printf "| Usage:\n|\n"
12692         help showtty
12693     end
12694 end
12695 document showtty
12696 Syntax: (gdb) showtty <tty struct>
12697 |     showtty            Display information about a struct tty
12698 end
12699 
12700 define showeventsourceobject
12701     set $kgm_vt = *((void **) $arg1)
12702     if $kgm_lp64
12703         set $kgm_vt = $kgm_vt - 16
12704     end
12705     pcprint $kgm_vt
12706 end
12707 document showeventsourceobject
12708 Syntax: (gdb) showeventsourceobject <prefix> <object>
12709 | Routine to display information about an IOEventSource subclass.
12710 end
12711 
12712 define showworkloopallocator
12713         set $kgm_workloop = (struct IOWorkLoop*)$arg0
12714         set $kgm_bt = (void**)$kgm_workloop->reserved->allocationBacktrace
12715         set $kgm_bt_count = 0
12716         while $kgm_bt_count != (sizeof(IOWorkLoop::ExpansionData.allocationBacktrace) / sizeof(IOWorkLoop::ExpansionData.allocationBacktrace[0]))
12717                 set $kgm_frame_address = (void*)$kgm_bt[$kgm_bt_count]
12718                 if $kgm_frame_address != 0
12719                         if (((unsigned long) $kgm_frame_address < (unsigned long) &_mh_execute_header || \
12720                              (unsigned long) $kgm_frame_address >= (unsigned long) &last_kernel_symbol ) \
12721                             && ($kgm_show_kmod_syms == 0))
12722                                 showkmodaddr $kgm_frame_address
12723                         else
12724                                 output /a $kgm_frame_address
12725                         end
12726                         printf "\n"
12727                 end
12728                 set $kgm_bt_count = $kgm_bt_count + 1
12729         end
12730 end
12731 document showworkloopallocator
12732 Syntax: (gdb) showworkloopallocator <workloop>
12733 | Routine to display the backtrace of the thread which allocated the workloop in question. Only
12734 | valid on DEBUG kernels.
12735 end
12736 
12737 define showworkloopeventsources
12738         set $kgm_eventsource = (struct IOEventSource*)$arg0
12739     while $kgm_eventsource != 0
12740         printf "     "
12741         printf "EventSource:\t"
12742         showptr $kgm_eventsource
12743         printf " Description: "
12744         showeventsourceobject _ $kgm_eventsource
12745         printf "\n"
12746         if $kgm_eventsource->action != 0
12747                 printf "          "
12748                         printf "Action: \t"
12749                 pcprint $kgm_eventsource->action
12750                 printf "\n"
12751         end
12752         if $kgm_eventsource->owner != 0
12753                 printf "          "
12754                         printf "Owner: \t"
12755                         showptr $kgm_eventsource->owner
12756                         printf " Description: "
12757                         showeventsourceobject _ $kgm_eventsource->owner
12758                 printf "\n"
12759         end
12760         set $kgm_eventsource = $kgm_eventsource->eventChainNext
12761         printf "\n"
12762     end
12763 end
12764 document showworkloopeventsources
12765 Syntax: (gdb) showworkloopeventsources
12766 | Routine to walk an IOEventSource chain associated with an IOWorkLoop and print information
12767 | about each event source in the chain.
12768 end
12769 
12770 define showworkloopheader
12771     printf "thread    "
12772     showptrhdrpad
12773     printf "  workloop "
12774     showptrhdrpad
12775     printf "    pri state\tLockGroupName\n"
12776 end
12777 document showworkloopheader
12778 Syntax: (gdb) showworkloopheader
12779 | Routine to print out header info about an IOKit workloop.
12780 end
12781 
12782 define showworkloop
12783         set $kgm_workloopthread = (struct thread*)$arg0
12784         set $kgm_workloop = (struct IOWorkLoop*)$arg1
12785     showptr $kgm_workloopthread
12786         printf "  "
12787         showptr $kgm_workloop
12788         printf "   %3d ", $kgm_workloopthread.sched_pri
12789         set $kgm_state = $kgm_workloopthread.state
12790         if $kgm_state & 0x80
12791             printf "I" 
12792         end
12793         if $kgm_state & 0x40
12794             printf "P" 
12795         end
12796         if $kgm_state & 0x20
12797             printf "A" 
12798         end
12799         if $kgm_state & 0x10
12800             printf "H" 
12801         end
12802         if $kgm_state & 0x08
12803             printf "U" 
12804         end
12805         if $kgm_state & 0x04
12806             printf "R" 
12807         end
12808         if $kgm_state & 0x02
12809             printf "S" 
12810         end
12811         if $kgm_state & 0x01
12812             printf "W"
12813         end
12814         printf "\t\t"
12815         set $kgm_gateLock = ( struct _IORecursiveLock *)$kgm_workloop->gateLock
12816         if $kgm_gateLock != 0
12817                 set $kgm_lockGroup = (struct _lck_grp_*)($kgm_gateLock->group)
12818                 printf "%s", $kgm_lockGroup->lck_grp_name
12819         else
12820                 printf "No WorkLoop Lock found"
12821         end
12822         printf "\n\n"
12823         
12824         #Allocation backtrace is only valid on DEBUG kernels.
12825         #printf "Allocation path:\n\n"
12826         #showworkloopallocator $kgm_workloop
12827         #printf "\n\n"
12828         
12829         if $kgm_workloop->eventChain != 0
12830                 printf "Active event sources:\n\n"
12831                 showworkloopeventsources $kgm_workloop->eventChain
12832         end
12833         if $kgm_workloop->reserved->passiveEventChain != 0
12834                 printf "Passive event sources:\n"
12835                 showworkloopeventsources $kgm_workloop->reserved->passiveEventChain
12836         end
12837 end
12838 document showworkloop
12839 Syntax: (gdb) showworkloop <thread> <workloop>
12840 | Routine to print out info about an IOKit workloop.
12841 end
12842 
12843 define showallworkloopthreads
12844     set $kgm_head_taskp = &tasks
12845     set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12846         set $kgm_head_actp = &($kgm_taskp->threads)
12847         set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
12848         while $kgm_actp != $kgm_head_actp
12849                 if ($kgm_actp->continuation == _ZN10IOWorkLoop10threadMainEv)
12850                         showworkloopheader
12851                         showworkloop $kgm_actp $kgm_actp->parameter
12852                 else
12853                         if ($kgm_actp->kernel_stack != 0)
12854                                 if ($kgm_mtype == $kgm_mtype_x86_64)
12855                                         #Warning: Grokking stack looking for hopeful workloops until we squirrel some info in thread_t.
12856                                         set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0xB8))
12857                                 else
12858                                         if ($kgm_mtype == $kgm_mtype_i386)
12859                                                 set $kgm_workloop = *((struct IOWorkLoop **)($kgm_actp->kernel_stack + kernel_stack_size - 0x3C))
12860                                         end
12861                                 end
12862                                 if ($kgm_workloop != 0)
12863                                         set $kgm_vt = *((void **) $kgm_workloop)
12864                                         if $kgm_lp64
12865                                                 set $kgm_vt = $kgm_vt - 16
12866                                         end
12867                                         if ($kgm_vt == &_ZTV10IOWorkLoop)
12868                                                 showworkloopheader
12869                                                 showworkloop $kgm_actp $kgm_workloop
12870                                         end
12871                                 end
12872                         end
12873                 end
12874                 set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
12875         end
12876         printf "\n"
12877 end
12878 document showallworkloopthreads
12879 Syntax: (gdb) showallworkloopthreads
12880 | Routine to print out info about all IOKit workloop threads in the system. This macro will find
12881 | all IOWorkLoop threads blocked in continuations and on i386 and x86_64 systems will make a
12882 | best-effort guess to find any workloops that are actually not blocked in a continuation. For a
12883 | complete list, it is best to compare the output of this macro against the output of 'showallstacks'.
12884 end
12885 
12886 define showthreadfortid
12887         set $kgm_id_found = 0
12888         
12889         set $kgm_head_taskp = &tasks
12890         set $kgm_taskp = (struct task *)($kgm_head_taskp->next)
12891         while $kgm_taskp != $kgm_head_taskp
12892                 set $kgm_head_actp = &($kgm_taskp->threads)
12893                 set $kgm_actp = (struct thread *)($kgm_taskp->threads.next)
12894                 while $kgm_actp != $kgm_head_actp
12895                         set $kgm_thread = *(struct thread *)$kgm_actp
12896                         set $kgm_thread_id = $kgm_thread.thread_id
12897                         if ($kgm_thread_id == $arg0)
12898                                 showptr $kgm_actp
12899                                 printf "\n"
12900                                 set $kgm_id_found = 1
12901                                 loop_break
12902                         end
12903                         set $kgm_actp = (struct thread *)($kgm_actp->task_threads.next)
12904                 end
12905                 if ($kgm_id_found == 1)
12906                         loop_break
12907                 end
12908                 set $kgm_taskp = (struct task *)($kgm_taskp->tasks.next)
12909         end
12910         if ($kgm_id_found == 0)
12911                 printf  "Not a valid thread_id\n"
12912         end
12913 end
12914 
12915 document showthreadfortid
12916 Syntax:  showthreadfortid  <thread_id>
12917 |The thread structure contains a unique thread_id value for each thread.
12918 |This command is used to retrieve the address of the thread structure(thread_t) 
12919 |corresponding to a given thread_id.
12920 end
12921 
12922 define showtaskbusyportsint
12923     set $kgm_isp = ((task_t)$arg0)->itk_space
12924         set $kgm_iindex = 0
12925         while ( $kgm_iindex < $kgm_isp->is_table_size )
12926                 set $kgm_iep = &($kgm_isp->is_table[$kgm_iindex])
12927                 if $kgm_iep->ie_bits & 0x00020000
12928                         set $kgm_port = ((ipc_port_t)$kgm_iep->ie_object)
12929                         if $kgm_port->ip_messages.data.port.msgcount > 0
12930                                 showport $kgm_port
12931                         end
12932                 end
12933                 set $kgm_iindex = $kgm_iindex + 1
12934         end
12935 end
12936 
12937 define showtaskbusyports
12938     showtaskbusyportsint $arg0
12939 end
12940 
12941 document showtaskbusyports
12942 Syntax:  showtaskbusyports <task>
12943 |Routine to print information about receive rights belonging to this task that
12944 |have enqueued messages. This is often a sign of a blocked or hung process.
12945 end
12946 
12947 define showallbusyports
12948     set $kgm_head_taskp = &tasks
12949     set $kgm_cur_taskp = (struct task *)($kgm_head_taskp->next)
12950     while $kgm_cur_taskp != $kgm_head_taskp
12951                 showtaskbusyportsint $kgm_cur_taskp
12952         set $kgm_cur_taskp = (struct task *)($kgm_cur_taskp->tasks.next)
12953     end
12954 end
12955 
12956 document showallbusyports
12957 Syntax:  showallbusyports
12958 |Routine to print information about all receive rights on the system that
12959 |have enqueued messages.
12960 end
12961 
12962 define showallproviders
12963     set $kgm_providerp = dtrace_provider
12964     while $kgm_providerp
12965         p *(dtrace_provider_t *)$kgm_providerp
12966         printf "\n"
12967         set $kgm_providerp = (dtrace_provider_t *)($kgm_providerp->dtpv_next)
12968     end
12969 end
12970 
12971 document showallproviders
12972 Syntax: showallproviders
12973 | Display summary listing of all dtrace_providers
12974 end
12975 
12976 define showmodctlheader
12977     printf   "modctl    "
12978     showptrhdrpad
12979     printf "  stale     "
12980     showptrhdrpad
12981     printf "  symbols   "
12982     showptrhdrpad
12983     printf "  address   "
12984     showptrhdrpad
12985     printf "  size      "
12986     showptrhdrpad
12987     printf "  loadid    loaded  nenabled  flags      name\n"
12988 end
12989 
12990 define showmodctlint
12991     set $kgm_modctlp = (struct modctl *)$arg0
12992     showptr $kgm_modctlp
12993     printf "  "
12994     showptr $kgm_modctlp->mod_stale
12995     printf "  "
12996     showptr $kgm_modctlp->mod_user_symbols
12997     printf "  "
12998     showptr $kgm_modctlp->mod_address
12999     printf "  "
13000     showptr $kgm_modctlp->mod_size
13001     printf "  "
13002     printf "%6d  ", $kgm_modctlp->mod_loadcnt
13003     printf "%6d  ", $kgm_modctlp->mod_loaded
13004     printf "%6d  ", $kgm_modctlp->mod_nenabled
13005     printf "    0x%x  ", $kgm_modctlp->mod_flags
13006     printf "%s\n", $kgm_modctlp->mod_modname
13007 end
13008 
13009 define showmodctl
13010     showmodctlheader
13011     showmodctlint $arg0
13012 end
13013 document showmodctl
13014 Syntax: (gdb) showmodctl <addr>
13015 | Display info about a dtrace modctl
13016 end
13017 
13018 define showallmodctls
13019     showmodctlheader
13020     set $kgm_modctlp = (struct modctl *)dtrace_modctl_list
13021     while $kgm_modctlp
13022         showmodctlint $kgm_modctlp
13023         set $kgm_modctlp = $kgm_modctlp->mod_next
13024     end
13025 end
13026 document showallmodctls
13027 Syntax: (gdb) showallmodctls
13028 | Display summary listing of all dtrace modctls
13029 end
13030 
13031 define showfbtprobe
13032   printf "Be very patient, this traverses a large list \n"
13033   set $kgm_indx = 0
13034   set $kgm_found = 0
13035   set $kgm_depth = 0
13036   while $kgm_indx < fbt_probetab_size && !$kgm_found
13037     set $kgm_fbt_probep = (struct fbt_probe *)fbt_probetab[$kgm_indx]
13038     set $kgm_depth = 0
13039     if $kgm_fbt_probep
13040       set $kgm_probeid = (struct fbt_probe *)$kgm_fbt_probep->fbtp_id
13041       if $kgm_probeid == $arg0
13042         set $kgm_found = 1
13043         loop_break
13044       else
13045         set $kgm_fbt_probep = $kgm_fbt_probep->fbtp_hashnext
13046         while $kgm_fbt_probep
13047           set $kgm_depth++
13048           set $kgm_probeid = (struct fbt_probe *)$kgm_fbt_probep->fbtp_id
13049           if $kgm_probeid == $arg0
13050             set $kgm_found = 1
13051             loop_break
13052           else
13053             set $kgm_fbt_probep = $kgm_fbt_probep->fbtp_hashnext
13054           end
13055         end
13056       end
13057     end
13058     if !$kgm_found
13059       set $kgm_indx++
13060     else
13061       printf "fbt_probetab[index=%d], depth=%d, 0x%x\n", $kgm_indx, $kgm_depth, $kgm_fbt_probep
13062       printf "(gdb) p *(struct fbt_probe *)0x%x\n", $kgm_fbt_probep
13063       p *(struct fbt_probe *)$kgm_fbt_probep
13064       set $kgm_fbtp_ctl = (struct fbt_probe *)$kgm_fbt_probep->fbtp_ctl
13065       showmodctl $kgm_fbtp_ctl
13066       loop_break
13067     end
13068   end
13069 end
13070 document showfbtprobe
13071 Syntax: (gdb) showfbtprobe <id>
13072 | Display info about an fbt probe given an id.
13073 | Traverses fbt_probetab and matches <id> with fbtp_id.
13074 | The <id> is found using dtrace -l
13075 end
13076 
13077 define showzstacktrace
13078         set $kgm_trace = (void*)$arg0
13079         if ($argc == 1)
13080                 set $kgm_trace_size = 15
13081         end
13082         if ($argc == 2)
13083                 set $kgm_trace_size = $arg1
13084         end
13085         set $kgm_trace_current = 0
13086         while ($kgm_trace_current < $kgm_trace_size)
13087                 set $kgm_trace_addr = (void**)$kgm_trace + $kgm_trace_current
13088                 set $kgm_trace_value = *((void**)$kgm_trace_addr) 
13089                 #printf "\t\t"
13090                 output /a $kgm_trace_value
13091                 set $kgm_trace_current = $kgm_trace_current + 1
13092                 printf "\n"
13093         end
13094 end
13095 
13096 document showzstacktrace
13097 Syntax:  showzstacktrace <saved stacktrace> [size]
13098 | Routine to print a stacktrace stored by OSBacktrace.
13099 | size is optional, defaults to 15.
13100 end
13101 
13102 define showzalloc
13103         set $kgm_zallocation = zallocations[$arg0]
13104         print $kgm_zallocation
13105         showztrace $kgm_zallocation->za_trace_index
13106 end
13107 
13108 document showzalloc
13109 Syntax:  showzalloc <index>
13110 | Prints a zallocation from the zallocations array based off its index, 
13111 | and prints the associated symbolicated backtrace.
13112 end
13113 
13114 define showztrace
13115         set $kgm_ztrace = &ztraces[$arg0]
13116         showztraceaddr $kgm_ztrace
13117 end
13118 
13119 document showztrace
13120 Syntax:  showztrace <trace index>
13121 | Prints the backtrace from the ztraces array at index
13122 end
13123 
13124 define showztraceaddr
13125         print *$arg0
13126         showzstacktrace $arg0->zt_stack ($arg0)->zt_depth
13127 end
13128 
13129 document showztraceaddr
13130 Syntax:  showztraceaddr <trace address>
13131 | Prints the struct ztrace passed in
13132 end
13133 
13134 #TODO: Iterate through the hash table, or make top_ztrace accurate in the face of deallocations (better idea).
13135 define showtopztrace
13136         set $kgm_top_ztrace = top_ztrace
13137         printf "Index: %d\n", (top_ztrace - ztraces)
13138         showztraceaddr $kgm_top_ztrace
13139 end
13140 
13141 document showtopztrace
13142 Syntax:  showtopztrace 
13143 | Shows the ztrace with the biggest size. (according to top_ztrace, not by iterating through the hash table)
13144 end
13145 
13146 define showzallocs
13147         set $kgm_zallocation_current_index = 0
13148         set $kgm_zallocations_count = 0
13149         set $kgm_max_zallocation = zleak_alloc_buckets
13150         printf "INDEX  ADDRESS     "
13151         if $kgm_lp64
13152         printf "         "
13153     end
13154         printf "TRACE   SIZE\n"
13155         while ($kgm_zallocation_current_index < $kgm_max_zallocation)
13156                 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
13157                 if ($kgm_zallocation_current->element != 0)
13158                         printf "%5d  %p   ", $kgm_zallocation_current_index, $kgm_zallocation_current->za_element
13159                         printf "%5d %6lu\n", $kgm_zallocation_current->za_trace_index, $kgm_zallocation_current->za_size
13160                         set $kgm_zallocations_count = $kgm_zallocations_count + 1
13161                 end
13162                 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
13163         end
13164         printf "Total allocations: %d\n", $kgm_zallocations_count
13165 end
13166 
13167 document showzallocs
13168 Syntax:  showzallocs
13169 | Prints all allocations in the zallocations table
13170 end
13171 
13172 define showzallocsfortrace
13173         set $kgm_zallocation_current_index = 0
13174         set $kgm_zallocations_count = 0
13175         set $kgm_max_zallocation = zleak_alloc_buckets
13176         printf "INDEX  ADDRESS     "
13177         if $kgm_lp64
13178         printf "         "
13179     end
13180         printf "SIZE\n"
13181         while ($kgm_zallocation_current_index < $kgm_max_zallocation)
13182                 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
13183                 if ($kgm_zallocation_current->element != 0 && $kgm_zallocation_current->za_trace_index == $arg0)
13184                         printf "%5d  %p ", $kgm_zallocation_current_index, $kgm_zallocation_current->za_element
13185                         printf "%6lu\n", $kgm_zallocation_current->size
13186                         set $kgm_zallocations_count = $kgm_zallocations_count + 1
13187                 end
13188                 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
13189         end
13190         printf "Total allocations: %d\n", $kgm_zallocations_count
13191 end
13192 
13193 document showzallocsfortrace
13194 Syntax:  showzallocsfortrace <trace index>
13195 | Prints all allocations pointing to the passed in trace's index into ztraces by looking through zallocations table
13196 end
13197 
13198 define showztraces
13199         showztracesabove 0
13200 end
13201 
13202 document showztraces
13203 Syntax:  showztraces
13204 | Prints all traces with size > 0
13205 end
13206 
13207 define showztracesabove
13208         set $kgm_ztrace_current_index = 0
13209         set $kgm_ztrace_count = 0
13210         set $kgm_max_ztrace = zleak_trace_buckets
13211         printf "INDEX    SIZE\n"
13212         while ($kgm_ztrace_current_index < $kgm_max_ztrace)
13213                 set $kgm_ztrace_current = ztraces[$kgm_ztrace_current_index]
13214                 if ($kgm_ztrace_current->zt_size > $arg0)
13215                         printf "%5d  %6lu\n", $kgm_ztrace_current_index, $kgm_ztrace_current->zt_size
13216                         set $kgm_ztrace_count = $kgm_ztrace_count + 1
13217                 end
13218                 set $kgm_ztrace_current_index = $kgm_ztrace_current_index + 1
13219         end
13220         printf "Total traces: %d\n", $kgm_ztrace_count
13221 end
13222 
13223 document showztracesabove
13224 Syntax:  showztracesabove <size>
13225 | Prints all traces with size greater than X
13226 end
13227 
13228 define showztracehistogram
13229         set $kgm_ztrace_current_index = 0
13230         set $kgm_ztrace_count = 0
13231         set $kgm_max_ztrace = zleak_trace_buckets
13232         printf "INDEX  HIT_COUNT  COLLISIONS\n"
13233         while ($kgm_ztrace_current_index < $kgm_max_ztrace)
13234                 set $kgm_ztrace_current = ztraces[$kgm_ztrace_current_index]
13235                 if ($kgm_ztrace_current->zt_hit_count != 0)
13236                         printf "%5d      %5d    %5d\n", $kgm_ztrace_current_index, $kgm_ztrace_current->zt_hit_count, $kgm_ztrace_current->zt_collisions
13237                         set $kgm_ztrace_count = $kgm_ztrace_count + 1
13238                 end
13239                 set $kgm_ztrace_current_index = $kgm_ztrace_current_index + 1
13240         end
13241         printf "Total traces: %d\n", $kgm_ztrace_count
13242 end
13243 
13244 document showztracehistogram
13245 Syntax:  showztracehistogram
13246 | Prints the histogram of the ztrace table
13247 end
13248 
13249 define showzallochistogram
13250         set $kgm_zallocation_current_index = 0
13251         set $kgm_zallocations_count = 0
13252         set $kgm_max_zallocation = zleak_alloc_buckets
13253         printf "INDEX  HIT_COUNT\n"
13254         while ($kgm_zallocation_current_index < $kgm_max_zallocation)
13255                 set $kgm_zallocation_current = zallocations[$kgm_zallocation_current_index]
13256                 if ($kgm_zallocation_current->za_hit_count != 0)
13257                         printf "%5d      %5d\n", $kgm_zallocation_current_index, $kgm_zallocation_current->za_hit_count
13258                         set $kgm_zallocations_count = $kgm_zallocations_count + 1
13259                 end
13260                 set $kgm_zallocation_current_index = $kgm_zallocation_current_index + 1
13261         end
13262         printf "Total allocations: %d\n", $kgm_zallocations_count
13263 end
13264 
13265 document showzallochistogram
13266 Syntax:  showzallochistogram
13267 | Prints the histogram for the zalloc table
13268 end
13269 
13270 define showzstats
13271         printf "z_alloc_collisions: %u, z_trace_collisions: %u\n", z_alloc_collisions, z_trace_collisions
13272         printf "z_alloc_overwrites: %u, z_trace_overwrites: %u\n", z_alloc_overwrites, z_trace_overwrites
13273         printf "z_alloc_recorded: %u, z_trace_recorded: %u\n", z_alloc_recorded, z_trace_recorded
13274 end
13275 
13276 document showzstats
13277 Syntax:  showzstats
13278 | Prints the zone leak detection stats
13279 end
13280 
13281 
13282 set $kgm_au_sentry_hash_table_size = 97
13283 
13284 define showsession1
13285   set $p = (struct au_sentry *)$arg0
13286   showptr $p
13287   printf "  0x%08x  0x%08x  0x%016x", $p->se_auinfo.ai_asid, $p->se_auinfo.ai_auid, $p->se_auinfo.ai_flags
13288   printf "  %3ld  %3ld", $p->se_refcnt, $p->se_procnt
13289   printf "\n"
13290 end
13291 
13292 define showsessionhdr
13293   printf "au_sentry "
13294   showptrhdrpad
13295   printf "  ASID        AUID        FLAGS               C    P\n"
13296 end
13297 
13298 define showsession
13299   showsessionhdr
13300   showsession1 $arg0
13301 end
13302 
13303 document showsession
13304 Syntax:  showsession
13305 | Display info about a specified audit session
13306 end
13307 
13308 define showallsessions
13309   showsessionhdr
13310   set $kgm_au_sentry_hash_table = au_sentry_bucket
13311   set $i = $kgm_au_sentry_hash_table_size - 1
13312   while $i >= 0
13313     set $p = $kgm_au_sentry_hash_table[$i].lh_first
13314     while $p != 0
13315       showsession1 $p
13316       set $p = $p->se_link.le_next
13317     end
13318     set $i = $i - 1
13319   end
13320 end
13321 
13322 document showallsessions
13323 Syntax:  showallsessions
13324 | Prints the audit sessions in the global hash table
13325 end
13326 
13327 define showauhistorystack
13328   set $ii = $arg0
13329   set $pp = (void **)$arg1
13330   while $ii > 0
13331     printf "  "
13332     x/i $pp[$ii-1]
13333     set $ii = $ii - 1
13334   end
13335 end
13336 
13337 define showauhistory1
13338   set $p = (struct au_history *)$arg0
13339   set $stack_depth = $p->stack_depth
13340   set $stack = $p->stack
13341   showptr $p->ptr
13342   if $p->event == 1
13343     printf "    REF"
13344   end
13345   if $p->event == 2
13346     printf "  UNREF"
13347   end
13348   if $p->event == 3
13349     printf "  BIRTH"
13350   end
13351   if $p->event == 4
13352     printf "  DEATH"
13353   end
13354   if $p->event == 5
13355     printf "  FIND"
13356   end
13357   set $p = &$p->se
13358   printf "  0x%08x  0x%08x  0x%016x", $p->se_auinfo.ai_asid, $p->se_auinfo.ai_auid, $p->se_auinfo.ai_flags
13359   printf "  %3ld  %3ld", $p->se_refcnt, $p->se_procnt
13360   printf "\n"
13361   showauhistorystack $stack_depth $stack
13362 end
13363 
13364 define showauhistory
13365   set $i = (au_history_index-1) % au_history_size
13366   if au_history_index >= au_history_size
13367     set $n = au_history_size
13368   else
13369     set $n = au_history_index
13370   end
13371   while $n > 0
13372     if au_history[$i].ptr != 0 && (0 == $arg0 || au_history[$i].ptr == $arg0)
13373       printf "[% 4d]  ", $i
13374       showauhistory1 &au_history[$i]
13375     end
13376     set $n = $n - 1
13377     set $i = ($i - 1) % au_history_size
13378   end
13379 end
13380 
13381 define showallauhistory
13382   showauhistory 0
13383 end
13384 
13385 define showkwqheader
13386         printf "        kwq     "
13387     showptrhdrpad
13388         printf "    kwqaddr     "
13389     showptrhdrpad
13390     printf "  inqueue  fakecount  highseq  lowseq   flags   lastunlock    p_rwwc"
13391     printf "\n          "
13392 end
13393 
13394 define showkwqint
13395         printf "              "
13396         set $kgm_kwq = (ksyn_wait_queue_t)$arg0
13397         showptr $kgm_kwq
13398         printf "  "
13399         showptr $kgm_kwq->kw_addr
13400         printf "   "
13401         printf "  %d      ", $kgm_kwq->kw_inqueue
13402         printf "    %d  ", $kgm_kwq->kw_fakecount
13403         printf "     0x%x  ", $kgm_kwq->kw_highseq
13404         printf "  0x%x  ", $kgm_kwq->kw_lowseq
13405         printf "  0x%x  ", $kgm_kwq->kw_flags
13406         printf "  0x%x  ", $kgm_kwq->kw_lastunlockseq
13407         printf "    0x%x  ", $kgm_kwq->kw_pre_rwwc
13408         printf "\n"
13409 end
13410 
13411 define show_kwq
13412         showkwqheader
13413         showkwqint $arg0
13414 end
13415 
13416 document show_kwq
13417 Syntax: (gdb) show_kwq <kwq>
13418 | Display info about one ksyn_wait_queue
13419 end
13420 
13421 # Internal routine used by "showpthread_mutex" to abstract possible loads from
13422 # user space
13423 define _loadfrommutex
13424         if (kdp_pmap == 0)
13425                 set $kgm_loadval = *(uintptr_t *)$arg0
13426         else
13427         if ($kgm_x86_abi == 0xe)
13428               set $kgm_loadval = *(uint32_t *)$arg0
13429         else
13430         if ($kgm_x86_abi == 0xf)
13431             if ($kgm_mtype == $kgm_mtype_i386)
13432                     _loadk32m64 $arg0
13433                     set $kgm_loadval = $kgm_k32read64  
13434             else
13435                     set $kgm_loadval = *(uint32_t *)$arg0
13436             end
13437         end
13438         end
13439 end
13440 end
13441 
13442 define show_pthreadmutex
13443         set $newact = (struct thread *) $arg0
13444         set $ourtask = (struct task *)($newact->task)
13445         set $our_user_is64 = ($ourtask->taskFeatures[0] & 0x80000000)
13446         _kgm_flush_loop
13447         set $mutex = (void *)$arg1
13448         set kdp_pmap = $newact->task->map->pmap
13449         _kgm_flush_loop
13450         _kgm_update_loop
13451         set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
13452         set $kgm_x86_abi = $newiss.flavor
13453         if ($our_user_is64 != 0)
13454                 printf "\tUser 64Bit\n "
13455                 printf "\tSignature: "
13456                 set $nextval = $mutex
13457                 _loadfrommutex $nextval
13458                 printf "0x%x\n",$kgm_loadval
13459                 printf "\tflags: "
13460                 set $nextval = $mutex + 12
13461                 _loadfrommutex $nextval
13462                 printf "0x%x\n",$kgm_loadval
13463                 printf "\tSeqs: "
13464                 set $nextval = $mutex + 20
13465                 _loadfrommutex $nextval
13466                 printf "0x%x   ",$kgm_loadval
13467                 set $nextval = $mutex + 24
13468                 _loadfrommutex $nextval
13469                 printf "0x%x   ",$kgm_loadval
13470                 set $nextval = $mutex + 28
13471                 _loadfrommutex $nextval
13472                 printf "0x%x\n",$kgm_loadval
13473                 printf "\ttid[0]: "
13474                 set $nextval = $mutex + 32
13475                 _loadfrommutex $nextval
13476                 printf "0x%x\n",$kgm_loadval
13477                 printf "\ttid[1]: "
13478                 set $nextval = $mutex + 36
13479                 _loadfrommutex $nextval
13480                 printf "0x%x\n",$kgm_loadval
13481         else
13482                 printf "\tUser 32Bit\n "
13483                 printf "\tSignature: "
13484                 set $nextval = $mutex
13485                 _loadfrommutex $nextval
13486                 printf "0x%x\n",$kgm_loadval
13487                 printf "\tflags: "
13488                 set $nextval = $mutex + 8
13489                 _loadfrommutex $nextval
13490                 printf "0x%x\n",$kgm_loadval
13491                 printf "\tSeqs: "
13492                 set $nextval = $mutex + 16
13493                 _loadfrommutex $nextval
13494                 printf "0x%x   ",$kgm_loadval
13495                 set $nextval = $mutex + 20
13496                 _loadfrommutex $nextval
13497                 printf "0x%x   ",$kgm_loadval
13498                 set $nextval = $mutex + 24
13499                 _loadfrommutex $nextval
13500                 printf "0x%x\n",$kgm_loadval
13501                 printf "\ttid[0]: "
13502                 set $nextval = $mutex + 32
13503                 _loadfrommutex $nextval
13504                 printf "0x%x\n",$kgm_loadval
13505                 printf "\ttid[1]: "
13506                 set $nextval = $mutex + 36
13507                 _loadfrommutex $nextval
13508                 printf "0x%x\n",$kgm_loadval
13509         end
13510         printf "\n"
13511         resetstacks
13512 end
13513 
13514 
13515 document show_pthreadmutex
13516 Syntax: (gdb) show_pthreadmutex <thread> <user_mutexaddr>
13517 | Display the mutex contents from userspace.
13518 end
13519 
13520 
13521 define show_pthreadcondition
13522         set $newact = (struct thread *) $arg0
13523         set $ourtask = (struct task *)($newact->task)
13524         set $our_user_is64 = ($ourtask->taskFeatures[0] & 0x80000000)
13525         _kgm_flush_loop
13526         set $cond = (void *)$arg1
13527         set kdp_pmap = $newact->task->map->pmap
13528         _kgm_flush_loop
13529         _kgm_update_loop
13530         set $newiss = (x86_saved_state_t *) ($newact->machine.pcb->iss)
13531         set $kgm_x86_abi = $newiss.flavor
13532         if ($our_user_is64 != 0)
13533                 printf "\tUser 64Bit\n "
13534                 printf "\tSignature: "
13535                 set $nextval = $cond
13536                 _loadfrommutex $nextval
13537                 printf "0x%x\n",$kgm_loadval
13538                 printf "\tflags: "
13539                 set $nextval = $cond + 12
13540                 _loadfrommutex $nextval
13541                 printf "0x%x\n",$kgm_loadval
13542                 printf "\tSeqs: "
13543                 set $nextval = $cond + 24
13544                 _loadfrommutex $nextval
13545                 printf "0x%x   ",$kgm_loadval
13546                 set $nextval = $cond + 28
13547                 _loadfrommutex $nextval
13548                 printf "0x%x   ",$kgm_loadval
13549                 set $nextval = $cond + 32
13550                 _loadfrommutex $nextval
13551                 printf "0x%x\n",$kgm_loadval
13552                 printf "\tMutex lowaddr: "
13553                 set $nextval = $cond + 16
13554                 _loadfrommutex $nextval
13555                 printf "0x%08x\n",$kgm_loadval
13556                 printf "\tMutex highaddr: "
13557                 set $nextval = $cond + 20
13558                 _loadfrommutex $nextval
13559                 printf "0x%x\n",$kgm_loadval
13560         else
13561                 printf "\tUser 32Bit\n "
13562                 printf "\tSignature: "
13563                 set $nextval = $cond
13564                 _loadfrommutex $nextval
13565                 printf "0x%x\n",$kgm_loadval
13566                 printf "\tflags: "
13567                 set $nextval = $cond + 8
13568                 _loadfrommutex $nextval
13569                 printf "0x%x\n",$kgm_loadval
13570                 printf "\tSeqs: "
13571                 set $nextval = $cond + 16
13572                 _loadfrommutex $nextval
13573                 printf "0x%x   ",$kgm_loadval
13574                 set $nextval = $cond + 20
13575                 _loadfrommutex $nextval
13576                 printf "0x%x   ",$kgm_loadval
13577                 set $nextval = $cond + 24
13578                 _loadfrommutex $nextval
13579                 printf "0x%x\n",$kgm_loadval
13580                 printf "\tMutex addr: "
13581                 set $nextval = $cond + 12
13582                 _loadfrommutex $nextval
13583                 printf "0x%x\n",$kgm_loadval
13584         end
13585         printf "\n"
13586         resetstacks
13587 end
13588 
13589 
13590 document show_pthreadcondition
13591 Syntax: (gdb) show_pthreadcondition <thread> <user_cvaddr>
13592 | Display the condition variable contents from userspace.
13593 end
13594 
13595 define processortimers
13596     set $kgm_p = processor_list
13597     printf "Processor\t\t\t Last dispatch\t\t Next deadline\t\t difference\n"
13598     while $kgm_p
13599         printf "Processor %d: %p\t", $kgm_p->cpu_id, $kgm_p
13600         printf " 0x%016llx\t", $kgm_p->last_dispatch
13601         set $kgm_rt_timer = &(cpu_data_ptr[$kgm_p->cpu_id].rtclock_timer)
13602         printf " 0x%016llx    \t", $kgm_rt_timer->deadline
13603         set $kgm_rt_diff =  ((long long)$kgm_p->last_dispatch) - ((long long)$kgm_rt_timer->deadline)
13604         printf " 0x%016llx  ", $kgm_rt_diff
13605 # normally the $kgm_rt_diff will be close to the last dispatch time, or negative 
13606 # When it isn't, mark the result as bad. This is a suggestion, not an absolute
13607         if ( ($kgm_rt_diff > 0) && ((long long)$kgm_p->last_dispatch) - ($kgm_rt_diff + 1) > 0 )
13608             printf "probably BAD\n"
13609         else
13610             printf "(ok)\n"
13611         end
13612         # dump the call entries (Intel only)
13613         if (($kgm_mtype & $kgm_mtype_x86_mask) == $kgm_mtype_x86_any)
13614             printf "Next deadline set at: 0x%016llx. Timer call list:", $kgm_rt_timer->when_set
13615             set $kgm_entry = (queue_t *)$kgm_rt_timer->queue
13616             if ($kgm_entry == $kgm_rt_timer)
13617                 printf " (empty)\n"
13618             else
13619                 printf "\n entry:      "
13620                 showptrhdrpad
13621                 printf "deadline           soft_deadline      delta      (*func)(param0,param1)\n"
13622                 while $kgm_entry != $kgm_rt_timer
13623                     set $kgm_timer_call = (timer_call_t) $kgm_entry
13624                     set $kgm_call_entry = (struct call_entry *) $kgm_entry
13625                     printf " "
13626                     showptr $kgm_entry
13627                     printf ": 0x%016llx 0x%016llx 0x%08x (%p)(%p,%p)\n", \
13628                         $kgm_call_entry->deadline, \
13629                         $kgm_timer_call->soft_deadline, \
13630                         ($kgm_call_entry->deadline - $kgm_timer_call->soft_deadline), \
13631                         $kgm_call_entry->func, \
13632                         $kgm_call_entry->param0, $kgm_call_entry->param1
13633                     set $kgm_entry = $kgm_entry->next
13634                 end
13635             end
13636         end
13637         set $kgm_p = $kgm_p->processor_list
13638     end
13639     printf "\n"
13640 end
13641 
13642 document processortimers
13643 Syntax: (gdb) processortimers 
13644 | Print details of processor timers, noting any timer which might be suspicious
13645 end
13646 
13647 define maplocalcache
13648         if ($kgm_mtype == $kgm_mtype_arm)
13649                 mem 0x80000000 0xefffffff cache
13650                 set dcache-linesize-power 9
13651                 printf "GDB memory caching enabled. Be sure to disable by calling flushlocalcache before detaching or connecting to a new device\n"
13652         end
13653 end
13654 
13655 document maplocalcache
13656 Syntax: (gdb) maplocalcache 
13657 | Sets up memory regions for GDB to cache on read. Significantly increases debug speed over KDP
13658 end
13659 
13660 define flushlocalcache
13661         if ($kgm_mtype == $kgm_mtype_arm)
13662                 delete mem
13663                 printf "GDB memory caching disabled.\n"
13664         end
13665 end
13666 
13667 document flushlocalcache
13668 Syntax: (gdb) flushlocalcache 
13669 | Clears all memory regions
13670 end

Cache object: a88d42e3cc5392261bb49682dde25d26


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.