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 goes through and runs our 32 and 64-bit bad xsave contexts
20# tests using getcontextx() in lieu of the signal handler to create
21# invalid states. setcontext(2) in libc will try to kill the process if
22# this fails in most situations, so we basically go through and detect
23# that this is the case we expect (e.g. the system call returned an
24# error) and go from there.
25#
26
27unalias -a
28set -o pipefail
29
30xsave_arg0="$(basename $0)"
31xsave_dir="$(dirname $0)"
32xsave_bad32="$xsave_dir/xsave_baducontext.32"
33xsave_bad64="$xsave_dir/xsave_baducontext.64"
34xsave_exit=0
35
36warn()
37{
38	typeset msg="$*"
39	echo "TEST FAILED: $msg" >&2
40	xsave_exit=1
41}
42
43run_single()
44{
45	typeset prog=$1
46	typeset caseno=$2
47	typeset info=
48	typeset ret=
49	typeset desc=
50	typeset errno=
51
52	if ! info=$($prog -i $caseno); then
53		warn "failed to get test information for case $caseno"
54		return
55	fi
56
57	if ! eval $info || [[ -z "$desc" ]] || [[ -z "$errno" ]]; then
58		warn "failed to set test information"
59	fi
60
61	dtrace -q -w -c "$prog -r $caseno" -s /dev/stdin <<EOF
62syscall::setcontext:return
63/pid == \$target && arg1 != 0 && errno == $errno/
64{
65	printf("TEST PASSED: $desc\n");
66	stop();
67	raise(SIGKILL);
68	exit(0);
69}
70
71syscall::setcontext:return
72/pid == \$target && arg1 != 0 && errno != $errno/
73{
74	printf("errno mismatch: found %d, expected $errno\n", errno);
75	printf("TEST FAILED: $desc\n");
76	stop();
77	raise(SIGKILL);
78	exit(1);
79}
80
81proc:::exit
82/pid == \$target/
83{
84	printf("TEST FAILED: $desc: exited normally\n");
85	exit(1);
86}
87EOF
88	if (( $? != 0 )); then
89		xsave_exit=1
90	fi
91}
92
93run_prog()
94{
95	typeset prog="$1"
96	typeset count=
97
98	printf "Beginning tests from %s\n" "$prog"
99	count=$($prog -c)
100	if (( $? != 0 || count <= 0)); then
101		warn "failed to get entry count for $prog"
102		return
103	fi
104
105	for ((i = 0; i < count; i++)) {
106		run_single $prog $i
107	}
108}
109
110run_prog $xsave_bad32
111run_prog $xsave_bad64
112
113if (( xsave_exit == 0 )); then
114	printf "All tests passed successfully\n"
115fi
116exit $xsave_exit
117