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