xref: /freebsd/lib/csu/common/crtbegin.c (revision fb7128c25e50fd4e98721397c0e7ff4dbf8a4af8)
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 
2431d62a73SAndrew Turner #include <sys/cdefs.h>
2531d62a73SAndrew Turner __FBSDID("$FreeBSD$");
2631d62a73SAndrew Turner 
2731d62a73SAndrew Turner #include <sys/param.h>
2831d62a73SAndrew Turner 
2931d62a73SAndrew Turner #include "crt.h"
3031d62a73SAndrew Turner 
3131d62a73SAndrew Turner typedef void (*crt_func)(void);
3231d62a73SAndrew Turner 
33fd8767bbSAndrew Turner extern void *__dso_handle __hidden;
34fd8767bbSAndrew Turner 
35fd8767bbSAndrew Turner #ifdef SHARED
36fd8767bbSAndrew Turner void *__dso_handle = &__dso_handle;
37fd8767bbSAndrew Turner #else
38fd8767bbSAndrew Turner void *__dso_handle = 0;
39fd8767bbSAndrew Turner #endif
40fd8767bbSAndrew Turner 
4131d62a73SAndrew Turner /*
4231d62a73SAndrew Turner  * On some architectures and toolchains we may need to call the .dtors.
4331d62a73SAndrew Turner  * These are called in the order they are in the ELF file.
4431d62a73SAndrew Turner  */
4531d62a73SAndrew Turner #ifdef HAVE_CTORS
4631d62a73SAndrew Turner static void __do_global_dtors_aux(void) __used;
4731d62a73SAndrew Turner 
48*fb7128c2SAndrew Turner static crt_func __CTOR_LIST__[] __section(".ctors") = {
4931d62a73SAndrew Turner 	(crt_func)-1
5031d62a73SAndrew Turner };
51*fb7128c2SAndrew Turner static crt_func __DTOR_LIST__[] __section(".dtors") = {
5231d62a73SAndrew Turner 	(crt_func)-1
5331d62a73SAndrew Turner };
5431d62a73SAndrew Turner 
5531d62a73SAndrew Turner static void
5631d62a73SAndrew Turner __do_global_dtors_aux(void)
5731d62a73SAndrew Turner {
5831d62a73SAndrew Turner 	crt_func fn;
5931d62a73SAndrew Turner 	int n;
6031d62a73SAndrew Turner 
6131d62a73SAndrew Turner 	for (n = 1;; n++) {
6231d62a73SAndrew Turner 		fn = __DTOR_LIST__[n];
6331d62a73SAndrew Turner 		if (fn == (crt_func)0 || fn == (crt_func)-1)
6431d62a73SAndrew Turner 			break;
6531d62a73SAndrew Turner 		fn();
6631d62a73SAndrew Turner 	}
6731d62a73SAndrew Turner }
6831d62a73SAndrew Turner 
6931d62a73SAndrew Turner asm (
7031d62a73SAndrew Turner     ".pushsection .fini		\n"
7131d62a73SAndrew Turner     "\t" INIT_CALL_SEQ(__do_global_dtors_aux) "\n"
7231d62a73SAndrew Turner     ".popsection		\n"
7331d62a73SAndrew Turner );
7431d62a73SAndrew Turner #endif
7531d62a73SAndrew Turner 
7631d62a73SAndrew Turner /*
7731d62a73SAndrew Turner  * Handler for gcj. These provide a _Jv_RegisterClasses function and fill
7831d62a73SAndrew Turner  * out the .jcr section. We just need to call this function with a pointer
7931d62a73SAndrew Turner  * to the appropriate section.
8031d62a73SAndrew Turner  */
8131d62a73SAndrew Turner extern void _Jv_RegisterClasses(void *) __weak_symbol;
8231d62a73SAndrew Turner static void register_classes(void) __used;
8331d62a73SAndrew Turner 
84*fb7128c2SAndrew Turner static crt_func __JCR_LIST__[] __section(".jcr") __used = { };
8531d62a73SAndrew Turner 
8631d62a73SAndrew Turner #ifndef CTORS_CONSTRUCTORS
8731d62a73SAndrew Turner __attribute__((constructor))
8831d62a73SAndrew Turner #endif
8931d62a73SAndrew Turner static void
9031d62a73SAndrew Turner register_classes(void)
9131d62a73SAndrew Turner {
9231d62a73SAndrew Turner 
9331d62a73SAndrew Turner 	if (_Jv_RegisterClasses != NULL && __JCR_LIST__[0] != 0)
9431d62a73SAndrew Turner 		_Jv_RegisterClasses(__JCR_LIST__);
9531d62a73SAndrew Turner }
9631d62a73SAndrew Turner 
9731d62a73SAndrew Turner /*
9831d62a73SAndrew Turner  * We can't use constructors when they use the .ctors section as they may be
9931d62a73SAndrew Turner  * placed before __CTOR_LIST__.
10031d62a73SAndrew Turner  */
10131d62a73SAndrew Turner #ifdef CTORS_CONSTRUCTORS
10231d62a73SAndrew Turner asm (
10331d62a73SAndrew Turner     ".pushsection .init		\n"
10431d62a73SAndrew Turner     "\t" INIT_CALL_SEQ(register_classes) "\n"
10531d62a73SAndrew Turner     ".popsection		\n"
10631d62a73SAndrew Turner );
10731d62a73SAndrew Turner #endif
108