xref: /freebsd-src/lib/csu/tests/fini_test.c (revision a2f733abcff64628b7771a47089628b7327a88bd)
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/types.h>
3331d62a73SAndrew Turner #include <sys/wait.h>
3431d62a73SAndrew Turner 
3531d62a73SAndrew Turner #include <errno.h>
366ec0ee84SAndrew Turner #include <stdbool.h>
3731d62a73SAndrew Turner #include <stdlib.h>
3831d62a73SAndrew Turner #include <unistd.h>
3931d62a73SAndrew Turner 
4031d62a73SAndrew Turner #include <atf-c.h>
4131d62a73SAndrew Turner 
4231d62a73SAndrew Turner #include <crt.h>
4331d62a73SAndrew Turner 
446ec0ee84SAndrew Turner extern bool run_dtors_test;
456ec0ee84SAndrew Turner extern bool run_fini_array_test;
466ec0ee84SAndrew Turner void dso_handle_check(void);
476ec0ee84SAndrew Turner 
486ec0ee84SAndrew Turner 
496ec0ee84SAndrew Turner #ifndef DSO_BASE
5031d62a73SAndrew Turner typedef void (*func_ptr)(void);
5131d62a73SAndrew Turner 
526ec0ee84SAndrew Turner bool run_dtors_test = false;
536ec0ee84SAndrew Turner bool run_fini_array_test = false;
5431d62a73SAndrew Turner 
5531d62a73SAndrew Turner static void
dtors_handler(void)5631d62a73SAndrew Turner dtors_handler(void)
5731d62a73SAndrew Turner {
5831d62a73SAndrew Turner 
5931d62a73SAndrew Turner 	if (run_dtors_test)
6031d62a73SAndrew Turner 		_exit(1);
6131d62a73SAndrew Turner }
6231d62a73SAndrew Turner __section(".dtors") __used static func_ptr dtors_func =
6331d62a73SAndrew Turner     &dtors_handler;
646ec0ee84SAndrew Turner #endif
6531d62a73SAndrew Turner 
666ec0ee84SAndrew Turner #ifndef DSO_LIB
6731d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(dtors_test);
ATF_TC_BODY(dtors_test,tc)6831d62a73SAndrew Turner ATF_TC_BODY(dtors_test, tc)
6931d62a73SAndrew Turner {
7031d62a73SAndrew Turner 	pid_t pid, wpid;
7131d62a73SAndrew Turner 	int status;
7231d62a73SAndrew Turner 
7331d62a73SAndrew Turner 	pid = fork();
7431d62a73SAndrew Turner 	switch(pid) {
7531d62a73SAndrew Turner 	case -1:
7631d62a73SAndrew Turner 		break;
7731d62a73SAndrew Turner 	case 0:
7831d62a73SAndrew Turner 		run_dtors_test = true;
7931d62a73SAndrew Turner 		exit(0);
8031d62a73SAndrew Turner 	default:
8131d62a73SAndrew Turner 		while ((wpid = waitpid(pid, &status, 0)) == -1 &&
8231d62a73SAndrew Turner 		    errno == EINTR)
8331d62a73SAndrew Turner 			;
8431d62a73SAndrew Turner #ifdef HAVE_CTORS
8531d62a73SAndrew Turner 		ATF_REQUIRE_MSG(WEXITSTATUS(status) == 1,
8631d62a73SAndrew Turner 		    ".dtors failed to run");
8731d62a73SAndrew Turner #else
8831d62a73SAndrew Turner 		ATF_REQUIRE_MSG(WEXITSTATUS(status) == 0,
8931d62a73SAndrew Turner 		    ".dtors incorrectly ran");
9031d62a73SAndrew Turner #endif
9131d62a73SAndrew Turner 		break;
9231d62a73SAndrew Turner 	}
9331d62a73SAndrew Turner }
946ec0ee84SAndrew Turner #endif
9531d62a73SAndrew Turner 
966ec0ee84SAndrew Turner #ifndef DSO_BASE
9731d62a73SAndrew Turner static void
fini_array_handler(void)9831d62a73SAndrew Turner fini_array_handler(void)
9931d62a73SAndrew Turner {
10031d62a73SAndrew Turner 
10131d62a73SAndrew Turner 	if (run_fini_array_test)
10231d62a73SAndrew Turner 		_exit(1);
10331d62a73SAndrew Turner }
10431d62a73SAndrew Turner __section(".fini_array") __used static func_ptr fini_array_func =
10531d62a73SAndrew Turner     &fini_array_handler;
1066ec0ee84SAndrew Turner #endif
10731d62a73SAndrew Turner 
1086ec0ee84SAndrew Turner #ifndef DSO_LIB
10931d62a73SAndrew Turner ATF_TC_WITHOUT_HEAD(fini_array_test);
ATF_TC_BODY(fini_array_test,tc)11031d62a73SAndrew Turner ATF_TC_BODY(fini_array_test, tc)
11131d62a73SAndrew Turner {
11231d62a73SAndrew Turner 	pid_t pid, wpid;
11331d62a73SAndrew Turner 	int status;
11431d62a73SAndrew Turner 
11531d62a73SAndrew Turner 	pid = fork();
11631d62a73SAndrew Turner 	switch(pid) {
11731d62a73SAndrew Turner 	case -1:
11831d62a73SAndrew Turner 		break;
11931d62a73SAndrew Turner 	case 0:
12031d62a73SAndrew Turner 		run_fini_array_test = true;
12131d62a73SAndrew Turner 		exit(0);
12231d62a73SAndrew Turner 	default:
12331d62a73SAndrew Turner 		while ((wpid = waitpid(pid, &status, 0)) == -1 &&
12431d62a73SAndrew Turner 		    errno == EINTR)
12531d62a73SAndrew Turner 			;
12631d62a73SAndrew Turner 		ATF_REQUIRE_MSG(WEXITSTATUS(status) == 1,
12731d62a73SAndrew Turner 		    ".fini_array failed to run");
12831d62a73SAndrew Turner 		break;
12931d62a73SAndrew Turner 	}
13031d62a73SAndrew Turner }
1316ec0ee84SAndrew Turner #endif
13231d62a73SAndrew Turner 
1336ec0ee84SAndrew Turner #ifndef DSO_BASE
13423513043SAndrew Turner extern void *__dso_handle;
13523513043SAndrew Turner 
1366ec0ee84SAndrew Turner void
dso_handle_check(void)1376ec0ee84SAndrew Turner dso_handle_check(void)
1386ec0ee84SAndrew Turner {
1396ec0ee84SAndrew Turner 	void *dso = __dso_handle;
1406ec0ee84SAndrew Turner 
141*f9fd7337SJohn Baldwin #if defined(DSO_LIB) || defined(__PIE__)
1426ec0ee84SAndrew Turner 	ATF_REQUIRE_MSG(dso != NULL,
143*f9fd7337SJohn Baldwin 	    "Null __dso_handle in DSO/PIE");
1446ec0ee84SAndrew Turner #else
1456ec0ee84SAndrew Turner 	ATF_REQUIRE_MSG(dso == NULL,
1466ec0ee84SAndrew Turner 	    "Invalid __dso_handle in non-DSO");
1476ec0ee84SAndrew Turner #endif
1486ec0ee84SAndrew Turner }
1496ec0ee84SAndrew Turner #endif
1506ec0ee84SAndrew Turner 
1516ec0ee84SAndrew Turner #ifndef DSO_LIB
15223513043SAndrew Turner ATF_TC_WITHOUT_HEAD(dso_handle_test);
ATF_TC_BODY(dso_handle_test,tc)15323513043SAndrew Turner ATF_TC_BODY(dso_handle_test, tc)
15423513043SAndrew Turner {
15523513043SAndrew Turner 
1566ec0ee84SAndrew Turner 	dso_handle_check();
15723513043SAndrew Turner }
15823513043SAndrew Turner 
ATF_TP_ADD_TCS(tp)15931d62a73SAndrew Turner ATF_TP_ADD_TCS(tp)
16031d62a73SAndrew Turner {
16131d62a73SAndrew Turner 
16231d62a73SAndrew Turner 	ATF_TP_ADD_TC(tp, dtors_test);
16331d62a73SAndrew Turner 	ATF_TP_ADD_TC(tp, fini_array_test);
16423513043SAndrew Turner 	ATF_TP_ADD_TC(tp, dso_handle_test);
16531d62a73SAndrew Turner 
16631d62a73SAndrew Turner 	return (atf_no_error());
16731d62a73SAndrew Turner }
1686ec0ee84SAndrew Turner #endif
169