1# $NetBSD: t_static_destructor.sh,v 1.11 2025/11/05 21:24:48 christos Exp $ 2# 3# Copyright (c) 2017 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# This code is derived from software contributed to The NetBSD Foundation 7# by Kamil Rytarowski. 8# 9# Redistribution and use in source and binary forms, with or without 10# modification, are permitted provided that the following conditions 11# are met: 12# 1. Redistributions of source code must retain the above copyright 13# notice, this list of conditions and the following disclaimer. 14# 2. Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in the 16# documentation and/or other materials provided with the distribution. 17# 18# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28# POSSIBILITY OF SUCH DAMAGE. 29# 30 31mktest() { 32 cat > $@.cpp << EOF 33#include <iostream> 34struct A { 35 int i; 36 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 37 ~A() {std::cout << "DTOR A:" << i << std::endl;} 38}; 39struct B { 40 A *m_a; 41 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 42 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 43}; 44int $@(void) {struct B b;return 0;} 45EOF 46} 47 48check() { 49 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" $@ 50} 51 52ccmain() { 53 atf_check -s exit:0 -o ignore -e ignore c++ $@ -o main main.cpp 54 check ./main 55} 56 57 58mkmain() { 59 cat > main.cpp << EOF 60#include <cstdlib> 61int $@(void); 62int main(void) {$@();exit(0);} 63EOF 64} 65 66cclib() { 67 atf_check -s exit:0 -o ignore -e ignore \ 68 c++ "$@" -fPIC -shared -o libpic.so pic.cpp 69} 70 71check32() { 72 # check whether this arch is 64bit 73 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 74 atf_skip "this is not a 64 bit architecture" 75 return 1 76 fi 77 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 78 atf_skip "c++ -m32 not supported on this architecture" 79 return 1 80 else 81 if fgrep -q _LP64 ./def32; then 82 atf_fail "c++ -m32 does not generate netbsd32 binaries" 83 return 1 84 fi 85 fi 86 return 0 87} 88 89check59301() { 90 case `uname -m` in 91 riscv) atf_expect_fail "PR port-riscv/59301:" \ 92 " riscv: missing MKPROFILE=yes support" 93 return 1 94 ;; 95 esac 96 return 0 97} 98 99atf_test_case static_destructor 100static_destructor_head() { 101 atf_set "descr" "compile and run \"hello world\"" 102 atf_set "require.progs" "c++" 103} 104 105atf_test_case static_destructor_profile 106static_destructor_profile_head() { 107 atf_set "descr" "compile and run \"hello world\" with profiling option" 108 atf_set "require.progs" "c++" 109} 110 111atf_test_case static_destructor_static 112static_destructor_static_head() { 113 atf_set "descr" "compile and run \"hello world\" with static option" 114 atf_set "require.progs" "c++" 115} 116 117atf_test_case static_destructor_pic 118static_destructor_pic_head() { 119 atf_set "descr" "compile and run PIC \"hello world\"" 120 atf_set "require.progs" "c++" 121} 122 123atf_test_case static_destructor_pic_32 124static_destructor_pic_32_head() { 125 atf_set "descr" "compile and run 32-bit PIC \"hello world\"" 126 atf_set "require.progs" "c++" 127} 128 129atf_test_case static_destructor_pic_profile 130static_destructor_pic_profile_head() { 131 atf_set "descr" "compile and run PIC \"hello world\" with profiling option" 132 atf_set "require.progs" "c++" 133} 134 135atf_test_case static_destructor_pic_profile_32 136static_destructor_pic_profile_32_head() { 137 atf_set "descr" "compile and run 32-bit PIC \"hello world\" with profiling option" 138 atf_set "require.progs" "c++" 139} 140 141atf_test_case static_destructor_profile_32 142static_destructor_profile_32_head() { 143 atf_set "descr" "compile and run 32-bit \"hello world\" with profiling option" 144 atf_set "require.progs" "c++" 145} 146 147atf_test_case static_destructor_pie 148static_destructor_pie_head() { 149 atf_set "descr" "compile and run position independent (PIE) \"hello world\"" 150 atf_set "require.progs" "c++" 151} 152 153atf_test_case static_destructor32 154static_destructor32_head() { 155 atf_set "descr" "compile and run \"hello world\" for/in netbsd32 emulation" 156 atf_set "require.progs" "c++ file diff cat" 157} 158 159static_destructor_body() { 160 mktest main 161 ccmain 162} 163 164static_destructor_profile_body() { 165 check59301 || return 166 167 mktest main 168 ccmain -static -pg 169} 170 171static_destructor_profile_32_body() { 172 check32 || return 173 check59301 || return 174 175 mktest main 176 ccmain -static -pg -m32 177} 178 179 180static_destructor_static_body() { 181 mktest main 182 ccmain -static 183} 184 185static_destructor_pic_body() { 186 mktest pic 187 mkmain pic 188 cclib 189 ccmain -L${PWD} -Wl,-R${PWD} -lpic 190} 191 192static_destructor_pic_32_body() { 193 check32 || return 194 mktest pic 195 mkmain pic 196 cclib -m32 197 ccmain -m32 -L${PWD} -Wl,-R${PWD} -lpic 198} 199 200static_destructor_pic_profile_body() { 201 check59301 || return 202 203 mktest pic 204 mkmain pic 205 cclib -pg 206 ccmain -pg -L${PWD} -Wl,-R${PWD} -lpic 207} 208 209static_destructor_pic_profile_32_body() { 210 check32 || return 211 check59301 || return 212 213 mktest pic 214 mkmain pic 215 cclib -m32 -pg 216 ccmain -m32 -pg -L${PWD} -Wl,-R${PWD} -lpic 217} 218 219static_destructor_pie_body() { 220 # check whether this arch supports -pie 221 if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then 222 atf_skip "c++ -pie not supported on this architecture" 223 fi 224 mktest main 225 ccmain -fpie -pie 226} 227 228static_destructor32_body() { 229 check32 || return 230 231 mktest main 232 atf_check -s exit:0 -o ignore -e ignore c++ -o hello32 -m32 main.cpp 233 atf_check -s exit:0 -o ignore -e ignore c++ -o hello64 main.cpp 234 file -b ./hello32 > ./ftype32 235 file -b ./hello64 > ./ftype64 236 if diff ./ftype32 ./ftype64 >/dev/null; then 237 atf_fail "generated binaries do not differ" 238 fi 239 echo "32bit binaries on this platform are:" 240 cat ./ftype32 241 echo "While native (64bit) binaries are:" 242 cat ./ftype64 243 check ./hello32 244 atf_check -s exit:0 -o ignore -e ignore c++ -o hello -m32 \ 245 -static main.cpp 246 check ./hello 247} 248 249atf_init_test_cases() 250{ 251 252 atf_add_test_case static_destructor 253 atf_add_test_case static_destructor_profile 254 atf_add_test_case static_destructor_pic 255 atf_add_test_case static_destructor_pie 256 atf_add_test_case static_destructor32 257 atf_add_test_case static_destructor_static 258 atf_add_test_case static_destructor_pic_32 259 atf_add_test_case static_destructor_pic_profile 260 atf_add_test_case static_destructor_pic_profile_32 261 atf_add_test_case static_destructor_profile_32 262} 263