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