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