1#!/usr/bin/ksh 2# 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright 2023 Oxide Computer Company 16# 17 18# 19# This test attempts to verify that we can mdb (via libproc / thread_db) 20# and xregs sees the expected extended register set. It also ensures 21# that the same values are visible via a core file from that process at 22# the same point. 23# 24 25unalias -a 26set -o pipefail 27export LANG=C.UTF-8 28 29mx_exit=0 30mx_arg0="$(basename $0)" 31mx_dir="$(dirname $0)" 32mx_data="$mx_dir/data" 33mx_tmpdir="/tmp/mdb_xregs.$$" 34 35typeset -A mx_seed 36mx_seed["32"]=0x12900922 37mx_seed["64"]=0x11900456 38typeset -A mx_hwtype 39mx_hwtype["32"]="$mx_dir/xsu_hwtype.32" 40mx_hwtype["64"]="$mx_dir/xsu_hwtype.64" 41typeset -A mx_setprog 42mx_setprog["32"]="$mx_dir/xregs_set.32" 43mx_setprog["64"]="$mx_dir/xregs_set.64" 44 45warn() 46{ 47 typeset msg="$*" 48 echo "TEST FAILED: $msg" >&2 49 mx_exit=1 50} 51 52fatal() 53{ 54 typeset msg="$*" 55 [[ -z "$msg" ]] && msg="failed" 56 echo "$mx_arg0: $msg" >&2 57 exit 1 58} 59 60cleanup() 61{ 62 [[ -n "$mx_tmpdir" ]] && rm -rf "$mx_tmpdir" 63} 64 65setup() 66{ 67 if ! mkdir $mx_tmpdir; then 68 fatal "failed to create temporary directory: $mx_tmpdir" 69 fi 70} 71 72check_file() 73{ 74 typeset src="$1" 75 typeset act="$2" 76 typeset desc="$3" 77 78 if [[ ! -f "$act" ]]; then 79 warn "failed to generate $act" 80 return 81 fi 82 83 if ! diff -q $src $act; then 84 diff -u $src $act 85 warn "$desc: $act did not match expected output" 86 else 87 printf "TEST PASSED: %s\n" "$desc" 88 fi 89} 90 91# 92# Run one instance of mdb to grab and get our first pass data files 93# against a real process. We're not really counting on our exit status 94# from mdb here, mostly on whether or not the generated files all exist 95# in the end. We gather data from the generated cores in a separate run. 96# 97run_live_mdb() 98{ 99 typeset prog="$1" 100 typeset seed="$2" 101 typeset fpregs="$3" 102 typeset core="$4" 103 typeset coreloc="$5" 104 105 mdb $prog <<EOF 106yield::bp 107::run $seed 108::tmodel lwp 109::fpregs ! cat > $fpregs.lwp 110::tmodel thread 111::fpregs ! cat > $fpregs.thread 112_uberdata::printf "$core.%u" uberdata_t pid ! cat > $coreloc 113::gcore -o $core 114::kill 115\$q 116EOF 117} 118 119# 120# We've been given a core file that matches something we just ran above. We 121# should be able to read the ::fpregs from it and get the exact same data. 122# 123check_core() 124{ 125 typeset core="$1" 126 typeset output="$2" 127 typeset check="$3" 128 129 if ! mdb -e "::fpregs ! cat > $output" $core; then 130 warn "mdb failed to get ::fpregs from $core" 131 return 132 fi 133 134 check_file $check $output "extracted core matches" 135} 136 137run_one_isa() 138{ 139 typeset isa="$1" 140 typeset target=${mx_setprog[$isa]} 141 typeset hwprog=${mx_hwtype[$isa]} 142 typeset seed=${mx_seed[$isa]} 143 typeset coreloc="$mx_tmpdir/coreloc" 144 typeset fpu_type= 145 typeset corename= 146 typeset fpregs= 147 typeset check= 148 149 if ! fpu_type=$($hwprog 2>/dev/null); then 150 warn "failed to determine $isa-bit FPU type" 151 return 152 fi 153 154 printf "Discovered FPU: %s %s-bit\n" $fpu_type $isa 155 corename="$mx_tmpdir/core.$fpu_type.$isa" 156 fpregs="$mx_tmpdir/fpregs.$fpu_type.$isa" 157 check="$mx_data/mdb_xregs.$fpu_type.$isa" 158 159 run_live_mdb $target $seed $fpregs $corename $coreloc 160 check_file "$check" "$fpregs.lwp" "$isa-bit $fpu_type ::fpregs (lwp)" 161 check_file "$check" "$fpregs.lwp" "$isa-bit $fpu_type ::fpregs (thread)" 162 163 if [[ ! -f "$coreloc" ]]; then 164 warn "missing core file location file, cannot run core tests" 165 return 166 fi 167 168 typeset -i ncores=0 169 for f in $(cat $coreloc); do 170 ((ncores++)) 171 if [[ ! -f "$f" ]]; then 172 warn "core file location $f is not a file" 173 continue 174 fi 175 176 check_core "$f" "$mx_tmpdir/fpregs.core" $check 177 done 178 179 if ((ncores == 0)); then 180 warn "No core files found!" 181 fi 182} 183 184setup 185trap 'cleanup' EXIT 186 187run_one_isa "32" 188run_one_isa "64" 189 190exit $mx_exit 191