1 # $NetBSD: t_static_destructor.sh,v 1.7 2025/04/16 01:52:42 riastradh 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 31 atf_test_case static_destructor 32 static_destructor_head() { 33 atf_set "descr" "compile and run \"hello world\"" 34 atf_set "require.progs" "c++" 35 } 36 37 atf_test_case static_destructor_profile 38 static_destructor_profile_head() { 39 atf_set "descr" "compile and run \"hello world\" with profiling option" 40 atf_set "require.progs" "c++" 41 } 42 43 atf_test_case static_destructor_static 44 static_destructor_static_head() { 45 atf_set "descr" "compile and run \"hello world\" with static option" 46 atf_set "require.progs" "c++" 47 } 48 49 atf_test_case static_destructor_pic 50 static_destructor_pic_head() { 51 atf_set "descr" "compile and run PIC \"hello world\"" 52 atf_set "require.progs" "c++" 53 } 54 55 atf_test_case static_destructor_pic_32 56 static_destructor_pic_32_head() { 57 atf_set "descr" "compile and run 32-bit PIC \"hello world\"" 58 atf_set "require.progs" "c++" 59 } 60 61 atf_test_case static_destructor_pic_profile 62 static_destructor_pic_profile_head() { 63 atf_set "descr" "compile and run PIC \"hello world\" with profiling option" 64 atf_set "require.progs" "c++" 65 } 66 67 atf_test_case static_destructor_pic_profile_32 68 static_destructor_pic_profile_32_head() { 69 atf_set "descr" "compile and run 32-bit PIC \"hello world\" with profiling option" 70 atf_set "require.progs" "c++" 71 } 72 73 atf_test_case static_destructor_profile_32 74 static_destructor_profile_32_head() { 75 atf_set "descr" "compile and run 32-bit \"hello world\" with profiling option" 76 atf_set "require.progs" "c++" 77 } 78 79 atf_test_case static_destructor_pie 80 static_destructor_pie_head() { 81 atf_set "descr" "compile and run position independent (PIE) \"hello world\"" 82 atf_set "require.progs" "c++" 83 } 84 85 atf_test_case static_destructor32 86 static_destructor32_head() { 87 atf_set "descr" "compile and run \"hello world\" for/in netbsd32 emulation" 88 atf_set "require.progs" "c++ file diff cat" 89 } 90 91 static_destructor_body() { 92 cat > test.cpp << EOF 93 #include <iostream> 94 struct A { 95 int i; 96 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 97 ~A() {std::cout << "DTOR A:" << i << std::endl;} 98 }; 99 struct B { 100 A *m_a; 101 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 102 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 103 }; 104 int main(void) {struct B b;return 0;} 105 EOF 106 atf_check -s exit:0 -o ignore -e ignore c++ -o hello test.cpp 107 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 108 } 109 110 static_destructor_profile_body() { 111 case `uname -m` in 112 riscv) atf_expect_fail "PR port-riscv/59301:" \ 113 " riscv: missing MKPROFILE=yes support" 114 ;; 115 esac 116 117 cat > test.cpp << EOF 118 #include <iostream> 119 struct A { 120 int i; 121 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 122 ~A() {std::cout << "DTOR A:" << i << std::endl;} 123 }; 124 struct B { 125 A *m_a; 126 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 127 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 128 }; 129 int main(void) {struct B b;return 0;} 130 EOF 131 atf_check -s exit:0 -o ignore -e ignore c++ -static -pg -o hello test.cpp 132 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 133 } 134 135 static_destructor_profile_32_body() { 136 # check whether this arch is 64bit 137 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 138 atf_skip "this is not a 64 bit architecture" 139 fi 140 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 141 atf_skip "c++ -m32 not supported on this architecture" 142 else 143 if fgrep -q _LP64 ./def32; then 144 atf_fail "c++ -m32 does not generate netbsd32 binaries" 145 fi 146 fi 147 148 case `uname -m` in 149 riscv) atf_expect_fail "PR port-riscv/59301:" \ 150 " riscv: missing MKPROFILE=yes support" 151 ;; 152 esac 153 154 cat > test.cpp << EOF 155 #include <iostream> 156 struct A { 157 int i; 158 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 159 ~A() {std::cout << "DTOR A:" << i << std::endl;} 160 }; 161 struct B { 162 A *m_a; 163 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 164 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 165 }; 166 int main(void) {struct B b;return 0;} 167 EOF 168 atf_check -s exit:0 -o ignore -e ignore c++ -static -m32 -pg -o hello test.cpp 169 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 170 } 171 172 173 static_destructor_static_body() { 174 cat > test.cpp << EOF 175 #include <iostream> 176 struct A { 177 int i; 178 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 179 ~A() {std::cout << "DTOR A:" << i << std::endl;} 180 }; 181 struct B { 182 A *m_a; 183 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 184 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 185 }; 186 int main(void) {struct B b;return 0;} 187 EOF 188 atf_check -s exit:0 -o ignore -e ignore c++ -static -o hello test.cpp 189 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 190 } 191 192 static_destructor_pic_body() { 193 cat > test.cpp << EOF 194 #include <cstdlib> 195 int callpic(void); 196 int main(void) {callpic();exit(0);} 197 EOF 198 cat > pic.cpp << EOF 199 #include <iostream> 200 struct A { 201 int i; 202 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 203 ~A() {std::cout << "DTOR A:" << i << std::endl;} 204 }; 205 struct B { 206 A *m_a; 207 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 208 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 209 }; 210 int callpic(void) {struct B b;} 211 EOF 212 213 atf_check -s exit:0 -o ignore -e ignore \ 214 c++ -fPIC -shared -o libtest.so pic.cpp 215 atf_check -s exit:0 -o ignore -e ignore \ 216 c++ -o hello test.cpp -L. -ltest 217 218 export LD_LIBRARY_PATH=. 219 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 220 } 221 222 static_destructor_pic_32_body() { 223 # check whether this arch is 64bit 224 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 225 atf_skip "this is not a 64 bit architecture" 226 fi 227 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 228 atf_skip "c++ -m32 not supported on this architecture" 229 else 230 if fgrep -q _LP64 ./def32; then 231 atf_fail "c++ -m32 does not generate netbsd32 binaries" 232 fi 233 fi 234 235 cat > test.cpp << EOF 236 #include <cstdlib> 237 int callpic(void); 238 int main(void) {callpic();exit(0);} 239 EOF 240 cat > pic.cpp << EOF 241 #include <iostream> 242 struct A { 243 int i; 244 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 245 ~A() {std::cout << "DTOR A:" << i << std::endl;} 246 }; 247 struct B { 248 A *m_a; 249 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 250 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 251 }; 252 int callpic(void) {struct B b;} 253 EOF 254 255 atf_check -s exit:0 -o ignore -e ignore \ 256 c++ -m32 -fPIC -shared -o libtest.so pic.cpp 257 atf_check -s exit:0 -o ignore -e ignore \ 258 c++ -m32 -o hello test.cpp -L. -ltest 259 260 export LD_LIBRARY_PATH=. 261 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 262 } 263 264 static_destructor_pic_profile_body() { 265 case `uname -m` in 266 riscv) atf_expect_fail "PR port-riscv/59301:" \ 267 " riscv: missing MKPROFILE=yes support" 268 ;; 269 esac 270 271 cat > test.cpp << EOF 272 #include <cstdlib> 273 int callpic(void); 274 int main(void) {callpic();exit(0);} 275 EOF 276 cat > pic.cpp << EOF 277 #include <iostream> 278 struct A { 279 int i; 280 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 281 ~A() {std::cout << "DTOR A:" << i << std::endl;} 282 }; 283 struct B { 284 A *m_a; 285 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 286 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 287 }; 288 int callpic(void) {struct B b;} 289 EOF 290 291 atf_check -s exit:0 -o ignore -e ignore \ 292 c++ -pg -fPIC -shared -o libtest.so pic.cpp 293 atf_check -s exit:0 -o ignore -e ignore \ 294 c++ -pg -o hello test.cpp -L. -ltest 295 296 export LD_LIBRARY_PATH=. 297 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 298 } 299 300 static_destructor_pic_profile_32_body() { 301 # check whether this arch is 64bit 302 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 303 atf_skip "this is not a 64 bit architecture" 304 fi 305 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 306 atf_skip "c++ -m32 not supported on this architecture" 307 else 308 if fgrep -q _LP64 ./def32; then 309 atf_fail "c++ -m32 does not generate netbsd32 binaries" 310 fi 311 fi 312 313 case `uname -m` in 314 riscv) atf_expect_fail "PR port-riscv/59301:" \ 315 " riscv: missing MKPROFILE=yes support" 316 ;; 317 esac 318 319 cat > test.cpp << EOF 320 #include <cstdlib> 321 int callpic(void); 322 int main(void) {callpic();exit(0);} 323 EOF 324 cat > pic.cpp << EOF 325 #include <iostream> 326 struct A { 327 int i; 328 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 329 ~A() {std::cout << "DTOR A:" << i << std::endl;} 330 }; 331 struct B { 332 A *m_a; 333 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 334 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 335 }; 336 int callpic(void) {struct B b;} 337 EOF 338 339 atf_check -s exit:0 -o ignore -e ignore \ 340 c++ -m32 -pg -fPIC -shared -o libtest.so pic.cpp 341 atf_check -s exit:0 -o ignore -e ignore \ 342 c++ -m32 -pg -o hello test.cpp -L. -ltest 343 344 export LD_LIBRARY_PATH=. 345 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 346 } 347 348 static_destructor_pie_body() { 349 # check whether this arch supports -pie 350 if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then 351 atf_skip "c++ -pie not supported on this architecture" 352 fi 353 cat > test.cpp << EOF 354 #include <iostream> 355 struct A { 356 int i; 357 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 358 ~A() {std::cout << "DTOR A:" << i << std::endl;} 359 }; 360 struct B { 361 A *m_a; 362 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 363 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 364 }; 365 int main(void) {struct B b;return 0;} 366 EOF 367 atf_check -s exit:0 -o ignore -e ignore c++ -fpie -pie -o hello test.cpp 368 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 369 } 370 371 static_destructor32_body() { 372 # check whether this arch is 64bit 373 if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then 374 atf_skip "this is not a 64 bit architecture" 375 fi 376 if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then 377 atf_skip "c++ -m32 not supported on this architecture" 378 else 379 if fgrep -q _LP64 ./def32; then 380 atf_fail "c++ -m32 does not generate netbsd32 binaries" 381 fi 382 fi 383 384 cat > test.cpp << EOF 385 #include <iostream> 386 struct A { 387 int i; 388 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 389 ~A() {std::cout << "DTOR A:" << i << std::endl;} 390 }; 391 struct B { 392 A *m_a; 393 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 394 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 395 }; 396 int main(void) {struct B b;return 0;} 397 EOF 398 atf_check -s exit:0 -o ignore -e ignore c++ -o hello32 -m32 test.cpp 399 atf_check -s exit:0 -o ignore -e ignore c++ -o hello64 test.cpp 400 file -b ./hello32 > ./ftype32 401 file -b ./hello64 > ./ftype64 402 if diff ./ftype32 ./ftype64 >/dev/null; then 403 atf_fail "generated binaries do not differ" 404 fi 405 echo "32bit binaries on this platform are:" 406 cat ./ftype32 407 echo "While native (64bit) binaries are:" 408 cat ./ftype64 409 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello32 410 411 # do another test with static 32bit binaries 412 cat > test.cpp << EOF 413 #include <iostream> 414 struct A { 415 int i; 416 A(int i):i(i){std::cout << "CTOR A" << std::endl;} 417 ~A() {std::cout << "DTOR A:" << i << std::endl;} 418 }; 419 struct B { 420 A *m_a; 421 B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;} 422 ~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;} 423 }; 424 int main(void) {struct B b;return 0;} 425 EOF 426 atf_check -s exit:0 -o ignore -e ignore c++ -o hello -m32 \ 427 -static test.cpp 428 atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" ./hello 429 } 430 431 atf_init_test_cases() 432 { 433 434 atf_add_test_case static_destructor 435 atf_add_test_case static_destructor_profile 436 atf_add_test_case static_destructor_pic 437 atf_add_test_case static_destructor_pie 438 atf_add_test_case static_destructor32 439 atf_add_test_case static_destructor_static 440 atf_add_test_case static_destructor_pic_32 441 atf_add_test_case static_destructor_pic_profile 442 atf_add_test_case static_destructor_pic_profile_32 443 atf_add_test_case static_destructor_profile_32 444 } 445