├── LICENSE ├── README.md ├── bhyve ├── vmrun-10.sh └── vmrun.sh ├── dtrace ├── callout_funcs.d ├── crypto_drivers.d ├── crypto_new_session.d ├── eperm.d ├── g_media.d ├── ipmi_req.d ├── make_ktr ├── rendezvous.d ├── schedgraph.d ├── set_regs_diff.py ├── syscall_error.d ├── syscalls.d └── vfsfilt.d └── gdb ├── build ├── build_gmp ├── chelsio ├── dot.gdbinit.kernel ├── dot.gdbinit.paths ├── gdb4 ├── gdb6 ├── gdb6.amd64 ├── gdb6.i386 └── gdb6.riscv /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2016 John Baldwin 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 | SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kdbg 2 | FreeBSD kernel debugging scripts 3 | 4 | This simple repository holds things I find useful for kernel debugging on FreeBSD. 5 | 6 | ## gdb/ 7 | 8 | The gdb/ subdirectory holds a set of scripts useful with the kgdb front-end to gdb. To use these scripts, do the following in kgdb: 9 | 10 | ``` 11 | % git clone https://github.com/bsdjhb/kdbg.git 12 | % cd kdbg/gdb 13 | % kgdb 14 | .... 15 | (kgdb) source gdb6 16 | ``` 17 | 18 | Filename | Description 19 | --- | --- 20 | build | Wrapper script to configure and build gdb from git using the same setup as the devel/gdb port. 21 | chelsio | Commands for use with the cxgb(4) and cxgbe(4) drivers (Chelsio T3/T4/T5 NICs). Requires gdb6. 22 | dot.gdbinit.kernel | Older scripts from the main source tree. My plan is to eventually move useful scripts out of here to gdb6 and remove this. 23 | dot.gdbinit.paths | See above. 24 | gdb4 | General commands for use with FreeBSD 4.x 25 | gdb6 | General commands for use with FreeBSD 6.x and later 26 | gdb6.amd64 | amd64-specific commands for gdb6. Included automatically by gdb6 on amd64 kernels. 27 | gdb6.i386 | i386-specific commands for gdb6. Included automatically by gdb6 on i386 kernels. 28 | gdb6.riscv | riscv-specific commands for gdb6. 29 | 30 | ## dtrace/ 31 | 32 | The dtrace/ subdirectory holds various DTrace scripts. 33 | 34 | Filename | Description 35 | --- | --- 36 | callout\_funcs.d | Simple histograms of timer functions 37 | crypto\_drivers.d | Histogram of which drivers are used to service OpenCrypto requests 38 | crypto\_new\_session.d | Trace crypto drivers probing crypto sessions 39 | eperm.d | Determine the source of an `EPERM` error from `stat()` 40 | g_media.d | Trace source of ZFS `SPA_PROBE` requests. 41 | ipmi_req.d | Trace ioctl requests to `/dev/ipmi0` 42 | rendezvous.d | Generate stats of SMP rendezvous. 43 | schedgraph.d | Generate KTR_SCHED-like output for use with schedgraph. Use the `make_ktr` script to convert the output of this script into what schedgraph expects. I got the original version from rstone@FreeBSD.org. 44 | set_regs_diff.py | Output the registers actually changed by each `PT_SETREGS` `ptrace(2)` operation 45 | syscalls.d | Simple system call histogram. 46 | vfsfilt.d | Trace `EVFILT_VNODE` event activations 47 | 48 | ## bhyve/ 49 | 50 | The bhyve/ subdirectory holds various variants of vmrun.sh. 51 | -------------------------------------------------------------------------------- /bhyve/vmrun-10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2013 NetApp, Inc. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 | # SUCH DAMAGE. 26 | # 27 | # $FreeBSD: stable/10/share/examples/bhyve/vmrun.sh 284899 2015-06-28 01:21:55Z neel $ 28 | # 29 | 30 | LOADER=/usr/sbin/bhyveload 31 | BHYVECTL=/usr/sbin/bhyvectl 32 | FBSDRUN=/usr/sbin/bhyve 33 | 34 | DEFAULT_MEMSIZE=512M 35 | DEFAULT_CPUS=2 36 | DEFAULT_TAPDEV=tap0 37 | DEFAULT_CONSOLE=stdio 38 | 39 | DEFAULT_VIRTIO_DISK="./diskdev" 40 | DEFAULT_ISOFILE="./release.iso" 41 | 42 | errmsg() { 43 | echo "*** $1" 44 | } 45 | 46 | usage() { 47 | local msg=$1 48 | 49 | echo "Usage: vmrun.sh [-ahi] [-c ] [-C ] [-d ]" 50 | echo " [-e ] [-g ] [-H ]" 51 | echo " [-I ] [-m ]" 52 | echo " [-t ] " 53 | echo "" 54 | echo " -h: display this help message" 55 | echo " -a: force memory mapped local APIC access" 56 | echo " -c: number of virtual cpus (default is ${DEFAULT_CPUS})" 57 | echo " -C: console device (default is ${DEFAULT_CONSOLE})" 58 | echo " -d: virtio diskdev file (default is ${DEFAULT_VIRTIO_DISK})" 59 | echo " -e: set FreeBSD loader environment variable" 60 | echo " -g: listen for connection from kgdb at " 61 | echo " -H: host filesystem to export to the loader" 62 | echo " -i: force boot of the Installation CDROM image" 63 | echo " -I: Installation CDROM image location (default is ${DEFAULT_ISOFILE})" 64 | echo " -m: memory size (default is ${DEFAULT_MEMSIZE})" 65 | echo " -p: pass-through a host PCI device at bus/slot/func (e.g. 10/0/0)" 66 | echo " -t: tap device for virtio-net (default is $DEFAULT_TAPDEV)" 67 | echo "" 68 | [ -n "$msg" ] && errmsg "$msg" 69 | exit 1 70 | } 71 | 72 | if [ `id -u` -ne 0 ]; then 73 | errmsg "This script must be executed with superuser privileges" 74 | exit 1 75 | fi 76 | 77 | kldstat -n vmm > /dev/null 2>&1 78 | if [ $? -ne 0 ]; then 79 | errmsg "vmm.ko is not loaded" 80 | exit 1 81 | fi 82 | 83 | force_install=0 84 | isofile=${DEFAULT_ISOFILE} 85 | memsize=${DEFAULT_MEMSIZE} 86 | console=${DEFAULT_CONSOLE} 87 | cpus=${DEFAULT_CPUS} 88 | tap_total=0 89 | disk_total=0 90 | apic_opt="" 91 | gdbport=0 92 | loader_opt="" 93 | pass_total=0 94 | 95 | while getopts ac:C:d:e:g:hH:iI:m:p:t: c ; do 96 | case $c in 97 | a) 98 | apic_opt="-a" 99 | ;; 100 | c) 101 | cpus=${OPTARG} 102 | ;; 103 | C) 104 | console=${OPTARG} 105 | ;; 106 | d) 107 | disk_dev=${OPTARG%%,*} 108 | disk_opts=${OPTARG#${disk_dev}} 109 | eval "disk_dev${disk_total}=\"${disk_dev}\"" 110 | eval "disk_opts${disk_total}=\"${disk_opts}\"" 111 | disk_total=$(($disk_total + 1)) 112 | ;; 113 | e) 114 | loader_opt="${loader_opt} -e ${OPTARG}" 115 | ;; 116 | g) 117 | gdbport=${OPTARG} 118 | ;; 119 | H) 120 | host_base=`realpath ${OPTARG}` 121 | ;; 122 | i) 123 | force_install=1 124 | ;; 125 | I) 126 | isofile=${OPTARG} 127 | ;; 128 | m) 129 | memsize=${OPTARG} 130 | ;; 131 | p) 132 | eval "pass_dev${pass_total}=\"${OPTARG}\"" 133 | pass_total=$(($pass_total + 1)) 134 | ;; 135 | t) 136 | eval "tap_dev${tap_total}=\"${OPTARG}\"" 137 | tap_total=$(($tap_total + 1)) 138 | ;; 139 | *) 140 | usage 141 | ;; 142 | esac 143 | done 144 | 145 | if [ $tap_total -eq 0 ] ; then 146 | tap_total=1 147 | tap_dev0="${DEFAULT_TAPDEV}" 148 | fi 149 | if [ $disk_total -eq 0 ] ; then 150 | disk_total=1 151 | disk_dev0="${DEFAULT_VIRTIO_DISK}" 152 | 153 | fi 154 | 155 | shift $((${OPTIND} - 1)) 156 | 157 | if [ $# -ne 1 ]; then 158 | usage "virtual machine name not specified" 159 | fi 160 | 161 | vmname="$1" 162 | if [ -n "${host_base}" ]; then 163 | loader_opt="${loader_opt} -h ${host_base}" 164 | fi 165 | 166 | make_and_check_diskdev() 167 | { 168 | local virtio_diskdev="$1" 169 | # Create the virtio diskdev file if needed 170 | if [ ! -f ${virtio_diskdev} ]; then 171 | echo "virtio disk device file \"${virtio_diskdev}\" does not exist." 172 | echo "Creating it ..." 173 | truncate -s 8G ${virtio_diskdev} > /dev/null 174 | fi 175 | 176 | if [ ! -r ${virtio_diskdev} ]; then 177 | echo "virtio disk device file \"${virtio_diskdev}\" is not readable" 178 | exit 1 179 | fi 180 | 181 | if [ ! -w ${virtio_diskdev} ]; then 182 | echo "virtio disk device file \"${virtio_diskdev}\" is not writable" 183 | exit 1 184 | fi 185 | } 186 | 187 | echo "Launching virtual machine \"$vmname\" ..." 188 | 189 | first_diskdev="$disk_dev0" 190 | 191 | ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1 192 | 193 | while [ 1 ]; do 194 | 195 | file -s ${first_diskdev} | grep "boot sector" > /dev/null 196 | rc=$? 197 | if [ $rc -ne 0 ]; then 198 | file -s ${first_diskdev} | grep ": Unix Fast File sys" > /dev/null 199 | rc=$? 200 | fi 201 | if [ $rc -ne 0 ]; then 202 | need_install=1 203 | else 204 | need_install=0 205 | fi 206 | 207 | if [ $force_install -eq 1 -o $need_install -eq 1 ]; then 208 | if [ ! -r ${isofile} ]; then 209 | echo -n "Installation CDROM image \"${isofile}\" " 210 | echo "is not readable" 211 | exit 1 212 | fi 213 | BOOTDISKS="-d ${isofile}" 214 | installer_opt="-s 31:0,ahci-cd,${isofile}" 215 | else 216 | BOOTDISKS="" 217 | i=0 218 | while [ $i -lt $disk_total ] ; do 219 | eval "disk=\$disk_dev${i}" 220 | if [ -r ${disk} ] ; then 221 | BOOTDISKS="$BOOTDISKS -d ${disk} " 222 | fi 223 | i=$(($i + 1)) 224 | done 225 | installer_opt="" 226 | fi 227 | 228 | ${LOADER} -c ${console} -m ${memsize} ${BOOTDISKS} ${loader_opt} \ 229 | ${vmname} 230 | bhyve_exit=$? 231 | if [ $bhyve_exit -ne 0 ]; then 232 | break 233 | fi 234 | 235 | # 236 | # Build up args for additional tap and disk devices now. 237 | # 238 | nextslot=2 # slot 0 is hostbridge, slot 1 is lpc 239 | devargs="" # accumulate disk/tap args here 240 | i=0 241 | while [ $i -lt $tap_total ] ; do 242 | eval "tapname=\$tap_dev${i}" 243 | devargs="$devargs -s $nextslot:0,virtio-net,${tapname} " 244 | nextslot=$(($nextslot + 1)) 245 | i=$(($i + 1)) 246 | done 247 | 248 | i=0 249 | while [ $i -lt $disk_total ] ; do 250 | eval "disk=\$disk_dev${i}" 251 | eval "opts=\$disk_opts${i}" 252 | make_and_check_diskdev "${disk}" 253 | devargs="$devargs -s $nextslot:0,virtio-blk,${disk}${opts} " 254 | nextslot=$(($nextslot + 1)) 255 | i=$(($i + 1)) 256 | done 257 | 258 | i=0 259 | while [ $i -lt $pass_total ] ; do 260 | eval "pass=\$pass_dev${i}" 261 | devargs="$devargs -s $nextslot:0,passthru,${pass} " 262 | nextslot=$(($nextslot + 1)) 263 | i=$(($i + 1)) 264 | done 265 | 266 | if kldstat -qm nmdm; then 267 | devargs="$devargs -l com2,/dev/nmdm${vmname}2B " 268 | fi 269 | devargs="$devargs -s $nextslot:0,virtio-rnd " 270 | nextslot=$(($nextslot + 1)) 271 | 272 | ${FBSDRUN} -b -c ${cpus} -m ${memsize} ${apic_opt} -A -H -P \ 273 | -g ${gdbport} \ 274 | -s 0:0,hostbridge \ 275 | -s 1:0,lpc \ 276 | ${devargs} \ 277 | -l com1,${console} \ 278 | ${installer_opt} \ 279 | ${vmname} 280 | 281 | bhyve_exit=$? 282 | # bhyve returns the following status codes: 283 | # 0 - VM has been reset 284 | # 1 - VM has been powered off 285 | # 2 - VM has been halted 286 | # 3 - VM generated a triple fault 287 | # all other non-zero status codes are errors 288 | # 289 | if [ $bhyve_exit -ne 0 ]; then 290 | break 291 | fi 292 | done 293 | 294 | 295 | case $bhyve_exit in 296 | 0|1|2) 297 | # Cleanup /dev/vmm entry when bhyve did not exit 298 | # due to an error. 299 | ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1 300 | ;; 301 | esac 302 | 303 | exit $bhyve_exit 304 | -------------------------------------------------------------------------------- /bhyve/vmrun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | # 5 | # Copyright (c) 2013 NetApp, Inc. 6 | # All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions 10 | # are met: 11 | # 1. Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in the 15 | # documentation and/or other materials provided with the distribution. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | # SUCH DAMAGE. 28 | # 29 | # 30 | 31 | GRUB=/usr/local/sbin/grub-bhyve 32 | LOADER=/usr/sbin/bhyveload 33 | BHYVECTL=/usr/sbin/bhyvectl 34 | FBSDRUN=/usr/sbin/bhyve 35 | 36 | DEFAULT_MEMSIZE=512M 37 | DEFAULT_CPUS=2 38 | DEFAULT_TAPDEV=tap0 39 | DEFAULT_CONSOLE=stdio 40 | 41 | DEFAULT_NIC=virtio-net 42 | DEFAULT_DISK=virtio-blk 43 | DEFAULT_VIRTIO_DISK="./diskdev" 44 | DEFAULT_ISOFILE="./release.iso" 45 | 46 | DEFAULT_VNCHOST="127.0.0.1" 47 | DEFAULT_VNCPORT=5900 48 | DEFAULT_VNCSIZE="w=1024,h=768" 49 | 50 | errmsg() { 51 | echo "*** $1" 52 | } 53 | 54 | usage() { 55 | local msg=$1 56 | 57 | echo "Usage: vmrun.sh [-aAEghiTuvw] [-c ] [-C ]" \ 58 | "[-d ]" 59 | echo " [-e ] [-f ]" \ 60 | "[-F ]" 61 | echo " [-G [w][address:]port] [-H ]" 62 | echo " [-I ] [-l ]" 63 | echo " [-L ]" 64 | echo " [-m ]" \ 65 | "[-n ]" 66 | echo " [-p ]" 67 | echo " [-P ] [-t ] " 68 | echo "" 69 | echo " -h: display this help message" 70 | echo " -a: force memory mapped local APIC access" 71 | echo " -A: use AHCI disk emulation instead of ${DEFAULT_DISK}" 72 | echo " -c: number of virtual cpus (default: ${DEFAULT_CPUS})" 73 | echo " -C: console device (default: ${DEFAULT_CONSOLE})" 74 | echo " -d: virtio diskdev file (default: ${DEFAULT_VIRTIO_DISK})" 75 | echo " -e: set FreeBSD loader environment variable" 76 | echo " -E: Use UEFI mode (amd64 only)" 77 | echo " -f: Use a specific boot firmware (e.g., EDK2, U-Boot)" 78 | echo " -F: Use a custom UEFI GOP framebuffer size" \ 79 | "(default: ${DEFAULT_VNCSIZE}) (amd64 only)" 80 | echo " -g: Use grub-bhyve (amd64 only)" 81 | echo " -G: bind the GDB stub to the specified address" 82 | echo " -H: host filesystem to export to the loader" 83 | echo " -i: force boot of the Installation CDROM image" 84 | echo " -I: Installation CDROM image location" \ 85 | "(default: ${DEFAULT_ISOFILE})" 86 | echo " -l: the OS loader to use (default: /boot/userboot.so) (amd64 only)" 87 | echo " -L: IP address for UEFI GOP VNC server" \ 88 | "(default: ${DEFAULT_VNCHOST})" 89 | echo " -m: memory size (default: ${DEFAULT_MEMSIZE})" 90 | echo " -n: network adapter emulation type" \ 91 | "(default: ${DEFAULT_NIC})" 92 | echo " -p: pass-through a host PCI device (e.g ppt0 or" \ 93 | "bus/slot/func) (amd64 only)" 94 | echo " -P: UEFI GOP VNC port (default: ${DEFAULT_VNCPORT})" 95 | echo " -t: tap device for virtio-net (default: $DEFAULT_TAPDEV)" 96 | echo " -T: Enable tablet device (for UEFI GOP) (amd64 only)" 97 | echo " -u: RTC keeps UTC time" 98 | echo " -v: Wait for VNC client connection before booting VM" 99 | echo " -w: ignore unimplemented MSRs (amd64 only)" 100 | echo "" 101 | [ -n "$msg" ] && errmsg "$msg" 102 | exit 1 103 | } 104 | 105 | if [ `id -u` -ne 0 ]; then 106 | errmsg "This script must be executed with superuser privileges" 107 | exit 1 108 | fi 109 | 110 | kldstat -n vmm > /dev/null 2>&1 111 | if [ $? -ne 0 ]; then 112 | errmsg "vmm.ko is not loaded" 113 | exit 1 114 | fi 115 | 116 | platform=$(uname -m) 117 | if [ "${platform}" != amd64 -a "${platform}" != arm64 ]; then 118 | errmsg "This script is only supported on amd64 and arm64 platforms" 119 | exit 1 120 | fi 121 | 122 | force_install=0 123 | isofile=${DEFAULT_ISOFILE} 124 | memsize=${DEFAULT_MEMSIZE} 125 | console=${DEFAULT_CONSOLE} 126 | cpus=${DEFAULT_CPUS} 127 | nic=${DEFAULT_NIC} 128 | tap_total=0 129 | disk_total=0 130 | disk_emulation=${DEFAULT_DISK} 131 | loader_opt="" 132 | pass_total=0 133 | use_grub= 134 | 135 | # EFI-specific options 136 | efi_mode=0 137 | efi_firmware="/usr/local/share/uefi-firmware/BHYVE_UEFI.fd" 138 | vncwait="" 139 | vnchost=${DEFAULT_VNCHOST} 140 | vncport=${DEFAULT_VNCPORT} 141 | vncsize=${DEFAULT_VNCSIZE} 142 | tablet="" 143 | 144 | # arm64 only 145 | uboot_firmware="/usr/local/share/u-boot/u-boot-bhyve-arm64/u-boot.bin" 146 | 147 | case ${platform} in 148 | amd64) 149 | bhyverun_opt="-H -P" 150 | opts="aAc:C:d:e:Ef:F:gG:hH:iI:l:L:m:n:p:P:t:Tuvw" 151 | ;; 152 | arm64) 153 | bhyverun_opt="" 154 | opts="aAc:C:d:e:f:F:G:hH:iI:L:m:n:P:t:uv" 155 | ;; 156 | esac 157 | 158 | while getopts $opts c ; do 159 | case $c in 160 | a) 161 | bhyverun_opt="${bhyverun_opt} -a" 162 | ;; 163 | A) 164 | disk_emulation="ahci-hd" 165 | ;; 166 | c) 167 | cpus=${OPTARG} 168 | ;; 169 | C) 170 | console=${OPTARG} 171 | ;; 172 | d) 173 | disk_dev=${OPTARG%%,*} 174 | disk_opts=${OPTARG#${disk_dev}} 175 | eval "disk_dev${disk_total}=\"${disk_dev}\"" 176 | eval "disk_opts${disk_total}=\"${disk_opts}\"" 177 | disk_total=$(($disk_total + 1)) 178 | ;; 179 | e) 180 | loader_opt="${loader_opt} -e ${OPTARG}" 181 | ;; 182 | E) 183 | efi_mode=1 184 | ;; 185 | f) 186 | firmware="${OPTARG}" 187 | ;; 188 | F) 189 | vncsize="${OPTARG}" 190 | ;; 191 | g) 192 | use_grub=1 193 | ;; 194 | G) 195 | bhyverun_opt="${bhyverun_opt} -G ${OPTARG}" 196 | ;; 197 | H) 198 | host_base=`realpath ${OPTARG}` 199 | ;; 200 | i) 201 | force_install=1 202 | ;; 203 | I) 204 | isofile=${OPTARG} 205 | ;; 206 | l) 207 | loader_opt="${loader_opt} -l ${OPTARG}" 208 | ;; 209 | L) 210 | vnchost="${OPTARG}" 211 | ;; 212 | m) 213 | memsize=${OPTARG} 214 | ;; 215 | n) 216 | nic=${OPTARG} 217 | ;; 218 | p) 219 | eval "pass_dev${pass_total}=\"${OPTARG}\"" 220 | pass_total=$(($pass_total + 1)) 221 | ;; 222 | P) 223 | vncport="${OPTARG}" 224 | ;; 225 | t) 226 | eval "tap_dev${tap_total}=\"${OPTARG}\"" 227 | tap_total=$(($tap_total + 1)) 228 | ;; 229 | T) 230 | tablet="-s 30,xhci,tablet" 231 | ;; 232 | u) 233 | bhyverun_opt="${bhyverun_opt} -u" 234 | ;; 235 | v) 236 | vncwait=",wait" 237 | ;; 238 | w) 239 | bhyverun_opt="${bhyverun_opt} -w" 240 | ;; 241 | *) 242 | usage 243 | ;; 244 | esac 245 | done 246 | 247 | if [ $tap_total -eq 0 ] ; then 248 | tap_total=1 249 | tap_dev0="${DEFAULT_TAPDEV}" 250 | fi 251 | if [ $disk_total -eq 0 ] ; then 252 | disk_total=1 253 | disk_dev0="${DEFAULT_VIRTIO_DISK}" 254 | 255 | fi 256 | 257 | shift $((${OPTIND} - 1)) 258 | 259 | if [ $# -ne 1 ]; then 260 | usage "virtual machine name not specified" 261 | fi 262 | 263 | vmname="$1" 264 | if [ -n "${host_base}" ]; then 265 | loader_opt="${loader_opt} -h ${host_base}" 266 | fi 267 | 268 | # If PCI passthru devices are configured then guest memory must be wired 269 | if [ ${pass_total} -gt 0 ]; then 270 | loader_opt="${loader_opt} -S" 271 | bhyverun_opt="${bhyverun_opt} -S" 272 | fi 273 | 274 | if [ ${efi_mode} -eq 1 -a -n "$use_grub" ]; then 275 | echo "Error: both EFI and grub enabled" 276 | exit 1 277 | fi 278 | 279 | if [ -z "$firmware" ]; then 280 | case ${platform} in 281 | amd64) 282 | firmware="${efi_firmware}" 283 | firmware_pkg="edk2-bhyve" 284 | ;; 285 | arm64) 286 | firmware="${uboot_firmware}" 287 | firmware_pkg="u-boot-bhyve-arm64" 288 | ;; 289 | esac 290 | fi 291 | 292 | if [ -n "${firmware}" -a ! -f "${firmware}" ]; then 293 | echo "Error: Firmware file ${firmware} doesn't exist." 294 | if [ -n "${firmware_pkg}" ]; then 295 | echo " Try: pkg install ${firmware_pkg}" 296 | fi 297 | exit 1 298 | fi 299 | 300 | make_and_check_diskdev() 301 | { 302 | local virtio_diskdev="$1" 303 | # Create the virtio diskdev file if needed 304 | if [ ! -e ${virtio_diskdev} ]; then 305 | echo "virtio disk device file \"${virtio_diskdev}\" does not exist." 306 | echo "Creating it ..." 307 | truncate -s 8G ${virtio_diskdev} > /dev/null 308 | fi 309 | 310 | if [ ! -r ${virtio_diskdev} ]; then 311 | echo "virtio disk device file \"${virtio_diskdev}\" is not readable" 312 | exit 1 313 | fi 314 | 315 | if [ ! -w ${virtio_diskdev} ]; then 316 | echo "virtio disk device file \"${virtio_diskdev}\" is not writable" 317 | exit 1 318 | fi 319 | } 320 | 321 | echo "Launching virtual machine \"$vmname\" ..." 322 | 323 | first_diskdev="$disk_dev0" 324 | 325 | ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1 326 | 327 | while [ 1 ]; do 328 | 329 | if [ -n "$use_grub" ]; then 330 | device_map=`mktemp -t grub-bhyve` || exit 1 331 | fi 332 | 333 | file -s ${first_diskdev} | grep "boot sector" > /dev/null 334 | rc=$? 335 | if [ $rc -ne 0 ]; then 336 | file -s ${first_diskdev} | \ 337 | grep ": Unix Fast File sys" > /dev/null 338 | rc=$? 339 | fi 340 | if [ $rc -ne 0 ]; then 341 | need_install=1 342 | else 343 | need_install=0 344 | fi 345 | 346 | if [ $force_install -eq 1 -o $need_install -eq 1 ]; then 347 | if [ ! -r ${isofile} ]; then 348 | echo -n "Installation CDROM image \"${isofile}\" " 349 | echo "is not readable" 350 | exit 1 351 | fi 352 | BOOTDISKS="-d ${isofile}" 353 | installer_opt="-s 31:0,ahci-cd,${isofile}" 354 | if [ -n "$device_map" ]; then 355 | echo "(cd0) ${isofile}" >> ${device_map} 356 | loader_opt="${loader_opt} -r cd0" 357 | fi 358 | else 359 | BOOTDISKS="" 360 | i=0 361 | while [ $i -lt $disk_total ] ; do 362 | eval "disk=\$disk_dev${i}" 363 | if [ -r ${disk} ] ; then 364 | BOOTDISKS="$BOOTDISKS -d ${disk} " 365 | if [ -n "$device_map" ]; then 366 | echo "(hd${i}) ${disk}" >> ${device_map} 367 | fi 368 | fi 369 | i=$(($i + 1)) 370 | done 371 | if [ -n "$device_map" ]; then 372 | loader_opt="${loader_opt} -r hd0,msdos1" 373 | fi 374 | installer_opt="" 375 | fi 376 | 377 | if [ ${platform} = amd64 -a ${efi_mode} -eq 0 ]; then 378 | if [ -n "$use_grub" ]; then 379 | if [ "${console}" != "stdio" ]; then 380 | loader_opt="${loader_opt} -c ${console}" 381 | fi 382 | ${GRUB} -M ${memsize} -m ${device_map} \ 383 | ${loader_opt} ${vmname} 384 | rm ${device_map} 385 | device_map= 386 | else 387 | ${LOADER} -c ${console} -m ${memsize} ${BOOTDISKS} \ 388 | ${loader_opt} ${vmname} 389 | fi 390 | bhyve_exit=$? 391 | if [ $bhyve_exit -ne 0 ]; then 392 | break 393 | fi 394 | fi 395 | 396 | # 397 | # Build up args for additional tap and disk devices now. 398 | # 399 | devargs="-s 0:0,hostbridge" # accumulate disk/tap args here 400 | case ${platform} in 401 | amd64) 402 | console_opt="-l com1,${console}" 403 | devargs="$devargs -s 1:0,lpc " 404 | nextslot=2 # slot 0 is hostbridge, slot 1 is lpc 405 | ;; 406 | arm64) 407 | console_opt="-o console=${console}" 408 | devargs="$devargs -o bootrom=${firmware} " 409 | nextslot=1 # slot 0 is hostbridge 410 | ;; 411 | esac 412 | 413 | i=0 414 | while [ $i -lt $disk_total ] ; do 415 | eval "disk=\$disk_dev${i}" 416 | eval "opts=\$disk_opts${i}" 417 | make_and_check_diskdev "${disk}" 418 | devargs="$devargs -s $nextslot:0,$disk_emulation,${disk}${opts} " 419 | nextslot=$(($nextslot + 1)) 420 | i=$(($i + 1)) 421 | done 422 | 423 | i=0 424 | while [ $i -lt $tap_total ] ; do 425 | eval "tapname=\$tap_dev${i}" 426 | devargs="$devargs -s $nextslot:0,${nic},${tapname} " 427 | nextslot=$(($nextslot + 1)) 428 | i=$(($i + 1)) 429 | done 430 | 431 | i=0 432 | while [ $i -lt $pass_total ] ; do 433 | eval "pass=\$pass_dev${i}" 434 | bsfform="$(echo "${pass}" | grep "^[0-9]\+/[0-9]\+/[0-9]\+$")" 435 | if [ -z "${bsfform}" ]; then 436 | bsf="$(pciconf -l "${pass}" 2>/dev/null)" 437 | if [ $? -ne 0 ]; then 438 | errmsg "${pass} is not a host PCI device" 439 | exit 1 440 | fi 441 | bsf="$(echo "${bsf}" | awk -F: '{print $2"/"$3"/"$4}')" 442 | else 443 | bsf="${pass}" 444 | fi 445 | devargs="$devargs -s $nextslot:0,passthru,${bsf} " 446 | nextslot=$(($nextslot + 1)) 447 | i=$(($i + 1)) 448 | done 449 | 450 | efiargs="" 451 | if [ ${efi_mode} -gt 0 ]; then 452 | efiargs="-s 29,fbuf,tcp=${vnchost}:${vncport}," 453 | efiargs="${efiargs}${vncsize}${vncwait}" 454 | efiargs="${efiargs} -l bootrom,${firmware}" 455 | efiargs="${efiargs} ${tablet}" 456 | fi 457 | 458 | if kldstat -qm nmdm; then 459 | devargs="$devargs -l com2,/dev/nmdm${vmname}2B " 460 | fi 461 | devargs="$devargs -s $nextslot:0,virtio-rnd " 462 | nextslot=$(($nextslot + 1)) 463 | 464 | ${FBSDRUN} -c ${cpus} -m ${memsize} ${bhyverun_opt} \ 465 | ${efiargs} \ 466 | ${devargs} \ 467 | ${console_opt} \ 468 | ${installer_opt} \ 469 | ${vmname} 470 | 471 | bhyve_exit=$? 472 | # bhyve returns the following status codes: 473 | # 0 - VM has been reset 474 | # 1 - VM has been powered off 475 | # 2 - VM has been halted 476 | # 3 - VM generated a triple fault 477 | # all other non-zero status codes are errors 478 | # 479 | if [ $bhyve_exit -ne 0 ]; then 480 | break 481 | fi 482 | done 483 | 484 | 485 | case $bhyve_exit in 486 | 0|1|2) 487 | # Cleanup /dev/vmm entry when bhyve did not exit 488 | # due to an error. 489 | ${BHYVECTL} --vm=${vmname} --destroy > /dev/null 2>&1 490 | ;; 491 | esac 492 | 493 | exit $bhyve_exit 494 | -------------------------------------------------------------------------------- /dtrace/callout_funcs.d: -------------------------------------------------------------------------------- 1 | callout_execute:::callout-start 2 | { 3 | self->start = timestamp; 4 | self->func = args[0]->c_func; 5 | @funcs[self->func] = count(); 6 | } 7 | 8 | callout_execute:::callout-end 9 | { 10 | @functimes[self->func] = sum(timestamp - self->start); 11 | } 12 | 13 | END 14 | { 15 | printf("\n\nCallout function counts:\n"); 16 | printa("%@8u %a\n", @funcs); 17 | printf("\nCallout function runtime:\n"); 18 | printa("%@d %a\n", @functimes); 19 | } 20 | -------------------------------------------------------------------------------- /dtrace/crypto_drivers.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | fbt::crypto_invoke:entry 4 | { 5 | @[stringof(((struct cryptocap *)arg0)->cc_dev->nameunit)] = count(); 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /dtrace/crypto_new_session.d: -------------------------------------------------------------------------------- 1 | fbt::crypto_newsession:entry 2 | { 3 | print(*args[1]); 4 | } 5 | 6 | fbt::crypto_newsession:return 7 | /arg1 != 0/ 8 | { 9 | printf("returned %d", arg1); 10 | } 11 | 12 | fbt::crypto_checkdriver:entry 13 | { 14 | printf("(0x%x)", arg1) 15 | } 16 | 17 | fbt::crypto_checkdriver:return 18 | { 19 | printf("=> %p", (void *)arg1) 20 | } 21 | 22 | fbt::crypto_select_driver:entry 23 | { 24 | printf("(%p, 0x%x)", arg1, arg2) 25 | } 26 | 27 | fbt::crypto_select_driver:return 28 | { 29 | printf("=> %p", (void *)arg1) 30 | } 31 | 32 | /* 33 | fbt::driver_suitable:entry 34 | { 35 | printf("(%p, %p)", arg1, arg2); 36 | } 37 | 38 | fbt::driver_suitable:return 39 | { 40 | printf("=> %d", arg1) 41 | } 42 | */ 43 | 44 | fbt::swcr_setup_auth:return 45 | /arg1 != 0/ 46 | { 47 | printf("returned %d", arg1); 48 | } 49 | 50 | fbt::swcr_setup_cipher:return 51 | /arg1 != 0/ 52 | { 53 | printf("returned %d", arg1); 54 | } 55 | 56 | /* 57 | fbt::swcr_setup_gcm:return 58 | /arg1 != 0/ 59 | { 60 | printf("returned %d", arg1); 61 | } 62 | */ 63 | 64 | fbt::swcr_probesession:return 65 | { 66 | printf("returned %d", arg1); 67 | } 68 | 69 | fbt::check_csp:return 70 | { 71 | printf("returned %d", arg1); 72 | } 73 | 74 | fbt::swcr_newsession:entry 75 | { 76 | printf("called"); 77 | } 78 | 79 | fbt::swcr_newsession:return 80 | /arg1 != 0/ 81 | { 82 | printf("returned %d", arg1); 83 | } 84 | 85 | /* 86 | fbt::ccr_aes_setkey:return 87 | /arg1 != 0/ 88 | { 89 | printf("returned %d", arg1); 90 | } 91 | */ 92 | 93 | fbt::ccr_probesession:return 94 | { 95 | printf("returned %d", arg1); 96 | } 97 | 98 | fbt::ccr_newsession:return 99 | /arg1 != 0/ 100 | { 101 | printf("returned %d", arg1); 102 | } 103 | 104 | fbt::aesni_probesession:return 105 | { 106 | printf("returned %d", arg1); 107 | } 108 | 109 | fbt::aesni_newsession:return 110 | /arg1 != 0/ 111 | { 112 | printf("returned %d", arg1); 113 | } 114 | 115 | fbt::isal_probesession:return 116 | { 117 | printf("returned %d", arg1); 118 | } 119 | 120 | fbt::isal_newsession:return 121 | /arg1 != 0/ 122 | { 123 | printf("returned %d", arg1); 124 | } 125 | 126 | fbt::ossl_probesession:return 127 | { 128 | printf("returned %d", arg1); 129 | } 130 | 131 | fbt::ossl_newsession:return 132 | /arg1 != 0/ 133 | { 134 | printf("returned %d", arg1); 135 | } 136 | -------------------------------------------------------------------------------- /dtrace/eperm.d: -------------------------------------------------------------------------------- 1 | syscall::lstat:entry 2 | { 3 | self->trace = 1 4 | } 5 | 6 | syscall:::return 7 | { 8 | self->trace = 0 9 | } 10 | 11 | fbt::namei:return 12 | /self->trace == 1 && curthread->td_proc->p_comm == "stat"/ 13 | { 14 | printf("namei returned %d", arg1); 15 | } 16 | 17 | fbt::vn_stat:return 18 | /self->trace == 1 && curthread->td_proc->p_comm == "stat"/ 19 | { 20 | printf("vn_stat returned %d", arg1); 21 | } 22 | 23 | fbt:::return 24 | /self->trace == 2 && arg1 == EPERM && curthread->td_proc->p_comm == "stat"/ 25 | { 26 | printf("%s returned EPERM.", probefunc); 27 | } 28 | -------------------------------------------------------------------------------- /dtrace/g_media.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | /* /args[0] == g_new_provider_event/ */ 4 | fbt::g_post_event:entry 5 | { 6 | printf("geom event scheduled by pid %d (%s)", 7 | curthread->td_proc->p_pid, curthread->td_proc->p_comm); 8 | /* stack(); */ 9 | } 10 | 11 | /* / arg0 == 4 / */ 12 | 13 | fbt::spa_async_request:entry 14 | { 15 | printf("SPA_PROBE requested by pid %d (%s)", 16 | curthread->td_proc->p_pid, curthread->td_proc->p_comm); 17 | stack(); 18 | } 19 | -------------------------------------------------------------------------------- /dtrace/ipmi_req.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | fbt::ipmi_ioctl:entry 4 | { 5 | printf("IPMI request by pid %d (%s)", 6 | curthread->td_proc->p_pid, curthread->td_proc->p_comm); 7 | /* stack(); */ 8 | } 9 | -------------------------------------------------------------------------------- /dtrace/make_ktr: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sort -k 2nrb $1 | cat -n > $2 4 | 5 | -------------------------------------------------------------------------------- /dtrace/rendezvous.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | /* /args[0] == g_new_provider_event/ */ 4 | fbt::smp_rendezvous_cpus:entry 5 | { 6 | @stacks[stack()] = count(); 7 | @counts[execname, curthread->td_proc->p_pid] = count(); 8 | } 9 | -------------------------------------------------------------------------------- /dtrace/schedgraph.d: -------------------------------------------------------------------------------- 1 | #pragma D option quiet 2 | #pragma D option bufpolicy=ring 3 | 4 | inline int TDF_IDLETD = 0x00000020; 5 | 6 | /* 7 | * Reasons that the current thread can not be run yet. 8 | * More than one may apply. 9 | */ 10 | inline int TDI_SUSPENDED = 0x0001; /* On suspension queue. */ 11 | inline int TDI_SLEEPING = 0x0002; /* Actually asleep! (tricky). */ 12 | inline int TDI_SWAPPED = 0x0004; /* Stack not in mem. Bad juju if run. */ 13 | inline int TDI_LOCK = 0x0008; /* Stopped on a lock. */ 14 | inline int TDI_IWAIT = 0x0010; /* Awaiting interrupt. */ 15 | 16 | inline string KTDSTATE[struct thread * td] = \ 17 | (((td)->td_inhibitors & TDI_SLEEPING) != 0 ? "sleep" : \ 18 | ((td)->td_inhibitors & TDI_SUSPENDED) != 0 ? "suspended" : \ 19 | ((td)->td_inhibitors & TDI_SWAPPED) != 0 ? "swapped" : \ 20 | ((td)->td_inhibitors & TDI_LOCK) != 0 ? "blocked" : \ 21 | ((td)->td_inhibitors & TDI_IWAIT) != 0 ? "iwait" : "yielding"); 22 | 23 | inline int NOCPU = 0xff; 24 | 25 | sched:::load-change 26 | / args[0] == NOCPU / 27 | { 28 | printf("%d %d KTRGRAPH group:\"load\", id:\"global load\", counter:\"%d\", attributes: \"none\"\n", cpu, timestamp, args[1]); 29 | } 30 | 31 | sched:::load-change 32 | / args[0] != NOCPU / 33 | { 34 | printf("%d %d KTRGRAPH group:\"load\", id:\"CPU %d load\", counter:\"%d\", attributes: \"none\"\n", cpu, timestamp, args[0], args[1]); 35 | 36 | } 37 | 38 | proc:::exit 39 | { 40 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"proc exit\", attributes: prio:td\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid); 41 | } 42 | 43 | proc:::lwp-exit 44 | { 45 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"exit\", attributes: prio:td\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid); 46 | } 47 | 48 | sched:::change-pri 49 | { 50 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", point:\"priority change\", attributes: prio:%d, new prio:%d, linkedto:\"%s/%s tid %d\"\n", cpu, timestamp, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid, args[0]->td_priority, arg2, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid); 51 | } 52 | 53 | sched:::lend-pri 54 | { 55 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", point:\"lend prio\", attributes: prio:%d, new prio:%d, linkedto:\"%s/%s tid %d\"\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid, args[0]->td_priority, arg2, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid); 56 | } 57 | 58 | sched:::enqueue 59 | { 60 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"runq add\", attributes: prio:%d, linkedto:\"%s/%s tid %d\"\n", cpu, timestamp, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid, args[0]->td_priority, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid); 61 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", point:\"wokeup\", attributes: linkedto:\"%s/%s tid %d\"\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid); 62 | } 63 | 64 | sched:::dequeue 65 | { 66 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"runq rem\", attributes: prio:%d, linkedto:\"%s/%s tid %d\"\n", cpu, timestamp, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid, args[0]->td_priority, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid); 67 | } 68 | 69 | sched:::tick 70 | { 71 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", point:\"statclock\", attributes: prio:%d, stathz:%d\n", cpu, timestamp, args[0]->td_proc->p_comm, args[0]->td_name, args[0]->td_tid, args[0]->td_priority, `stathz ? `stathz : `hz); 72 | } 73 | 74 | sched:::off-cpu 75 | / curthread->td_flags & TDF_IDLETD / 76 | { 77 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"idle\", attributes: prio:%d\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid, curthread->td_priority); 78 | } 79 | 80 | sched:::off-cpu 81 | / (curthread->td_flags & TDF_IDLETD) == 0 / 82 | { 83 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"%s\", attributes: prio:%d, wmesg:\"%s\", lockname:\"%s\"\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid, KTDSTATE[curthread], curthread->td_priority, curthread->td_wmesg ? stringof(curthread->td_wmesg) : "(null)", curthread->td_lockname ? stringof(curthread->td_lockname) : "(null)"); 84 | } 85 | 86 | sched:::on-cpu 87 | { 88 | printf("%d %d KTRGRAPH group:\"thread\", id:\"%s/%s tid %d\", state:\"running\", attributes: prio:%d\n", cpu, timestamp, curthread->td_proc->p_comm, curthread->td_name, curthread->td_tid, curthread->td_priority); 89 | } 90 | 91 | callout_execute:::callout-start 92 | { 93 | printf("%d %d KTRGRAPH group:\"callout\", id:\"callout %s\", state:\"running\", attributes: func:%a, arg:%p\n", cpu, timestamp, curthread->td_name, args[0]->c_func, args[0]->c_arg); 94 | } 95 | 96 | callout_execute:::callout-end 97 | { 98 | printf("%d %d KTRGRAPH group:\"callout\", id:\"callout %s\", state:\"idle\", attributes: \"none\"\n", cpu, timestamp, curthread->td_name); 99 | } 100 | 101 | tick-5s 102 | { 103 | exit(0); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /dtrace/set_regs_diff.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python 2 | 3 | import re 4 | import subprocess 5 | import sys 6 | 7 | class States: 8 | Init, Entry, Middle, Return = range(4) 9 | 10 | dscript = """ 11 | fbt::set_regs:entry 12 | { 13 | self->td = args[0]; 14 | printf("entry:\\n"); 15 | print(*self->td->td_frame); 16 | printf("\\n"); 17 | } 18 | 19 | fbt::set_regs:return 20 | { 21 | printf("return:\\n"); 22 | print(*self->td->td_frame); 23 | printf("\\n"); 24 | } 25 | """ 26 | 27 | tracer = subprocess.Popen(['stdbuf', '-o', 'L', 'dtrace', '-q', '-n', dscript], 28 | close_fds=True, stdout=subprocess.PIPE) 29 | reg_re = re.compile('\s+.* (\w+) = (\w+)') 30 | 31 | state = States.Init 32 | while True: 33 | line = tracer.stdout.readline() 34 | if line == '': 35 | break 36 | line = line.rstrip() 37 | if line == 'entry:': 38 | assert state == States.Init 39 | state = States.Entry 40 | before = {} 41 | regs = before 42 | elif line == 'return:': 43 | assert state == States.Middle 44 | state = States.Return 45 | after = {} 46 | regs = after 47 | elif line == 'struct trapframe {': 48 | assert len(regs) == 0 49 | elif line == '}': 50 | if state == States.Entry: 51 | state = States.Middle 52 | else: 53 | assert state == States.Return 54 | assert len(before) == len(after) 55 | print "set_regs() changes:" 56 | for reg in before.keys(): 57 | assert reg in after 58 | if before[reg] == after[reg]: 59 | continue 60 | print " %s: %s => %s" % (reg, before[reg], after[reg]) 61 | state = States.Init 62 | else: 63 | m = reg_re.match(line) 64 | if m == None: 65 | print "Invalid line: %s" % (line) 66 | sys.exit(1) 67 | if m.group(1) in regs: 68 | print "Duplicate register: %s" % (m.group[1]) 69 | sys.exit(1) 70 | regs[m.group(1)] = m.group(2) 71 | -------------------------------------------------------------------------------- /dtrace/syscall_error.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | /* 4 | * $1 = system call to look for errors 5 | * $2 = error value to find 6 | * $3 = binary name 7 | */ 8 | 9 | syscall::$$1:entry 10 | /curthread->td_proc->p_comm == $$3/ 11 | { 12 | self->trace = 1 13 | } 14 | 15 | syscall:::return 16 | /self->trace == 1/ 17 | { 18 | self->trace = 0 19 | } 20 | 21 | fbt:::return 22 | /self->trace == 1 && arg1 == $2/ 23 | { 24 | printf("%s returned %d.", probefunc, $2); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /dtrace/syscalls.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | syscall:::entry 4 | { 5 | @counts[probefunc] = count() 6 | } -------------------------------------------------------------------------------- /dtrace/vfsfilt.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -s 2 | 3 | fbt::filt_vfsvnode:entry 4 | { 5 | printf("vnode filter %#x for %p", args[1], args[0]->kn_hook); 6 | } -------------------------------------------------------------------------------- /gdb/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Setup a build env and build gdb similar to how ports builds it 4 | 5 | usage() 6 | { 7 | cat <&1` 225 | if [ $? -ne 0 ]; then 226 | echo "Compilers are not executable:" 227 | echo " CC=${CC}" 228 | echo " CXX=${CXX}" 229 | exit 1 230 | fi 231 | 232 | CFLAGS="-pipe -g -O2 -fno-strict-aliasing -fcommon" 233 | CFLAGS="${CFLAGS} -Wno-unused-function -Wno-unused-variable" 234 | 235 | if echo "${cc_version}" | grep -q clang ; then 236 | # clang-specific warnings to disable 237 | CFLAGS="${CFLAGS} -Wno-absolute-value" 238 | CFLAGS="${CFLAGS} -Wno-parentheses-equality" 239 | CFLAGS="${CFLAGS} -Wno-unknown-warning-option" 240 | 241 | if [ -n "${CLANG_TARGET}" ]; then 242 | CC_FLAGS="-target ${CLANG_TARGET} ${CC_FLAGS}" 243 | fi 244 | CC_FLAGS="${CC_FLAGS} ${CLANG_CC_FLAGS}" 245 | LDFLAGS="${LDFLAGS} -fuse-ld=lld" 246 | fi 247 | if [ -n "${ROOTFS}" ]; then 248 | CC_FLAGS="${CC_FLAGS} --sysroot=${ROOTFS}" 249 | CONFIGURE_ARGS="--with-build-sysroot=${ROOTFS}" 250 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-rpath" 251 | fi 252 | 253 | if [ -n "${GMP_PATH}" ]; then 254 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-gmp=${ROOTFS}${GMP_PATH}" 255 | fi 256 | if [ -n "${MPFR_PATH}" ]; then 257 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-mpfr=${ROOTFS}${MPFR_PATH}" 258 | fi 259 | CC="${CC} ${CC_FLAGS}" 260 | CXX="${CXX} ${CC_FLAGS}" 261 | 262 | if [ -n "${AR}" ]; then 263 | CONFIGURE_ENV="${CONFIGURE_ENV} AR=${AR}" 264 | fi 265 | 266 | if [ -n "${WITH_UBSAN}" ]; then 267 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-ubsan" 268 | else 269 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-ubsan" 270 | fi 271 | 272 | if [ -n "${PYTHON}" ]; then 273 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-python=${PYTHON}" 274 | else 275 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --without-python" 276 | fi 277 | 278 | if [ -n "${HOST}" ]; then 279 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --without-expat" 280 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-source-highlight" 281 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-sim" 282 | CONFIGURE_ENV="${CONFIGURE_ENV} gl_cv_func_gettimeofday_clobber=no" 283 | if echo "$HOST" | grep -q freebsd; then 284 | FREEBSD_HOST=yes 285 | fi 286 | else 287 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-expat" 288 | FREEBSD_HOST=yes 289 | fi 290 | 291 | if [ -n "${FREEBSD_HOST}" ]; then 292 | CFLAGS="${CFLAGS} -DRL_NO_COMPAT -DLIBICONV_PLUG" 293 | CPPFLAGS="${CPPFLAGS} -DLIBICONV_PLUG" 294 | fi 295 | 296 | if [ -z "${WANT_BINUTILS}" ]; then 297 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-binutils" 298 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-ld" 299 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-gold" 300 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-gas" 301 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-gprof" 302 | fi 303 | 304 | if [ -z "${WANT_SIM}" ]; then 305 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-sim" 306 | fi 307 | 308 | if [ -z "${WANT_WERROR}" ]; then 309 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-werror" 310 | fi 311 | 312 | # First, make an obj tree 313 | mkdir $obj 314 | 315 | # Next, run configure 316 | CONFIGURE_ARGS="--enable-targets=all \ 317 | --with-separate-debug-dir=/usr/lib/debug \ 318 | --without-libunwind-ia64 --enable-tui \ 319 | --prefix=${ROOTFS}${LOCALBASE} --mandir=${ROOTFS}${LOCALBASE}/man \ 320 | --infodir=${ROOTFS}${LOCALBASE}/info/ \ 321 | --build=${cfgarch}-portbld-freebsd${version} --disable-nls \ 322 | --with-system-zlib --enable-64-bit-bfd ${CONFIGURE_ARGS}" 323 | 324 | if [ -n "${HOST}" ]; then 325 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --host=${HOST}" 326 | fi 327 | 328 | if [ -n "${TARGET}" ]; then 329 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --target=${TARGET}" 330 | fi 331 | 332 | (cd $obj; 333 | env CC_FOR_BUILD="cc" CC="${CC}" CPP="cpp" CXX="${CXX}" \ 334 | CFLAGS="${CFLAGS}" \ 335 | CPPFLAGS="${CPPFLAGS}" \ 336 | CXXFLAGS="${CFLAGS}" \ 337 | LDFLAGS="${LDFLAGS}" LIBS="" \ 338 | INSTALL="/usr/bin/install -c " \ 339 | INSTALL_DATA="install -m 0644" \ 340 | INSTALL_LIB="install -m 444" \ 341 | INSTALL_PROGRAM="install -m 555" \ 342 | INSTALL_SCRIPT="install -m 555" \ 343 | CONFIGURED_M4=m4 CONFIGURED_BISON=byacc TMPDIR="/tmp" MAKE=gmake \ 344 | PYTHON="${PYTHON}" SHELL=/bin/sh CONFIG_SHELL=/bin/sh \ 345 | CONFIG_SITE=/usr/ports/Templates/config.site \ 346 | lt_cv_sys_max_cmd_len=262144 ${CONFIGURE_ENV} \ 347 | ${GDB_DIR}/configure ${CONFIGURE_ARGS} ) 348 | -------------------------------------------------------------------------------- /gdb/build_gmp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Setup a build env and build gdb similar to how ports builds it 4 | 5 | usage() 6 | { 7 | cat <&1` 248 | if [ $? -ne 0 ]; then 249 | echo "Compilers are not executable:" 250 | echo " CC=${CC}" 251 | echo " CXX=${CXX}" 252 | exit 1 253 | fi 254 | 255 | if echo "${cc_version}" | grep -q clang ; then 256 | if [ -n "${CLANG_TARGET}" ]; then 257 | CC_FLAGS="-target ${CLANG_TARGET} ${CC_FLAGS}" 258 | fi 259 | CC_FLAGS="${CC_FLAGS} ${CLANG_CC_FLAGS}" 260 | : ${LDFLAGS:="-fuse-ld=lld -Wl,--gdb-index"} 261 | fi 262 | if [ -n "${ROOTFS}" ]; then 263 | CC_FLAGS="${CC_FLAGS} --sysroot=${ROOTFS}" 264 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-sysroot=${ROOTFS}" 265 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-rpath" 266 | fi 267 | CC="${CC} ${CC_FLAGS}" 268 | CXX="${CXX} ${CC_FLAGS}" 269 | 270 | if [ -n "${AR}" ]; then 271 | CONFIGURE_ENV="${CONFIGURE_ENV} AR=${AR}" 272 | fi 273 | 274 | # First, make an obj tree 275 | mkdir $obj 276 | 277 | # Next, run configure 278 | CONFIGURE_ARGS="--enable-cxx --prefix=${ROOTFS}/usr/local \ 279 | --mandir=${ROOTFS}/usr/local/man --infodir=${ROOTFS}/usr/local/info/ \ 280 | --build=${cfgarch}-portbld-freebsd${version} ${CONFIGURE_ARGS}" 281 | 282 | if [ -n "${HOST}" ]; then 283 | CONFIGURE_ARGS="${CONFIGURE_ARGS} --host=${HOST}" 284 | fi 285 | 286 | (cd $obj; 287 | env CC_FOR_BUILD="cc" CC="${CC}" CPP="cpp" CXX="${CXX}" \ 288 | CFLAGS="-pipe -g -O2 -fno-strict-aliasing" \ 289 | CPPFLAGS="" \ 290 | CXXFLAGS="-pipe -g -O2 -fno-strict-aliasing" \ 291 | LDFLAGS="${LDFLAGS}" LIBS="" \ 292 | INSTALL="/usr/bin/install -c " \ 293 | INSTALL_DATA="install -m 0644" \ 294 | INSTALL_LIB="install -m 444" \ 295 | INSTALL_PROGRAM="install -m 555" \ 296 | INSTALL_SCRIPT="install -m 555" \ 297 | CONFIGURED_M4=m4 CONFIGURED_BISON=byacc TMPDIR="/tmp" MAKE=gmake \ 298 | SHELL=/bin/sh CONFIG_SHELL=/bin/sh \ 299 | CONFIG_SITE=/usr/ports/Templates/config.site \ 300 | lt_cv_sys_max_cmd_len=262144 ${CONFIGURE_ENV} \ 301 | ${GMP_DIR}/configure ${CONFIGURE_ARGS} ) 302 | -------------------------------------------------------------------------------- /gdb/chelsio: -------------------------------------------------------------------------------- 1 | # Chelsio-specific kernel macros 2 | 3 | # T3 commands 4 | 5 | # For each cxgb device, execute $arg0 passing the port_info structure as the 6 | # argument 7 | define fe_cxgb_helper 8 | if ($arg1->nameunit != 0) 9 | if ($arg1->nameunit[0] == 'c' && $arg1->nameunit[1] == 'x' && \ 10 | $arg1->nameunit[2] == 'g' && $arg1->nameunit[3] == 'b' && \ 11 | $arg1->nameunit[4] >= '0' && $arg1->nameunit[4] <= '9') 12 | set $pi = (struct port_info *)$arg1->softc 13 | $arg0 $pi 14 | end 15 | end 16 | end 17 | 18 | define fe_cxgb 19 | devwalk fe_cxgb_helper $arg0 20 | end 21 | 22 | # For each cxgbc device, execute $arg0 passing the adapter structure as the 23 | # argument. Note that we can't do a cast of the cxgbc softc directly, 24 | # so instead this finds the first cxgb device on each controller and uses 25 | # pi->adapter. 26 | define fe_cxgbc_helper 27 | if ($arg1->nameunit != 0) 28 | if ($arg1->nameunit[0] == 'c' && $arg1->nameunit[1] == 'x' && \ 29 | $arg1->nameunit[2] == 'g' && $arg1->nameunit[3] == 'b' && \ 30 | $arg1->nameunit[4] >= '0' && $arg1->nameunit[4] <= '9') 31 | if ($arg1->parent->children.tqh_first == $arg1) 32 | set $pi = (struct port_info *)$arg1->softc 33 | $arg0 $pi->adapter 34 | end 35 | end 36 | end 37 | end 38 | 39 | define fe_cxgbc 40 | devwalk fe_cxgbc_helper $arg0 41 | end 42 | 43 | define tcam_helper 44 | printf "%s: %d entries", $arg0->dev->nameunit, $arg0->mc5.tcam_size 45 | if ($arg0->params.offload) 46 | printf " (offload)" 47 | end 48 | printf "\n" 49 | end 50 | 51 | define tcam 52 | fe_cxgbc tcam_helper 53 | end 54 | 55 | document tcam 56 | Display number of TCAM entries for any Chelsio T3 adapters. 57 | end 58 | 59 | define filters_helper 60 | if ($arg0->filters != 0) 61 | printf "%s: %d filters:\n", $arg0->dev->nameunit, \ 62 | $arg0->params.mc5.nfilters 63 | set $i = 0 64 | while ($i < $arg0->params.mc5.nfilters) 65 | set $f = $arg0->filters + $i 66 | if ($f->valid) 67 | printf "%6d: ", $i 68 | print_ip &$f->sip 69 | printf ":" 70 | printf "%d ", $f->sport 71 | print_ip &$f->dip 72 | printf ":" 73 | printf "%d ", $f->dport 74 | if ($f->vlan != 0xfff) 75 | printf "vlan %d ", $f->vlan 76 | end 77 | if ($f->pkt_type == 0) 78 | printf "ANY " 79 | else 80 | if ($f->pkt_type == 1) 81 | printf "TCP " 82 | else 83 | if ($f->pkt_type == 2) 84 | printf "UDP " 85 | else 86 | printf "FRAG " 87 | end 88 | end 89 | end 90 | if ($f->pass) 91 | printf "PASS " 92 | else 93 | printf "DROP " 94 | end 95 | if ($f->rss == 0) 96 | printf "Q:%d", $f->qset 97 | else 98 | printf "RSS" 99 | end 100 | if ($f->locked) 101 | printf " LK" 102 | end 103 | printf "\n" 104 | end 105 | set $i = $i + 1 106 | end 107 | end 108 | end 109 | 110 | define filters 111 | fe_cxgbc filters_helper 112 | end 113 | 114 | document filters 115 | Display filter rules for any Chelsio T3 adapters. 116 | end 117 | 118 | define ctrlq_helper 119 | set $txq = $arg0->sge.qs[0].txq[2] 120 | printf "%s: size %d in_use %d processed %d cleaned %d\n", \ 121 | $arg0->dev->nameunit, $txq->size, $txq->in_use, $txq->processed, \ 122 | $txq->cleaned 123 | end 124 | 125 | define ctrlq 126 | fe_cxgbc ctrlq_helper 127 | end 128 | 129 | document ctrlq 130 | Display ctrlq stats for any Chelsio T3 adapters. 131 | end 132 | 133 | set $F_RSPD_GEN2 = 1 134 | 135 | define qset 136 | set $qs = (struct sge_qset *)$arg0 137 | printf "queueset %d:\n", $qs - $qs->port->adapter.sge.qs 138 | set $pending = 0 139 | set $idx = $qs->rspq.cidx 140 | set $r = $qs->rspq.desc[$idx] 141 | set $gen = $qs->rspq.gen 142 | while ($idx >= 0 && ($r->intr_gen & $F_RSPD_GEN2) == $gen) 143 | set $pending = $pending + 1 144 | set $idx = $idx + 1 145 | if ($idx == $qs->rspq.size) 146 | set $idx = 0 147 | set $gen = $gen ^ 1 148 | end 149 | if ($idx == $qs->rspq.cidx) 150 | set $idx = -1 151 | end 152 | set $r = $qs->rspq.desc[$idx] 153 | end 154 | printf " rspq size: %d cidx: %d credits: %d pending: %d\n", \ 155 | $qs->rspq.size, $qs->rspq.cidx, $qs->rspq.credits, $pending 156 | printf " fl0 size: %d cidx: %d\n", $qs->fl[0].size, $qs->fl[0].cidx 157 | printf " fl1 size: %d cidx: %d\n", $qs->fl[1].size, $qs->fl[1].cidx 158 | end 159 | 160 | document qset 161 | Display stats about a SGE qset. 162 | end 163 | 164 | define qsets_helper 165 | printf "%s: queue sets:\n", $arg0->ifp->if_xname 166 | set $i = 0 167 | while ($i < $arg0->nqsets) 168 | set $qs = $arg0->adapter->sge.qs + $arg0->first_qset + $i 169 | printf " %d: %p\n", $qs - $arg0->adapter->sge.qs, $qs 170 | set $i = $i + 1 171 | end 172 | end 173 | 174 | define qsets 175 | fe_cxgb qsets_helper 176 | end 177 | 178 | document qsets 179 | List T3 queue sets. 180 | end 181 | 182 | define txd 183 | set $txd = $arg0 184 | set $cpl = (struct cpl_tx_pkt *)$txd 185 | if ($osrelease >= '8') 186 | bswap32 $cpl->wr.u.ilp32.wr_lo $_wrlo 187 | bswap32 $cpl->wr.u.ilp32.wr_hi $_wrhi 188 | else 189 | bswap32 $cpl->wr.wr_lo $_wrlo 190 | bswap32 $cpl->wr.wr_hi $_wrhi 191 | end 192 | printf "wr hi: 0x%08lx lo: 0x%08lx\n", $_wrhi, $_wrlo 193 | bswap32 $cpl->cntrl $_cntrl 194 | bswap32 $cpl->len $_len 195 | printf "cntrl: 0x%08lx len: %u\n", $_cntrl, $_len & ~0x80000000 196 | end 197 | 198 | document txd 199 | Dump T3 tx descriptor state. 200 | end 201 | 202 | # T4/T5 commands 203 | 204 | # For each cxgbe or cxl device, execute $arg0 passing the port_info 205 | # structure as the argument 206 | define fe_cxgbe_helper 207 | if ($arg1->nameunit != 0) 208 | if ($arg1->nameunit[0] == 'c' && $arg1->nameunit[1] == 'x' && \ 209 | $arg1->nameunit[2] == 'g' && $arg1->nameunit[3] == 'b' && \ 210 | $arg1->nameunit[4] == 'e' && \ 211 | $arg1->nameunit[5] >= '0' && $arg1->nameunit[5] <= '9') 212 | set $pi = (struct port_info *)$arg1->softc 213 | $arg0 $pi 214 | end 215 | if ($arg1->nameunit[0] == 'c' && $arg1->nameunit[1] == 'x' && \ 216 | $arg1->nameunit[2] == 'l' && \ 217 | $arg1->nameunit[3] >= '0' && $arg1->nameunit[3] <= '9') 218 | set $pi = (struct port_info *)$arg1->softc 219 | $arg0 $pi 220 | end 221 | if ($arg1->nameunit[0] == 'c' && $arg1->nameunit[1] == 'c' && \ 222 | $arg1->nameunit[2] >= '0' && $arg1->nameunit[2] <= '9') 223 | set $pi = (struct port_info *)$arg1->softc 224 | $arg0 $pi 225 | end 226 | end 227 | end 228 | 229 | define fe_cxgbe 230 | devwalk fe_cxgbe_helper $arg0 231 | end 232 | 233 | set $S_RSPD_GEN = 7 234 | set $M_RSPD_LEN = 0x7fffffff 235 | 236 | set $S_RSPD_TYPE = 4 237 | set $M_RSPD_TYPE = 0x3 238 | 239 | set $X_RSPD_TYPE_FLBUF = 0 240 | set $X_RSPD_TYPE_CPL = 1 241 | set $X_RSPD_TYPE_INTR = 2 242 | 243 | set $CPL_CLOSE_CON_RPL = 0x32 244 | set $CPL_ISCSI_HDR = 0x33 245 | set $CPL_RX_DATA = 0x39 246 | set $CPL_RX_PKT = 0x3B 247 | set $CPL_RX_DDP_COMPLETE = 0x3F 248 | set $CPL_PASS_ESTABLISH = 0x41 249 | set $CPL_RX_DATA_DDP = 0x42 250 | set $CPL_RX_ISCSI_CMP = 0x45 251 | set $CPL_RX_ISCSI_DDP = 0x49 252 | set $CPL_ISCSI_DATA = 0xB2 253 | set $CPL_FW4_ACK = 0xC3 254 | 255 | set $IQ_ESIZE = 64 256 | 257 | set $DDP_ERR = 0x0ffe8000 258 | 259 | set $F_DDP_BUF_IDX = 0x4000000 260 | 261 | define bhs 262 | set $_bhs = (struct iscsi_bhs *)$arg0 263 | printf " iSCSI %02x", $_bhs->bhs_opcode 264 | end 265 | 266 | define cpl 267 | set $_ot = (union opcode_tid *)$arg0 268 | bswap32 $_ot->opcode_tid $_tid 269 | set $_tid = $_tid & 0xFFFFFF 270 | printf " CPL %02x tid %d", $_ot->opcode, $_tid 271 | if ($_ot->opcode == $CPL_CLOSE_CON_RPL) 272 | set $_cpl = (struct cpl_close_con_rpl *)$_ot 273 | bswap32 $_cpl->snd_nxt $_snd_nxt 274 | bswap32 $_cpl->rcv_nxt $_rcv_nxt 275 | printf " (CLOSE_CON_RPL) status %#x snd_nxt %d rcv_nxt %d", \ 276 | $_cpl->status, $_snd_nxt, $_rcv_nxt 277 | end 278 | if ($_ot->opcode == $CPL_ISCSI_HDR) 279 | set $_cpl = (struct cpl_iscsi_hdr *)$_ot 280 | bswap16 $_cpl->pdu_len_ddp $_len 281 | bswap32 $_cpl->seq $_seq 282 | printf " (ISCSI_HDR) seq %u len %d", $_seq, $_len 283 | bhs ($_cpl+1) 284 | end 285 | if ($_ot->opcode == $CPL_RX_DATA) 286 | set $_cpl = (struct cpl_rx_data *)$_ot 287 | bswap16 $_cpl->len $_len 288 | bswap32 $_cpl->seq $_seq 289 | printf " (RX_DATA) seq %u len %d", $_seq, $_len 290 | if ($_cpl->ddp_off) 291 | printf " DDP off" 292 | else 293 | printf " DDP on" 294 | end 295 | end 296 | if ($_ot->opcode == $CPL_RX_PKT) 297 | set $_cpl = (struct cpl_rx_pkt *)$_ot 298 | printf " (RX_PKT)" 299 | if ($_cpl->vlan_ex) 300 | bswap16 $_cpl->vlan $_vlan 301 | printf " vlan %d", $_vlan 302 | end 303 | end 304 | if ($_ot->opcode == $CPL_PASS_ESTABLISH) 305 | set $_cpl = (struct cpl_pass_establish *)$_ot 306 | printf " (PASS_ESTABLISH)" 307 | end 308 | if ($_ot->opcode == $CPL_RX_DDP_COMPLETE) 309 | set $_cpl = (struct cpl_rx_ddp_complete *)$_ot 310 | printf " (RX_DDP_COMPLETE)" 311 | bswap32 $_cpl->ddp_report $_report 312 | bswap32 $_cpl->rcv_nxt $_rcv_nxt 313 | printf " buf %d rcv_nxt %d", $_report & $F_DDP_BUF_IDX ? 1 : 0, \ 314 | $_rcv_nxt 315 | end 316 | if ($_ot->opcode == $CPL_RX_DATA_DDP) 317 | set $_cpl = (struct cpl_rx_data_ddp *)$_ot 318 | printf " (RX_DATA_DDP)" 319 | bswap32 $_cpl->ddpvld $_vld 320 | if ($_vld & $DDP_ERR) 321 | printf " invalid (%x)", $_vld 322 | else 323 | bswap32 $_cpl->u.ddp_report $_report 324 | bswap16 $_cpl->len $_len 325 | printf " buf %d len %d", $_report & $F_DDP_BUF_IDX ? 1 : 0, $_len 326 | end 327 | end 328 | if ($_ot->opcode == $CPL_RX_ISCSI_CMP) 329 | set $_cpl = (struct cpl_rx_iscsi_cmp *)$_ot 330 | printf " (RX_ISCSI_CMP)" 331 | bswap32 $_cpl->ddpvld $_vld 332 | if ($_vld & $DDP_ERR) 333 | printf " invalid (%x)", $_vld 334 | else 335 | bswap16 $_cpl->pdu_len_ddp $_len 336 | bswap32 $_cpl->seq $_seq 337 | printf " seq %u len %d", $_seq, $_len 338 | bhs ($_cpl+1) 339 | end 340 | end 341 | if ($_ot->opcode == $CPL_RX_ISCSI_DDP) 342 | set $_cpl = (struct cpl_rx_data_ddp *)$_ot 343 | printf " (RX_ISCSI_DDP)" 344 | bswap32 $_cpl->ddpvld $_vld 345 | if ($_vld & $DDP_ERR) 346 | printf " invalid (%x)", $_vld 347 | else 348 | bswap32 $_cpl->seq $_seq 349 | bswap16 $_cpl->len $_len 350 | printf " seq %u len %d", $_seq, $_len 351 | end 352 | end 353 | if ($_ot->opcode == $CPL_ISCSI_DATA) 354 | set $_cpl = (struct cpl_iscsi_data *)$_ot 355 | bswap16 $_cpl->len $_len 356 | bswap32 $_cpl->seq $_seq 357 | printf " (ISCSI_DATA) seq %u len %d", $_seq, $_len 358 | end 359 | if ($_ot->opcode == $CPL_FW4_ACK) 360 | set $_cpl = (struct cpl_fw4_ack *)$_ot 361 | printf " (FW4_ACK)" 362 | bswap32 $_cpl->snd_nxt $_snd_nxt 363 | bswap32 $_cpl->snd_una $_snd_una 364 | printf " credits %d snd_nxt %u snd_una %u", $_cpl->credits, $_snd_nxt, \ 365 | $_snd_una 366 | end 367 | end 368 | 369 | # 370 | define iq_msg 371 | set $_offset = (char *)$arg0->desc + ($arg1 * $IQ_ESIZE) 372 | set $_rss = (struct rss_header *)$_offset 373 | set $_ctrl = (struct rsp_ctrl *)($_offset + ($IQ_ESIZE - sizeof(struct rsp_ctrl))) 374 | set $_rspd_type = ($_ctrl->u.type_gen >> $S_RSPD_TYPE) & $M_RSPD_TYPE 375 | bswap16 $_rss->qid $_qid 376 | printf "[%2d]: gen %d qid %d", $arg1, $_ctrl->u.type_gen >> $S_RSPD_GEN, \ 377 | $_qid 378 | bswap32 $_ctrl->pldbuflen_qid $_lq 379 | if $_rspd_type == $X_RSPD_TYPE_FLBUF 380 | printf " FLBUF len: %d CPL %02x", $_lq & $M_RSPD_LEN, $_rss->opcode 381 | else 382 | if $_rspd_type == $X_RSPD_TYPE_CPL 383 | set $_cpl = $_rss + 1 384 | cpl $_cpl 385 | else 386 | if $_rspd_type == $X_RSPD_TYPE_INTR 387 | printf " INTR %d", $_lq 388 | else 389 | printf " type %d", $_rspd_type 390 | end 391 | end 392 | end 393 | printf "\n" 394 | end 395 | 396 | # 397 | define iq_msg_raw 398 | set $_base = (char *)$arg0->desc + ($arg1 * $IQ_ESIZE) 399 | set $_offset = 0 400 | while ($_offset < $IQ_ESIZE) 401 | printf "%02x ", ((unsigned)*$_base) & 0xff 402 | set $_offset = $_offset + 1 403 | set $_base = $_base + 1 404 | if ($_offset % 16 == 0) 405 | printf "\n" 406 | end 407 | end 408 | end 409 | 410 | # 411 | define iq_msgs 412 | set $_iq = (struct sge_iq *)$arg0 413 | set $_idx = $arg1 414 | set $_count = $arg2 415 | while ($_count-- > 0) 416 | iq_msg $arg0 $_idx 417 | set $_idx = $_idx + 1 418 | if ($_idx == $_iq->qsize) 419 | set $_idx = 0 420 | end 421 | end 422 | end 423 | 424 | define decode_dump 425 | set $_base = (char *)$arg0 426 | set $_offset = 0 427 | while ($_offset < $arg1) 428 | printf "%02x ", ((unsigned)*$_base) & 0xff 429 | set $_offset = $_offset + 1 430 | set $_base = $_base + 1 431 | if ($_offset % 16 == 0) 432 | printf "\n" 433 | end 434 | end 435 | if ($_offset % 16 != 0) 436 | printf "\n" 437 | end 438 | end 439 | 440 | define intrq 441 | set $_iq = (struct sge_iq *)$arg0 442 | printf "cntxt_id: %d qsize: %d\n", $_iq->cntxt_id, $_iq->qsize 443 | set $_i = 0 444 | while ($_i < $_iq->qsize) 445 | iq_msg $_iq $_i 446 | set $_i = $_i + 1 447 | end 448 | end 449 | 450 | set $EQ_ESIZE = 64 451 | 452 | set $S_FW_WR_OP = 24 453 | set $M_FW_WR_OP = 0xff 454 | 455 | set $S_FW_WR_IMMDLEN = 0 456 | set $M_FW_WR_IMMDLEN = 0xff 457 | 458 | set $F_FW_WR_EQUIQ = (1 << 31) 459 | set $F_FW_WR_EQUEQ = (1 << 30) 460 | 461 | set $S_FW_WR_LEN16 = 0 462 | set $M_FW_WR_LEN16 = 0xff 463 | 464 | set $FW_ULPTX_WR = 0x04 465 | set $FW_TP_WR = 0x05 466 | set $FW_ETH_TX_PKT_WR = 0x08 467 | set $FW_ETH_TX_PKT_VM_WR = 0x11 468 | 469 | set $S_CPL_OPCODE = 24 470 | 471 | set $CPL_ACT_OPEN_REQ = 0x3 472 | set $CPL_SET_TCB_FIELD = 0x5 473 | set $CPL_TX_PKT = 0xe 474 | set $CPL_TX_PKT_LSO = 0xed 475 | set $CPL_TX_PKT_XT = 0xee 476 | 477 | set $F_NO_REPLY = (1 << 15) 478 | 479 | set $S_ULPTX_NSGE = 0 480 | set $M_ULPTX_NSGE = 0xFFFF 481 | 482 | define cpl_msg 483 | set $_ot = (union opcode_tid *)($_wr + 1) 484 | bswap32 $_ot->opcode_tid $_tid 485 | set $_tid = $_tid & 0xFFFFFF 486 | printf " CPL %02x tid %d", $_ot->opcode, $_tid 487 | if ($_ot->opcode == $CPL_ACT_OPEN_REQ) 488 | printf " ACT_OPEN_REQ" 489 | end 490 | if ($_ot->opcode == $CPL_SET_TCB_FIELD) 491 | printf " SET_TCB_FIELD" 492 | set $_cpl = (struct cpl_set_tcb_field_core *)$_ot 493 | bswap16 $_cpl->reply_ctrl $_reply_ctrl 494 | if ($_reply_ctrl & $F_NO_REPLY) 495 | printf " NO_REPLY" 496 | end 497 | bswap16 $_cpl->word_cookie $_word_cookie 498 | printf " word %#x cookie %#x", $_word_cookie & 0x1F, \ 499 | ($_word_cookie >> 5) & 0x7 500 | bswap64 $_cpl->mask $_mask 501 | printf " mask %#lx", $_mask 502 | bswap64 $_cpl->val $_val 503 | printf " val %#lx", $_val 504 | end 505 | if ($_ot->opcode == $CPL_TX_PKT_LSO) 506 | printf " LSO" 507 | set $_lso = (struct cpl_tx_pkt_lso_core *)$_ot 508 | set $_ot = (union opcode_tid *)($_lso + 1) 509 | printf " CPL %02x", $_ot->opcode 510 | end 511 | if ($_ot->opcode == $CPL_TX_PKT || $_ot->opcode == $CPL_TX_PKT_XT) 512 | set $_cpl = (struct cpl_tx_pkt_core *)$_ot 513 | bswap16 $_cpl->len $_pktlen 514 | if ($_ot->opcode == $CPL_TX_PKT) 515 | printf " TXPKT (pktlen %d)", $_pktlen 516 | else 517 | printf " TXPKT_XT (pktlen %d)", $_pktlen 518 | end 519 | set $_immdlen = ($_op_immdlen >> $S_FW_WR_IMMDLEN) & $M_FW_WR_IMMDLEN 520 | # Subtract out LSO header if it exists 521 | set $_immdlen = $_immdlen - ((uintptr_t)$_ot - (uintptr_t)($_wr + 1)) 522 | set $_immdlen = $_immdlen - sizeof(struct cpl_tx_pkt_core) 523 | if ($_immdlen > 0) 524 | printf " immediate" 525 | else 526 | set $_usgl = (struct ulptx_sgl *)($_cpl + 1) 527 | bswap32 $_usgl->cmd_nsge $_cmd_nsge 528 | set $_nsegs = ($_cmd_nsge >> $S_ULPTX_NSGE) & $M_ULPTX_NSGE 529 | if ($eq_verbose) 530 | set $_seg_idx = 1 531 | bswap64 $_usgl->addr0 $_sgaddr 532 | bswap32 $_usgl->len0 $_sglen 533 | printf "\n\t[0]: %#llx : %#x", $_sgaddr, $_sglen 534 | set $_segs = $_usgl->sge 535 | while ($_seg_idx + 1 < $_nsegs) 536 | bswap64 $_segs->addr[0] $_sgaddr 537 | bswap32 $_segs->len[0] $_sglen 538 | printf "\n\t[%d]: %#llx : %#x", $_seg_idx, $_sgaddr, $_sglen 539 | bswap64 $_segs->addr[1] $_sgaddr 540 | bswap32 $_segs->len[1] $_sglen 541 | printf "\n\t[%d]: %#llx : %#x", $_seg_idx + 1, $_sgaddr, \ 542 | $_sglen 543 | set $_seg_idx = $_seg_idx + 2 544 | set $_segs = $_segs + 1 545 | end 546 | if ($_seg_idx < $_nsegs) 547 | bswap64 $_segs->addr[0] $_sgaddr 548 | bswap32 $_segs->len[0] $_sglen 549 | printf "\n\t[%d]: %#llx : %#x", $_seg_idx, $_sgaddr, $_sglen 550 | end 551 | else 552 | printf " %d segs", $_nsegs 553 | end 554 | end 555 | end 556 | end 557 | 558 | define eq_msg 559 | set $_hdr = (uint32_t *)&$arg0->desc[$arg1] 560 | bswap32 $_hdr[0] $_op_immdlen 561 | bswap32 $_hdr[1] $_equiq_to_len16 562 | set $_wr_op = ($_op_immdlen >> $S_FW_WR_OP) & $M_FW_WR_OP 563 | set $_len16 = ($_equiq_to_len16 >> $S_FW_WR_LEN16) & $M_FW_WR_LEN16 564 | printf "[%2d]: fw op %#x len16 %d", $arg1, $_wr_op, $_len16 565 | if ($_equiq_to_len16 & $F_FW_WR_EQUIQ) 566 | printf " UIQ" 567 | end 568 | if ($_equiq_to_len16 & $F_FW_WR_EQUEQ) 569 | printf " UEQ" 570 | end 571 | if ($_wr_op == $FW_ULPTX_WR) 572 | #set $_wr = (struct fw_ulptx_wr *)$_hdr 573 | printf " ULPTX" 574 | # not a CPL, would have to parse ULPTX 575 | end 576 | if ($_wr_op == $FW_TP_WR) 577 | # Really struct fw_tp_wr, but this is the same size 578 | set $_wr = (struct fw_ulptx_wr *)$_hdr 579 | cpl_msg 580 | end 581 | if ($_wr_op == $FW_ETH_TX_PKT_WR) 582 | set $_wr = (struct fw_eth_tx_pkt_wr *)$_hdr 583 | cpl_msg 584 | end 585 | if ($_wr_op == $FW_ETH_TX_PKT_VM_WR) 586 | set $_wr = (struct fw_eth_tx_pkt_vm_wr *)$_hdr 587 | cpl_msg 588 | end 589 | printf "\n" 590 | end 591 | 592 | # 593 | define eq_msg_raw 594 | set $_base = (char *)&$arg0->desc[$arg1] 595 | set $_offset = 0 596 | while ($_offset < $EQ_ESIZE) 597 | printf "%02x ", ((unsigned)*$_base) & 0xff 598 | set $_offset = $_offset + 1 599 | set $_base = $_base + 1 600 | if ($_offset % 16 == 0) 601 | printf "\n" 602 | end 603 | end 604 | end 605 | 606 | # 607 | define eq_msgs 608 | set $_idx = $arg1 609 | set $_count = $arg2 610 | while ($_count-- > 0) 611 | eq_msg $arg0 $_idx 612 | if ($_len16 == 0) 613 | set $_idx = $_idx + 1 614 | else 615 | set $_idx = $_idx + ($_len16 + 3) / 4 616 | end 617 | end 618 | end 619 | 620 | # 621 | define eq_msgs_raw 622 | set $_idx = $arg1 623 | set $_count = $arg2 624 | while ($_count-- > 0) 625 | eq_msg_raw $arg0 $_idx 626 | if ($_idx < $arg0->sidx - 1) 627 | set $_idx = $_idx + 1 628 | else 629 | set $_idx = 0 630 | end 631 | end 632 | end 633 | 634 | define eq_buf_ring 635 | set $_eq = (struct sge_eq *)$arg0 636 | printf "cntxt_id: %d qsize: %d cap: %d\n", \ 637 | $_eq->cntxt_id, $_eq->qsize, $_eq->cap 638 | bswap32 $_eq->spg->qid $_qid 639 | bswap16 $_eq->spg->cidx $_cidx 640 | bswap16 $_eq->spg->pidx $_pidx 641 | printf "spg qid: %d cidx: %d pidx: %d\n", $_qid, $_cidx, $_pidx 642 | end 643 | 644 | define eq_mp_ring 645 | set $_eq = (struct sge_eq *)$arg0 646 | set $_eq_spg = (struct sge_qstat *)&$_eq->desc[$_eq->sidx] 647 | printf "cntxt_id: %d sidx: %d cidx: %d pidx: %d dbidx: %d\n", \ 648 | $_eq->cntxt_id, $_eq->sidx, $_eq->cidx, $_eq->pidx, $_eq->dbidx 649 | bswap32 $_eq_spg->qid $_qid 650 | bswap16 $_eq_spg->cidx $_cidx 651 | bswap16 $_eq_spg->pidx $_pidx 652 | printf "spg qid: %d cidx: %d pidx: %d\n", $_qid, $_cidx, $_pidx 653 | end 654 | 655 | define eq 656 | # XXX: Not a perfect test 657 | if (osreldate >= 1100052 || (osreldate < 1100000 && osreldate >= 1001518)) 658 | eq_mp_ring $arg0 659 | else 660 | eq_buf_ring $arg0 661 | end 662 | end 663 | 664 | define iq 665 | set $_iq = (struct sge_iq *)$arg0 666 | printf "cntxt_id: %d qsize: %d\n", \ 667 | $_iq->cntxt_id, $_iq->qsize 668 | set $_offset = (char *)$_iq->desc + (($_iq->qsize - 1) * $IQ_ESIZE) 669 | set $_iq_spg = (struct sge_qstat *)$_offset 670 | bswap32 $_iq_spg->qid $_qid 671 | bswap16 $_iq_spg->cidx $_cidx 672 | bswap16 $_iq_spg->pidx $_pidx 673 | printf "spg qid: %d cidx: %d pidx: %d\n", $_qid, $_cidx, $_pidx 674 | end 675 | 676 | define queues_vi_helper 677 | printf "%s: queues:\n", $arg0->ifp->if_xname 678 | if ($arg0 == $arg0->pi->vi) 679 | printf " ctrlq: %p\n", $arg0->pi->adapter->sge.ctrlq + $arg0->pi->port_id 680 | end 681 | set $i = 0 682 | while ($i < $arg0->nrxq) 683 | printf " rxq %d: %p\n", $i, $arg0->pi->adapter->sge.rxq + $arg0->first_rxq + $i 684 | set $i = $i + 1 685 | end 686 | set $i = 0 687 | while ($i < $arg0->ntxq) 688 | printf " txq %d: %p\n", $i, $arg0->pi->adapter->sge.txq + $arg0->first_txq + $i 689 | set $i = $i + 1 690 | end 691 | set $i = 0 692 | while ($i < $arg0->nofldrxq) 693 | printf " ofld_rxq %d: %p\n", $i, $arg0->pi->adapter->sge.ofld_rxq + $arg0->first_ofld_rxq + $i 694 | set $i = $i + 1 695 | end 696 | set $i = 0 697 | while ($i < $arg0->nofldtxq) 698 | printf " ofld_txq %d: %p\n", $i, $arg0->pi->adapter->sge.ofld_txq + $arg0->first_ofld_txq + $i 699 | set $i = $i + 1 700 | end 701 | end 702 | 703 | define queues_helper 704 | set $j = 0 705 | while ($j < $arg0->nvi) 706 | set $vi = &$arg0->vi[$j] 707 | queues_vi_helper $vi 708 | set $j = $j + 1 709 | end 710 | end 711 | 712 | define queues 713 | fe_cxgbe queues_helper 714 | end 715 | 716 | define toesock 717 | tcpsock $arg0 718 | set $toep = (struct toepcb *)$tp->t_toe 719 | end 720 | 721 | define vis_helper 722 | printf "%s: pi %p\n", $arg0->dev->nameunit, $arg0 723 | set $i = 0 724 | while ($i < $arg0->nvi) 725 | set $vi = &$arg0->vi[$i] 726 | printf " [%d]: %s: %p\n", $i, $vi->dev->nameunit, $vi 727 | set $i = $i + 1 728 | end 729 | end 730 | 731 | define vis 732 | fe_cxgbe vis_helper 733 | end 734 | 735 | define td_helper 736 | if $arg0->adapter->port[0] == $arg0 737 | printf "%s: td %p\n", $arg0->adapter->dev->nameunit, \ 738 | $arg0->adapter->tom_softc 739 | end 740 | end 741 | 742 | define toedevs 743 | fe_cxgbe td_helper 744 | end 745 | -------------------------------------------------------------------------------- /gdb/dot.gdbinit.kernel: -------------------------------------------------------------------------------- 1 | define xi 2 | x/10i $eip 3 | end 4 | define xs 5 | x/12x $esp 6 | end 7 | define xb 8 | x/12x $ebp 9 | end 10 | define z 11 | ni 12 | x/1i $eip 13 | end 14 | define zs 15 | si 16 | x/1i $eip 17 | end 18 | define xp 19 | printf " esp: " 20 | output/x $esp 21 | echo ( 22 | output (((int)$ebp)-(int)$esp)/4-4 23 | printf " words on stack)\n ebp: " 24 | output/x $ebp 25 | printf "\n eip: " 26 | x/1i $eip 27 | printf "Saved ebp: " 28 | output/x *(int*)$ebp 29 | printf " (maximum of " 30 | output ((*(int*)$ebp)-(int)$ebp)/4-4 31 | printf " parameters possible)\nSaved eip: " 32 | x/1i *(int*)($ebp+4) 33 | printf "\nParm 1 at " 34 | output/x (int) ($ebp+8) 35 | printf ": " 36 | output (char*) *(int*)($ebp+8) 37 | printf "\nParm 2 at " 38 | output/x (int) ($ebp+12) 39 | printf ": " 40 | output (char*) *(int*)($ebp+12) 41 | printf "\nParm 3 at " 42 | output/x (int) ($ebp+16) 43 | printf ": " 44 | output (char*) *(int*)($ebp+16) 45 | printf "\nParm 4 at " 46 | output/x (int) ($ebp+20) 47 | printf ": " 48 | output (char*) *(int*)($ebp+20) 49 | echo \n 50 | end 51 | document xp 52 | Show the register contents and the first four parameter 53 | words of the current frame. 54 | end 55 | define xxp 56 | printf " esp: " 57 | output/x $esp 58 | printf "\n ebp: " 59 | output/x $ebp 60 | printf "\n eip: " 61 | x/1i $eip 62 | printf "Saved ebp: " 63 | output/x *(int*)$ebp 64 | printf " (maximum of " 65 | output ((*(int*)$ebp)-(int)$ebp)/4-4 66 | printf " parameters possible)\nSaved eip: " 67 | x/1i *(int*)($ebp+4) 68 | printf "\nParm 1 at " 69 | output/x (int) ($ebp+8) 70 | printf ": " 71 | output (char*) *(int*)($ebp+8) 72 | printf "\nParm 2 at " 73 | output/x (int) ($ebp+12) 74 | printf ": " 75 | output (char*) *(int*)($ebp+12) 76 | printf "\nParm 3 at " 77 | output/x (int) ($ebp+16) 78 | printf ": " 79 | output (char*) *(int*)($ebp+16) 80 | printf "\nParm 4 at " 81 | output/x (int) ($ebp+20) 82 | printf ": " 83 | output (char*) *(int*)($ebp+20) 84 | printf "\nParm 5 at " 85 | output/x (int) ($ebp+24) 86 | printf ": " 87 | output (char*) *(int*)($ebp+24) 88 | printf "\nParm 6 at " 89 | output/x (int) ($ebp+28) 90 | printf ": " 91 | output (char*) *(int*)($ebp+28) 92 | printf "\nParm 7 at " 93 | output/x (int) ($ebp+32) 94 | printf ": " 95 | output (char*) *(int*)($ebp+32) 96 | printf "\nParm 8 at " 97 | output/x (int) ($ebp+36) 98 | printf ": " 99 | output (char*) *(int*)($ebp+36) 100 | printf "\nParm 9 at " 101 | output/x (int) ($ebp+40) 102 | printf ": " 103 | output (char*) *(int*)($ebp+40) 104 | printf "\nParm 10 at " 105 | output/x (int) ($ebp+44) 106 | printf ": " 107 | output (char*) *(int*)($ebp+44) 108 | echo \n 109 | end 110 | document xxp 111 | Show the register contents and the first ten parameter 112 | words of the current frame. 113 | end 114 | define xp0 115 | x/12x *(int*)$esp 116 | p *(int*)$esp 117 | p (char*)*$esp 118 | end 119 | define xp1 120 | x/12x *(int*)($ebp+4) 121 | p *(int*)($ebp+4) 122 | p (char**)($ebp+4) 123 | end 124 | define xp2 125 | x/12x *(int*)($ebp+8) 126 | p *(int*)($ebp+8) 127 | p *(char**)($ebp+8) 128 | end 129 | define xp3 130 | x/12x *(int*)($ebp+12) 131 | p *(int*)($ebp+12) 132 | p (char**)($ebp+12) 133 | end 134 | define xp4 135 | x/12x *(int*)($ebp+16) 136 | p *(int*)($ebp+16) 137 | p (char**)($ebp+16) 138 | end 139 | document xp0 140 | Show the first parameter of current stack frame in various formats 141 | end 142 | document xp1 143 | Show the second parameter of current stack frame in various formats 144 | end 145 | document xp2 146 | Show the third parameter of current stack frame in various formats 147 | end 148 | document xp3 149 | Show the fourth parameter of current stack frame in various formats 150 | end 151 | document xp4 152 | Show the fifth parameter of current stack frame in various formats 153 | end 154 | define f0 155 | f 0 156 | xp 157 | end 158 | define f1 159 | f 1 160 | xp 161 | end 162 | define f2 163 | f 2 164 | xp 165 | end 166 | define f3 167 | f 3 168 | xp 169 | end 170 | define f4 171 | f 4 172 | xp 173 | end 174 | define f5 175 | f 5 176 | xp 177 | end 178 | document f0 179 | Select stack frame 0 and show assembler-level details 180 | end 181 | document f1 182 | Select stack frame 1 and show assembler-level details 183 | end 184 | document f2 185 | Select stack frame 2 and show assembler-level details 186 | end 187 | document f3 188 | Select stack frame 3 and show assembler-level details 189 | end 190 | document f4 191 | Select stack frame 4 and show assembler-level details 192 | end 193 | document f5 194 | Select stack frame 5 and show assembler-level details 195 | end 196 | document z 197 | Single step 1 instruction (over calls) and show next instruction. 198 | end 199 | document zs 200 | Single step 1 instruction (through calls) and show next instruction. 201 | end 202 | document xi 203 | List the next 10 instructions from the current IP value 204 | end 205 | document xs 206 | Show the last 12 words on stack in hex 207 | end 208 | document xb 209 | Show 12 words starting at current BP value in hex 210 | end 211 | define tr 212 | target remote /dev/cuaa0 213 | end 214 | document tr 215 | Attach to a remote kernel via /dev/cuaa0 216 | end 217 | set output-radix 16 218 | define pname 219 | p (char *)curproc->p_comm 220 | end 221 | document pname 222 | Print the command name of the current process 223 | end 224 | define bpp 225 | set $bp = (struct buf *) $arg0 226 | if $bp->b_io.bio_dev 227 | printf " Buffer at 0x%x: dev 0x%x data 0x%x bcount 0x%x blkno 0x%x resid 0x%x\n", \ 228 | $bp, \ 229 | $bp->b_io.bio_dev->si_udev, \ 230 | $bp->b_io.bio_data, \ 231 | $bp->b_io.bio_bcount, \ 232 | $bp->b_io.bio_blkno, \ 233 | $bp->b_io.bio_resid 234 | else 235 | printf " Buffer at 0x%x: dev (none) data 0x%x bcount 0x%x blkno 0x%x resid 0x%x\n", \ 236 | $bp, \ 237 | $bp->b_io.bio_data, \ 238 | $bp->b_io.bio_bcount, \ 239 | $bp->b_io.bio_blkno, \ 240 | $bp->b_io.bio_resid 241 | end 242 | printf " Command: " 243 | if $bp->b_io->bio_cmd == 1 244 | printf "Read, " 245 | end 246 | if $bp->b_io->bio_cmd == 2 247 | printf "Write, " 248 | end 249 | if $bp->b_io->bio_cmd == 4 250 | printf "Delete, " 251 | end 252 | if $bp->b_io->bio_cmd == 8 253 | printf "Format, " 254 | end 255 | printf "flags 0x%x: ", $bp->b_flags 256 | if $bp->b_flags & 0x200 257 | printf "done " 258 | end 259 | if $bp->b_flags & 0x800 260 | printf "error " 261 | end 262 | if $bp->b_flags & 0x40000 263 | printf "phys " 264 | end 265 | printf "\n" 266 | end 267 | define bpl 268 | set $bp = (struct buf *) $arg0 269 | printf "b_proc: " 270 | output $bp->b_proc 271 | printf "\nb_flags: " 272 | output $bp->b_flags 273 | printf "\nb_qindex: " 274 | output $bp->b_qindex 275 | printf "\nb_usecount: " 276 | output $bp->b_usecount 277 | printf "\nb_error: " 278 | output $bp->b_error 279 | printf "\nb_bufsize: " 280 | output $bp->b_bufsize 281 | printf "\nb_io.bio_bcount: " 282 | output $bp->b_io.bio_bcount 283 | printf "\nb_io.bio_resid: " 284 | output $bp->b_io.bio_resid 285 | printf "\nb_io.bio_dev: " 286 | output $bp->b_io.bio_dev 287 | printf "\nb_io.bio_data: " 288 | output $bp->b_io.bio_data 289 | printf "\nb_kvasize: " 290 | output $bp->b_kvasize 291 | printf "\nb_lblkno: " 292 | output $bp->b_lblkno 293 | printf "\nb_io.bio_blkno: " 294 | output $bp->b_io.bio_blkno 295 | printf "\nb_iodone: " 296 | output $bp->b_iodone 297 | printf "\nb_vp: " 298 | output $bp->b_vp 299 | printf "\nb_dirtyoff: " 300 | output $bp->b_dirtyoff 301 | printf "\nb_dirtyend: " 302 | output $bp->b_dirtyend 303 | printf "\nb_generation: " 304 | output $bp->b_generation 305 | printf "\nb_rcred: " 306 | output $bp->b_rcred 307 | printf "\nb_wcred: " 308 | output $bp->b_wcred 309 | printf "\nb_validoff: " 310 | output $bp->b_validoff 311 | printf "\nb_validend: " 312 | output $bp->b_validend 313 | printf "\nb_pblkno: " 314 | output $bp->b_pblkno 315 | printf "\nb_saveaddr: " 316 | output $bp->b_saveaddr 317 | printf "\nb_savekva: " 318 | output $bp->b_savekva 319 | printf "\nb_driver1: " 320 | output $bp->b_driver1 321 | printf "\nb_driver2: " 322 | output $bp->b_driver2 323 | printf "\nb_spc: " 324 | output $bp->b_spc 325 | printf "\nb_npages: " 326 | output $bp->b_npages 327 | printf "\n" 328 | end 329 | define bp 330 | bpp bp 331 | end 332 | define bpd 333 | printf "Buffer data:\n%s", (char *) bp->b_io.bio_data 334 | end 335 | document bpd 336 | Show the contents (char*) of bp->data in the current frame. 337 | end 338 | document bp 339 | Show information about the buffer header pointed to by the 340 | variable bp in the current frame. 341 | end 342 | document bpp 343 | Show summary information about the buffer header (struct bp) pointed 344 | at by the parameter. 345 | end 346 | document bpl 347 | Show detailled information about the buffer header (struct bp) pointed 348 | at by the parameter. 349 | end 350 | document bpl 351 | Show detailled information about the buffer header (struct bp) pointed 352 | at by the local variable bp. 353 | end 354 | define bx 355 | printf "\n b_vnbufs " 356 | output/x bp->b_vnbufs 357 | printf "\n b_freelist " 358 | output/x bp->b_freelist 359 | printf "\n b_act " 360 | output/x bp->b_act 361 | printf "\n b_flags " 362 | output/x bp->b_flags 363 | printf "\n b_qindex " 364 | output/x bp->b_qindex 365 | printf "\n b_usecount " 366 | output/x bp->b_usecount 367 | printf "\n b_error " 368 | output/x bp->b_error 369 | printf "\n b_bufsize " 370 | output/x bp->b_bufsize 371 | printf "\n b_io.bio_bcount " 372 | output/x bp->b_io.bio_bcount 373 | printf "\n b_io.bio_resid " 374 | output/x bp->b_io.bio_resid 375 | printf "\n b_io.bio_dev " 376 | output/x bp->b_io.bio_dev 377 | printf "\n b_io.bio_data " 378 | output/x bp->b_io.bio_data 379 | printf "\n b_kvasize " 380 | output/x bp->b_kvasize 381 | printf "\n b_io.bio_blkno " 382 | output/x bp->b_io.bio_blkno 383 | printf "\n b_iodone_chain " 384 | output/x bp->b_iodone_chain 385 | printf "\n b_vp " 386 | output/x bp->b_vp 387 | printf "\n b_dirtyoff " 388 | output/x bp->b_dirtyoff 389 | printf "\n b_validoff " 390 | output/x bp->b_validoff 391 | echo \n 392 | end 393 | define ddb 394 | set boothowto=0x80000000 395 | s 396 | end 397 | document ddb 398 | Switch back to ddb. 399 | end 400 | define ps 401 | set $nproc = nprocs 402 | set $aproc = allproc.lh_first 403 | set $proc = allproc.lh_first 404 | printf " pid proc addr uid pri ppid pgrp flag stat comm wchan\n" 405 | while (--$nproc >= 0) 406 | set $pptr = $proc.p_pptr 407 | if ($pptr == 0) 408 | set $pptr = $proc 409 | end 410 | if ($proc.p_stat) 411 | printf "%5d %08x %08x %4d ", \ 412 | $proc.p_pid, $aproc, \ 413 | $proc.p_addr, $proc.p_cred->p_ruid 414 | if ($proc.p_rtprio.type == 3) 415 | printf "%3d ", $pptr->p_priority 416 | else 417 | printf "%3d*", $proc.p_rtprio.prio 418 | end 419 | printf "%5d %5d %06x %d %-10s ", \ 420 | $pptr->p_pid, $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_stat, \ 421 | &$proc.p_comm[0] 422 | if ($proc.p_wchan) 423 | if ($proc.p_wmesg) 424 | printf "%s ", $proc.p_wmesg 425 | end 426 | printf "%x", $proc.p_wchan 427 | end 428 | printf "\n" 429 | end 430 | set $aproc = $proc.p_list.le_next 431 | if ($aproc == 0 && $nproc > 0) 432 | set $aproc = zombproc 433 | end 434 | set $proc = $aproc 435 | end 436 | end 437 | document ps 438 | "ps" -- when kernel debugging, type out a ps-like listing of active processes. 439 | end 440 | define pregs 441 | set $nproc = nprocs 442 | set $aproc = allproc.lh_first 443 | set $proc = allproc.lh_first 444 | while (--$nproc >= 0) 445 | set $pptr = $proc.p_pptr 446 | if ($proc->p_pid == $arg0) 447 | set $pcba = $pptr->p_addr->u_pcb 448 | printf "eax\t%d\t%x", $pcba->pcb_eax, $pcba->pcb_eax 449 | printf "ecx\t%d\t%x", $pcba->pcb_ecx, $pcba->pcb_ecx 450 | printf "edx\t%d\t%x", $pcba->pcb_edx, $pcba->pcb_edx 451 | printf "ebx\t%d\t%x", $pcba->pcb_ebx, $pcba->pcb_ebx 452 | printf "esp\t%d\t%x", $pcba->pcb_esp, $pcba->pcb_esp 453 | printf "ebp\t%d\t%x", $pcba->pcb_ebp, $pcba->pcb_ebp 454 | printf "esi\t%d\t%x", $pcba->pcb_esi, $pcba->pcb_esi 455 | printf "edi\t%d\t%x", $pcba->pcb_edi, $pcba->pcb_edi 456 | printf "eip\t%d\t%x", $pcba->pcb_eip, $pcba->pcb_eip 457 | printf "eflags\t%d\t%x", $pcba->pcb_eflags, $pcba->pcb_eflags 458 | printf "cs\t%d\t%x", $pcba->pcb_cs, $pcba->pcb_cs 459 | printf "ss\t%d\t%x", $pcba->pcb_ss, $pcba->pcb_ss 460 | printf "ds\t%d\t%x", $pcba->pcb_ds, $pcba->pcb_ds 461 | printf "es\t%d\t%x", $pcba->pcb_es, $pcba->pcb_es 462 | printf "fs\t%d\t%x", $pcba->pcb_fs, $pcba->pcb_fs 463 | printf "gs\t%d\t%x", $pcba->pcb_gs, $pcba->pcb_gs 464 | x/1i $pcba->pcb_eip 465 | set $nproc = 0 466 | end 467 | set $aproc = $proc.p_list.le_next 468 | if ($aproc == 0 && $nproc > 0) 469 | set $aproc = zombproc 470 | end 471 | set $proc = $aproc 472 | end 473 | end 474 | document pregs 475 | Show some pcb contents of process whose pid is specified. 476 | end 477 | define btr 478 | set $frame = $arg0 479 | set $fno = 0 480 | while (*(int *) $frame > 0xc0000000) 481 | set $myebp = *(int *) $frame 482 | set $myeip = *(int *) ($frame + 4) 483 | printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp 484 | x/1i $myeip 485 | set $frame = $myebp 486 | set $fno = $fno + 1 487 | end 488 | end 489 | document btr 490 | Show a backtrace from the ebp address specified. This can be used to 491 | get a backtrace from any stack resident in memory. 492 | end 493 | define btp 494 | set $nproc = nprocs 495 | set $aproc = allproc.lh_first 496 | set $proc = allproc.lh_first 497 | while (--$nproc >= 0) 498 | if ($proc->p_pid == $arg0) 499 | btr $proc->p_addr->u_pcb->pcb_ebp 500 | set $nproc = 0 501 | else 502 | set $aproc = $proc.p_list.le_next 503 | if ($aproc == 0 && $nproc > 0) 504 | set $aproc = zombproc 505 | end 506 | set $proc = $aproc 507 | end 508 | end 509 | end 510 | document btp 511 | Show a backtrace for the process whose pid is specified as a parameter. 512 | end 513 | define btpa 514 | set $nproc = nprocs 515 | set $aproc = allproc.lh_first 516 | set $proc = allproc.lh_first 517 | printf " pid proc addr uid ppid pgrp flag stat comm wchan\n" 518 | while (--$nproc >= 0) 519 | set $pptr = $proc.p_pptr 520 | if ($pptr == 0) 521 | set $pptr = $proc 522 | end 523 | if ($proc.p_stat) 524 | printf "%5d %08x %08x %4d %5d %5d %06x %d %-10s ", \ 525 | $proc.p_pid, $aproc, \ 526 | $proc.p_addr, $proc.p_cred->p_ruid, $pptr->p_pid, \ 527 | $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_stat, \ 528 | &$proc.p_comm[0] 529 | if ($proc.p_wchan) 530 | if ($proc.p_wmesg) 531 | printf "%s ", $proc.p_wmesg 532 | end 533 | printf "%x", $proc.p_wchan 534 | end 535 | printf "\n" 536 | if ($proc->p_flag & 4) 537 | btr $proc->p_addr->u_pcb->pcb_ebp 538 | else 539 | echo (not loaded)\n 540 | end 541 | end 542 | set $aproc = $proc.p_list.le_next 543 | if ($aproc == 0 && $nproc > 0) 544 | set $aproc = zombproc 545 | end 546 | set $proc = $aproc 547 | end 548 | end 549 | document btpa 550 | Show backtraces for all processes in the system. 551 | end 552 | define btpp 553 | if ($myvectorproc->p_flag & 4) 554 | btr $myvectorproc->p_addr->u_pcb->pcb_ebp 555 | else 556 | echo (not loaded)\n 557 | end 558 | end 559 | document btpp 560 | Show a backtrace for the process previously selected with 'defproc'. 561 | end 562 | define defproc 563 | set $nproc = nprocs 564 | set $aproc = allproc.lh_first 565 | set $proc = allproc.lh_first 566 | while (--$nproc >= 0) 567 | if ($proc->p_pid == $arg0) 568 | set $pptr = $proc.p_pptr 569 | if ($pptr == 0) 570 | set $pptr = $proc 571 | end 572 | set $myvectorproc = $proc 573 | if ($proc.p_stat) 574 | printf "%5d %08x %08x %4d %5d %5d %06x %d %-10s ", \ 575 | $proc.p_pid, $aproc, \ 576 | $proc.p_addr, $proc.p_cred->p_ruid, $pptr->p_pid, \ 577 | $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_stat, \ 578 | &$proc.p_comm[0] 579 | if ($proc.p_wchan) 580 | if ($proc.p_wmesg) 581 | printf "%s ", $proc.p_wmesg 582 | end 583 | printf "%x", $proc.p_wchan 584 | end 585 | printf "\n" 586 | end 587 | btpp 588 | set $nproc = 0 589 | else 590 | set $proc = $proc.p_list.le_next 591 | end 592 | end 593 | end 594 | document defproc 595 | Specify a process for btpp and fr commands. 596 | end 597 | define fr 598 | set $fno = 0 599 | set $searching = 1 600 | if ($myvectorproc->p_flag & 4) 601 | set $frame = $myvectorproc->p_addr->u_pcb->pcb_ebp 602 | while (($searching == 1) && (*(int *) $frame > 0xc0000000)) 603 | set $myebp = *(int *) $frame 604 | set $myeip = *(int *) ($frame + 4) 605 | if ($fno == $arg0) 606 | printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp 607 | x/1i $myeip 608 | printf "Called from %8x, stack frame at %8x\n", *(int *) ($myebp+4), *(int *) $myebp 609 | printf "last 20 local variables:\n" 610 | x/20x ($myebp-80) 611 | printf "call parameters:\n" 612 | x/8x ($myebp+8) 613 | set $searching = 0 614 | else 615 | set $frame = $myebp 616 | set $fno = $fno + 1 617 | end 618 | end 619 | if ($searching == 1) 620 | echo frame not found\n 621 | end 622 | else 623 | printf "process %d is not loaded in memory\n", $myvectorproc->p_pid 624 | end 625 | end 626 | document fr 627 | Show the frame of the stack of the process previously selected with 'defproc'. 628 | end 629 | set height 70 630 | set width 120 631 | define vdev 632 | if (vp->v_type == VBLK) 633 | p *vp->v_un.vu_spec.vu_specinfo 634 | printf "numoutput: %d\n", vp->v_numoutput 635 | else 636 | echo "Not a block device" 637 | end 638 | end 639 | document vdev 640 | Show some information of the vnode pointed to by the local variable vp. 641 | end 642 | define y 643 | echo Check your .gdbinit, it contains a y command\n 644 | end 645 | define kldstat 646 | set $file = linker_files.tqh_first 647 | printf "Id Refs Address Size Name\n" 648 | while ($file != 0) 649 | printf "%2d %4d 0x%8x %8x %s\n", \ 650 | $file->id, \ 651 | $file->refs, \ 652 | $file->address, \ 653 | $file->size, \ 654 | $file->filename 655 | set $file = $file->link.tqe_next 656 | end 657 | end 658 | document kldstat 659 | Equivalent of the kldstat(9) command, without options. 660 | end 661 | define msgbuf 662 | printf "%s", msgbufp->msg_ptr 663 | end 664 | document msgbuf 665 | Print the system message buffer (dmesg). This can take a long time due to the time it takes to transmit the data across a serial line. 666 | end 667 | define icnt 668 | set $irq = 0 669 | set $mask = imen 670 | while ($irq < 23) 671 | if ($mask & 1) 672 | printf "%d*\t", *intr_countp [$irq] 673 | else 674 | printf "%d\t", *intr_countp [$irq] 675 | end 676 | if (($irq & 7) == 7) 677 | printf "\n" 678 | end 679 | set $irq = $irq + 1 680 | set $mask = $mask >> 1 681 | end 682 | printf "\nimen: %x\n", imen 683 | end 684 | document icnt 685 | Print the interrupt counts for the first 16 interrupts 686 | end 687 | set $last=75 688 | set $seg=43 689 | 690 | # kmem_hdr 691 | define kmemhdr 692 | printf "\tINUSE\tCALLS\tMEMUSED\tLIMBLK\tMAPBLK\tMAXUSED\t\tLIMIT\n" 693 | end 694 | 695 | # pkmem 696 | define pkmem 697 | set $kp=(struct kmemstats *)$arg0 698 | set $n = (struct kmemstats *)$kp - (struct kmemstats *)kmemstats 699 | printf "%d:\t%d\t%d", $n, $kp->ks_inuse, $kp->ks_calls 700 | printf "\t0x%x\t%d", $kp->ks_memuse, $kp->ks_limblocks 701 | printf "\t%d\t0x%x\t\t%d\n", $kp->ks_mapblocks, $kp->ks_maxused, $kp->ks_limit 702 | end 703 | 704 | define kmemdump 705 | set $kp=(struct kmemstats *)(kmemstats + $arg0) 706 | kmemhdr 707 | pkmem $kp 708 | end 709 | 710 | define kdumpall 711 | set $i=0 712 | 713 | kmemhdr 714 | set $kp = (struct kmemstats *)kmemstats 715 | while ($i < $last) 716 | pkmem $kp 717 | set $kp++ 718 | set $i++ 719 | end 720 | end 721 | define ktr 722 | set $idx = ktr_idx - 1 723 | set $last = ktr_idx 724 | if ($idx == -1) 725 | set $idx = ktr_entries - 1 726 | end 727 | while ($idx != $last) 728 | set $kent = &ktr_buf[$idx] 729 | set $time = $kent->ktr_tv.tv_nsec 730 | set $ts = $kent->ktr_tv.tv_sec 731 | set $desc = $kent->ktr_desc 732 | printf "%3d %d:%9.9d ", $idx, $ts, $time 733 | # printf $desc, $kent->ktr_parm1, $kent->ktr_parm2, $kent->ktr_parm3, $kent->ktr_parm4, $kent->ktr_parm5 734 | if (ktr_extend) 735 | printf "cpu%d %s.%d\t%s\n", $kent->ktr_cpu, $kent->ktr_filename, $kent->ktr_line, $kent->ktr_desc 736 | else 737 | printf "%s %p %p %p %p %p\n", $desc, $kent->ktr_parm1, $kent->ktr_parm2, $kent->ktr_parm3, $kent->ktr_parm4, $kent->ktr_parm5 738 | end 739 | set $idx = $idx - 1 740 | if ($idx == -1) 741 | set $idx = ktr_entries - 1 742 | end 743 | end 744 | end 745 | define ktrc 746 | set $idx = ktr_idx - 1 747 | set $last = ktr_idx 748 | if ($idx == -1) 749 | set $idx = ktr_entries - 1 750 | end 751 | while ($idx != $last) 752 | if (ktr_buf[$idx]->ktr_cpu == $arg0) 753 | set $kent = &ktr_buf[$idx] 754 | set $time = $kent->ktr_tv.tv_nsec 755 | set $ts = $kent->ktr_tv.tv_sec 756 | set $desc = $kent->ktr_desc 757 | printf "%3d %d:%9.9d ", $idx, $ts, $time 758 | if (ktr_extend) 759 | printf "cpu%d %s.%d\t%s\n", $kent->ktr_cpu, $kent->ktr_filename, $kent->ktr_line, $kent->ktr_desc 760 | else 761 | printf "%s %p %p %p %p %p\n", $desc, $kent->ktr_parm1, $kent->ktr_parm2, $kent->ktr_parm3, $kent->ktr_parm4, $kent->ktr_parm5 762 | end 763 | end 764 | set $idx = $idx - 1 765 | if ($idx == -1) 766 | set $idx = ktr_entries - 1 767 | end 768 | end 769 | end 770 | define tc 771 | set $tc = timecounter 772 | printf "Timecounter: %s\n", $tc->tc_name 773 | set $i = 0 774 | while ($i == 0 || $tc != timecounter) 775 | printf "tc%d: tv: %ld:%ld raw: %ld:%ld\n", $i, $tc->tc_microtime->tv_sec, $tc->tc_microtime->tv_usec, $tc->tc_offset_sec, $tc->tc_offset_micro 776 | set $tc = $tc->tc_other 777 | set $i = $i + 1 778 | end 779 | end 780 | -------------------------------------------------------------------------------- /gdb/dot.gdbinit.paths: -------------------------------------------------------------------------------- 1 | set remotebaud 57600 2 | set remotetimeout 1 3 | set complaints 1 4 | set print pretty 5 | -------------------------------------------------------------------------------- /gdb/gdb4: -------------------------------------------------------------------------------- 1 | # $Yahoo: //depot/jhb/tools/gdb4#1 $ 2 | # General kernel macros 3 | 4 | # Macros 5 | set $PID_MAX = 99999 6 | 7 | set $P_CONTROLT = 0x2 8 | set $P_INMEM = 0x4 9 | set $P_PPWAIT = 0x10 10 | set $P_SINTR = 0x80 11 | set $P_SYSTEM = 0x200 12 | set $P_TRACED = 0x800 13 | set $P_WEXIT = 0x02000 14 | set $P_JAILED = 0x1000000 15 | 16 | set $SIDL = 1 17 | set $SRUN = 2 18 | set $SSLEEP = 3 19 | set $SSTOP = 4 20 | set $SZOMB = 5 21 | 22 | set $VROOT = 0x0001 23 | set $VTEXT = 0x0020 24 | set $VSYSTEM = 0x0080 25 | set $VDOOMED = 0x40000 26 | set $VFREE = 0x80000 27 | 28 | set $CTLTYPE = 0xf 29 | set $CTLTYPE_NODE = 1 30 | 31 | set $LK_WAITDRAIN = 0x00080000 32 | 33 | # Number of chars output by %p 34 | set $PTRWIDTH = (sizeof(void *) * 2 + 2) 35 | 36 | # Lookup a process specified via $arg0. We first check to see if it 37 | # is a valid PID, if not, we assume it is a pointer to a struct proc. 38 | # If it looks like a PID, we walk the process lists to find it. The 39 | # proc pointer is returned in $arg1. 40 | define lookup_proc 41 | set $_pid = (int)$arg0 42 | set $arg1 = (struct proc *)$arg0 43 | if ($_pid <= $PID_MAX) 44 | set $_zomb = 0 45 | set $_p = allproc.lh_first 46 | while ($_p) 47 | if ($_p->p_pid == $_pid) 48 | set $arg1 = $_p 49 | set $_p = 0 50 | else 51 | set $_p = $_p->p_list.le_next 52 | if ($_p == 0 && $_zomb == 0) 53 | set $_p = zombproc.lh_first 54 | set $_zomb = 1 55 | end 56 | end 57 | end 58 | end 59 | end 60 | 61 | # formatting helper 62 | # spaces 63 | define spaces 64 | set $_count = $arg0 65 | while (--$_count >= 0) 66 | printf " " 67 | end 68 | end 69 | 70 | # procstate

