131d62a73SAndrew Turner /*- 231d62a73SAndrew Turner * SPDX-License-Identifier: BSD-2-Clause 331d62a73SAndrew Turner * 431d62a73SAndrew Turner * Copyright (c) 2018 Andrew Turner 531d62a73SAndrew Turner * 631d62a73SAndrew Turner * This software was developed by SRI International and the University of 731d62a73SAndrew Turner * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 831d62a73SAndrew Turner * ("CTSRD"), as part of the DARPA CRASH research programme. 931d62a73SAndrew Turner * 1031d62a73SAndrew Turner * Redistribution and use in source and binary forms, with or without 1131d62a73SAndrew Turner * modification, are permitted provided that the following conditions 1231d62a73SAndrew Turner * are met: 1331d62a73SAndrew Turner * 1. Redistributions of source code must retain the above copyright 1431d62a73SAndrew Turner * notice, this list of conditions and the following disclaimer. 1531d62a73SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 1631d62a73SAndrew Turner * notice, this list of conditions and the following disclaimer in the 1731d62a73SAndrew Turner * documentation and/or other materials provided with the distribution. 1831d62a73SAndrew Turner * 1931d62a73SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2031d62a73SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2131d62a73SAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2231d62a73SAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2331d62a73SAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2431d62a73SAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2531d62a73SAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2631d62a73SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2731d62a73SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2831d62a73SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2931d62a73SAndrew Turner * SUCH DAMAGE. 3031d62a73SAndrew Turner */ 3131d62a73SAndrew Turner 3231d62a73SAndrew Turner #include <sys/cdefs.h> 3331d62a73SAndrew Turner __FBSDID("$FreeBSD$"); 3431d62a73SAndrew Turner 356ec0ee84SAndrew Turner #ifndef DSO_LIB 3631d62a73SAndrew Turner #include <atf-c.h> 376ec0ee84SAndrew Turner #endif 3831d62a73SAndrew Turner 3931d62a73SAndrew Turner #include <crt.h> 4031d62a73SAndrew Turner 4131d62a73SAndrew Turner typedef void (*func_ptr)(void); 4231d62a73SAndrew Turner 436ec0ee84SAndrew Turner extern volatile int jcr_run; 446ec0ee84SAndrew Turner extern const func_ptr *jcr_ptr; 456ec0ee84SAndrew Turner extern const void *jcr_func_ptr; 466ec0ee84SAndrew Turner extern volatile int ctors_run; 476ec0ee84SAndrew Turner extern volatile int preinit_array_run; 486ec0ee84SAndrew Turner extern volatile int preinit_array_state; 496ec0ee84SAndrew Turner extern volatile int init_array_run; 506ec0ee84SAndrew Turner extern volatile int init_array_state; 516ec0ee84SAndrew Turner 526ec0ee84SAndrew Turner #ifndef DSO_BASE 536ec0ee84SAndrew Turner volatile int jcr_run; 546ec0ee84SAndrew Turner const func_ptr *jcr_ptr; 556ec0ee84SAndrew Turner volatile int ctors_run; 566ec0ee84SAndrew Turner volatile int preinit_array_run; 576ec0ee84SAndrew Turner volatile int preinit_array_state = -1; 586ec0ee84SAndrew Turner volatile int init_array_run; 596ec0ee84SAndrew Turner volatile int init_array_state = -1; 6031d62a73SAndrew Turner 6131d62a73SAndrew Turner void _Jv_RegisterClasses(const func_ptr *); 6231d62a73SAndrew Turner 63bb966f87SAndrew Turner __section(".jcr") __used static func_ptr jcr_func = (func_ptr)1; 646ec0ee84SAndrew Turner const void *jcr_func_ptr = &jcr_func; 6531d62a73SAndrew Turner 6631d62a73SAndrew Turner void 679e26e65cSAndrew Turner _Jv_RegisterClasses(const func_ptr *jcr) 6831d62a73SAndrew Turner { 6931d62a73SAndrew Turner 7031d62a73SAndrew Turner jcr_run = 1; 7131d62a73SAndrew Turner jcr_ptr = jcr; 7231d62a73SAndrew Turner } 736ec0ee84SAndrew Turner #endif 7431d62a73SAndrew Turner 756ec0ee84SAndrew Turner #ifndef DSO_LIB 7631d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(jcr_test); 7731d62a73SAndrew Turner ATF_TC_BODY(jcr_test, tc) 7831d62a73SAndrew Turner { 7931d62a73SAndrew Turner 8031d62a73SAndrew Turner ATF_REQUIRE_MSG(jcr_run == 1, ".jcr not run"); 816ec0ee84SAndrew Turner ATF_REQUIRE_MSG(jcr_ptr == jcr_func_ptr, 8231d62a73SAndrew Turner "Incorrect pointer passed to _Jv_RegisterClasses"); 8331d62a73SAndrew Turner } 846ec0ee84SAndrew Turner #endif 8531d62a73SAndrew Turner 866ec0ee84SAndrew Turner #ifndef DSO_BASE 8731d62a73SAndrew Turner static void 8831d62a73SAndrew Turner ctors_handler(void) 8931d62a73SAndrew Turner { 9031d62a73SAndrew Turner 9131d62a73SAndrew Turner ctors_run = 1; 9231d62a73SAndrew Turner } 9331d62a73SAndrew Turner __section(".ctors") __used static func_ptr ctors_func = 9431d62a73SAndrew Turner &ctors_handler; 956ec0ee84SAndrew Turner #endif 9631d62a73SAndrew Turner 976ec0ee84SAndrew Turner #ifndef DSO_LIB 9831d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(ctors_test); 9931d62a73SAndrew Turner ATF_TC_BODY(ctors_test, tc) 10031d62a73SAndrew Turner { 10131d62a73SAndrew Turner 10231d62a73SAndrew Turner #ifdef HAVE_CTORS 10331d62a73SAndrew Turner ATF_REQUIRE_MSG(ctors_run == 1, ".ctors not run"); 10431d62a73SAndrew Turner #else 10531d62a73SAndrew Turner ATF_REQUIRE_MSG(ctors_run == 0, ".ctors run"); 10631d62a73SAndrew Turner #endif 10731d62a73SAndrew Turner } 1086ec0ee84SAndrew Turner #endif 10931d62a73SAndrew Turner 110*ca34591fSAndrew Turner #if !defined(DSO_BASE) && !defined(DSO_LIB) 11131d62a73SAndrew Turner static void 11231d62a73SAndrew Turner preinit_array_handler(void) 11331d62a73SAndrew Turner { 11431d62a73SAndrew Turner 11531d62a73SAndrew Turner preinit_array_run = 1; 11631d62a73SAndrew Turner preinit_array_state = init_array_run; 11731d62a73SAndrew Turner } 11831d62a73SAndrew Turner __section(".preinit_array") __used static func_ptr preinit_array_func = 11931d62a73SAndrew Turner &preinit_array_handler; 1206ec0ee84SAndrew Turner #endif 12131d62a73SAndrew Turner 1226ec0ee84SAndrew Turner #ifndef DSO_LIB 12331d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(preinit_array_test); 12431d62a73SAndrew Turner ATF_TC_BODY(preinit_array_test, tc) 12531d62a73SAndrew Turner { 12631d62a73SAndrew Turner 1276ec0ee84SAndrew Turner #ifdef DSO_BASE 1286ec0ee84SAndrew Turner /* Check .preinit_array wasn't run in a DSO */ 1296ec0ee84SAndrew Turner ATF_REQUIRE_MSG(preinit_array_run == 0, ".preinit_array run in DSO"); 1306ec0ee84SAndrew Turner #else 13131d62a73SAndrew Turner ATF_REQUIRE_MSG(preinit_array_run == 1, ".preinit_array not run"); 13231d62a73SAndrew Turner ATF_REQUIRE_MSG(preinit_array_state == 0, 13331d62a73SAndrew Turner ".preinit_array was not run before .init_array"); 1346ec0ee84SAndrew Turner #endif 13531d62a73SAndrew Turner } 1366ec0ee84SAndrew Turner #endif 13731d62a73SAndrew Turner 1386ec0ee84SAndrew Turner #ifndef DSO_BASE 13931d62a73SAndrew Turner static void 14031d62a73SAndrew Turner init_array_handler(void) 14131d62a73SAndrew Turner { 14231d62a73SAndrew Turner 14331d62a73SAndrew Turner init_array_run = 1; 14431d62a73SAndrew Turner init_array_state = preinit_array_run; 14531d62a73SAndrew Turner } 14631d62a73SAndrew Turner __section(".init_array") __used static func_ptr init_array_func = 14731d62a73SAndrew Turner &init_array_handler; 1486ec0ee84SAndrew Turner #endif 14931d62a73SAndrew Turner 1506ec0ee84SAndrew Turner #ifndef DSO_LIB 15131d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(init_array_test); 15231d62a73SAndrew Turner ATF_TC_BODY(init_array_test, tc) 15331d62a73SAndrew Turner { 15431d62a73SAndrew Turner 15531d62a73SAndrew Turner ATF_REQUIRE_MSG(init_array_run == 1, ".init_array not run"); 1566ec0ee84SAndrew Turner #ifndef DSO_BASE 15731d62a73SAndrew Turner ATF_REQUIRE_MSG(init_array_state == 1, 15831d62a73SAndrew Turner ".init_array was not run after .preinit_array"); 1596ec0ee84SAndrew Turner #endif 16031d62a73SAndrew Turner } 16131d62a73SAndrew Turner 16231d62a73SAndrew Turner ATF_TP_ADD_TCS(tp) 16331d62a73SAndrew Turner { 16431d62a73SAndrew Turner 16531d62a73SAndrew Turner ATF_TP_ADD_TC(tp, jcr_test); 16631d62a73SAndrew Turner ATF_TP_ADD_TC(tp, ctors_test); 16731d62a73SAndrew Turner ATF_TP_ADD_TC(tp, preinit_array_test); 16831d62a73SAndrew Turner ATF_TP_ADD_TC(tp, init_array_test); 16931d62a73SAndrew Turner 17031d62a73SAndrew Turner return (atf_no_error()); 17131d62a73SAndrew Turner } 1726ec0ee84SAndrew Turner #endif 173