xref: /freebsd/lib/csu/tests/init_test.c (revision 31d62a73c2e6ac0ff413a7a17700ffc7dce254ef)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2018 Andrew Turner
5  *
6  * This software was developed by SRI International and the University of
7  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
8  * ("CTSRD"), as part of the DARPA CRASH research programme.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <atf-c.h>
36 
37 #include <crt.h>
38 
39 typedef void (*func_ptr)(void);
40 
41 static volatile int jcr_run;
42 static const func_ptr *jcr_ptr;
43 static volatile int ctors_run;
44 static volatile int preinit_array_run;
45 static volatile int preinit_array_state = -1;
46 static volatile int init_array_run;
47 static volatile int init_array_state = -1;
48 
49 void _Jv_RegisterClasses(const func_ptr *);
50 
51 __section(".jcr") __used static func_ptr jcr_func = (func_ptr)1;
52 
53 void
54 _Jv_RegisterClasses(const func_ptr *jcr __unused)
55 {
56 
57 	jcr_run = 1;
58 	jcr_ptr = jcr;
59 }
60 
61 ATF_TC_WITHOUT_HEAD(jcr_test);
62 ATF_TC_BODY(jcr_test, tc)
63 {
64 
65 	ATF_REQUIRE_MSG(jcr_run == 1, ".jcr not run");
66 	ATF_REQUIRE_MSG(jcr_ptr == &jcr_func,
67 	    "Incorrect pointer passed to _Jv_RegisterClasses");
68 }
69 
70 static void
71 ctors_handler(void)
72 {
73 
74 	ctors_run = 1;
75 }
76 __section(".ctors") __used static func_ptr ctors_func =
77     &ctors_handler;
78 
79 ATF_TC_WITHOUT_HEAD(ctors_test);
80 ATF_TC_BODY(ctors_test, tc)
81 {
82 
83 #ifdef HAVE_CTORS
84 	ATF_REQUIRE_MSG(ctors_run == 1, ".ctors not run");
85 #else
86 	ATF_REQUIRE_MSG(ctors_run == 0, ".ctors run");
87 #endif
88 }
89 
90 static void
91 preinit_array_handler(void)
92 {
93 
94 	preinit_array_run = 1;
95 	preinit_array_state = init_array_run;
96 }
97 __section(".preinit_array") __used static func_ptr preinit_array_func =
98     &preinit_array_handler;
99 
100 ATF_TC_WITHOUT_HEAD(preinit_array_test);
101 ATF_TC_BODY(preinit_array_test, tc)
102 {
103 
104 	ATF_REQUIRE_MSG(preinit_array_run == 1, ".preinit_array not run");
105 	ATF_REQUIRE_MSG(preinit_array_state == 0,
106 	    ".preinit_array was not run before .init_array");
107 }
108 
109 static void
110 init_array_handler(void)
111 {
112 
113 	init_array_run = 1;
114 	init_array_state = preinit_array_run;
115 }
116 __section(".init_array") __used static func_ptr init_array_func =
117     &init_array_handler;
118 
119 ATF_TC_WITHOUT_HEAD(init_array_test);
120 ATF_TC_BODY(init_array_test, tc)
121 {
122 
123 	ATF_REQUIRE_MSG(init_array_run == 1, ".init_array not run");
124 	ATF_REQUIRE_MSG(init_array_state == 1,
125 	    ".init_array was not run after .preinit_array");
126 }
127 
128 ATF_TP_ADD_TCS(tp)
129 {
130 
131 	ATF_TP_ADD_TC(tp, jcr_test);
132 	ATF_TP_ADD_TC(tp, ctors_test);
133 	ATF_TP_ADD_TC(tp, preinit_array_test);
134 	ATF_TP_ADD_TC(tp, init_array_test);
135 
136 	return (atf_no_error());
137 }
138