71 | # Helper function for 'ps' to dump process state string 72 | define procstate 73 | # First determine the primary process state 74 | if ($arg0->p_stat == $SIDL) 75 | printf "N" 76 | end 77 | if ($arg0->p_stat == $SRUN) 78 | printf "R" 79 | end 80 | if ($arg0->p_stat == $SSLEEP) 81 | if ($arg0->p_flag & $P_SINTR) 82 | printf "S" 83 | else 84 | printf "D" 85 | end 86 | end 87 | if ($arg0->p_stat == $SSTOP) 88 | printf "T" 89 | end 90 | if ($arg0->p_stat == $SZOMB) 91 | printf "Z" 92 | end 93 | 94 | # Extra states 95 | set $i = 5 96 | if (!($arg0->p_flag & $P_INMEM)) 97 | printf "W" 98 | set $i = $i - 1 99 | end 100 | if ($arg0->p_flag & $P_TRACED) 101 | printf "X" 102 | set $i = $i - 1 103 | end 104 | if ($arg0->p_flag & $P_WEXIT && $arg0->p_stat != $SZOMB) 105 | printf "E" 106 | set $i = $i - 1 107 | end 108 | if ($arg0->p_flag & $P_PPWAIT) 109 | printf "V" 110 | set $i = $i - 1 111 | end 112 | if ($arg0->p_flag & $P_SYSTEM || $p->p_lock > 0) 113 | printf "L" 114 | set $i = $i - 1 115 | end 116 | if ($arg0->p_pgrp != 0 && $arg0->p_pgrp->pg_session != 0 && \ 117 | $arg0->p_pgrp->pg_session->s_leader == $arg0 && $i > 0) 118 | printf "s" 119 | set $i = $i - 1 120 | end 121 | if ($arg0->p_flag & $P_CONTROLT && $i > 0) 122 | printf "+" 123 | set $i = $i - 1 124 | end 125 | if ($arg0->p_flag & $P_JAILED && $i > 0) 126 | printf "J" 127 | set $i = $i - 1 128 | end 129 | while ($i != 0) 130 | printf " " 131 | set $i = $i - 1 132 | end 133 | end 134 | 135 | # dumpproc 136 | # ps helper to dump info about a given process 137 | define dumpproc 138 | set $pp = $arg0.p_pptr 139 | if ($pp == 0) 140 | set $pp = $arg0 141 | end 142 | if ($arg0.p_cred == 0) 143 | set $uid = 0 144 | else 145 | set $uid = $arg0.p_cred->p_ruid 146 | end 147 | if ($arg0.p_pgrp == 0) 148 | set $pgid = 0 149 | else 150 | set $pgid = $arg0.p_pgrp->pg_id 151 | end 152 | printf "%5d %5d %5d %5d ", $arg0.p_pid, $pp->p_pid, $pgid, $uid 153 | 154 | printf " " 155 | procstate $arg0 156 | printf " " 157 | 158 | if ($arg0->p_stat == $SSLEEP) 159 | printf " %-8.8s %p ", $arg0->p_wmesg, $arg0->p_wchan 160 | else 161 | if ($arg0->p_stat == $SRUN && $arg0->p_oncpu != 0xff) 162 | printf " CPU %2d ", $arg0->p_oncpu 163 | else 164 | printf " " 165 | end 166 | spaces $PTRWIDTH 167 | printf " " 168 | end 169 | if ($arg0->p_flag & $P_SYSTEM) 170 | printf "[" 171 | end 172 | printf "%s", $arg0->p_comm 173 | if ($arg0->p_flag & $P_SYSTEM) 174 | printf "]" 175 | end 176 | printf "\n" 177 | end 178 | 179 | # ps: equivalent of the userland command 180 | define ps 181 | set $nproc = nprocs 182 | set $p = allproc.lh_first 183 | printf " pid ppid pgrp uid state wmesg " 184 | set $foo = ($PTRWIDTH - 5) / 2 185 | spaces $foo 186 | printf "wchan" 187 | set $foo = $PTRWIDTH - 5 - $foo 188 | spaces $foo 189 | printf " cmd\n" 190 | while (--$nproc >= 0) 191 | dumpproc $p 192 | set $p = $p.p_list.le_next 193 | if ($p == 0 && $nproc > 0) 194 | set $p = zombproc.lh_first 195 | end 196 | end 197 | end 198 | document ps 199 | Show process status without options. 200 | end 201 | 202 | # qps: "quick" ps skips any procs that are asleep 203 | define qps 204 | set $nproc = nprocs 205 | set $p = allproc.lh_first 206 | printf " pid ppid pgrp uid state wmesg " 207 | set $foo = ($PTRWIDTH - 5) / 2 208 | spaces $foo 209 | printf "wchan" 210 | set $foo = $PTRWIDTH - 5 - $foo 211 | spaces $foo 212 | printf " cmd\n" 213 | while (--$nproc >= 0) 214 | if ($p.p_stat != $SSLEEP) 215 | dumpproc $p 216 | end 217 | set $p = $p.p_list.le_next 218 | if ($p == 0 && $nproc > 0) 219 | set $p = zombproc.lh_first 220 | end 221 | end 222 | end 223 | document qps 224 | Show process status of non-idle processes without options. 225 | end 226 | 227 | # dmesg: print msgbuf. Can take forever. 228 | define dmesg 229 | printf "%s", msgbufp->msg_ptr 230 | end 231 | document dmesg 232 | Print the system message buffer (dmesg) This can take a long time due to the time it takes to transmit the data across a serial line and even on a firewire connection the processing time slows it down 233 | end 234 | 235 | # checkmem: check unallocated memory for modifications 236 | # this assumes that DIAGNOSTIC is set, which causes 237 | # free memory to be set to 0xdeadc0de 238 | # 239 | # Use: checkmem offset length 240 | define checkmem 241 | set $offset = $arg0 242 | # XXX sizeof int. Needs changing for 64 bit machines. 243 | # subtract 1 because the last word is always different. 244 | set $length = $arg1 / 4 - 1 245 | set $word = 0 246 | while ($word < $length) 247 | if ((int *) $offset) [$word] != 0xdeadc0de 248 | printf "invalid word 0x%x at 0x%x\n", ((int *) $offset) [$word], \ 249 | &((int *) $offset) [$word] 250 | end 251 | set $word = $word + 1 252 | end 253 | end 254 | 255 | document checkmem 256 | Check unallocated memory for modifications This assumes that DIAGNOSTIC is set which causes free memory to be set to 0xdeadc0de. 257 | end 258 | 259 | define kldstat 260 | set $kld = linker_files.tqh_first 261 | printf "Id Refs Address Size Name\n" 262 | while ($kld != 0) 263 | printf "%2d %4d 0x%08x %-8x %s\n", \ 264 | $kld->id, $kld->refs, $kld->address, $kld->size, $kld->filename 265 | set $kld = $kld->link.tqe_next 266 | end 267 | end 268 | 269 | document kldstat 270 | Lists the modules that were loaded when the kernel crashed. 271 | end 272 | 273 | define kldstat-v 274 | set $kld = linker_files.tqh_first 275 | printf "Id Refs Address Size Name\n" 276 | while ($kld != 0) 277 | printf "%2d %4d 0x%08x %-8x %s\n", \ 278 | $kld->id, $kld->refs, $kld->address, $kld->size, $kld->filename 279 | printf " Contains modules:\n" 280 | printf " Id Name\n" 281 | set $module = $kld->modules.tqh_first 282 | while ($module != 0) 283 | printf " %2d %s\n", $module->id, $module->name 284 | set $module = $module->link.tqe_next 285 | end 286 | set $kld = $kld->link.tqe_next 287 | end 288 | end 289 | 290 | # printpcpu 291 | # helper function for pcpu and allpcpu 292 | define printpcpu 293 | set $_gd = $arg0 294 | printf "cpuid = %d\n", $_gd.gd_cpuid 295 | printf "curproc = " 296 | if ($_gd.gd_curproc != 0) 297 | printf "%p: pid %d \"%s\"\n", $_gd.gd_curproc, \ 298 | $_gd.gd_curproc->p_pid, $_gd.gd_curproc->p_comm 299 | else 300 | printf "none\n" 301 | end 302 | printf "curpcb = %p\n", $_gd.gd_curpcb 303 | printf "npxproc = " 304 | if ($_gd.gd_npxproc != 0) 305 | printf "%p: pid %d \"%s\"\n", $_gd.gd_npxproc, \ 306 | $_gd.gd_npxproc->p_pid, $_gd.gd_npxproc->p_comm 307 | else 308 | printf "none\n" 309 | end 310 | end 311 | 312 | define pcpu 313 | printpcpu ((struct privatespace *)SMP_prvspace)[$arg0].globaldata 314 | end 315 | 316 | document pcpu 317 | Display per-CPU information for a specified CPU. 318 | end 319 | 320 | define allpcpu 321 | set $i = 0 322 | while ($i < mp_ncpus) 323 | printpcpu $i 324 | printf "\n" 325 | end 326 | end 327 | 328 | document allpcpu 329 | Display per-CPU information for all CPUs. 330 | end 331 | 332 | define lockmgr_owner 333 | if (((struct lock *)$arg0)->lk_exclusivecount != 0) 334 | set $pid = ((struct lock *)$arg0)->lk_lockholder 335 | lookup_proc $pid $p 336 | printf "p: %p\n", $p 337 | printf "pid: %d, p_comm: %s\n", $p->p_pid, $p->p_comm 338 | end 339 | if (((struct lock *)$arg0)->lk_sharecount != 0) 340 | printf "share count: %d\n", ((struct lock *)$arg0)->lk_sharecount 341 | end 342 | end 343 | 344 | document lockmgr_owner 345 | Displays the owner of a given lockmgr lock 346 | end 347 | 348 | # vtagname 349 | # helper function for vprint 350 | define vtagname 351 | if ($arg0 == VT_NON) 352 | printf "VT_NON" 353 | else 354 | if ($arg0 == VT_UFS) 355 | printf "VT_UFS" 356 | else 357 | if ($arg0 == VT_NFS) 358 | printf "VT_NFS" 359 | else 360 | if ($arg0 == VT_MFS) 361 | printf "VT_MFS" 362 | else 363 | if ($arg0 == VT_FDESC) 364 | printf "VT_FDESC" 365 | else 366 | if ($arg0 == VT_PORTAL) 367 | printf "VT_PORTAL" 368 | else 369 | if ($arg0 == VT_NULL) 370 | printf "VT_NULL" 371 | else 372 | if ($arg0 == VT_UMAP) 373 | printf "VT_UMAP" 374 | else 375 | if ($arg0 == VT_KERNFS) 376 | printf "VT_KERNFS" 377 | else 378 | if ($arg0 == VT_PROCFS) 379 | printf "VT_PROCFS" 380 | else 381 | if ($arg0 == VT_ISOFS) 382 | printf "VT_ISOFS" 383 | else 384 | if ($arg0 == VT_UNION) 385 | printf "VT_UNION" 386 | else 387 | if ($arg0 == VT_MSDOSFS) 388 | printf "VT_MSDOSFS" 389 | else 390 | printf "VT_??:%d", $arg0 391 | end 392 | end 393 | end 394 | end 395 | end 396 | end 397 | end 398 | end 399 | end 400 | end 401 | end 402 | end 403 | end 404 | end 405 | 406 | # vtypename 407 | # helper function for vprint 408 | define vtypename 409 | if ($arg0 == VNON) 410 | printf "VNON" 411 | else 412 | if ($arg0 == VREG) 413 | printf "VREG" 414 | else 415 | if ($arg0 == VDIR) 416 | printf "VDIR" 417 | else 418 | if ($arg0 == VBLK) 419 | printf "VBLK" 420 | else 421 | if ($arg0 == VCHR) 422 | printf "VCHR" 423 | else 424 | if ($arg0 == VLNK) 425 | printf "VLNK" 426 | else 427 | if ($arg0 == VSOCK) 428 | printf "VSOCK" 429 | else 430 | if ($arg0 == VFIFO) 431 | printf "VFIFO" 432 | else 433 | if ($arg0 == VBAD) 434 | printf "VBAD" 435 | else 436 | printf "V??:%d", $arg0 437 | end 438 | end 439 | end 440 | end 441 | end 442 | end 443 | end 444 | end 445 | end 446 | end 447 | 448 | # vprint 449 | # helper function to dump info about a vnode 450 | define vprint 451 | set $vp = (struct vnode *)$arg0 452 | printf "%p: ", $vp 453 | printf "tag " 454 | vtagname $vp->v_tag 455 | printf " type " 456 | vtypename $vp->v_type 457 | printf "\n" 458 | printf " usecount %d, writecount %d, refcount %d\n", \ 459 | $vp->v_usecount, $vp->v_writecount, $vp->v_holdcnt 460 | printf " flags (" 461 | set $_pipe = 0 462 | if ($vp->v_flag & $VROOT) 463 | printf "VROOT" 464 | set $_pipe = 1 465 | end 466 | if ($vp->v_flag & $VTEXT) 467 | if ($_pipe) 468 | printf "|" 469 | end 470 | printf "VTEXT" 471 | set $_pipe = 1 472 | end 473 | if ($vp->v_flag & $VSYSTEM) 474 | if ($_pipe) 475 | printf "|" 476 | end 477 | printf "VSYSTEM" 478 | set $_pipe = 1 479 | end 480 | if ($vp->v_flag & $VDOOMED) 481 | if ($_pipe) 482 | printf "|" 483 | end 484 | printf "VDOOMED" 485 | set $_pipe = 1 486 | end 487 | if ($vp->v_flag & $VFREE) 488 | if ($_pipe) 489 | printf "|" 490 | end 491 | printf "VFREE" 492 | set $_pipe = 1 493 | end 494 | printf ")" 495 | printf "\n" 496 | set $_vobj = $vp->v_object 497 | if ($_vobj != 0) 498 | printf " v_object %p ref %d pages %d\n", $_vobj, $_vobj->ref_count, \ 499 | $_vobj->resident_page_count 500 | end 501 | printf " " 502 | # lockmgr_printinfo() 503 | set $_lkp = $vp->v_vnlock 504 | printf "lock type " 505 | if ($_lkp->lk_wmesg) 506 | printf "%s: ", $_lkp->lk_wmesg 507 | else 508 | printf "(null): " 509 | end 510 | if ($_lkp->lk_sharecount) 511 | printf "SHARED (count %d)", $_lkp->lk_sharecount 512 | else 513 | if ($_lkp->lk_exclusivecount) 514 | printf "EXCL (count %d) by proc %d", $_lkp->lk_exclusivecount, \ 515 | $_lkp->lk_lockholder 516 | else 517 | printf "UNLOCKED" 518 | end 519 | end 520 | if ($_lkp->lk_waitcount > 0) 521 | printf " with %d pending", $_lkp->lk_waitcount 522 | end 523 | printf "\n" 524 | # XXX: no VOP_PRINT 525 | end 526 | 527 | define lockedvnodes 528 | printf "Locked vnodes\n" 529 | set $mp = mountlist.tqh_first 530 | while ($mp != 0) 531 | set $lvp = $mp->mnt_nvnodelist.tqh_first 532 | while ($lvp != 0) 533 | if ($lvp->v_vnlock != 0 && \ 534 | ($lvp->v_vnlock->lk_exclusivecount != 0 || \ 535 | $lvp->v_vnlock->lk_sharecount != 0)) 536 | vprint $lvp 537 | end 538 | set $lvp = $lvp->v_nmntvnodes.tqe_next 539 | end 540 | set $mp = $mp->mnt_list.tqe_next 541 | end 542 | end 543 | 544 | document lockedvnodes 545 | List all of the locked vnodes in the system 546 | end 547 | 548 | # helper functions for sleepchain, return success or failure in $arg1 and 549 | # if ok, owner in $arg2, $arg0 is proc 550 | define lk_chain 551 | set $lkp = (struct lock *)$arg0->p_wchan 552 | # imperfect test to see if the wchan is a lockmgr lock maybe 553 | if ($lkp->lk_wmesg != $arg0->p_wmesg) 554 | # it might be sleeping on &lkp->lk_flags during a drain 555 | set $lkp = (struct lock *)((char *)$lkp - (int)(&((struct lock *)0)->lk_flags)) 556 | if ($lkp->lk_wmesg != $arg0->p_wmesg || !($lkp->lk_flags & $LK_WAITDRAIN)) 557 | set $lkp = 0 558 | end 559 | end 560 | if ($lkp) 561 | set $arg1 = 1 562 | printf "blocked on lk \"%s\" ", $lkp->lk_wmesg 563 | if ($lkp->lk_sharecount) 564 | printf "SHARED (count %d)", $lkp->lk_sharecount 565 | set $arg2 = 0 566 | else 567 | printf "EXCL (count %d)", $lkp->lk_exclusivecount 568 | set $arg2 = $lkp->lk_lockholder 569 | end 570 | else 571 | set $arg1 = 0 572 | end 573 | end 574 | 575 | define sleepchain 576 | set $count = 20 577 | lookup_proc $arg0 $p 578 | while ($p != 0) 579 | printf " proc %d (%s) ", $p->p_pid, $p->p_comm 580 | if ($p->p_wchan != 0) 581 | lk_chain $td $ok $owner 582 | if ($ok != 0) 583 | set $p = $owner 584 | if ($p == $arg0 || --$count == 0) 585 | printf "\n DEADLOCK" 586 | set $p = 0 587 | end 588 | else 589 | printf "non-lock sleep" 590 | set $p = 0 591 | end 592 | else 593 | set $p = 0 594 | end 595 | printf "\n" 596 | end 597 | end 598 | 599 | document sleepchain 600 | Like lockchain but for sleep locks 601 | end 602 | 603 | # sysctl_oid name namelen 604 | def sysctl_oid 605 | set $oid = sysctl__children.slh_first 606 | set $index = 0 607 | while ($oid != 0 && $index < $arg1) 608 | if ($oid->oid_number == $arg0[$index]) 609 | set $index = $index + 1 610 | printf "%6d: %s\n", $oid->oid_number, $oid->oid_name 611 | if (($oid->oid_kind & $CTLTYPE) == $CTLTYPE_NODE) 612 | if ($oid->oid_handler != 0) 613 | set $oid = 0 614 | else 615 | set $oid = ((struct sysctl_oid_list *)$oid->oid_arg1)->slh_first 616 | end 617 | else 618 | set $oid = 0 619 | end 620 | else 621 | set $oid = $oid->oid_link.sle_next 622 | end 623 | end 624 | end 625 | 626 | document sysctl_oid 627 | Try to lookup the name of a sysctl OID. 628 | end 629 | 630 | def memstat 631 | printf "%8d K Active (%2d%%)\n", cnt.v_active_count * cnt.v_page_size / 1024, cnt.v_active_count * 100 / cnt.v_page_count 632 | printf "%8d K Inact (%2d%%)\n", cnt.v_inactive_count * cnt.v_page_size / 1024, cnt.v_inactive_count * 100 / cnt.v_page_count 633 | printf "%8d K Wired (%2d%%)\n", cnt.v_wire_count * cnt.v_page_size / 1024, cnt.v_wire_count * 100 / cnt.v_page_count 634 | printf "%8d K Cache (%2d%%)\n", cnt.v_cache_count * cnt.v_page_size / 1024, cnt.v_cache_count * 100 / cnt.v_page_count 635 | printf "%8d K Buf\n", bufspace / $div 636 | printf "%8d K Free (%2d%%)\n", cnt.v_free_count * cnt.v_page_size / 1024, cnt.v_free_count * 100 / cnt.v_page_count 637 | end 638 | 639 | document memstat 640 | Show top-like memory usage summary 641 | end 642 | 643 | define devstate 644 | if ($arg0->state == DS_NOTPRESENT) 645 | printf "NOT PRESENT" 646 | else 647 | if ($arg0->state == DS_ALIVE) 648 | printf "ALIVE " 649 | else 650 | if ($arg0->state == DS_ATTACHED) 651 | printf "ATTACHED " 652 | else 653 | if ($arg0->state == DS_BUSY) 654 | printf "BUSY: %-5d", $arg0->busy 655 | else 656 | printf "???: %-6d", $arg0->state 657 | end 658 | end 659 | end 660 | end 661 | end 662 | 663 | define dumpdev 664 | set $foo = $PTRWIDTH - 4 665 | if ($dev->nameunit) 666 | printf "%-20s ", $dev->nameunit 667 | else 668 | printf "(null) " 669 | end 670 | devstate $dev 671 | if ($dev->softc) 672 | printf " %p", $dev->softc 673 | else 674 | printf " NULL" 675 | spaces $foo 676 | end 677 | if ($dev->ivars) 678 | printf " %p", $dev->ivars 679 | else 680 | printf " NULL" 681 | spaces $foo 682 | end 683 | printf "\n" 684 | end 685 | 686 | # List device info as 687 | define lsdev 688 | printf " name state " 689 | set $foo = ($PTRWIDTH - 5) / 2 690 | set $bar = $PTRWIDTH - 5 - $foo 691 | spaces $foo 692 | printf "softc" 693 | spaces $bar 694 | printf " " 695 | spaces $foo 696 | printf "ivars\n" 697 | set $dc = devclasses->tqh_first 698 | while ($dc != 0) 699 | set $i = 0 700 | while ($i < $dc->maxunit) 701 | set $dev = $dc->devices[$i] 702 | if ($dev != 0) 703 | dumpdev $dev 704 | end 705 | set $i = $i + 1 706 | end 707 | set $dc = $dc->link.tqe_next 708 | end 709 | end 710 | 711 | document lsdev 712 | Show new-bus devices. 713 | end 714 | 715 | # Show the new-bus device tree 716 | define devinfo 717 | set $indent = 0 718 | set $dev = root_bus 719 | set $ignore = 0 720 | while ($dev != 0) 721 | if ($dev->nameunit != 0 && $ignore == 0) 722 | spaces $indent 723 | printf "%s\n", $dev->nameunit 724 | end 725 | if ($dev->children.tqh_first != 0 && $ignore == 0) 726 | set $dev = $dev->children.tqh_first 727 | set $indent = $indent + 1 728 | set $ignore = 0 729 | else 730 | if ($dev->link.tqe_next != 0) 731 | set $dev = $dev->link.tqe_next 732 | set $ignore = 0 733 | else 734 | set $indent = $indent - 1 735 | set $dev = $dev->parent 736 | set $ignore = 1 737 | end 738 | end 739 | end 740 | end 741 | 742 | document devinfo 743 | Show new-bus heirarchy similar to devinfo(8). 744 | end 745 | 746 | define ip 747 | set $_ip = (u_int32_t)$arg0 748 | printf "%d.%d.%d.%d\n", $_ip >> 24, $_ip >> 16 & 0xff, \ 749 | $_ip >> 8 & 0xff, $_ip & 0xff 750 | end 751 | 752 | document ip 753 | Print IPv4 address in dotted-decimal format. 754 | end 755 | 756 | define sin 757 | set $_sin = (struct sockaddr_in *)$arg0 758 | set $_port = $_sin->sin_port >> 8 | ($_sin->sin_port & 0xff) << 8 759 | printf "IP: " 760 | ip $_sin->sin_addr.s_addr 761 | printf "port: %d\n", $_port 762 | end 763 | 764 | document sin 765 | Display IP and port of a AF_INET socket address. 766 | end 767 | 768 | define prison_ips 769 | printf "host: %s\n", $arg0->pr_host 770 | set $_i = 0 771 | while ($_i < $arg0->pr_nips) 772 | ip $arg0->pr_ips[$_i]->pi_ip 773 | set $_i = $_i + 1 774 | end 775 | end 776 | 777 | document prison_ips 778 | Display IP addresses of a JAILED_VIPS prison. 779 | end 780 | -------------------------------------------------------------------------------- /gdb/gdb6.amd64: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | # amd64-specific kernel macros 3 | 4 | if (osreldate >= 1000046) 5 | set $DMAP_MIN_ADDRESS = 0xfffff80000000000 6 | set $DMAP_MAX_ADDRESS = 0xfffffc0000000000 7 | else 8 | set $DMAP_MIN_ADDRESS = 0xffffff0000000000 9 | set $DMAP_MAX_ADDRESS = 0xffffff8000000000 10 | end 11 | set $PG_PDE_PAT = 0x1000 12 | set $PG_PTE_PAT = 0x80 13 | set $PG_PS = 0x80 14 | set $PG_A = 0x20 15 | set $PG_NC_PCD = 0x10 16 | set $PG_NC_PWT = 0x8 17 | set $PG_U = 0x4 18 | set $PG_V = 0x1 19 | set $PG_PS_FRAME = 0xfffffffe00000 20 | set $PG_FRAME = 0xffffffffff000 21 | set $PDMAP = 0xffff804000000000 22 | set $PTMAP = 0xffff800000000000 23 | set $PDRMASK = 0x1fffff 24 | set $PAGE_MASK = 0xfff 25 | set $PAGE_SIZE = 0x1000 26 | set $PDE_MASK = 0x7ffffff 27 | set $PTE_MASK = 0xfffffffff 28 | set $PML4SHIFT = 0x27 29 | set $PDPSHIFT = 0x1e 30 | set $PDRSHIFT = 0x15 31 | set $PAGE_SHIFT = 0xc 32 | set $NPML4EPGSHIFT = 0x9 33 | set $NPDPEPGSHIFT = 0x9 34 | set $NPDEPGSHIFT = 0x9 35 | set $NPTEPGSHIFT = 0x9 36 | 37 | set $MC_STATUS_ADDRV = 0x0400000000000000 38 | set $MC_STATUS_MISCV = 0x0800000000000000 39 | 40 | set $VM_NFREEPOOL = 3 41 | set $VM_NFREELIST = 2 42 | set $VM_FREELIST_DEFAULT = 0 43 | set $VM_NFREEORDER = 13 44 | 45 | define pmap_pml4e 46 | set $_pm = (struct pmap *)$arg0 47 | set $_va = (long)$arg1 48 | if ($_pm == 0) 49 | set $_pm = &kernel_pmap_store 50 | end 51 | set $arg2 = $_pm->pm_pml4[(($_va >> $PML4SHIFT) & (((long)1 << $NPML4EPGSHIFT) - 1))] 52 | end 53 | 54 | document pmap_pml4e 55 | Given a pmap and virtual address, lookup the value of the pml4 entry and 56 | store it in the 3rd arg. 57 | end 58 | 59 | define phys_to_dmap 60 | set $arg1 = (long)$arg0 | $DMAP_MIN_ADDRESS 61 | end 62 | 63 | document phys_to_dmap 64 | Given a physical address, return the corresponding virtual address in the 65 | direct map in the 2nd arg. 66 | end 67 | 68 | define pmap_pdpe 69 | pmap_pml4e $arg0 $arg1 $_pml4e 70 | if (!($_pml4e & $PG_V)) 71 | set $arg2 = 0 72 | else 73 | set $_va = (long)$arg1 74 | set $_temp = (long)$_pml4e & $PG_FRAME 75 | phys_to_dmap $_temp $__pdpe 76 | set $arg2 = ((pdp_entry_t *)$__pdpe)[(($_va >> $PDPSHIFT) & \ 77 | (((long)1 << $NPDPEPGSHIFT) - 1))] 78 | end 79 | end 80 | 81 | document pmap_pdpe 82 | Given a pmap and virtual address, lookup the value of the pdp entry and 83 | store it in the 3rd arg. 84 | end 85 | 86 | define pmap_pde 87 | pmap_pdpe $arg0 $arg1 $_pdpe 88 | if (!($_pdpe & $PG_V)) 89 | set $arg2 = 0 90 | else 91 | set $_va = (long)$arg1 92 | set $_temp = (long)$_pdpe & $PG_FRAME 93 | phys_to_dmap $_temp $__pde 94 | set $arg2 = ((pd_entry_t *)$__pde)[(($_va >> $PDRSHIFT) & \ 95 | (((long)1 << $NPDEPGSHIFT) - 1))] 96 | end 97 | end 98 | 99 | document pmap_pde 100 | Given a pmap and virtual address, lookup the value of the page directory entry 101 | and store it in the 3rd arg. 102 | end 103 | 104 | define pmap_pte 105 | pmap_pde $arg0 $arg1 $_pde 106 | if (!($_pde & $PG_V)) 107 | set $arg2 = 0 108 | else 109 | if ($_pde & $PG_PS) 110 | set $arg2 = $_pde 111 | else 112 | set $_va = (long)$arg1 113 | set $_temp = (long)$_pde & $PG_FRAME 114 | phys_to_dmap $_temp $__pte 115 | set $arg2 = ((pt_entry_t *)$__pte)[(($_va >> $PAGE_SHIFT) & \ 116 | (((long)1 << $NPTEPGSHIFT) - 1))] 117 | end 118 | end 119 | end 120 | 121 | document pmap_pte 122 | Given a pmap and virtual address, lookup the value of the page table entry 123 | and store it in the 3rd arg. 124 | end 125 | 126 | define pmap_kextract 127 | set $va = (long)$arg0 128 | set $pa = -1 129 | if ($va >= $DMAP_MIN_ADDRESS && $va <= $DMAP_MAX_ADDRESS) 130 | set $pa = $va - $DMAP_MIN_ADDRESS 131 | else 132 | pmap_pde 0 $arg0 $pde 133 | if ($pde & $PG_V) 134 | if ($pde & $PG_PS) 135 | set $pa = ($pde & $PG_PS_FRAME) | ($va & $PDRMASK) 136 | else 137 | pmap_pte 0 $arg0 $pte 138 | if ($pte & $PG_V) 139 | set $pa = ($pte & $PG_FRAME) | \ 140 | ($va & $PAGE_MASK) 141 | end 142 | end 143 | end 144 | end 145 | if ($pa == -1) 146 | printf "Invalid, unmapped, or unfaulted address\n" 147 | else 148 | printf "KVA %p => 0x%lx\n", $va, $pa 149 | end 150 | end 151 | 152 | document pmap_kextract 153 | Map a kernel virtual address to a physical address on amd64. 154 | 'kextract' in kgdb is more portable. 155 | end 156 | 157 | define pmap_extract 158 | set $va = (long)$arg1 159 | set $pa = -1 160 | pmap_pde $arg0 $arg1 $pde 161 | if ($pde & $PG_V) 162 | if ($pde & $PG_PS) 163 | set $pa = ($pde & $PG_PS_FRAME) | ($va & $PDRMASK) 164 | else 165 | pmap_pte $arg0 $arg1 $pte 166 | if ($pte & $PG_V) 167 | set $pa = ($pte & $PG_FRAME) | ($va & $PAGE_MASK) 168 | end 169 | end 170 | end 171 | if ($pa == -1) 172 | printf "Invalid, unmapped, or unfaulted address\n" 173 | else 174 | printf "VA %p => 0x%lx\n", $va, $pa 175 | end 176 | end 177 | 178 | document pmap_extract 179 | Map a user virtual address to a physical address on amd64. 180 | end 181 | 182 | define rawpte 183 | set $va = (long)$arg1 184 | set $pte = 0 185 | pmap_pde $arg0 $arg1 $pde 186 | if (($pde & ($PG_V | $PG_PS)) == $PG_V) 187 | pmap_pte $arg0 $arg1 $pte 188 | end 189 | if ($pte == 0) 190 | printf "VA %p => PDE 0x%lx\n", $va, $pde 191 | set $_pat = $pde & ($PG_PDE_PAT | $PG_NC_PCD | $PG_NC_PWT) 192 | else 193 | printf "VA %p => PTE 0x%lx\n", $va, $pte 194 | set $_pat = $pte & ($PG_PTE_PAT | $PG_NC_PCD | $PG_NC_PWT) 195 | end 196 | printf "PAT bits: 0x%lx\n", $_pat 197 | end 198 | 199 | document rawpte 200 | Display the raw PTE/PDE for a given virtual address. 201 | end 202 | 203 | define pmap_check_pgu 204 | set $pm = &kernel_pmap_store 205 | set $i = 256 206 | while ($i < 512) 207 | set $pml4e = $pm->pm_pml4[$i] 208 | if ($pml4e & ($PG_U | $PG_V)) == ($PG_U | $PG_V) 209 | printf "pml4e[%d]\n", $i 210 | set $_temp = (long)$pml4e & $PG_FRAME 211 | phys_to_dmap $_temp $pdp 212 | set $j = 0 213 | while ($j < 512) 214 | set $pdpe = ((pdp_entry_t *)$pdp)[$j] 215 | if ($pdpe & ($PG_V | $PG_U)) == ($PG_V | $PG_U) 216 | if ($pdpe & $PG_PS) 217 | set $va = $DMAP_MIN_ADDRESS | ($i << $PML4SHIFT) | \ 218 | ($j << $PDPSHIFT) 219 | printf "%p: 1GB PG_V | PG_U | PG_PS\n", $va 220 | else 221 | printf "pdpe[%d,%d]\n", $i, $j 222 | set $_temp = (long)$pdpe & $PG_FRAME 223 | phys_to_dmap $_temp $pd 224 | set $k = 0 225 | while ($k < 512) 226 | set $k = $k + 1 227 | set $pde = ((pd_entry_t *)$pd)[$k] 228 | if ($pde & ($PG_V | $PG_U)) == ($PG_V | $PG_U) 229 | if ($pde & $PG_PS) 230 | set $va = $DMAP_MIN_ADDRESS | \ 231 | ($i << $PML4SHIFT) | \ 232 | ($j << $PDPSHIFT) | \ 233 | ($k << $PDRSHIFT) 234 | printf "%p: 2MB PG_V | PG_U | PG_PS\n", \ 235 | $va 236 | else 237 | printf "pde[%d,%d,%d]\n", $i, $j, $k 238 | set $_temp = (long)$pde & $PG_FRAME 239 | phys_to_dmap $_temp $pt 240 | set $l = 0 241 | while ($l < 512) 242 | set $pte = ((pt_entry_t *)$pt)[$l] 243 | if ($pte & ($PG_V | $PG_U)) == ($PG_V | $PG_U) 244 | set $va = $DMAP_MIN_ADDRESS | \ 245 | ($i << $PML4SHIFT) | \ 246 | ($j << $PDPSHIFT) | \ 247 | ($k << $PDRSHIFT) | \ 248 | ($l << $PAGE_SHIFT) 249 | printf "%p: 4KB PG_V | PG_U\n", $va 250 | printf "PML4E: %llx\n", $pml4e 251 | printf "PDPE: %llx\n", $pdpe 252 | printf "PDE: %llx\n", $pde 253 | printf "PTE: %llx\n", $pte 254 | end 255 | set $l = $l + 1 256 | end 257 | end 258 | end 259 | set $k = $k + 1 260 | end 261 | end 262 | end 263 | set $j = $j + 1 264 | end 265 | end 266 | set $i = $i + 1 267 | end 268 | end 269 | 270 | define pmap_checkpgu_pml4 271 | set $_pm = (struct pmap *)$arg0 272 | set $i = 1 273 | set $start = 0 274 | set $last = $_pm->pm_pml4[0] & $PG_U 275 | while ($i < 512) 276 | if ($_pm->pm_pml4[$i] & $PG_U) != $last 277 | printf "%d-%d: ", $start, $i-1 278 | if $last == 0 279 | printf "\n" 280 | else 281 | printf "PG_U\n" 282 | end 283 | set $start = $i 284 | set $last = $_pm->pm_pml4[$i] & $PG_U 285 | end 286 | set $i = $i + 1 287 | end 288 | printf "%d-%d: ", $start, $i-1 289 | if $last == 0 290 | printf "\n" 291 | else 292 | printf "PG_U\n" 293 | end 294 | end 295 | 296 | define pmap_checkdmap_pgu 297 | set $pm = &kernel_pmap_store 298 | set $va = (uint64_t)&dmapbase 299 | while ($va < &dmaplimit) 300 | pmap_pdpe $pm $va $_pdpe 301 | if ($_pdpe & ($PG_V | $PG_U)) == ($PG_V | $PG_U) 302 | printf "%p: PG_V | PG_U", $va 303 | if ($_pdpe & $PG_PS) 304 | printf " | PG_PS (XXX)" 305 | end 306 | printf "\n" 307 | else 308 | if $_pdpe & ($PG_PS | $PG_V) 309 | printf "%p: PG_V | PG_PS (ok)\n", $va 310 | end 311 | end 312 | set $va = $va + (1024 * 1024 * 1024) 313 | end 314 | end 315 | 316 | define pmap_pages 317 | set $pm = (struct pmap *)$arg0 318 | set $sva = $arg1 319 | set $eva = $arg2 320 | set $pv = $pm->pm_pvlist.tqh_first 321 | while ($pv != 0) 322 | if ($pv->pv_va >= $sva && $pv->pv_va <= $eva) 323 | printf "%08llx: page XXX\n", $pv->pv_va 324 | end 325 | set $pv = $pv->pv_plist.tqe_next 326 | end 327 | end 328 | 329 | document pmap_pages 330 | Given a pmap, a starting virtual address, and an ending virtual address, 331 | list all the pages that fall in the range. 332 | end 333 | 334 | # Do a backtrace given %rip and %rbp as args 335 | define bt 336 | set $_rip = $arg0 337 | set $_rbp = $arg1 338 | set $i = 0 339 | while ($_rbp != 0 || $_rip != 0) 340 | printf "%2d: pc ", $i 341 | if ($_rip != 0) 342 | x/1i $_rip 343 | else 344 | printf "\n" 345 | end 346 | if ($_rbp == 0) 347 | set $_rip = 0 348 | else 349 | set $fr = (struct amd64_frame *)$_rbp 350 | set $_rbp = $fr->f_frame 351 | set $_rip = $fr->f_retaddr 352 | set $i = $i + 1 353 | end 354 | end 355 | end 356 | 357 | document bt 358 | Given values for %rip and %rbp, perform a manual backtrace. 359 | end 360 | 361 | define btf 362 | bt $arg0.tf_rip $arg0.tf_rbp 363 | end 364 | 365 | document btf 366 | Do a manual backtrace from a specified trapframe. 367 | end 368 | 369 | define irqs 370 | set $e = event_list->tqh_first 371 | while ($e != 0) 372 | if ($e->ie_source != 0 && $e->ie_handlers.tqh_first != 0) 373 | set $src = (struct intsrc *)$e->ie_source 374 | if ($src->is_pic->pic_enable_source == &ioapic_enable_source) 375 | set $_cpu = ((struct ioapic_intsrc *)$src)->io_cpu 376 | else 377 | if ($src->is_pic->pic_enable_source == &msi_enable_source) 378 | set $_cpu = ((struct msi_intsrc *)$src)->msi_cpu 379 | else 380 | set $_cpu = 0 381 | end 382 | end 383 | printf "CPU %d: %s\n", $_cpu, $e->ie_fullname 384 | end 385 | set $e = $e->ie_list.tqe_next 386 | end 387 | end 388 | 389 | document irqs 390 | Dump list of IRQs with associated CPU. 391 | end 392 | 393 | define mca_log_old 394 | printf "MCA: bank %d, status 0x%016llx\n", $arg0.mr_bank, $arg0.mr_status 395 | printf "MCA: CPU %d xxxx\n", $arg0.mr_apic_id 396 | if ($arg0.mr_status & $MC_STATUS_ADDRV) 397 | printf "MCA: Address 0x%llx\n", $arg0.mr_addr 398 | end 399 | if ($arg0.mr_status & $MC_STATUS_MISCV) 400 | printf "MCA: Misc 0x%llx\n", $arg0.mr_misc 401 | end 402 | end 403 | 404 | define mca_log 405 | printf "MCA: Bank %d, Status 0x%016llx\n", $arg0.mr_bank, $arg0.mr_status 406 | printf "MCA: Global Cap 0x%016llx, Status 0x%016llx\n", $arg0.mr_mcg_cap, \ 407 | $arg0.mr_mcg_status 408 | printf "MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor, \ 409 | $arg0.mr_cpu_id, $arg0.mr_apic_id 410 | printf "MCA: CPU %d xxxx\n", $arg0.mr_cpu 411 | if ($arg0.mr_status & $MC_STATUS_ADDRV) 412 | printf "MCA: Address 0x%llx\n", $arg0.mr_addr 413 | end 414 | if ($arg0.mr_status & $MC_STATUS_MISCV) 415 | printf "MCA: Misc 0x%llx\n", $arg0.mr_misc 416 | end 417 | end 418 | 419 | define mca 420 | set $mr = mca_records.stqh_first 421 | while ($mr != 0) 422 | if (sizeof($mr->rec) == 40) 423 | mca_log_old $mr->rec 424 | else 425 | mca_log $mr->rec 426 | end 427 | set $mr = $mr->link.stqe_next 428 | end 429 | end 430 | 431 | document mca 432 | Display machine check records in dmesg format for mcelog parsing. 433 | end 434 | 435 | directory /sys/amd64/include 436 | directory /sys/amd64/compile/GENERIC 437 | -------------------------------------------------------------------------------- /gdb/gdb6.i386: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | # i386-specific kernel macros 3 | 4 | set $PG_PDE_PAT = 0x1000 5 | set $PG_PTE_PAT = 0x80 6 | set $PG_PS = 0x80 7 | set $PG_NC_PCD = 0x10 8 | set $PG_NC_PWT = 0x8 9 | set $PG_V = 0x1 10 | set $PG_PS_FRAME = 0xffe00000 11 | set $PG_FRAME = 0xfffff000 12 | set $PTMAP = 0x9fc00000 13 | set $PDRMASK = 0x1fffff 14 | set $PAGE_MASK = 0xfff 15 | set $PAGE_SIZE = 0x1000 16 | set $PDRSHIFT = 0x15 17 | set $PAGE_SHIFT = 0xc 18 | 19 | define pmap_pde 20 | set $_pm = (struct pmap *)$arg0 21 | if ($_pm == 0) 22 | set $_pm = &kernel_pmap_store 23 | end 24 | set $arg2 = $_pm->pm_pdir[(vm_offset_t)$arg1 >> $PDRSHIFT] 25 | end 26 | 27 | document pmap_pde 28 | Given a pmap and virtual address, lookup the value of the page directory entry 29 | and store it in the 3rd arg. 30 | end 31 | 32 | define pmap_pte 33 | pmap_pde $arg0 $arg1 $_pde 34 | if (!($_pde & $PG_V)) 35 | set $arg2 = 0 36 | else 37 | if ($_pde & $PG_PS) 38 | set $arg2 = $_pde 39 | else 40 | set $arg2 = ((pt_entry_t *)$PTMAP)[(vm_offset_t)$arg1 >> $PAGE_SHIFT] 41 | end 42 | end 43 | end 44 | 45 | document pmap_pte 46 | Given a pmap and virtual address, lookup the value of the page table entry 47 | and store it in the 3rd arg. 48 | end 49 | 50 | define pmap_kextract 51 | set $va = (long)$arg0 52 | set $pa = -1 53 | pmap_pde 0 $arg0 $pde 54 | if ($pde & $PG_V) 55 | if ($pde & $PG_PS) 56 | set $pa = ($pde & $PG_PS_FRAME) | ($va & $PDRMASK) 57 | else 58 | pmap_pte 0 $arg0 $pte 59 | if ($pte & $PG_V) 60 | set $pa = ($pte & $PG_FRAME) | ($va & $PAGE_MASK) 61 | end 62 | end 63 | end 64 | if ($pa == -1) 65 | printf "Invalid or unmapped address\n" 66 | else 67 | printf "KVA %p => 0x%lx\n", $va, $pa 68 | end 69 | end 70 | 71 | document pmap_kextract 72 | Map a kernel virtual address to a physical address on i386. 73 | 'kextract' in kgdb is more portable. 74 | end 75 | 76 | define pmap_extract 77 | set $va = (long)$arg1 78 | set $pa = -1 79 | pmap_pde $arg0 $arg1 $pde 80 | if ($pde & $PG_V) 81 | if ($pde & $PG_PS) 82 | set $pa = ($pde & $PG_PS_FRAME) | ($va & $PDRMASK) 83 | else 84 | pmap_pte $arg0 $arg1 $pte 85 | if ($pte & $PG_V) 86 | set $pa = ($pte & $PG_FRAME) | ($va & $PAGE_MASK) 87 | end 88 | end 89 | end 90 | if ($pa == -1) 91 | printf "Invalid or unmapped address\n" 92 | else 93 | printf "VA %p => 0x%lx\n", $va, $pa 94 | end 95 | end 96 | 97 | document pmap_extract 98 | Map a user virtual address to a physical address on i386. 99 | end 100 | 101 | define rawpte 102 | set $va = (long)$arg1 103 | set $pte = 0 104 | pmap_pde $arg0 $arg1 $pde 105 | if (($pde & ($PG_V | $PG_PS)) == $PG_V) 106 | pmap_pte $arg0 $arg1 $pte 107 | end 108 | if ($pte == 0) 109 | printf "VA %p => PDE 0x%lx\n", $va, $pde 110 | set $_pat = $pde & ($PG_PDE_PAT | $PG_NC_PCD | $PG_NC_PWT) 111 | else 112 | printf "VA %p => PTE 0x%lx\n", $va, $pte 113 | set $_pat = $pte & ($PG_PTE_PAT | $PG_NC_PCD | $PG_NC_PWT) 114 | end 115 | printf "PAT bits: 0x%lx\n", $_pat 116 | end 117 | 118 | document rawpte 119 | Display the raw PTE/PDE for a given virtual address. 120 | end 121 | 122 | define pmap_pages 123 | set $pm = (struct pmap *)$arg0 124 | set $sva = $arg1 125 | set $eva = $arg2 126 | set $pv = $pm->pm_pvlist.tqh_first 127 | while ($pv != 0) 128 | if ($pv->pv_va >= $sva && $pv->pv_va <= $eva) 129 | printf "%08llx: page XXX\n", $pv->pv_va 130 | end 131 | set $pv = $pv->pv_plist.tqe_next 132 | end 133 | end 134 | 135 | document pmap_pages 136 | Given a pmap, a starting virtual address, and an ending virtual address, 137 | list all the pages that fall in the range. 138 | end 139 | 140 | # Do a backtrace given %eip and %ebp as args 141 | define bt 142 | set $_eip = $arg0 143 | set $_ebp = $arg1 144 | set $i = 0 145 | while ($_ebp != 0 || $_eip != 0) 146 | printf "%2d: pc ", $i 147 | if ($_eip != 0) 148 | x/1i $_eip 149 | else 150 | printf "\n" 151 | end 152 | if ($_ebp == 0) 153 | set $_eip = 0 154 | else 155 | set $fr = (struct i386_frame *)$_ebp 156 | set $_ebp = $fr->f_frame 157 | set $_eip = $fr->f_retaddr 158 | set $i = $i + 1 159 | end 160 | end 161 | end 162 | 163 | document bt 164 | Given values for %eip and %ebp, perform a manual backtrace. 165 | end 166 | 167 | define btf 168 | bt $arg0.tf_eip $arg0.tf_ebp 169 | end 170 | 171 | document btf 172 | Do a manual backtrace from a specified trapframe. 173 | end 174 | 175 | define irqs 176 | set $e = event_list->tqh_first 177 | while ($e != 0) 178 | if ($e->ie_source != 0 && $e->ie_handlers.tqh_first != 0) 179 | set $src = (struct intsrc *)$e->ie_source 180 | if ($src->is_pic->pic_enable_source == &ioapic_enable_source) 181 | set $_cpu = ((struct ioapic_intsrc *)$src)->io_cpu 182 | else 183 | if ($src->is_pic->pic_enable_source == &msi_enable_source) 184 | set $_cpu = ((struct msi_intsrc *)$src)->msi_cpu 185 | else 186 | set $_cpu = 0 187 | end 188 | end 189 | printf "CPU %d: %s\n", $_cpu, $e->ie_fullname 190 | end 191 | set $e = $e->ie_list.tqe_next 192 | end 193 | end 194 | 195 | document irqs 196 | Dump list of IRQs with associated CPU. 197 | end 198 | 199 | directory /sys/i386/include 200 | directory /sys/i386/compile/GENERIC 201 | -------------------------------------------------------------------------------- /gdb/gdb6.riscv: -------------------------------------------------------------------------------- 1 | # riscv-specific kernel macros 2 | 3 | set $DMAP_MIN_ADDRESS = (0xffffffd000000000UL) 4 | set $DMAP_MAX_ADDRESS = (0xfffffff000000000UL) 5 | 6 | set $L0_SHIFT = 39 7 | 8 | set $L1_SHIFT = 30 9 | set $L1_SIZE = (1ULL << $L1_SHIFT) 10 | set $L1_OFFSET = ($L1_SIZE - 1) 11 | 12 | set $L2_SHIFT = 21 13 | set $L2_SIZE = (1ULL << $L2_SHIFT) 14 | set $L2_OFFSET = ($L2_SIZE - 1) 15 | 16 | set $L3_SHIFT = 12 17 | set $L3_SIZE = (1ULL << $L3_SHIFT) 18 | set $L3_OFFSET = ($L3_SIZE - 1) 19 | 20 | set $Ln_ENTRIES = (1ULL << 9) 21 | set $Ln_ADDR_MASK = ($Ln_ENTRIES - 1) 22 | 23 | set $PAGE_SIZE = $L3_SIZE 24 | 25 | set $PTE_SC = 0x8000000000000000 26 | set $PTE_LC = 0x4000000000000000 27 | set $PTE_D = 0x80 28 | set $PTE_A = 0x40 29 | set $PTE_G = 0x20 30 | set $PTE_U = 0x10 31 | set $PTE_X = 0x08 32 | set $PTE_W = 0x04 33 | set $PTE_R = 0x02 34 | set $PTE_V = 0x01 35 | set $PTE_RX = ($PTE_R | $PTE_X) 36 | set $PTE_RWX = ($PTE_R | $PTE_W | $PTE_X) 37 | set $PTE_PERMS = ($PTE_RWX | $PTE_LC | $PTE_SC) 38 | 39 | set $PTE_PPN0_S = 10 40 | set $PTE_PPN1_S = 19 41 | set $PTE_PPN2_S = 28 42 | set $PTE_PPN3_S = 37 43 | 44 | define phys_to_dmap 45 | set $arg1 = ((long)$arg0 - dmap_phys_base) | $DMAP_MIN_ADDRESS 46 | end 47 | 48 | document phys_to_dmap 49 | Given a physical address, return the corresponding virtual address in the 50 | direct map in the 2nd arg. 51 | end 52 | 53 | define pmap_l1 54 | set $_pm = (struct pmap *)$arg0 55 | set $_va = (long)$arg1 56 | if ($_pm == 0) 57 | set $_pm = &kernel_pmap_store 58 | end 59 | set $arg2 = $_pm->pm_l1[($_va >> $L1_SHIFT) & $Ln_ADDR_MASK] 60 | end 61 | 62 | document pmap_l1 63 | Given a pmap and a virtual address, lookup the value of the L1 entry and 64 | store it in the 3rd arg. 65 | end 66 | 67 | define pmap_l2 68 | pmap_l1 $arg0 $arg1 $_l1e 69 | if (($_l1e & $PTE_V) == 0) 70 | set $arg2 = 0 71 | else 72 | if (($_l1e & $PTE_RX) != 0) 73 | set $arg2 = $_l1e 74 | else 75 | set $_va = (long)$arg1 76 | set $_temp = ((long)$_l1e >> $PTE_PPN0_S) * $PAGE_SIZE 77 | phys_to_dmap $_temp $_l2t 78 | set $arg2 = ((uint64_t *)$_l2t)[($_va >> $L2_SHIFT) & $Ln_ADDR_MASK] 79 | end 80 | end 81 | end 82 | 83 | document pmap_l2 84 | Given a pmap and a virtual address, lookup the value of the L2 entry and 85 | store it in the 3rd arg. 86 | end 87 | 88 | define pmap_l3 89 | pmap_l2 $arg0 $arg1 $_l2e 90 | if (($_l2e & $PTE_V) == 0) 91 | set $arg2 = 0 92 | else 93 | if (($_l2e & $PTE_RX) != 0) 94 | set $arg2 = $_l2e 95 | else 96 | set $_va = (long)$arg1 97 | set $_temp = ((long)$_l1e >> $PTE_PPN0_S) * $PAGE_SIZE 98 | phys_to_dmap $_temp $_l3t 99 | set $arg2 = ((uint64_t *)$_l3t)[($_va >> $L3_SHIFT) & $Ln_ADDR_MASK] 100 | end 101 | end 102 | end 103 | 104 | document pmap_l3 105 | Given a pmap and a virtual address, lookup the value of the L3 entry and 106 | store it in the 3rd arg. 107 | end 108 | 109 | define pmap_kextract 110 | set $va = (long)$arg0 111 | set $pa = -1 112 | if ($va >= $DMAP_MIN_ADDRESS && $va <= $DMAP_MAX_ADDRESS) 113 | set $pa = $va - $DMAP_MIN_ADDRESS 114 | else 115 | pmap_l3 0 $arg0 $l3e 116 | if ($l3e & $PTE_V) 117 | set $pa = ($l3e >> $PTE_PPN0_S) * $PAGE_SIZE 118 | end 119 | end 120 | if ($pa == -1) 121 | printf "Invalid, unmapped, or unfaulted address\n" 122 | else 123 | printf "KVA %p => 0x%lx\n", $va, $pa 124 | end 125 | end 126 | 127 | document pmap_kextract 128 | Map a kernel virtual address to a physical address on riscv. 129 | 'kextract' in kgdb is more portable. 130 | end 131 | 132 | define pmap_extract 133 | set $va = (long)$arg1 134 | set $pa = -1 135 | pmap_l3 $arg0 $arg1 $l3e 136 | if ($l3e & $PTE_V) 137 | set $pa = ($l3e >> $PTE_PPN0_S) * $PAGE_SIZE 138 | end 139 | if ($pa == -1) 140 | printf "Invalid, unmapped, or unfaulted address\n" 141 | else 142 | printf "VA %p => 0x%lx\n", $va, $pa 143 | end 144 | end 145 | 146 | document pmap_extract 147 | Map a user virtual address to a physical address on amd64. 148 | end 149 | 150 | define pmap_perms_print 151 | if ($start != -1) 152 | printf "%p - %p: ", $start, $end 153 | if ($perms & $PTE_R) 154 | printf "R" 155 | else 156 | printf "-" 157 | end 158 | if ($perms & $PTE_W) 159 | printf "W" 160 | else 161 | printf "-" 162 | end 163 | if ($perms & $PTE_X) 164 | printf "X" 165 | else 166 | printf "-" 167 | end 168 | if ($perms & $PTE_LC) 169 | printf "L" 170 | else 171 | printf "-" 172 | end 173 | if ($perms & $PTE_SC) 174 | printf "S" 175 | else 176 | printf "-" 177 | end 178 | printf "\n" 179 | end 180 | set $start = -1 181 | end 182 | 183 | define pmap_perms_l3 184 | if (($l3e & $PTE_V) == 0) 185 | pmap_perms_print 186 | else 187 | if ($start == -1 || ($l3e & $PTE_PERMS) != $perms) 188 | pmap_perms_print 189 | set $start = $va 190 | set $perms = $l3e & $PTE_PERMS 191 | end 192 | set $end = $va + ($L3_SIZE - 1) 193 | end 194 | set $va = $va + $L3_SIZE 195 | end 196 | 197 | define pmap_perms_l2 198 | if (($l2e & $PTE_V) == 0) 199 | pmap_perms_print 200 | set $va = $va + $L2_SIZE 201 | else 202 | if (($l2e & $PTE_RX) != 0) 203 | if ($start == -1 || ($l2e & $PTE_PERMS) != $perms) 204 | pmap_perms_print 205 | set $start = $va 206 | set $perms = $l2e & $PTE_PERMS 207 | end 208 | set $end = $va + ($L2_SIZE - 1) 209 | set $va = $va + $L2_SIZE 210 | else 211 | set $temp3 = (($l2e >> $PTE_PPN0_S) * $PAGE_SIZE) 212 | phys_to_dmap $temp3 $l3t 213 | set $k = 0 214 | while ($k < 512) 215 | set $l3e = ((uint64_t *)$l3t)[$k] 216 | pmap_perms_l3 217 | set $k = $k + 1 218 | end 219 | end 220 | end 221 | end 222 | 223 | define pmap_perms_l1 224 | if (($l1e & $PTE_V) == 0) 225 | pmap_perms_print 226 | set $va = $va + $L1_SIZE 227 | else 228 | if (($l1e & $PTE_RX) != 0) 229 | if ($start == -1 || ($l1e & $PTE_PERMS) != $perms) 230 | pmap_perms_print 231 | set $start = $va 232 | set $perms = $l1e & $PTE_PERMS 233 | end 234 | set $end = $va + ($L1_SIZE - 1) 235 | set $va = $va + $L1_SIZE 236 | else 237 | set $temp2 = (($l1e >> $PTE_PPN0_S) * $PAGE_SIZE) 238 | phys_to_dmap $temp2 $l2t 239 | set $j = 0 240 | while ($j < 512) 241 | set $l2e = ((uint64_t *)$l2t)[$j] 242 | pmap_perms_l2 243 | set $j = $j + 1 244 | end 245 | end 246 | end 247 | end 248 | 249 | define pmap_dump_perms 250 | set $pm = (struct pmap *)$arg0 251 | if ($pm == 0) 252 | set $pm = &kernel_pmap_store 253 | end 254 | 255 | set $perms = 0 256 | set $start = -1 257 | set $end = 0 258 | set $i = 0 259 | set $va = 0 260 | while ($i < 512) 261 | set $l1e = $pm->pm_l1[$i] 262 | pmap_perms_l1 263 | set $i = $i + 1 264 | if ($i == 256) 265 | set $va = $va + 0xffffff8000000000 266 | end 267 | end 268 | if ($start != -1) 269 | pmap_perms_print 270 | end 271 | end 272 | 273 | define pmap_print_pte 274 | set $_indent = $arg0 * 2 275 | while ($_indent > 0) 276 | printf " " 277 | set $_indent = $_indent - 1 278 | end 279 | printf "%p - %p: ", $va, $va + $arg2 - 1 280 | if ($arg1 & $PTE_V) 281 | if ($arg1 & $PTE_D) 282 | printf "D" 283 | else 284 | printf "-" 285 | end 286 | if ($arg1 & $PTE_A) 287 | printf "A" 288 | else 289 | printf "-" 290 | end 291 | if ($arg1 & $PTE_G) 292 | printf "G" 293 | else 294 | printf "-" 295 | end 296 | if ($arg1 & $PTE_U) 297 | printf "U" 298 | else 299 | printf "-" 300 | end 301 | if ($arg1 & $PTE_X) 302 | printf "X" 303 | else 304 | printf "-" 305 | end 306 | if ($arg1 & $PTE_W) 307 | printf "W" 308 | else 309 | printf "-" 310 | end 311 | if ($arg1 & $PTE_R) 312 | printf "R" 313 | else 314 | printf "-" 315 | end 316 | if ($arg1 & $PTE_LC) 317 | printf "L" 318 | else 319 | printf "-" 320 | end 321 | if ($arg1 & $PTE_SC) 322 | printf "S" 323 | else 324 | printf "-" 325 | end 326 | else 327 | printf "invalid" 328 | end 329 | printf "\n" 330 | end 331 | 332 | define pmap_dump_l3 333 | pmap_print_pte 2 $l3e $L3_SIZE 334 | set $va = $va + $L3_SIZE 335 | end 336 | 337 | define pmap_dump_l2 338 | if (($l2e & ($PTE_V | $PTE_RX)) == $PTE_V) 339 | set $temp3 = (($l2e >> $PTE_PPN0_S) * $PAGE_SIZE) 340 | phys_to_dmap $temp3 $l3t 341 | set $k = 0 342 | while ($k < 512) 343 | set $l3e = ((uint64_t *)$l3t)[$k] 344 | pmap_dump_l3 345 | set $k = $k + 1 346 | end 347 | else 348 | pmap_print_pte 1 $l2e $L2_SIZE 349 | set $va = $va + $L2_SIZE 350 | end 351 | end 352 | 353 | define pmap_dump_l1 354 | if (($l1e & ($PTE_V | $PTE_RX)) == $PTE_V) 355 | set $temp2 = (($l1e >> $PTE_PPN0_S) * $PAGE_SIZE) 356 | phys_to_dmap $temp2 $l2t 357 | set $j = 0 358 | while ($j < 512) 359 | set $l2e = ((uint64_t *)$l2t)[$j] 360 | pmap_dump_l2 361 | set $j = $j + 1 362 | end 363 | else 364 | if ($l1e & $PTE_V) 365 | pmap_print_pte 0 $l1e $L1_SIZE 366 | end 367 | set $va = $va + $L1_SIZE 368 | end 369 | end 370 | 371 | define pmap_dump_ptes 372 | set $pm = (struct pmap *)$arg0 373 | if ($pm == 0) 374 | set $pm = &kernel_pmap_store 375 | end 376 | 377 | set $i = 0 378 | set $va = 0 379 | while ($i < 512) 380 | set $l1e = $pm->pm_l1[$i] 381 | pmap_dump_l1 382 | set $i = $i + 1 383 | if ($i == 256) 384 | set $va = $va + 0xffffff8000000000 385 | end 386 | end 387 | end 388 | --------------------------------------------------------------------------------