xref: /illumos-gate/usr/src/test/os-tests/tests/xsave/mdb_xregs.ksh (revision b210e77709da8e42dfe621e10ccf4be504206058)
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