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
9set print asm-demangle on
10set 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.
15set backtrace sanity-checks off
16
17echo Loading Kernel GDB Macros package.  Type "help kgm" for more info.\n
18
19define kgm
20printf ""
21echo  These are the gdb macros for kernel debugging.  Type "help kgm" for more info.\n
22end
23
24document 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.
315end
316
317# This macro should appear before any symbol references, to facilitate
318# a gdb "source" without a loaded symbol file.
319define showversion
320    kdp-kernelversion
321end
322
323document showversion
324Syntax: 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.
332end
333
334set $kgm_mtype_ppc      = 0x00000012
335set $kgm_mtype_arm      = 0x0000000C
336
337set $kgm_mtype_i386     = 0x00000007
338set $kgm_mtype_x86_64   = 0x01000007
339set $kgm_mtype_x86_any  = $kgm_mtype_i386
340set $kgm_mtype_x86_mask = 0xFEFFFFFF
341
342set $kgm_mtype = ((unsigned int *)&_mh_execute_header)[1]
343set $kgm_lp64 = $kgm_mtype & 0x01000000
344
345set $kgm_manual_pkt_ppc    = 0x549C
346set $kgm_manual_pkt_i386   = 0x249C
347set $kgm_manual_pkt_x86_64 = 0xFFFFFF8000002930
348set $kgm_manual_pkt_arm    = 0xFFFF04A0
349
350set $kgm_kdp_pkt_data_len   = 128
351
352# part of data packet
353set $kgm_kdp_pkt_hdr_req_off = 0
354set $kgm_kdp_pkt_hdr_seq_off = 1
355set $kgm_kdp_pkt_hdr_len_off = 2
356set $kgm_kdp_pkt_hdr_key_off = 4
357
358# after data packet
359set $kgm_kdp_pkt_len_off     = $kgm_kdp_pkt_data_len
360set $kgm_kdp_pkt_input_off   = $kgm_kdp_pkt_data_len + 4
361
362set $kgm_kdp_pkt_hostreboot = 0x13
363set $kgm_kdp_pkt_hdr_size   = 8
364
365
366set $kgm_readphys_force_kdp     = 0
367set $kgm_readphys_force_physmap = 0
368
369set $kgm_lcpu_self      = 0xFFFE
370
371set $kgm_reg_depth = 0
372set $kgm_reg_depth_max = 0xFFFF
373set $kgm_reg_plane = (IORegistryPlane *) gIOServicePlane
374set $kgm_namekey = (OSSymbol *) 0
375set $kgm_childkey = (OSSymbol *) 0
376
377set $kgm_show_object_addrs = 0
378set $kgm_show_object_retain = 0
379set $kgm_show_props = 0
380set $kgm_show_data_alwaysbytes = 0
381
382set $kgm_show_kmod_syms = 0
383
384# send a manual packet header that doesn't require knowing the location
385# of everything.
386define 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
413end
414
415# Print a pointer
416define showptr
417    if $kgm_lp64
418        printf "0x%016llx", $arg0
419    else
420        printf "0x%08x", $arg0
421    end
422end
423
424# for headers, leave 8 chars for LP64 pointers
425define showptrhdrpad
426    if $kgm_lp64
427        printf "        "
428    end
429end
430
431# Print a userspace pointer, using $kgm_tasp
432define 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
439end
440
441define showkmodheader
442    printf   "kmod_info "
443    showptrhdrpad
444    printf "  address   "
445    showptrhdrpad
446    printf "  size      "
447    showptrhdrpad
448    printf "  id    refs     version  name\n"
449end
450
451define 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
463end
464
465# cached info of the last kext found, to speed up subsequent lookups
466set $kgm_pkmod = 0
467set $kgm_pkmodst = 0
468set $kgm_pkmoden = 0
469
470define 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
494end
495
496define showkmodaddr
497    showkmodaddrint $arg0
498end
499document showkmodaddr
500Syntax: (gdb) showkmodaddr <addr>
501| Given an address, print the offset and name for the kmod containing it
502end
503
504define showkmod
505    showkmodheader
506    showkmodint $arg0
507end
508document showkmod
509Syntax: (gdb) showkmod <kmod>
510| Routine to print info about a kext
511end
512
513define showkext
514    showkmod $arg0
515end
516document showkext
517Syntax: (gdb) showkext <kmod_info_address>
518| Routine to print info about a kext
519end
520
521define 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
528end
529document showallkmods
530Syntax: (gdb) showallkmods
531| Routine to print a summary listing of all loaded kexts
532end
533
534define showallkexts
535    showallkmods
536end
537document showallkexts
538Syntax: (gdb) showallkexts
539| Routine to print a summary listing of all loaded kexts
540end
541
542# See OSKextVersion.c for the C code this is based on
543#
544set $KGM_OSKEXT_VERS_MAJ_MULT   = 100000000
545set $KGM_OSKEXT_VERS_MIN_MULT   = 1000000
546set $KGM_OSKEXT_VERS_REV_MULT   = 10000
547set $KGM_OSKEXT_VERS_STAGE_MULT = 1000
548
549define 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
591end
592
593define 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
629end
630document showallknownkexts
631Syntax: (gdb) showallknownkexts
632| Routine to print a summary listing of all kexts, loaded or not
633end
634
635define 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"
647end
648
649
650define 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
857end	    
858
859define showact
860    showactheader
861    showactint $arg0 0
862end
863document showact
864Syntax: (gdb) showact <activation> 
865| Routine to print out the state of a specific thread.
866end
867
868
869define showactstack
870    showactheader
871    showactint $arg0 1
872end
873document showactstack
874Syntax: (gdb) showactstack <activation> 
875| Routine to print out the stack of a specific thread.
876end
877
878
879define 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
895end
896document showallthreads
897Syntax: (gdb) showallthreads
898| Routine to print out info about all threads in the system.
899end
900
901define 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
906end
907
908define 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
922end
923document showcurrentthreads
924Syntax: (gdb) showcurrentthreads
925| Routine to print out info about the thread running on each cpu.
926end
927
928
929define _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
953end
954
955define _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
979end
980
981define 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
1099end
1100document showallprocessors
1101Syntax: (gdb) showallprocessors
1102| Routine to print out info about all psets and processors
1103end
1104
1105set $decode_wait_events = 0
1106define 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
1129end
1130
1131document showallstacks
1132Syntax: (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.
1137end
1138
1139define 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
1153end
1154
1155document showcurrentstacks
1156Syntax: (gdb) showcurrentstacks
1157| Routine to print out the thread running on each cpu (incl. its stack)
1158end
1159
1160define showwaiterheader
1161    printf "waiters     thread      "
1162    printf "processor   pri  state  wait_queue  wait_event\n"
1163end
1164
1165define 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
1181end
1182
1183define 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
1195end
1196
1197define 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
1207end
1208
1209    
1210define showwaitqmemberheader
1211    printf "set-members wait_queue  interlock   "
1212    printf "pol  type   member_cnt  waiter_cnt\n"
1213end
1214
1215define 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"
1232end
1233
1234
1235define showwaitqmemberofheader
1236    printf "member-of   wait_queue  interlock   "
1237    printf "pol  type   member_cnt  waiter_cnt\n"
1238end
1239
1240define 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
1257end
1258
1259define 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
1273end
1274
1275define showwaitqheader
1276    printf "wait_queue  ref_count   interlock   "
1277    printf "pol  type   member_cnt  waiter_cnt\n"
1278end
1279
1280define 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"
1302end
1303
1304define 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
1314end
1315
1316define 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"
1326end
1327
1328define showvmeheader
1329    printf "    entry     "
1330    showptrhdrpad
1331    printf "  start               prot  #page  object    "
1332    showptrhdrpad
1333    printf "  offset\n"
1334end
1335
1336define 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"
1393end
1394
1395
1396define 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
1466end
1467
1468define 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
1477end
1478document showmapwired
1479Syntax: (gdb) showmapwired <vm_map>
1480| Routine to print out a summary listing of all the entries with wired pages in a vm_map
1481end
1482
1483define showmapvme
1484	showmapheader
1485	showvmint $arg0 1
1486end
1487document showmapvme
1488Syntax: (gdb) showmapvme <vm_map>
1489| Routine to print out a summary listing of all the entries in a vm_map
1490end
1491
1492
1493define showmap
1494	showmapheader
1495	showvmint $arg0 0
1496end
1497document showmap
1498Syntax: (gdb) showmap <vm_map>
1499| Routine to print out info about the specified vm_map
1500end
1501
1502define 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
1512end
1513document showallvm
1514Syntax: (gdb) showallvm
1515| Routine to print a summary listing of all the vm maps
1516end
1517
1518
1519define 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
1529end
1530document showallvme
1531Syntax: (gdb) showallvme
1532| Routine to print a summary listing of all the vm map entries
1533end
1534
1535
1536define 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"
1546end
1547
1548define showipceheader
1549    printf "            "
1550    showptrhdrpad
1551    printf "object      "
1552    showptrhdrpad
1553    showptrhdrpad
1554    printf "name        rite urefs  destname    "
1555    showptrhdrpad
1556    printf "destination\n"
1557end
1558
1559define 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
1621end
1622
1623define 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"
1670end
1671
1672
1673define showipc
1674    set $kgm_isp = (ipc_space_t)$arg0
1675    showipcheader
1676    showipcint $kgm_isp 0 0
1677end
1678document showipc
1679Syntax: (gdb) showipc <ipc_space>
1680| Routine to print the status of the specified ipc space
1681end
1682
1683define showrights
1684	set $kgm_isp = (ipc_space_t)$arg0
1685    showipcheader
1686	showipcint $kgm_isp 1 0
1687end
1688document showrights
1689Syntax: (gdb) showrights <ipc_space>
1690| Routine to print a summary list of all the rights in a specified ipc space
1691end
1692
1693
1694define showtaskipc
1695	set $kgm_taskp = (task_t)$arg0
1696	showtaskheader
1697	showtaskint $kgm_taskp
1698        showipcheader
1699	showipcint $kgm_taskp->itk_space 0 0
1700end
1701document showtaskipc
1702Syntax: (gdb) showtaskipc <task>
1703| Routine to print info about the ipc space for a task
1704end
1705
1706
1707define showtaskrights
1708	set $kgm_taskp = (task_t)$arg0
1709	showtaskheader
1710	showtaskint $kgm_taskp
1711	showipcheader
1712	showipcint $kgm_taskp->itk_space 1 0
1713end
1714document showtaskrights
1715Syntax: (gdb) showtaskrights <task>
1716| Routine to print info about the ipc rights for a task
1717end
1718
1719define showtaskrightsbt
1720	set $kgm_taskp = (task_t)$arg0
1721	showtaskheader
1722	showtaskint $kgm_taskp
1723  	showipcheader
1724	showipcint $kgm_taskp->itk_space 1 1
1725end
1726document showtaskrightsbt
1727Syntax: (gdb) showtaskrightsbt <task>
1728| Routine to print info about the ipc rights for a task with backtraces
1729end
1730
1731define 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
1741end
1742document showallipc
1743Syntax: (gdb) showallipc
1744| Routine to print a summary listing of all the ipc spaces
1745end
1746
1747define showipcsumheader
1748    printf "task         "
1749    showptrhdrpad
1750    printf " pid         "
1751    printf " #acts         "
1752    printf " tsize "
1753    printf "command\n"
1754end
1755
1756define 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
1763end
1764
1765define 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
1773end
1774
1775document showipcsummary
1776Syntax: (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.
1780end
1781
1782
1783define 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
1793end
1794document showallrights
1795Syntax: (gdb) showallrights
1796| Routine to print a summary listing of all the ipc rights
1797end
1798
1799
1800define showtaskvm
1801	set $kgm_taskp = (task_t)$arg0
1802	showtaskheader
1803	showmapheader
1804	showtaskint $kgm_taskp
1805	showvmint $kgm_taskp->map 0
1806end
1807document showtaskvm
1808Syntax: (gdb) showtaskvm <task>
1809| Routine to print out info about a task's vm_map
1810end
1811
1812define showtaskvme
1813	set $kgm_taskp = (task_t)$arg0
1814	showtaskheader
1815	showtaskint $kgm_taskp
1816	showmapheader
1817	showvmint $kgm_taskp->map 1
1818end
1819document showtaskvme
1820Syntax: (gdb) showtaskvme <task>
1821| Routine to print out info about a task's vm_map_entries
1822end
1823
1824
1825define showtaskheader
1826    printf "task      "
1827    showptrhdrpad
1828    printf "  vm_map    "
1829    showptrhdrpad
1830    printf "  ipc_space "
1831    showptrhdrpad
1832    printf " #acts "
1833    showprocheader
1834end
1835
1836
1837define 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
1846end
1847
1848define showtask
1849    showtaskheader
1850    showtaskint $arg0
1851end
1852document showtask
1853Syntax (gdb) showtask <task>
1854| Routine to print out info about a task.
1855end
1856
1857
1858define 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
1869end
1870document showtaskthreads
1871Syntax: (gdb) showtaskthreads <task>
1872| Routine to print info about the threads in a task.
1873end
1874
1875
1876define 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
1887end
1888document showtaskstacks
1889Syntax: (gdb) showtaskstacks <task>
1890| Routine to print out the stack for each thread in a task.
1891end
1892
1893define 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
1914end
1915
1916define 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
1924end
1925document showalltasks
1926Syntax: (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)
1934end
1935
1936define showprocheader
1937    printf "  pid  process     "
1938    showptrhdrpad
1939    printf "io_policy    wq_state   command\n"
1940end
1941
1942define 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
2006end
2007
2008define 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
2021end
2022document showpid
2023Syntax: (gdb) showpid <pid>
2024| Routine to print a single process by pid
2025end
2026
2027define showproc
2028    showtaskheader
2029    set $kgm_procp = (struct proc *)$arg0
2030    showtaskint $kgm_procp->task
2031end
2032
2033
2034define kdb
2035    set switch_debugger=1
2036    continue
2037end
2038document 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.
2044end
2045
2046define 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"
2055end
2056
2057define 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"
2066end
2067
2068define 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"
2078end
2079
2080define 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"
2091end
2092
2093define 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
2122end
2123
2124define 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
2156end
2157
2158define showkmsg
2159    showkmsgint $arg0 0
2160end
2161
2162define 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"
2264end
2265
2266define 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
2290end
2291
2292define 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
2307end
2308
2309define 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
2325end
2326
2327define 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
2344end
2345
2346define 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
2373end
2374
2375define 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
2408end
2409
2410define showpset
2411    set $kgm_portoff = &(((struct ipc_port *)0)->ip_messages)
2412    showpsetheader
2413    showpsetint $arg0 1
2414end
2415
2416define showport
2417    showportheader
2418    showportint $arg0 1
2419end
2420
2421define 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
2429end
2430
2431define 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
2445end
2446
2447define 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"
2475end
2476
2477
2478define 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"
2488end
2489document zprint
2490Syntax: (gdb) zprint
2491| Routine to print a summary listing of all the kernel zones
2492end
2493
2494define 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
2506end
2507
2508
2509define 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"
2520end
2521document showallmtx
2522Syntax: (gdb) showallmtx
2523| Routine to print a summary listing of all mutexes
2524end
2525
2526define 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
2538end
2539
2540
2541define 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"
2552end
2553document showallrwlck
2554Syntax: (gdb) showallrwlck
2555| Routine to print a summary listing of all read/writer locks
2556end
2557
2558set $kdp_act_counter = 0
2559set $kdp_arm_act_counter = 0
2560
2561set $r0_save	= 0
2562set $r1_save	= 0
2563set $r2_save	= 0
2564set $r3_save	= 0
2565set $r4_save	= 0
2566set $r5_save	= 0
2567set $r6_save	= 0
2568set $r7_save	= 0
2569set $r8_save	= 0
2570set $r9_save	= 0
2571set $r10_save	= 0
2572set $r11_save	= 0
2573set $r12_save	= 0
2574set $sp_save	= 0
2575set $lr_save	= 0
2576set $pc_save	= 0
2577
2578define showcontext_int
2579	echo Context switched, current instruction pointer: 
2580	output/a $pc
2581	echo \n
2582end
2583
2584define 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
2689end
2690
2691document switchtoact  
2692Syntax: 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.
2698end     
2699
2700define 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
2758end
2759
2760
2761document switchtoctx  
2762Syntax: 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.
2767end     
2768
2769define 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
2838end     
2839        
2840document 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.
2845end     
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.
2849define hook-continue
2850       resetctx
2851end
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.
2855define hook-detach
2856       resetctx
2857end
2858
2859define resume_on
2860        set $resume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_RESUME
2861        dumpinfoint $resume
2862end
2863
2864document resume_on
2865| Syntax: resume_on
2866| The target system will resume when detaching  or exiting from gdb. 
2867| This is the default behavior.
2868end
2869
2870define resume_off
2871        set $noresume = KDP_DUMPINFO_SETINFO | KDP_DUMPINFO_NORESUME
2872        dumpinfoint $noresume
2873end
2874
2875document 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
2879end
2880
2881define 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
2892end
2893
2894document paniclog
2895| Syntax: paniclog
2896| Display the panic log information
2897|
2898end
2899
2900define 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
2916end
2917
2918document dumpcallqueue
2919| Syntax: dumpcallqueue <queue head>
2920| Displays the contents of the specified call_entry queue.
2921end
2922
2923define showtaskacts
2924showtaskthreads $arg0
2925end
2926document showtaskacts
2927| See help showtaskthreads.
2928end
2929
2930define showallacts
2931showallthreads
2932end
2933document showallacts
2934| See help showallthreads.
2935end
2936
2937
2938define 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
2947end
2948
2949document resetstacks
2950| Syntax: resetstacks
2951| Internal kgmacro routine used by the "showuserstack" macro 
2952| to reset the target pmap to the kernel pmap.
2953end
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.
2958define _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
2965end
2966
2967define _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
2973end
2974# Internal routine used by "_loadfrom" to read from 64-bit addresses
2975# on 32-bit kernels
2976define _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
2997end
2998
2999# Internal routine used by "showx86backtrace" to abstract possible loads from
3000# user space
3001define _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
3017end
3018end
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
3028set $kgm_cur_frame = 0
3029set $kgm_cur_pc = 0
3030set $kgm_x86_abi = 0
3031define 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
3081end
3082
3083define showx86backtrace2
3084	set $kgm_cur_frame = $arg0
3085	set $kgm_cur_pc = $arg1
3086	showx86backtrace
3087end
3088
3089define 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
3203end
3204document showuserstack
3205Syntax: 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.
3214end
3215
3216define 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
3233end
3234document showtaskuserstacks
3235Syntax: (gdb) showtaskuserstacks <task>
3236| Print out the user stack for each thread in a task, followed by the user libraries.
3237end
3238
3239
3240define 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
3397end
3398document showuserregisters
3399Syntax: 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
3406end
3407
3408define 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
3420end
3421document showtaskuserregisters
3422Syntax: (gdb) showtaskuserregisters <task>
3423| Print out the user registers for each thread in a task
3424end
3425
3426define 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
3431end
3432
3433document kdp-reboot
3434Syntax: kdp-reboot
3435|Reboot the remote target machine; not guaranteed to succeed. 
3436end
3437
3438define 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
3454end
3455
3456define kdp-version
3457       kdpversionint
3458       printf "KDP VERSION = %d, FEATURE = 0x%x\n", $kgm_kdp_version, $kgm_kdp_feature
3459end
3460
3461document kdp-version
3462Syntax: kdp-version
3463|Get the KDP protocol version being used by the kernel.
3464end
3465
3466define 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
3499end
3500
3501define sendcore
3502       if $argc > 1
3503       	  dumpinfoint KDP_DUMPINFO_CORE $arg1 $arg0
3504       else
3505       	  dumpinfoint KDP_DUMPINFO_CORE \0 $arg0
3506       end
3507end
3508
3509document sendcore
3510Syntax: 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.
3519end
3520
3521define sendsyslog
3522       if $argc > 1
3523       	  dumpinfoint KDP_DUMPINFO_SYSTEMLOG $arg1 $arg0
3524       else
3525       	  dumpinfoint KDP_DUMPINFO_SYSTEMLOG \0 $arg0
3526       end
3527end
3528
3529document sendsyslog
3530Syntax: 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.
3536end
3537
3538define 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
3548end
3549
3550document sendpaniclog
3551Syntax: 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.
3557end
3558
3559define 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
3601end
3602
3603document getdumpinfo
3604Syntax: getdumpinfo
3605|Retrieve the current remote dump settings. 
3606end
3607
3608define setdumpinfo
3609       dumpinfoint KDP_DUMPINFO_SETINFO $arg0 $arg1 $arg2 $arg3
3610end
3611
3612document setdumpinfo
3613Syntax: 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.
3618end
3619
3620define disablecore
3621       dumpinfoint KDP_DUMPINFO_DISABLE
3622end
3623
3624document disablecore
3625Syntax: 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.
3629end
3630
3631define 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
3657end
3658
3659document switchtocorethread
3660Syntax: 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.
3668end
3669
3670define 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
3736end
3737
3738define 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
3763end
3764
3765document resetcorectx
3766Syntax: 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.
3771end
3772
3773#Helper function for "showallgdbstacks"
3774
3775define 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
3853end	    
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
3861define 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
3878end
3879
3880document showallgdbstacks
3881Syntax: 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.
3891end
3892
3893define 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
3911end
3912
3913
3914document showallgdbcorestacks
3915Syntax: showallgdbcorestacks
3916|Corefile version of "showallgdbstacks"
3917end
3918
3919
3920define 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
3947end
3948
3949document switchtouserthread
3950Syntax: 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.
3973end
3974
3975define 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
3980end
3981
3982define showstring
3983    printf "\"%s\"", ((OSString *)$arg0)->string
3984end
3985
3986define shownumber
3987    printf "%lld", ((OSNumber *)$arg0)->value
3988end
3989
3990define showboolean
3991    if ($arg0 == gOSBooleanFalse)
3992	printf "No"
3993    else
3994	printf "Yes"
3995    end
3996end
3997
3998define 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"
4010end
4011
4012define 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 ">"
4071end
4072
4073define 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 "}"
4089end
4090
4091define 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
4100end
4101
4102define 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"
4120end
4121
4122
4123define 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
4135end
4136
4137define showorderedsetint
4138    set $kgm_array = ((OSOrderedSet *)$arg1)->array
4139    set $count = ((OSOrderedSet *)$arg1)->count
4140    printf "["
4141    showorderedsetarrayint $arg0 $kgm_array $count
4142    printf "]"
4143end
4144
4145define 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
4156end
4157
4158define showarrayint
4159    printf "("
4160    showarraysetint $arg0 $arg1
4161    printf ")"
4162end
4163
4164define showsetint
4165    set $kgm_array = ((OSSet *)$arg1)->members
4166    printf "["
4167    showarraysetint $arg0 $kgm_array
4168    printf "]"
4169end
4170
4171
4172define 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
4243end
4244
4245define 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"
4253end
4254document showobject
4255Syntax: (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.
4258end
4259
4260define 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
4271end
4272
4273
4274define _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
4298end
4299
4300define 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
4352end
4353
4354define 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
4372end
4373
4374define 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
4412end
4413
4414document setfindregistrystr
4415Syntax: (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
4419end
4420
4421define _findregistryprop
4422    set $reg       = (IOService *) $arg0
4423    set $kgm_props = $reg->fPropertyTable
4424    set $kgm_findregistry_verbose = 0
4425
4426    findregdictvalue $kgm_props 
4427end
4428
4429define findregistryprop
4430    set $reg       = (IOService *) $arg0
4431    set $kgm_props = $reg->fPropertyTable
4432
4433    set $kgm_findregistry_verbose = 1
4434    findregdictvalue $kgm_props 
4435end
4436
4437document findregistryprop
4438Syntax: (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
4450end
4451
4452define 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
4467end
4468
4469define _findregistryentry
4470    set $kgm_findregistry_verbose  = 0
4471    set $kgm_findregistry_continue = 0
4472    set $kgm_reg_depth             = 0
4473
4474    findregistryentryint gRegistryRoot
4475end
4476
4477define findregistryentry
4478    set $kgm_findregistry_verbose  = 1
4479    set $kgm_findregistry_continue = 0
4480    set $kgm_reg_depth             = 0
4481
4482    findregistryentryint gRegistryRoot
4483end
4484
4485define findregistryentries
4486    set $kgm_findregistry_verbose  = 1
4487    set $kgm_findregistry_continue = 1
4488    set $kgm_reg_depth             = 0
4489
4490    findregistryentryint gRegistryRoot
4491end
4492
4493document findregistryentry
4494Syntax: (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
4509end
4510
4511document findregistryentries
4512Syntax: (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.
4516end
4517
4518
4519define 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
4599end
4600
4601define 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
4613end
4614
4615define showregistry
4616    set $kgm_reg_depth  = 0
4617    set $kgm_show_props = 0
4618    showregistryentryint gRegistryRoot
4619end
4620document showregistry
4621Syntax: (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.
4624end
4625
4626define showregistryprops
4627    set $kgm_reg_depth  = 0
4628    set $kgm_show_props = 1
4629    showregistryentryint gRegistryRoot
4630end
4631document showregistryprops
4632Syntax: (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
4636end
4637
4638define showregistryentry
4639    set $kgm_reg_depth  = 0
4640    set $kgm_show_props = 1
4641    showregistryentryint $arg0
4642end
4643document showregistryentry
4644Syntax: (gdb) showregistryentry <object address>
4645| Show info about a registry entry; its properties and descendants in the current plane.
4646end
4647
4648define setregistryplane
4649    if ($arg0 != 0)
4650        set $kgm_reg_plane = (IORegistryPlane *) $arg0
4651    else
4652        showobjectint _ gIORegistryPlanes
4653        printf "\n"
4654    end
4655end
4656document setregistryplane
4657Syntax: (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.
4660end
4661
4662define 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
4680end
4681
4682define 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
4688end
4689
4690document showallclasses
4691Syntax: (gdb) showallclasses
4692| Show the instance counts and ivar size of all OSObject subclasses. See ioclasscount man page for details.
4693end
4694
4695define 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
4700end
4701
4702document showioalloc
4703Syntax: (gdb) showioalloc
4704| Show some accounting of memory allocated by IOKit allocators. See ioalloccount man page for details.
4705end
4706
4707define 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
4728end
4729
4730document showosobjecttracking
4731Syntax: (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.
4735end
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.
4741define 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
4815end
4816
4817define 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
4822end
4823
4824define 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
4829end
4830
4831define 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
4836end
4837
4838define 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
4843end
4844
4845define readphys
4846       readphys32 $arg0
4847end
4848
4849document readphys8
4850| See readphys64
4851end
4852
4853document readphys16
4854| See readphys64
4855end
4856
4857document readphys32
4858| See readphys64
4859end
4860
4861document 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.
4864end
4865
4866define 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
4896end
4897
4898define writephys8
4899       writephysint $arg0 8 $arg1 $kgm_lcpu_self
4900end
4901
4902define writephys16
4903       writephysint $arg0 16 $arg1 $kgm_lcpu_self
4904end
4905
4906define writephys32
4907       writephysint $arg0 32 $arg1 $kgm_lcpu_self
4908end
4909
4910define writephys64
4911       writephysint $arg0 64 $arg1 $kgm_lcpu_self
4912end
4913
4914document writephys8
4915| See writephys64
4916end
4917
4918document writephys16
4919| See writephys64
4920end
4921
4922document writephys32
4923| See writephys64
4924end
4925
4926document 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.
4929end
4930
4931define 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
4948end
4949
4950document 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
4957end
4958
4959define showprocfiles
4960    if ($argc == 1)
4961	_showprocheader
4962	_showprocfiles $arg0
4963    else
4964    	printf "| Usage:\n|\n"
4965	help showprocfiles
4966    end
4967end
4968document showprocfiles
4969Syntax: (gdb) showprocfiles <proc_t>
4970| Given a proc_t pointer, display the list of open file descriptors for the
4971| referenced process.
4972end
4973
4974define _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"
4989end
4990
4991define _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
5052end
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#
5060define showproclocks
5061    if ($argc == 1)
5062	_showproclocks $arg0
5063    else
5064    	printf "| Usage:\n|\n"
5065	help showproclocks
5066    end
5067end
5068document showproclocks
5069Syntax: (gdb) showproclocks <proc_t>
5070| Given a proc_t pointer, display the list of advisory file locks held by the
5071| referenced process.
5072end
5073
5074define _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"
5113end
5114
5115define 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
5259end
5260
5261document showprocinfo
5262Syntax: (gdb) showprocinfo <proc_t>
5263| Displays name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
5264end
5265
5266#
5267# dump the zombprocs 
5268#
5269define 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
5276end
5277
5278document zombproc
5279Syntax: (gdb) zombproc 
5280| Routine to print out all procs in the zombie list
5281end
5282
5283#
5284# dump the zombstacks 
5285#
5286define 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
5295end
5296
5297document zombstacks
5298Syntax: (gdb) zombstacks 
5299| Routine to print out all stacks of tasks that are exiting
5300end
5301
5302
5303#
5304# dump the allprocs
5305#
5306define 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
5313end
5314
5315document allproc
5316Syntax: (gdb) allproc 
5317| Routine to print out all process in the system 
5318| which are not in the zombie list
5319end
5320define 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
5328end
5329define 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
5438end
5439define showproctree
5440    if ($argc > 0)
5441        showproctreeint $arg0
5442    else
5443        showproctreeint 0
5444    end
5445end
5446document showproctree
5447Syntax: (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
5451end
5452
5453
5454define 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"
5475end
5476
5477document print_vnode
5478Syntax: (gdb) print_vnode <vnode>
5479| Prints out the fields of a vnode struct
5480end
5481
5482define 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
5517end
5518
5519document showprocvnodes
5520Syntax: (gdb) showprocvnodes <proc_address>
5521| Routine to print out all the open fds
5522| which are vnodes in a process
5523end
5524
5525define 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
5534end
5535
5536document showallprocvnodes
5537Syntax: (gdb) showallprocvnodes
5538| Routine to print out all the open fds
5539| which are vnodes 
5540end
5541
5542
5543#   
5544# dump the childrent of a proc 
5545#
5546define 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
5553end
5554
5555document showinitchild
5556Syntax: (gdb) showinitchild 
5557| Routine to print out all processes in the system 
5558| which are children of init process
5559end
5560
5561
5562define 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
5585end
5586document showmountallvnodes
5587Syntax: showmountallvnodes <struct mount *>
5588| Print the vnode inactive list
5589end
5590
5591
5592define 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
5601end
5602document showmountvnodes
5603Syntax: showmountvnodes <struct mount *>
5604| Print the vnode list
5605end
5606
5607
5608
5609define 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
5618end
5619document showworkqvnodes
5620Syntax: showworkqvnodes <struct mount *>
5621| Print the vnode worker list
5622end
5623
5624
5625define 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
5634end
5635
5636document shownewvnodes
5637Syntax: shownewvnodes <struct mount *>
5638| Print the new vnode list
5639end
5640
5641
5642#
5643# print mount point info
5644define 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"
5656end
5657
5658define 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
5664end
5665	
5666document showallmounts
5667Syntax: showallmounts
5668| Print all mount points
5669end
5670
5671define 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
5678end
5679
5680define 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
5696end
5697
5698document mbuf_walkpkt
5699Syntax: (gdb) mbuf_walkpkt <addr>
5700| Given an mbuf address, walk its m_nextpkt pointer
5701end
5702
5703define 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
5719end
5720
5721document mbuf_walk
5722Syntax: (gdb) mbuf_walk <addr>
5723| Given an mbuf address, walk its m_next pointer
5724end
5725
5726define 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
5736end
5737
5738document mbuf_buf2slab
5739| Given an mbuf object, find its corresponding slab address.
5740end
5741
5742define 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
5753end
5754
5755document mbuf_buf2mca
5756Syntax: (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.
5760end
5761
5762define 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
5814end
5815
5816document mbuf_showmca
5817Syntax: (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.
5820end
5821
5822define 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
5835end
5836
5837document mbuf_topleak
5838Syntax: (gdb) mbuf_topleak <num>
5839| Prints information about the top <num> suspected mbuf leakers
5840| where <num> is a value <= 5
5841end
5842
5843define 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
5860end
5861
5862document mbuf_traceleak
5863Syntax: (gdb) mbuf_traceleak <addr>
5864| Given an mbuf leak trace (mtrace) structure address, print out the
5865| stored information with that trace
5866end
5867
5868set $MCF_NOCPUCACHE = 0x10
5869
5870define 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
5929end
5930
5931document mcache_stat
5932Syntax: (gdb) mcache_stat
5933| Print all mcaches in the system.
5934end
5935
5936define 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"
5942end
5943
5944document mcache_showzone
5945Syntax: (gdb) mcache_showzone <mcache_addr>
5946| Print the type of backend (custom or zone) of a mcache.
5947end
5948
5949define 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
5958end
5959
5960document mcache_walkobj
5961Syntax: (gdb) mcache_walkobj <addr>
5962| Given a mcache object address, walk its obj_next pointer
5963end
5964
5965define 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
5996end
5997
5998document mcache_showcache
5999| Display the number of objects in the cache
6000end
6001
6002set $NSLABSPMB = sizeof(mcl_slabg_t)/sizeof(mcl_slab_t)
6003
6004define 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
6030end
6031
6032document mbuf_slabstbl
6033| Display the mbuf slabs table
6034end
6035
6036set $SLF_MAPPED=0x0001
6037set $SLF_PARTIAL=0x0002
6038set $SLF_DETACHED=0x0004
6039
6040define 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
6115end
6116
6117document mbuf_slabs
6118| Display all mbuf slabs in the group
6119end
6120
6121define 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
6156end
6157
6158document mbuf_stat
6159| Print extended mbuf allocator statistics.
6160end
6161
6162set $MB_INUSE = 0x1
6163set $MB_COMP_INUSE = 0x2
6164set $MB_SCVALID = 0x4
6165
6166set $MCLBYTES = 2048
6167set $MSIZE = 256
6168set $NBPG = 4096
6169set $M16KCLBYTES = 16384
6170
6171define 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
6297end
6298
6299document 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.
6302end
6303
6304define mbuf_showactive
6305	if $argc == 0
6306		mbuf_walkallslabs 1 0
6307	else
6308		mbuf_walkallslabs 1 0 $arg0
6309	end
6310end
6311
6312document mbuf_showactive
6313Syntax: (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).
6319end
6320
6321define mbuf_showinactive
6322	mbuf_walkallslabs 0 1
6323end
6324
6325document mbuf_showinactive
6326Syntax: (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.
6333end
6334
6335define mbuf_showall
6336	mbuf_walkallslabs 1 1
6337end
6338
6339document mbuf_showall
6340Syntax: (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.
6344end
6345
6346define mbuf_mcaobjs
6347end
6348
6349define 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
6468end
6469
6470document 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}.
6474end
6475
6476define 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
6500end
6501
6502document mbuf_countchain
6503Syntax: 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.
6506end
6507
6508set $RTF_UP          = 0x1
6509set $RTF_GATEWAY     = 0x2
6510set $RTF_HOST        = 0x4
6511set $RTF_REJECT      = 0x8
6512set $RTF_DYNAMIC     = 0x10
6513set $RTF_MODIFIED    = 0x20
6514set $RTF_DONE        = 0x40
6515set $RTF_DELCLONE    = 0x80
6516set $RTF_CLONING     = 0x100
6517set $RTF_XRESOLVE    = 0x200
6518set $RTF_LLINFO      = 0x400
6519set $RTF_STATIC      = 0x800
6520set $RTF_BLACKHOLE   = 0x1000
6521set $RTF_PROTO2      = 0x4000
6522set $RTF_PROTO1      = 0x8000
6523set $RTF_PRCLONING   = 0x10000
6524set $RTF_WASCLONED   = 0x20000
6525set $RTF_PROTO3      = 0x40000
6526set $RTF_PINNED      = 0x100000
6527set $RTF_LOCAL       = 0x200000
6528set $RTF_BROADCAST   = 0x400000
6529set $RTF_MULTICAST   = 0x800000
6530set $RTF_IFSCOPE     = 0x1000000
6531set $RTF_CONDEMNED   = 0x2000000
6532set $RTF_IFREF       = 0x4000000
6533set $RTF_PROXY       = 0x8000000
6534set $RTF_ROUTER      = 0x10000000
6535
6536set $AF_INET = 2
6537set $AF_INET6 = 30
6538set $AF_LINK = 18
6539
6540define 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
6673end
6674
6675set $RNF_ROOT   = 2
6676
6677define _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
6718end
6719
6720
6721define 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]
6730end
6731
6732document show_rt_inet
6733Syntax: (gdb) show_rt_inet
6734| Show the entries of the IPv4 routing table.
6735end
6736
6737define 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]
6746end
6747
6748document show_rt_inet6
6749Syntax: (gdb) show_rt_inet6
6750| Show the entries of the IPv6 routing table.
6751end
6752
6753define 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
6774end
6775
6776document rtentry_trash
6777Syntax: (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.
6781end
6782
6783set $CTRACE_STACK_SIZE = ctrace_stack_size
6784set $CTRACE_HIST_SIZE = ctrace_hist_size
6785
6786define 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
6896end
6897
6898document rtentry_showdbg
6899Syntax: (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.
6904end
6905
6906set $INIFA_TRACE_HIST_SIZE = inifa_trace_hist_size
6907
6908define 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
6978end
6979
6980document inifa_showdbg
6981Syntax: (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.
6986end
6987
6988set $IN6IFA_TRACE_HIST_SIZE = in6ifa_trace_hist_size
6989
6990define 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
7060end
7061
7062document in6ifa_showdbg
7063Syntax: (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.
7068end
7069
7070set $IFMA_TRACE_HIST_SIZE = ifma_trace_hist_size
7071
7072define 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
7114end
7115
7116document ifma_showdbg
7117Syntax: (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.
7122end
7123
7124set $INM_TRACE_HIST_SIZE = inm_trace_hist_size
7125
7126define 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
7168end
7169
7170document inm_showdbg
7171Syntax: (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.
7176end
7177
7178set $IF_REF_TRACE_HIST_SIZE = if_ref_trace_hist_size
7179
7180define 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
7224end
7225
7226document ifpref_showdbg
7227Syntax: (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.
7232end
7233
7234define 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
7255end
7256
7257set $NDPR_TRACE_HIST_SIZE = ndpr_trace_hist_size
7258
7259define 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
7303end
7304
7305document ndpr_showdbg
7306Syntax: (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.
7311end
7312
7313set $NDDR_TRACE_HIST_SIZE = nddr_trace_hist_size
7314
7315define 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
7359end
7360
7361document nddr_showdbg
7362Syntax: (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.
7367end
7368set $IMO_TRACE_HIST_SIZE = imo_trace_hist_size
7369
7370define 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
7414end
7415
7416document imo_showdbg
7417Syntax: (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.
7422end
7423
7424set $IM6O_TRACE_HIST_SIZE = im6o_trace_hist_size
7425
7426define 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
7470end
7471
7472document im6o_showdbg
7473Syntax: (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.
7478end
7479
7480document in6ifa_trash
7481Syntax: (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.
7485end
7486
7487define 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
7508end
7509
7510document inifa_trash
7511Syntax: (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.
7515end
7516
7517define 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
7540end
7541
7542document ifma_trash
7543Syntax: (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.
7547end
7548
7549define 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
7570end
7571
7572document inm_trash
7573Syntax: (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.
7577end
7578
7579define 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
7600end
7601
7602document in6m_trash
7603Syntax: (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.
7607end
7608
7609#
7610# print all OSMalloc stats 
7611
7612define ostag_print
7613set $kgm_tagp = (OSMallocTag)$arg0
7614printf "0x%08x: ", $kgm_tagp
7615printf "%8d ",$kgm_tagp->OSMT_refcnt
7616printf "%8x ",$kgm_tagp->OSMT_state
7617printf "%8x ",$kgm_tagp->OSMT_attr
7618printf "%s ",$kgm_tagp->OSMT_name
7619printf "\n"
7620end
7621
7622
7623define showosmalloc 
7624printf "TAG          COUNT     STATE     ATTR     NAME\n"
7625set $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"
7632end
7633document showosmalloc
7634Syntax: (gdb) showosmalloc
7635| Print the outstanding allocation count by OSMallocTags.
7636end
7637
7638
7639define 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"
7676end
7677document systemlog
7678| Syntax: systemlog
7679| Display the kernel's printf ring buffer
7680end
7681
7682
7683define 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
7709end
7710document hexdump
7711| Show the contents of memory as a hex/ASCII dump
7712| The following is the syntax:
7713| (gdb) hexdump <address> <length>
7714end
7715
7716
7717define 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
7732end
7733
7734define 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
7747end
7748
7749define 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
7754end
7755
7756define 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
7761end
7762
7763define show_in_addr
7764    set $ia = (unsigned char *)$arg0
7765    printf "%3u.%03u.%03u.%03u", $ia[0], $ia[1], $ia[2], $ia[3]
7766end
7767
7768define showsockaddr_in
7769    set $sin = (struct sockaddr_in *)$arg0
7770    set $sa_bytes = (unsigned char *)&($sin->sin_addr)
7771    show_in_addr $sa_bytes
7772end
7773
7774define 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]
7778end
7779
7780define 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
7784end
7785
7786define 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
7797end
7798
7799define 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
7832end
7833
7834document showifmultiaddrs
7835Syntax showifmultiaddrs <ifp>
7836| show the (struct ifnet).if_multiaddrs list of multicast addresses for the given ifp
7837end
7838
7839define 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
7853end
7854
7855document showinmultiaddrs
7856Syntax showinmultiaddrs
7857| show the contents of IPv4 multicast address records
7858end
7859
7860define 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
7874end
7875
7876document showin6multiaddrs
7877Syntax showin6multiaddrs
7878| show the contents of IPv6 multicast address records
7879end
7880
7881define 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
7924end
7925
7926define 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 ">"
8050end
8051
8052define 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
8063end
8064
8065document showifaddrs
8066Syntax: showifaddrs <ifp>
8067| show the (struct ifnet).if_addrhead list of addresses for the given ifp
8068end
8069
8070define 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
8089end
8090document ifconfig
8091Syntax: (gdb) ifconfig
8092| display ifconfig-like output, and print the (struct ifnet *) pointers for further inspection
8093end
8094
8095set $DLIF_INUSE	= 0x1
8096set $DLIF_REUSE	= 0x2
8097
8098define 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
8126end
8127
8128document showifnets
8129Syntax: (gdb) showifnets
8130| Display ifconfig-like output for all attached and detached interfaces
8131end
8132
8133define _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
8145end
8146
8147define _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
8158end
8159
8160define _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
8165end
8166
8167define _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
8174end
8175
8176define _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
8213end
8214
8215define _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
8235end
8236
8237define _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
8253end
8254
8255define _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
8271end
8272
8273
8274define 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"
8296end
8297document showsocket
8298Syntax: (gdb) showsocket <socket_address>
8299| Routine to print out a socket
8300end
8301
8302define 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
8329end
8330document showprocsockets
8331Syntax: (gdb) showprocsockets <proc_address>
8332| Routine to print out all the open fds
8333| which are sockets in a process
8334end
8335
8336define 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
8345end
8346document showallprocsockets
8347Syntax: (gdb) showallprocsockets
8348| Routine to print out all the open fds
8349| which are sockets 
8350end
8351
8352define _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
8357end
8358
8359set $INPCB_STATE_INUSE=0x1
8360set $INPCB_STATE_CACHED=0x2
8361set $INPCB_STATE_DEAD=0x3
8362
8363set $INP_RECVOPTS=0x01
8364set $INP_RECVRETOPTS=0x02
8365set $INP_RECVDSTADDR=0x04
8366set $INP_HDRINCL=0x08
8367set $INP_HIGHPORT=0x10
8368set $INP_LOWPORT=0x20
8369set $INP_ANONPORT=0x40
8370set $INP_RECVIF=0x80
8371set $INP_MTUDISC=0x100
8372set $INP_STRIPHDR=0x200
8373set $INP_RECV_ANYIF=0x400
8374set $INP_INADDR_ANY=0x800
8375set $INP_RECVTTL=0x1000
8376set $INP_UDP_NOCKSUM=0x2000
8377set $IN6P_IPV6_V6ONLY=0x008000
8378set $IN6P_PKTINFO=0x010000
8379set $IN6P_HOPLIMIT=0x020000
8380set $IN6P_HOPOPTS=0x040000
8381set $IN6P_DSTOPTS=0x080000
8382set $IN6P_RTHDR=0x100000
8383set $IN6P_RTHDRDSTOPTS=0x200000
8384set $IN6P_AUTOFLOWLABEL=0x800000
8385set $IN6P_BINDV6ONLY=0x10000000
8386
8387set $INP_IPV4=0x1
8388set $INP_IPV6=0x2
8389
8390set $IPPROTO_TCP=6
8391set $IPPROTO_UDP=17
8392
8393define _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
8534end
8535
8536define _dump_inpcbport
8537	set $ppcb = (struct inpcbport *)$arg0
8538	printf "%p: lport ", $ppcb
8539	_print_ntohs $ppcb->phd_port
8540end
8541
8542set $UDBHASHSIZE=16
8543
8544define _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
8622end
8623
8624set $N_TIME_WAIT_SLOTS=128
8625
8626define 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
8664end
8665document show_tcp_timewaitslots
8666Syntax: (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
8670end
8671
8672define show_tcp_pcbinfo
8673	_dump_pcbinfo &tcbinfo $IPPROTO_TCP
8674end
8675document show_tcp_pcbinfo
8676Syntax: (gdb) show_tcp_pcbinfo
8677| Print the list of TCP protocol control block information
8678end
8679
8680
8681define show_udp_pcbinfo
8682	_dump_pcbinfo &udbinfo $IPPROTO_UDP
8683end
8684document show_udp_pcbinfo
8685Syntax: (gdb) show_udp_pcbinfo
8686| Print the list of UDP protocol control block information
8687end
8688
8689define 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
8698end
8699
8700define 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
8711end
8712
8713define 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"
8723end
8724
8725document showvnodepath
8726Syntax: (gdb) showvnodepath <vnode>
8727| Prints the path for a vnode
8728end
8729
8730define 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
8764end
8765
8766document showallvols
8767Syntax: (gdb) showallvols
8768| Display a summary of mounted volumes
8769end
8770
8771define showvnodeheader
8772	printf "vnode     "
8773    showptrhdrpad
8774    printf "  usecount  iocount  v_data    "
8775    showptrhdrpad
8776    printf "  vtype  parent    "
8777    showptrhdrpad    
8778    printf "  name\n"
8779end
8780
8781define 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
8835end
8836
8837define showvnode
8838	showvnodeheader
8839	showvnodeint $arg0
8840end
8841
8842document showvnode
8843Syntax: (gdb) showvnode <vnode>
8844| Display info about one vnode
8845end
8846
8847define 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
8855end
8856
8857document showvolvnodes
8858Syntax: (gdb) showvolvnodes <mouont_t>
8859| Display info about all vnodes of a given mount_t
8860end
8861
8862define 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
8872end
8873
8874document showvolbusyvnodes
8875Syntax: (gdb) showvolbusyvnodes <mount_t>
8876| Display info about busy (iocount!=0) vnodes of a given mount_t
8877end
8878
8879define 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
8892end
8893
8894document showallbusyvnodes
8895Syntax: (gdb) showallbusyvnodes <vnode>
8896| Display info about all busy (iocount!=0) vnodes
8897end
8898
8899define 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
8910end
8911
8912document showallvnodes
8913Syntax: (gdb) showallvnodes
8914| Display info about all vnodes
8915end
8916
8917define _showvnodelockheader
8918    printf "*  type   W  held by        lock type  start               end\n"
8919    printf "-  -----  -  -------------  ---------  ------------------  ------------------\n"
8920end
8921
8922define _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"
8970end
8971# Body of showvnodelocks, not including header
8972define _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
8991end
8992
8993
8994define showvnodelocks
8995    if ($argc == 1)
8996    	_showvnodelockheader
8997	_showvnodelocks $arg0
8998    else
8999    	printf "| Usage:\n|\n"
9000	help showvnodelocks
9001    end
9002end
9003
9004document showvnodelocks
9005Syntax: (gdb) showvnodelocks <vnode_t>
9006| Given a vnodet pointer, display the list of advisory record locks for the
9007| referenced pvnodes
9008end
9009
9010define showbootargs
9011	printf "%s\n", (char*)((boot_args*)PE_state.bootArgs).CommandLine
9012end
9013
9014document showbootargs
9015Syntax: showbootargs
9016| Display boot arguments passed to the target kernel
9017end
9018
9019define 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
9094end
9095
9096document showbootermemorymap
9097Syntax: (gdb) showbootermemorymap
9098| Prints out the phys memory map from kernelBootArgs
9099end
9100
9101
9102define 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
9123end
9124document showstacksaftertask
9125Syntax: (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.
9128end
9129
9130define 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
9173end
9174
9175define 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
9184end
9185
9186document showpmworkqueue
9187Syntax: (gdb) showpmworkqueue
9188| Display the IOPMWorkQueue object
9189end
9190
9191define 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
9324end
9325
9326document showioservicepm
9327Syntax: (gdb) showioservicepm <IOServicePM pointer>
9328| Routine to dump the IOServicePM object
9329end
9330
9331define 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
9406end
9407
9408define 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
9420end
9421
9422define showregistrypmstate
9423#    setregistryplane gIOPowerPlane
9424    set $kgm_reg_depth  = 0
9425    set $kgm_show_props = 1
9426    showregistryentryintpmstate gRegistryRoot
9427end
9428
9429document showregistrypmstate
9430Syntax: (gdb) showregistrypmstate
9431| Routine to dump the PM state of each IOPower registry entry
9432end
9433
9434define 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
9459end
9460
9461document showstacksafterthread
9462Syntax: (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.
9465end
9466
9467define kdp-reenter
9468       set kdp_reentry_deadline = ((unsigned) $arg0)*1000
9469       continue
9470end
9471
9472document kdp-reenter
9473Syntax: (gdb) kdp-reenter <seconds>
9474| Schedules reentry into the debugger after <seconds> seconds, and resumes
9475| the target system.
9476end
9477
9478define _if_present
9479    if (!$arg0)
9480        printf " not"
9481    end
9482    printf " present"
9483end
9484
9485define 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
9524end
9525
9526document showMCAstate
9527Syntax: showMCAstate
9528| Print machine-check register state after MC exception.
9529end
9530
9531define _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
9627end
9628
9629define _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
9689end
9690
9691define _pmap_walk_x86
9692    set $kgm_pmap = (pmap_t) $arg0
9693    _pml4_walk $kgm_pmap->pm_cr3 $arg1
9694end
9695
9696define _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
9799end
9800
9801define _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
9945end
9946
9947# See ARM ARM Section B3.3
9948define _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
9993end
9994
9995define 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
10016end
10017
10018document pmap_walk
10019Syntax: (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.
10027end
10028
10029define 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
10044end
10045
10046document pmap_vtop
10047Syntax: (gdb) pmap_vtop <pmap> <virtual_address>
10048| For page-tables in <pmap> translate <virtual_address> to physical address.
10049end
10050
10051define 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
10092end
10093
10094document zstack
10095Syntax: (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.
10106end
10107
10108define 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
10131end
10132
10133document findoldest
10134Syntax: (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.
10141end
10142
10143define 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
10173end
10174
10175document countpcs
10176Syntax: (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.
10181end
10182
10183define 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
10211end
10212
10213document findelem
10214Syntax: (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.
10220end
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).
10235define _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
10355end
10356
10357define _unmap_user_data_from_task
10358    set kdp_pmap = 0
10359end
10360
10361# uses $kgm_taskp. Maps 32 bytes at a time and prints it
10362define _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
10389end
10390
10391# uses $kgm_taskp and $kgm_task_64. May modify $kgm_dyld_load_path
10392define _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    
10518end
10519
10520define _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
10577end
10578
10579define 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
10599end
10600document showuserlibraries
10601Syntax: (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.
10604end
10605
10606define 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
10792end
10793document showuserdyldinfo
10794Syntax: (gdb) showuserdyldinfo <task_t>
10795| For a given user task, inspect the dyld global info and print
10796| out all fields, including error messages.
10797end
10798
10799define 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"
10805end
10806
10807define _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
10851end
10852
10853define 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"
11087end
11088
11089define 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
11123end
11124
11125document showkerneldebugbuffercpu
11126Syntax:  showkerneldebugbuffercpu <cpu> <count>
11127| Prints the last N entries in the kernel debug buffer for CPU x.
11128end
11129
11130define 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
11150end
11151
11152document showkerneldebugbuffer
11153Syntax: 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.
11156end
11157
11158define 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
11169end
11170
11171document showallvmstats
11172Syntax: showallvmstats
11173| prints a summary of vm statistics in a table format
11174end
11175
11176define 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
11190end
11191
11192document memstats
11193Syntax: (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.
11196end
11197
11198define show_user_registers
11199       showuserregisters $arg0
11200end
11201
11202document show_user_registers
11203Syntax: 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
11206end
11207
11208define _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
11231end
11232
11233define _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
11273end
11274
11275define 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
11277end
11278
11279document strcmp_arg_pack64
11280Syntax: 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| 
11287end
11288
11289define 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
11331end
11332
11333document strcmp_nomalloc
11334Syntax: 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
11342end
11343
11344define 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
11365end
11366
11367document memcpy
11368Syntax: 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>
11371end
11372
11373# _pci_cfg_addr_value $addr $size
11374define _pci_cfg_addr_value
11375   readphysint $arg0 $arg1 $kgm_lcpu_self
11376   set $kgm_pci_cfg_value = $kgm_readphysint_result
11377end
11378
11379
11380set $kgm_pci_cfg_init = 0
11381define _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
11424end
11425
11426# _pci_cfg_addr $bus $dev $fcn $off
11427define _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
11435end
11436
11437define _pci_cfg_value
11438       _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11439       _pci_cfg_addr_value $kgm_pci_cfg_addr $arg4
11440end
11441
11442define 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
11445end
11446
11447define 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
11450end
11451
11452define 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
11455end
11456
11457document pci_cfg_read8
11458Syntax: (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>. 
11461end
11462
11463document pci_cfg_read16
11464Syntax: (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>.
11467end
11468
11469document pci_cfg_read32
11470Syntax: (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>.
11473end
11474
11475define pci_cfg_write8
11476       _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11477       writephysint $kgm_pci_cfg_addr 8 $arg4 $kgm_lcpu_self
11478end
11479
11480define pci_cfg_write16
11481       _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11482       writephysint $kgm_pci_cfg_addr 16 $arg4 $kgm_lcpu_self
11483end
11484
11485define pci_cfg_write32
11486       _pci_cfg_addr $arg0 $arg1 $arg2 $arg3 
11487       writephysint $kgm_pci_cfg_addr 32 $arg4 $kgm_lcpu_self
11488end
11489
11490document pci_cfg_write8
11491Syntax: (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>. 
11494end
11495
11496document pci_cfg_write16
11497Syntax: (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>. 
11500end
11501
11502document pci_cfg_write32
11503Syntax: (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>.
11506end
11507
11508
11509define 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      
11545end
11546
11547document pci_cfg_dump
11548Syntax: (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.
11552end
11553
11554set $kgm_pci_cfg_bus_start    = 0
11555set $kgm_pci_cfg_bus_max      = 8
11556set $kgm_pci_cfg_device_max   = 32
11557set $kgm_pci_cfg_function_max = 8
11558define _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
11592end
11593
11594define pci_cfg_dump_all
11595       _pci_cfg_scan 1
11596end
11597
11598document pci_cfg_dump_all
11599Syntax: (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. 
11603end
11604
11605define pci_cfg_scan
11606       printf "bus:dev:fcn: vendor device rev | class\n"
11607       printf "---------------------------------------\n"
11608       _pci_cfg_scan 0
11609end
11610
11611document pci_cfg_scan
11612Syntax: (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. 
11616end
11617
11618define 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
11647end
11648
11649define 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
11657end
11658
11659define 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
11667end
11668
11669define 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
11677end
11678
11679document readioport8
11680| See readioport32.
11681end
11682
11683document readioport16
11684| See readioport32.
11685end
11686
11687document readioport32
11688Syntax: (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.
11691end
11692
11693define 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
11720end
11721
11722define writeioport8
11723       set $lcpu = $kgm_lcpu_self
11724       if $argc > 2
11725       	  set $lcpu = $arg2
11726       end
11727       writeioportint $arg0 8 $arg1 $lcpu
11728end
11729
11730define writeioport16
11731       set $lcpu = $kgm_lcpu_self
11732       if $argc > 2
11733       	  set $lcpu = $arg2
11734       end
11735       writeioportint $arg0 16 $arg1 $lcpu
11736end
11737
11738define writeioport32
11739       set $lcpu = $kgm_lcpu_self
11740       if $argc > 2
11741       	  set $lcpu = $arg2
11742       end
11743       writeioportint $arg0 32 $arg1 $lcpu
11744end
11745
11746document writeioport8
11747| See writeioport32.
11748end
11749
11750document writeioport16
11751| See writeioport32.
11752end
11753
11754document writeioport32
11755Syntax: (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.
11759end
11760
11761define 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
11781end
11782
11783define 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
11791end
11792
11793define 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
11811end
11812
11813define writemsr64
11814       set $lcpu = $kgm_lcpu_self
11815       if $argc > 2
11816       	  set $lcpu = $arg2
11817       end
11818       writemsr64int $arg0 $arg1 $lcpu
11819end
11820
11821document writemsr64
11822Syntax: (gdb) writemsr64 <msr> <value> [lcpu (kernel's numbering convention)]
11823| Write <value> to the specified MSR. The CPU can be optionally specified.
11824end
11825
11826document readmsr64
11827Syntax: (gdb) readmsr64 <msr> [lcpu (kernel's numbering convention)]
11828| Read the specified MSR. The CPU can be optionally specified.
11829end
11830
11831# default if we can't find a registry entry
11832set $kgm_ioapic_addr           = 0xFEC00000
11833set $kgm_ioapic_init           = 0
11834
11835set $_ioapic_index_off         = 0x00
11836set $_ioapic_data_off          = 0x10
11837set $_ioapic_eoi_off           = 0x40
11838
11839set $_ioapic_index_id          = 0x00
11840set $_ioapic_index_ver         = 0x01
11841set $_ioapic_index_redir_base  = 0x10
11842
11843set $_apic_vector_mask         = 0xFF
11844set $_apic_timer_tsc_deadline  = 0x40000
11845set $_apic_timer_periodic      = 0x20000
11846set $_apic_masked              = 0x10000
11847set $_apic_trigger_level       = 0x08000
11848set $_apic_polarity_high       = 0x02000
11849set $_apic_pending             = 0x01000
11850
11851define _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
11877end
11878
11879define _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
11888end
11889
11890define _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"
11926end
11927
11928define 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
11935end
11936
11937document ioapic_read32
11938Syntax: (gdb) ioapic_read <offset>
11939| Read the IOAPIC register at the offset specified. 
11940end
11941
11942define 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
11948end
11949
11950document ioapic_write32
11951Syntax: (gdb) ioapic_write32 <offset> <value>
11952| Write the IOAPIC register at the offset specified. 
11953end
11954
11955define 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
11984end
11985
11986document ioapic_dump
11987Syntax: (gdb) ioapic_dump
11988| Dump all the IOAPIC entries.
11989end
11990
11991
11992set $_lapic_base_addr         = 0xFEE00000
11993set $_lapic_id                = 0x20
11994set $_lapic_version           = 0x30
11995set $_lapic_tpr               = 0x80
11996set $_lapic_apr               = 0x90
11997set $_lapic_ppr               = 0xA0
11998set $_lapic_eoi               = 0xB0
11999set $_lapic_ldr               = 0xD0
12000set $_lapic_dfr               = 0xE0
12001set $_lapic_sivr              = 0xF0
12002
12003set $_lapic_isr_size          = 0x10
12004set $_lapic_isr_num           = 8
12005set $_lapic_isr0              = 0x100
12006set $_lapic_tmr0              = 0x180
12007set $_lapic_irr0              = 0x200
12008
12009set $_lapic_esr               = 0x280
12010set $_lapic_esr_register      = 0x80
12011set $_lapic_esr_recv_vect     = 0x40
12012set $_lapic_esr_send_vect     = 0x20
12013
12014set $_lapic_icr0              = 0x300
12015set $_lapic_icr1              = 0x310
12016
12017set $_lapic_lvt_timer         = 0x320
12018set $_lapic_lvt_thermal       = 0x330
12019set $_lapic_lvt_pmcr          = 0x340
12020set $_lapic_lvt_lint0         = 0x350
12021set $_lapic_lvt_lint1         = 0x360
12022set $_lapic_lvt_error         = 0x370
12023
12024set $_lapic_icr               = 0x380
12025set $_lapic_ccr               = 0x390
12026set $_lapic_dcr               = 0x3E0
12027
12028set $_apic_cfg_msr          = 0x1B
12029set $_apic_cfg_msr_x2EN     = 0x00000C00
12030set $_x2apic_enabled         = -1
12031
12032# _lapic_addr $offset returns the actual address to use
12033define _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
12050end
12051
12052# _lapic_addr_value $offset $lcpu
12053define _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
12062end
12063
12064# lapic_read32 $offset [$lcpu]
12065define 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
12076end
12077
12078document lapic_read32
12079Syntax: (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.
12082end
12083
12084# lapic_write32 $offset $value [$lcpu]
12085define 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
12101end
12102
12103document lapic_write32
12104Syntax: (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.
12107end
12108
12109# lapic_dump [lcpu]
12110define 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
12250end
12251
12252document lapic_dump
12253Syntax: (gdb) lapic_dump [lcpu (kernel's numbering convention)]
12254| Dump all the LAPIC entries. The CPU can be optionally specified. 
12255end
12256 
12257define showknoteheader
12258   printf "            knote       filter           ident  kn_ptr      status\n"
12259end
12260
12261define 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"
12329end
12330
12331define 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
12354end
12355
12356define 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
12365end
12366document showprocknotes 
12367Syntax: showprocknotes <proc>
12368| Displays filter and status information for every kevent registered for
12369| the process.
12370end
12371
12372#
12373# Device node related debug macros
12374#
12375
12376define _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
12487end
12488
12489define _showwhohas
12490	# _showwhohas <major> <minor>
12491	printf "fd     "
12492	printf "fileglob    "
12493showptrhdrpad
12494	printf "vnode       "
12495showptrhdrpad
12496	printf "process     "
12497showptrhdrpad
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
12535end
12536
12537define _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
12587end
12588
12589define 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
12681end
12682document showvnodedev
12683Syntax: (gdb) showvnodedev <vnode>
12684|     showvnodedev       Display information about a device vnode
12685end
12686
12687define showtty
12688    if ($argc == 1)
12689	_showtty $arg0
12690    else
12691    	printf "| Usage:\n|\n"
12692	help showtty
12693    end
12694end
12695document showtty
12696Syntax: (gdb) showtty <tty struct>
12697|     showtty            Display information about a struct tty
12698end
12699
12700define showeventsourceobject
12701    set $kgm_vt = *((void **) $arg1)
12702    if $kgm_lp64
12703        set $kgm_vt = $kgm_vt - 16
12704    end
12705    pcprint $kgm_vt
12706end
12707document showeventsourceobject
12708Syntax: (gdb) showeventsourceobject <prefix> <object>
12709| Routine to display information about an IOEventSource subclass.
12710end
12711
12712define 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
12730end
12731document showworkloopallocator
12732Syntax: (gdb) showworkloopallocator <workloop>
12733| Routine to display the backtrace of the thread which allocated the workloop in question. Only
12734| valid on DEBUG kernels.
12735end
12736
12737define 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
12763end
12764document showworkloopeventsources
12765Syntax: (gdb) showworkloopeventsources
12766| Routine to walk an IOEventSource chain associated with an IOWorkLoop and print information
12767| about each event source in the chain.
12768end
12769
12770define showworkloopheader
12771    printf "thread    "
12772    showptrhdrpad
12773    printf "  workloop "
12774    showptrhdrpad
12775    printf "    pri state\tLockGroupName\n"
12776end
12777document showworkloopheader
12778Syntax: (gdb) showworkloopheader
12779| Routine to print out header info about an IOKit workloop.
12780end
12781
12782define 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
12837end
12838document showworkloop
12839Syntax: (gdb) showworkloop <thread> <workloop>
12840| Routine to print out info about an IOKit workloop.
12841end
12842
12843define 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"
12877end
12878document showallworkloopthreads
12879Syntax: (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'.
12884end
12885
12886define 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
12913end
12914
12915document showthreadfortid
12916Syntax:  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.
12920end
12921
12922define 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
12935end
12936
12937define showtaskbusyports
12938    showtaskbusyportsint $arg0
12939end
12940
12941document showtaskbusyports
12942Syntax:  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.
12945end
12946
12947define 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
12954end
12955
12956document showallbusyports
12957Syntax:  showallbusyports
12958|Routine to print information about all receive rights on the system that
12959|have enqueued messages.
12960end
12961
12962define 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
12969end
12970
12971document showallproviders
12972Syntax: showallproviders
12973| Display summary listing of all dtrace_providers
12974end
12975
12976define 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"
12988end
12989
12990define 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
13007end
13008
13009define showmodctl
13010    showmodctlheader
13011    showmodctlint $arg0
13012end
13013document showmodctl
13014Syntax: (gdb) showmodctl <addr>
13015| Display info about a dtrace modctl
13016end
13017
13018define 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
13025end
13026document showallmodctls
13027Syntax: (gdb) showallmodctls
13028| Display summary listing of all dtrace modctls
13029end
13030
13031define 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
13069end
13070document showfbtprobe
13071Syntax: (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
13075end
13076
13077define 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
13094end
13095
13096document showzstacktrace
13097Syntax:  showzstacktrace <saved stacktrace> [size]
13098| Routine to print a stacktrace stored by OSBacktrace.
13099| size is optional, defaults to 15.
13100end
13101
13102define showzalloc
13103	set $kgm_zallocation = zallocations[$arg0]
13104	print $kgm_zallocation
13105	showztrace $kgm_zallocation->za_trace_index
13106end
13107
13108document showzalloc
13109Syntax:  showzalloc <index>
13110| Prints a zallocation from the zallocations array based off its index, 
13111| and prints the associated symbolicated backtrace.
13112end
13113
13114define showztrace
13115	set $kgm_ztrace = &ztraces[$arg0]
13116	showztraceaddr $kgm_ztrace
13117end
13118
13119document showztrace
13120Syntax:  showztrace <trace index>
13121| Prints the backtrace from the ztraces array at index
13122end
13123
13124define showztraceaddr
13125	print *$arg0
13126	showzstacktrace $arg0->zt_stack ($arg0)->zt_depth
13127end
13128
13129document showztraceaddr
13130Syntax:  showztraceaddr <trace address>
13131| Prints the struct ztrace passed in
13132end
13133
13134#TODO: Iterate through the hash table, or make top_ztrace accurate in the face of deallocations (better idea).
13135define showtopztrace
13136	set $kgm_top_ztrace = top_ztrace
13137	printf "Index: %d\n", (top_ztrace - ztraces)
13138	showztraceaddr $kgm_top_ztrace
13139end
13140
13141document showtopztrace
13142Syntax:  showtopztrace 
13143| Shows the ztrace with the biggest size. (according to top_ztrace, not by iterating through the hash table)
13144end
13145
13146define 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
13165end
13166
13167document showzallocs
13168Syntax:  showzallocs
13169| Prints all allocations in the zallocations table
13170end
13171
13172define 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
13191end
13192
13193document showzallocsfortrace
13194Syntax:  showzallocsfortrace <trace index>
13195| Prints all allocations pointing to the passed in trace's index into ztraces by looking through zallocations table
13196end
13197
13198define showztraces
13199	showztracesabove 0
13200end
13201
13202document showztraces
13203Syntax:  showztraces
13204| Prints all traces with size > 0
13205end
13206
13207define 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
13221end
13222
13223document showztracesabove
13224Syntax:  showztracesabove <size>
13225| Prints all traces with size greater than X
13226end
13227
13228define 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
13242end
13243
13244document showztracehistogram
13245Syntax:  showztracehistogram
13246| Prints the histogram of the ztrace table
13247end
13248
13249define 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
13263end
13264
13265document showzallochistogram
13266Syntax:  showzallochistogram
13267| Prints the histogram for the zalloc table
13268end
13269
13270define 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
13274end
13275
13276document showzstats
13277Syntax:  showzstats
13278| Prints the zone leak detection stats
13279end
13280
13281
13282set $kgm_au_sentry_hash_table_size = 97
13283
13284define 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"
13290end
13291
13292define showsessionhdr
13293  printf "au_sentry "
13294  showptrhdrpad
13295  printf "  ASID        AUID        FLAGS               C    P\n"
13296end
13297
13298define showsession
13299  showsessionhdr
13300  showsession1 $arg0
13301end
13302
13303document showsession
13304Syntax:  showsession
13305| Display info about a specified audit session
13306end
13307
13308define 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
13320end
13321
13322document showallsessions
13323Syntax:  showallsessions
13324| Prints the audit sessions in the global hash table
13325end
13326
13327define 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
13335end
13336
13337define 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
13362end
13363
13364define 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
13379end
13380
13381define showallauhistory
13382  showauhistory 0
13383end
13384
13385define showkwqheader
13386	printf "        kwq     "
13387    showptrhdrpad
13388	printf "    kwqaddr     "
13389    showptrhdrpad
13390    printf "  inqueue  fakecount  highseq  lowseq   flags   lastunlock    p_rwwc"
13391    printf "\n          "
13392end
13393
13394define 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"
13409end
13410
13411define show_kwq
13412	showkwqheader
13413	showkwqint $arg0
13414end
13415
13416document show_kwq
13417Syntax: (gdb) show_kwq <kwq>
13418| Display info about one ksyn_wait_queue
13419end
13420
13421# Internal routine used by "showpthread_mutex" to abstract possible loads from
13422# user space
13423define _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
13439end
13440end
13441
13442define 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
13512end
13513
13514
13515document show_pthreadmutex
13516Syntax: (gdb) show_pthreadmutex <thread> <user_mutexaddr>
13517| Display the mutex contents from userspace.
13518end
13519
13520
13521define 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
13587end
13588
13589
13590document show_pthreadcondition
13591Syntax: (gdb) show_pthreadcondition <thread> <user_cvaddr>
13592| Display the condition variable contents from userspace.
13593end
13594
13595define 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"
13640end
13641
13642document processortimers
13643Syntax: (gdb) processortimers 
13644| Print details of processor timers, noting any timer which might be suspicious
13645end
13646
13647define 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
13653end
13654
13655document maplocalcache
13656Syntax: (gdb) maplocalcache 
13657| Sets up memory regions for GDB to cache on read. Significantly increases debug speed over KDP
13658end
13659
13660define flushlocalcache
13661	if ($kgm_mtype == $kgm_mtype_arm)
13662		delete mem
13663		printf "GDB memory caching disabled.\n"
13664	end
13665end
13666
13667document flushlocalcache
13668Syntax: (gdb) flushlocalcache 
13669| Clears all memory regions
13670end
13671