1*d3d203ebSskrll# $NetBSD: ubsan_common.subr,v 1.2 2022/06/12 08:55:36 skrll Exp $ 286ee7a4eSmgorny# 386ee7a4eSmgorny# Copyright (c) 2018, 2019 The NetBSD Foundation, Inc. 486ee7a4eSmgorny# All rights reserved. 586ee7a4eSmgorny# 686ee7a4eSmgorny# Redistribution and use in source and binary forms, with or without 786ee7a4eSmgorny# modification, are permitted provided that the following conditions 886ee7a4eSmgorny# are met: 986ee7a4eSmgorny# 1. Redistributions of source code must retain the above copyright 1086ee7a4eSmgorny# notice, this list of conditions and the following disclaimer. 1186ee7a4eSmgorny# 2. Redistributions in binary form must reproduce the above copyright 1286ee7a4eSmgorny# notice, this list of conditions and the following disclaimer in the 1386ee7a4eSmgorny# documentation and/or other materials provided with the distribution. 1486ee7a4eSmgorny# 1586ee7a4eSmgorny# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1686ee7a4eSmgorny# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1786ee7a4eSmgorny# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1886ee7a4eSmgorny# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 1986ee7a4eSmgorny# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2086ee7a4eSmgorny# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2186ee7a4eSmgorny# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2286ee7a4eSmgorny# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2386ee7a4eSmgorny# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2486ee7a4eSmgorny# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2586ee7a4eSmgorny# POSSIBILITY OF SUCH DAMAGE. 2686ee7a4eSmgorny# 2786ee7a4eSmgorny 2886ee7a4eSmgornytest_target() 2986ee7a4eSmgorny{ 3086ee7a4eSmgorny SUPPORT='n' 3186ee7a4eSmgorny if ! echo __GNUC__ | c++ -E - | grep -q __GNUC__; then 3286ee7a4eSmgorny SUPPORT='y' 3386ee7a4eSmgorny fi 3486ee7a4eSmgorny 3586ee7a4eSmgorny if ! echo __clang__ | c++ -E - | grep -q __clang__; then 3686ee7a4eSmgorny SUPPORT='y' 3786ee7a4eSmgorny fi 3886ee7a4eSmgorny} 3986ee7a4eSmgorny 4086ee7a4eSmgornyatf_test_case target_not_supported 4186ee7a4eSmgornytarget_not_supported_head() 4286ee7a4eSmgorny{ 4386ee7a4eSmgorny atf_set "descr" "Test forced skip" 4486ee7a4eSmgorny} 4586ee7a4eSmgorny 4686ee7a4eSmgornytarget_not_supported_body() 4786ee7a4eSmgorny{ 4886ee7a4eSmgorny atf_skip "Target is not supported" 4986ee7a4eSmgorny} 5086ee7a4eSmgorny 5186ee7a4eSmgorny# Add a new test case, with head & body. 5286ee7a4eSmgorny# asan_test_case <test-name> <description> <check-output> 5386ee7a4eSmgornyubsan_test_case() { 5486ee7a4eSmgorny atf_test_case "$1" 5586ee7a4eSmgorny eval "$1_head() { 5686ee7a4eSmgorny atf_set 'descr' 'Test Undefined Behavior for $2' 5786ee7a4eSmgorny atf_set 'require.progs' 'c++' 5886ee7a4eSmgorny }" 5986ee7a4eSmgorny 6086ee7a4eSmgorny atf_test_case "$1_profile" 6186ee7a4eSmgorny eval "$1_head() { 6286ee7a4eSmgorny atf_set 'descr' 'Test Undefined Behavior for $2 with profiling option' 6386ee7a4eSmgorny atf_set 'require.progs' 'c++' 6486ee7a4eSmgorny }" 6586ee7a4eSmgorny 6686ee7a4eSmgorny atf_test_case "$1_pic" 6786ee7a4eSmgorny eval "$1_head() { 6886ee7a4eSmgorny atf_set 'descr' 'Test Undefined Behavior for $2 with position independent code (PIC) flag' 6986ee7a4eSmgorny atf_set 'require.progs' 'c++' 7086ee7a4eSmgorny }" 7186ee7a4eSmgorny 7286ee7a4eSmgorny atf_test_case "$1_pie" 7386ee7a4eSmgorny eval "$1_head() { 7486ee7a4eSmgorny atf_set 'descr' 'Test Undefined Behavior for $2 with position independent execution (PIE) flag' 7586ee7a4eSmgorny atf_set 'require.progs' 'c++' 7686ee7a4eSmgorny }" 7786ee7a4eSmgorny 7886ee7a4eSmgorny atf_test_case "${1}32" 7986ee7a4eSmgorny eval "$1_head() { 8086ee7a4eSmgorny atf_set 'descr' 'Test Undefined Behavior for $2 in NetBSD_32 emulation' 8186ee7a4eSmgorny atf_set 'require.progs' 'c++ file diff cat' 8286ee7a4eSmgorny }" 8386ee7a4eSmgorny 8486ee7a4eSmgorny eval "$1_body() { 8586ee7a4eSmgorny echo \"\$UBSAN_CODE\" > test.cpp 8686ee7a4eSmgorny c++ -fsanitize=undefined -o test test.cpp 8786ee7a4eSmgorny # note: ignoring exit status due to inconsistency between gcc/clang 8886ee7a4eSmgorny # (and between individual tests) 8986ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./test 9086ee7a4eSmgorny } 9186ee7a4eSmgorny 9286ee7a4eSmgorny $1_profile_body() { 9386ee7a4eSmgorny echo \"\$UBSAN_CODE\" > test.cpp 94*d3d203ebSskrll c++ -fsanitize=undefined -static -o test -pg test.cpp 9586ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./test 9686ee7a4eSmgorny } 9786ee7a4eSmgorny 9886ee7a4eSmgorny $1_pic_body() { 9986ee7a4eSmgorny echo \"\$UBSAN_CODE\" > test.cpp 10086ee7a4eSmgorny c++ -DPIC_FOO -fsanitize=undefined -fPIC -shared -o libtest.so test.cpp 10186ee7a4eSmgorny c++ -DPIC_MAIN -o test test.cpp -fsanitize=undefined -L. -ltest 10286ee7a4eSmgorny 10386ee7a4eSmgorny export LD_LIBRARY_PATH=. 10486ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./test 10586ee7a4eSmgorny } 10686ee7a4eSmgorny 10786ee7a4eSmgorny $1_pie_body() { 10886ee7a4eSmgorny # check whether this arch supports -pice 10986ee7a4eSmgorny if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then 11086ee7a4eSmgorny atf_set_skip 'c++ -pie not supported on this architecture' 11186ee7a4eSmgorny fi 11286ee7a4eSmgorny echo \"\$UBSAN_CODE\" > test.cpp 11386ee7a4eSmgorny c++ -fsanitize=undefined -o test -fpie -pie test.cpp 11486ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./test 11586ee7a4eSmgorny } 11686ee7a4eSmgorny 11786ee7a4eSmgorny ${1}32_body() { 11886ee7a4eSmgorny # check whether this arch is 64bit 11986ee7a4eSmgorny if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 12086ee7a4eSmgorny atf_skip 'this is not a 64 bit architecture' 12186ee7a4eSmgorny fi 12286ee7a4eSmgorny if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 12386ee7a4eSmgorny atf_skip 'c++ -m32 not supported on this architecture' 12486ee7a4eSmgorny else 12586ee7a4eSmgorny if fgrep -q _LP64 ./def32; then 12686ee7a4eSmgorny atf_fail 'c++ -m32 does not generate netbsd32 binaries' 12786ee7a4eSmgorny fi 12886ee7a4eSmgorny fi 12986ee7a4eSmgorny 13086ee7a4eSmgorny echo \"\$UBSAN_CODE\" > test.cpp 13186ee7a4eSmgorny c++ -fsanitize=undefined -o df32 -m32 test.cpp 13286ee7a4eSmgorny c++ -fsanitize=undefined -o df64 test.cpp 13386ee7a4eSmgorny file -b ./df32 > ./ftype32 13486ee7a4eSmgorny file -b ./df64 > ./ftype64 13586ee7a4eSmgorny if diff ./ftype32 ./ftype64 >/dev/null; then 13686ee7a4eSmgorny atf_fail 'generated binaries do not differ' 13786ee7a4eSmgorny fi 13886ee7a4eSmgorny echo '32bit binaries on this platform are:' 13986ee7a4eSmgorny cat ./ftype32 14086ee7a4eSmgorny echo 'While native (64bit) binaries are:' 14186ee7a4eSmgorny cat ./ftype64 14286ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./df32 14386ee7a4eSmgorny 14486ee7a4eSmgorny# and another test with profile 32bit binaries 145*d3d203ebSskrll c++ -fsanitize=undefined -static -o test -pg -m32 test.cpp 14686ee7a4eSmgorny atf_check -s ignore -e match:'$3' ./test 14786ee7a4eSmgorny }" 14886ee7a4eSmgorny} 14986ee7a4eSmgorny 15086ee7a4eSmgornyubsan_add_test_cases() { 15186ee7a4eSmgorny test_target 15286ee7a4eSmgorny test $SUPPORT = 'n' && { 15386ee7a4eSmgorny atf_add_test_case target_not_supported 15486ee7a4eSmgorny return 0 15586ee7a4eSmgorny } 15686ee7a4eSmgorny 15786ee7a4eSmgorny atf_add_test_case "$1" 15886ee7a4eSmgorny# atf_add_test_case "$1_profile" 15986ee7a4eSmgorny atf_add_test_case "$1_pic" 16086ee7a4eSmgorny atf_add_test_case "$1_pie" 16186ee7a4eSmgorny# atf_add_test_case "${1}32" 16286ee7a4eSmgorny} 163