1351282Sdim//===-- crtbegin.c - Start of constructors and destructors ----------------===// 2351282Sdim// 3351282Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351282Sdim// See https://llvm.org/LICENSE.txt for license information. 5351282Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351282Sdim// 7351282Sdim//===----------------------------------------------------------------------===// 8351282Sdim 9351282Sdim#include <stddef.h> 10351282Sdim 11351282Sdim__attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle; 12351282Sdim 13360784Sdim#ifdef EH_USE_FRAME_REGISTRY 14351282Sdim__extension__ static void *__EH_FRAME_LIST__[] 15351282Sdim __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {}; 16351282Sdim 17351282Sdimextern void __register_frame_info(const void *, void *) __attribute__((weak)); 18351282Sdimextern void *__deregister_frame_info(const void *) __attribute__((weak)); 19360784Sdim#endif 20351282Sdim 21351282Sdim#ifndef CRT_HAS_INITFINI_ARRAY 22351282Sdimtypedef void (*fp)(void); 23351282Sdim 24351282Sdimstatic fp __CTOR_LIST__[] 25351282Sdim __attribute__((section(".ctors"), aligned(sizeof(fp)))) = {(fp)-1}; 26351282Sdimextern fp __CTOR_LIST_END__[]; 27351282Sdim#endif 28351282Sdim 29351282Sdimextern void __cxa_finalize(void *) __attribute__((weak)); 30351282Sdim 31351282Sdimstatic void __attribute__((used)) __do_init() { 32351282Sdim static _Bool __initialized; 33351282Sdim if (__builtin_expect(__initialized, 0)) 34351282Sdim return; 35351282Sdim __initialized = 1; 36351282Sdim 37360784Sdim#ifdef EH_USE_FRAME_REGISTRY 38351282Sdim static struct { void *p[8]; } __object; 39351282Sdim if (__register_frame_info) 40351282Sdim __register_frame_info(__EH_FRAME_LIST__, &__object); 41360784Sdim#endif 42351282Sdim#ifndef CRT_HAS_INITFINI_ARRAY 43351282Sdim const size_t n = __CTOR_LIST_END__ - __CTOR_LIST__ - 1; 44351282Sdim for (size_t i = n; i >= 1; i--) __CTOR_LIST__[i](); 45351282Sdim#endif 46351282Sdim} 47351282Sdim 48351282Sdim#ifdef CRT_HAS_INITFINI_ARRAY 49351282Sdim__attribute__((section(".init_array"), 50351282Sdim used)) static void (*__init)(void) = __do_init; 51360784Sdim#elif defined(__i386__) || defined(__x86_64__) 52351282Sdim__asm__(".pushsection .init,\"ax\",@progbits\n\t" 53351282Sdim "call " __USER_LABEL_PREFIX__ "__do_init\n\t" 54351282Sdim ".popsection"); 55360784Sdim#elif defined(__arm__) || defined(__aarch64__) 56351282Sdim__asm__(".pushsection .init,\"ax\",%progbits\n\t" 57351282Sdim "bl " __USER_LABEL_PREFIX__ "__do_init\n\t" 58351282Sdim ".popsection"); 59360784Sdim#elif defined(__powerpc__) || defined(__powerpc64__) 60360784Sdim__asm__(".pushsection .init,\"ax\",@progbits\n\t" 61360784Sdim "bl " __USER_LABEL_PREFIX__ "__do_init\n\t" 62360784Sdim "nop\n\t" 63360784Sdim ".popsection"); 64360784Sdim#elif defined(__sparc__) 65360784Sdim__asm__(".pushsection .init,\"ax\",@progbits\n\t" 66360784Sdim "call " __USER_LABEL_PREFIX__ "__do_init\n\t" 67360784Sdim ".popsection"); 68360784Sdim#else 69360784Sdim#error "crtbegin without .init_fini array unimplemented for this architecture" 70360784Sdim#endif // CRT_HAS_INITFINI_ARRAY 71351282Sdim 72351282Sdim#ifndef CRT_HAS_INITFINI_ARRAY 73351282Sdimstatic fp __DTOR_LIST__[] 74351282Sdim __attribute__((section(".dtors"), aligned(sizeof(fp)))) = {(fp)-1}; 75351282Sdimextern fp __DTOR_LIST_END__[]; 76351282Sdim#endif 77351282Sdim 78351282Sdimstatic void __attribute__((used)) __do_fini() { 79351282Sdim static _Bool __finalized; 80351282Sdim if (__builtin_expect(__finalized, 0)) 81351282Sdim return; 82351282Sdim __finalized = 1; 83351282Sdim 84351282Sdim if (__cxa_finalize) 85351282Sdim __cxa_finalize(__dso_handle); 86351282Sdim 87351282Sdim#ifndef CRT_HAS_INITFINI_ARRAY 88351282Sdim const size_t n = __DTOR_LIST_END__ - __DTOR_LIST__ - 1; 89351282Sdim for (size_t i = 1; i <= n; i++) __DTOR_LIST__[i](); 90351282Sdim#endif 91360784Sdim#ifdef EH_USE_FRAME_REGISTRY 92360784Sdim if (__deregister_frame_info) 93360784Sdim __deregister_frame_info(__EH_FRAME_LIST__); 94360784Sdim#endif 95351282Sdim} 96351282Sdim 97351282Sdim#ifdef CRT_HAS_INITFINI_ARRAY 98351282Sdim__attribute__((section(".fini_array"), 99351282Sdim used)) static void (*__fini)(void) = __do_fini; 100360784Sdim#elif defined(__i386__) || defined(__x86_64__) 101351282Sdim__asm__(".pushsection .fini,\"ax\",@progbits\n\t" 102351282Sdim "call " __USER_LABEL_PREFIX__ "__do_fini\n\t" 103351282Sdim ".popsection"); 104360784Sdim#elif defined(__arm__) || defined(__aarch64__) 105351282Sdim__asm__(".pushsection .fini,\"ax\",%progbits\n\t" 106351282Sdim "bl " __USER_LABEL_PREFIX__ "__do_fini\n\t" 107351282Sdim ".popsection"); 108360784Sdim#elif defined(__powerpc__) || defined(__powerpc64__) 109360784Sdim__asm__(".pushsection .fini,\"ax\",@progbits\n\t" 110360784Sdim "bl " __USER_LABEL_PREFIX__ "__do_fini\n\t" 111360784Sdim "nop\n\t" 112360784Sdim ".popsection"); 113360784Sdim#elif defined(__sparc__) 114360784Sdim__asm__(".pushsection .fini,\"ax\",@progbits\n\t" 115360784Sdim "call " __USER_LABEL_PREFIX__ "__do_fini\n\t" 116360784Sdim ".popsection"); 117360784Sdim#else 118360784Sdim#error "crtbegin without .init_fini array unimplemented for this architecture" 119351282Sdim#endif // CRT_HAS_INIT_FINI_ARRAY 120