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