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 #ifndef DSO_LIB 34 #include <atf-c.h> 35 #endif 36 37 #include <crt.h> 38 39 typedef void (*func_ptr)(void); 40 41 extern volatile int jcr_run; 42 extern const func_ptr *jcr_ptr; 43 extern const void *jcr_func_ptr; 44 extern volatile int ctors_run; 45 extern volatile int preinit_array_run; 46 extern volatile int preinit_array_state; 47 extern volatile int init_array_run; 48 extern volatile int init_array_state; 49 50 #ifndef DSO_BASE 51 volatile int jcr_run; 52 const func_ptr *jcr_ptr; 53 volatile int ctors_run; 54 volatile int preinit_array_run; 55 volatile int preinit_array_state = -1; 56 volatile int init_array_run; 57 volatile int init_array_state = -1; 58 59 void _Jv_RegisterClasses(const func_ptr *); 60 61 __section(".jcr") __used static func_ptr jcr_func = (func_ptr)1; 62 const void *jcr_func_ptr = &jcr_func; 63 64 void 65 _Jv_RegisterClasses(const func_ptr *jcr) 66 { 67 68 jcr_run = 1; 69 jcr_ptr = jcr; 70 } 71 #endif 72 73 #ifndef DSO_LIB 74 ATF_TC_WITHOUT_HEAD(jcr_test); 75 ATF_TC_BODY(jcr_test, tc) 76 { 77 78 ATF_REQUIRE_MSG(jcr_run == 1, ".jcr not run"); 79 ATF_REQUIRE_MSG(jcr_ptr == jcr_func_ptr, 80 "Incorrect pointer passed to _Jv_RegisterClasses"); 81 } 82 #endif 83 84 #ifndef DSO_BASE 85 static void 86 ctors_handler(void) 87 { 88 89 ctors_run = 1; 90 } 91 __section(".ctors") __used static func_ptr ctors_func = 92 &ctors_handler; 93 #endif 94 95 #ifndef DSO_LIB 96 ATF_TC_WITHOUT_HEAD(ctors_test); 97 ATF_TC_BODY(ctors_test, tc) 98 { 99 100 #ifdef HAVE_CTORS 101 ATF_REQUIRE_MSG(ctors_run == 1, ".ctors not run"); 102 #else 103 ATF_REQUIRE_MSG(ctors_run == 0, ".ctors run"); 104 #endif 105 } 106 #endif 107 108 #if !defined(DSO_BASE) && !defined(DSO_LIB) 109 static void 110 preinit_array_handler(void) 111 { 112 113 preinit_array_run = 1; 114 preinit_array_state = init_array_run; 115 } 116 __section(".preinit_array") __used static func_ptr preinit_array_func = 117 &preinit_array_handler; 118 #endif 119 120 #ifndef DSO_LIB 121 ATF_TC_WITHOUT_HEAD(preinit_array_test); 122 ATF_TC_BODY(preinit_array_test, tc) 123 { 124 125 #ifdef DSO_BASE 126 /* Check .preinit_array wasn't run in a DSO */ 127 ATF_REQUIRE_MSG(preinit_array_run == 0, ".preinit_array run in DSO"); 128 #else 129 ATF_REQUIRE_MSG(preinit_array_run == 1, ".preinit_array not run"); 130 ATF_REQUIRE_MSG(preinit_array_state == 0, 131 ".preinit_array was not run before .init_array"); 132 #endif 133 } 134 #endif 135 136 #ifndef DSO_BASE 137 static void 138 init_array_handler(void) 139 { 140 141 init_array_run = 1; 142 init_array_state = preinit_array_run; 143 } 144 __section(".init_array") __used static func_ptr init_array_func = 145 &init_array_handler; 146 #endif 147 148 #ifndef DSO_LIB 149 ATF_TC_WITHOUT_HEAD(init_array_test); 150 ATF_TC_BODY(init_array_test, tc) 151 { 152 153 ATF_REQUIRE_MSG(init_array_run == 1, ".init_array not run"); 154 #ifndef DSO_BASE 155 ATF_REQUIRE_MSG(init_array_state == 1, 156 ".init_array was not run after .preinit_array"); 157 #endif 158 } 159 160 ATF_TP_ADD_TCS(tp) 161 { 162 163 ATF_TP_ADD_TC(tp, jcr_test); 164 ATF_TP_ADD_TC(tp, ctors_test); 165 ATF_TP_ADD_TC(tp, preinit_array_test); 166 ATF_TP_ADD_TC(tp, init_array_test); 167 168 return (atf_no_error()); 169 } 170 #endif 171