xref: /freebsd/lib/csu/common/crtend.c (revision 21502f9a926c7e0c24ce230bb029fde4bf570a14)
131d62a73SAndrew Turner /*-
231d62a73SAndrew Turner  * SPDX-License-Identifier: BSD-1-Clause
331d62a73SAndrew Turner  *
431d62a73SAndrew Turner  * Copyright 2018 Andrew Turner
531d62a73SAndrew Turner  *
631d62a73SAndrew Turner  * Redistribution and use in source and binary forms, with or without
731d62a73SAndrew Turner  * modification, are permitted provided that the following conditions
831d62a73SAndrew Turner  * are met:
931d62a73SAndrew Turner  * 1. Redistributions of source code must retain the above copyright
1031d62a73SAndrew Turner  *    notice, this list of conditions and the following disclaimer.
1131d62a73SAndrew Turner  *
1231d62a73SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1331d62a73SAndrew Turner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1431d62a73SAndrew Turner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1531d62a73SAndrew Turner  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1631d62a73SAndrew Turner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1731d62a73SAndrew Turner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1831d62a73SAndrew Turner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1931d62a73SAndrew Turner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2031d62a73SAndrew Turner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2131d62a73SAndrew Turner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2231d62a73SAndrew Turner  */
2331d62a73SAndrew Turner 
24*21502f9aSKonstantin Belousov #include <sys/types.h>
2531d62a73SAndrew Turner #include "crt.h"
2631d62a73SAndrew Turner 
2731d62a73SAndrew Turner typedef void (*crt_func)(void);
2831d62a73SAndrew Turner 
29ecad1d05SJohn Baldwin static crt_func __JCR_END__[] __section(".jcr") __used = {
3020cb0deaSKyle Evans 	(crt_func)0
3120cb0deaSKyle Evans };
3220cb0deaSKyle Evans 
3320cb0deaSKyle Evans #ifdef HAVE_CTORS
3420cb0deaSKyle Evans 
3531d62a73SAndrew Turner /*
3631d62a73SAndrew Turner  * On some architectures and toolchains we may need to call the .ctors.
3731d62a73SAndrew Turner  * These are called in the reverse order they are in the ELF file.
3831d62a73SAndrew Turner  */
3931d62a73SAndrew Turner static void __do_global_ctors_aux(void) __used;
4031d62a73SAndrew Turner 
41fb7128c2SAndrew Turner static crt_func __CTOR_END__[] __section(".ctors") __used = {
4231d62a73SAndrew Turner 	(crt_func)0
4331d62a73SAndrew Turner };
44fb7128c2SAndrew Turner static crt_func __DTOR_END__[] __section(".dtors") __used = {
4531d62a73SAndrew Turner 	(crt_func)0
4631d62a73SAndrew Turner };
4731d62a73SAndrew Turner 
48*21502f9aSKonstantin Belousov extern const char startof_ctors[] __asm(".startof..ctors")
49*21502f9aSKonstantin Belousov     __weak_symbol __hidden;
50*21502f9aSKonstantin Belousov 
5131d62a73SAndrew Turner static void
5231d62a73SAndrew Turner __do_global_ctors_aux(void)
5331d62a73SAndrew Turner {
5431d62a73SAndrew Turner 	crt_func fn;
55*21502f9aSKonstantin Belousov 	uintptr_t ctors_start;
5631d62a73SAndrew Turner 	int n;
5731d62a73SAndrew Turner 
58*21502f9aSKonstantin Belousov 	ctors_start = (uintptr_t)&startof_ctors;
5931d62a73SAndrew Turner 	for (n = 1;; n++) {
6031d62a73SAndrew Turner 		fn = __CTOR_END__[-n];
61*21502f9aSKonstantin Belousov 		if (fn == (crt_func)0 || fn == (crt_func)-1 ||
62*21502f9aSKonstantin Belousov 		    (ctors_start > 0 &&
63*21502f9aSKonstantin Belousov 		    (uintptr_t)&__CTOR_END__[-n] < ctors_start))
6431d62a73SAndrew Turner 			break;
6531d62a73SAndrew Turner 		fn();
6631d62a73SAndrew Turner 	}
6731d62a73SAndrew Turner }
6831d62a73SAndrew Turner 
6931d62a73SAndrew Turner asm (
7031d62a73SAndrew Turner     ".pushsection .init		\n"
7131d62a73SAndrew Turner     "\t" INIT_CALL_SEQ(__do_global_ctors_aux) "\n"
7231d62a73SAndrew Turner     ".popsection		\n"
7331d62a73SAndrew Turner );
7431d62a73SAndrew Turner #endif
75