xref: /netbsd/tests/usr.bin/cc/ubsan_common.subr (revision d3d203eb)
1#	$NetBSD: ubsan_common.subr,v 1.2 2022/06/12 08:55:36 skrll Exp $
2#
3# Copyright (c) 2018, 2019 The NetBSD Foundation, 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28test_target()
29{
30	SUPPORT='n'
31	if ! echo __GNUC__ | cc -E - | grep -q __GNUC__; then
32		SUPPORT='y'
33	fi
34
35	if ! echo __clang__ | cc -E - | grep -q __clang__; then
36		SUPPORT='y'
37	fi
38}
39
40atf_test_case target_not_supported
41target_not_supported_head()
42{
43	atf_set "descr" "Test forced skip"
44}
45
46target_not_supported_body()
47{
48	atf_skip "Target is not supported"
49}
50
51# Add a new test case, with head & body.
52# asan_test_case <test-name> <description> <check-output>
53ubsan_test_case() {
54	atf_test_case "$1"
55	eval "$1_head() {
56		atf_set 'descr' 'Test Undefined Behavior for $2'
57		atf_set 'require.progs' 'cc'
58	}"
59
60	atf_test_case "$1_profile"
61	eval "$1_head() {
62		atf_set 'descr' 'Test Undefined Behavior for $2 with profiling option'
63		atf_set 'require.progs' 'cc'
64	}"
65
66	atf_test_case "$1_pic"
67	eval "$1_head() {
68		atf_set 'descr' 'Test Undefined Behavior for $2 with position independent code (PIC) flag'
69		atf_set 'require.progs' 'cc'
70	}"
71
72	atf_test_case "$1_pie"
73	eval "$1_head() {
74		atf_set 'descr' 'Test Undefined Behavior for $2 with position independent execution (PIE) flag'
75		atf_set 'require.progs' 'cc'
76	}"
77
78	atf_test_case "${1}32"
79	eval "$1_head() {
80		atf_set 'descr' 'Test Undefined Behavior for $2 in NetBSD_32 emulation'
81		atf_set 'require.progs' 'cc file diff cat'
82	}"
83
84	eval "$1_body() {
85		echo \"\$UBSAN_CODE\" > test.c
86		cc -fsanitize=undefined -o test test.c
87		# note: ignoring exit status due to inconsistency between gcc/clang
88		# (and between individual tests)
89		atf_check -s ignore -e match:'$3' ./test
90	}
91
92	$1_profile_body() {
93		echo \"\$UBSAN_CODE\" > test.c
94		cc -fsanitize=undefined -static -o test -pg test.c
95		atf_check -s ignore -e match:'$3' ./test
96	}
97
98	$1_pic_body() {
99		echo \"\$UBSAN_CODE\" > test.c
100		cc -DPIC_FOO -fsanitize=undefined -fPIC -shared -o libtest.so test.c
101		cc -DPIC_MAIN -o test test.c -fsanitize=undefined -L. -ltest
102
103		export LD_LIBRARY_PATH=.
104		atf_check -s ignore -e match:'$3' ./test
105	}
106
107	$1_pie_body() {
108		# check whether this arch supports -pice
109		if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
110			atf_set_skip 'cc -pie not supported on this architecture'
111		fi
112		echo \"\$UBSAN_CODE\" > test.c
113		cc -fsanitize=undefined -o test -fpie -pie test.c
114		atf_check -s ignore -e match:'$3' ./test
115	}
116
117	${1}32_body() {
118		# check whether this arch is 64bit
119		if ! cc -dM -E - < /dev/null | fgrep -q _LP64; then
120			atf_skip 'this is not a 64 bit architecture'
121		fi
122		if ! cc -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
123			atf_skip 'cc -m32 not supported on this architecture'
124		else
125			if fgrep -q _LP64 ./def32; then
126				atf_fail 'cc -m32 does not generate netbsd32 binaries'
127			fi
128		fi
129
130		echo \"\$UBSAN_CODE\" > test.c
131		cc -fsanitize=undefined -o df32 -m32 test.c
132		cc -fsanitize=undefined -o df64 test.c
133		file -b ./df32 > ./ftype32
134		file -b ./df64 > ./ftype64
135		if diff ./ftype32 ./ftype64 >/dev/null; then
136			atf_fail 'generated binaries do not differ'
137		fi
138		echo '32bit binaries on this platform are:'
139		cat ./ftype32
140		echo 'While native (64bit) binaries are:'
141		cat ./ftype64
142		atf_check -s ignore -e match:'$3' ./df32
143
144# and another test with profile 32bit binaries
145		cc -fsanitize=undefined -static -o test -pg -m32 test.c
146		atf_check -s ignore -e match:'$3' ./test
147	}"
148}
149
150ubsan_add_test_cases() {
151	test_target
152	test $SUPPORT = 'n' && {
153		atf_add_test_case target_not_supported
154		return 0
155	}
156
157	atf_add_test_case "$1"
158#	atf_add_test_case "$1_profile"
159	atf_add_test_case "$1_pic"
160	atf_add_test_case "$1_pie"
161#	atf_add_test_case "${1}32"
162}
163