1*06c3fb27SDimitry Andric //===-- crtbegin.c - Start of constructors and destructors ----------------===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric
9*06c3fb27SDimitry Andric #include <stddef.h>
10*06c3fb27SDimitry Andric
11*06c3fb27SDimitry Andric __attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle;
12*06c3fb27SDimitry Andric
13*06c3fb27SDimitry Andric #ifdef EH_USE_FRAME_REGISTRY
14*06c3fb27SDimitry Andric __extension__ static void *__EH_FRAME_LIST__[]
15*06c3fb27SDimitry Andric __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {};
16*06c3fb27SDimitry Andric
17*06c3fb27SDimitry Andric extern void __register_frame_info(const void *, void *) __attribute__((weak));
18*06c3fb27SDimitry Andric extern void *__deregister_frame_info(const void *) __attribute__((weak));
19*06c3fb27SDimitry Andric #endif
20*06c3fb27SDimitry Andric
21*06c3fb27SDimitry Andric #ifndef CRT_HAS_INITFINI_ARRAY
22*06c3fb27SDimitry Andric typedef void (*fp)(void);
23*06c3fb27SDimitry Andric
24*06c3fb27SDimitry Andric static fp __CTOR_LIST__[]
25*06c3fb27SDimitry Andric __attribute__((section(".ctors"), aligned(sizeof(fp)))) = {(fp)-1};
26*06c3fb27SDimitry Andric extern fp __CTOR_LIST_END__[];
27*06c3fb27SDimitry Andric #endif
28*06c3fb27SDimitry Andric
29*06c3fb27SDimitry Andric extern void __cxa_finalize(void *) __attribute__((weak));
30*06c3fb27SDimitry Andric
__do_init(void)31*06c3fb27SDimitry Andric static void __attribute__((used)) __do_init(void) {
32*06c3fb27SDimitry Andric static _Bool __initialized;
33*06c3fb27SDimitry Andric if (__builtin_expect(__initialized, 0))
34*06c3fb27SDimitry Andric return;
35*06c3fb27SDimitry Andric __initialized = 1;
36*06c3fb27SDimitry Andric
37*06c3fb27SDimitry Andric #ifdef EH_USE_FRAME_REGISTRY
38*06c3fb27SDimitry Andric static struct { void *p[8]; } __object;
39*06c3fb27SDimitry Andric if (__register_frame_info)
40*06c3fb27SDimitry Andric __register_frame_info(__EH_FRAME_LIST__, &__object);
41*06c3fb27SDimitry Andric #endif
42*06c3fb27SDimitry Andric #ifndef CRT_HAS_INITFINI_ARRAY
43*06c3fb27SDimitry Andric const size_t n = __CTOR_LIST_END__ - __CTOR_LIST__ - 1;
44*06c3fb27SDimitry Andric for (size_t i = n; i >= 1; i--) __CTOR_LIST__[i]();
45*06c3fb27SDimitry Andric #endif
46*06c3fb27SDimitry Andric }
47*06c3fb27SDimitry Andric
48*06c3fb27SDimitry Andric #ifdef CRT_HAS_INITFINI_ARRAY
49*06c3fb27SDimitry Andric __attribute__((section(".init_array"),
50*06c3fb27SDimitry Andric used)) static void (*__init)(void) = __do_init;
51*06c3fb27SDimitry Andric #elif defined(__i386__) || defined(__x86_64__)
52*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",@progbits\n\t"
53*06c3fb27SDimitry Andric "call __do_init\n\t"
54*06c3fb27SDimitry Andric ".popsection");
55*06c3fb27SDimitry Andric #elif defined(__riscv)
56*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",%progbits\n\t"
57*06c3fb27SDimitry Andric "call __do_init\n\t"
58*06c3fb27SDimitry Andric ".popsection");
59*06c3fb27SDimitry Andric #elif defined(__arm__) || defined(__aarch64__)
60*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",%progbits\n\t"
61*06c3fb27SDimitry Andric "bl __do_init\n\t"
62*06c3fb27SDimitry Andric ".popsection");
63*06c3fb27SDimitry Andric #elif defined(__mips__)
64*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",@progbits\n\t"
65*06c3fb27SDimitry Andric "jal __do_init\n\t"
66*06c3fb27SDimitry Andric ".popsection");
67*06c3fb27SDimitry Andric #elif defined(__powerpc__) || defined(__powerpc64__)
68*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",@progbits\n\t"
69*06c3fb27SDimitry Andric "bl __do_init\n\t"
70*06c3fb27SDimitry Andric "nop\n\t"
71*06c3fb27SDimitry Andric ".popsection");
72*06c3fb27SDimitry Andric #elif defined(__sparc__)
73*06c3fb27SDimitry Andric __asm__(".pushsection .init,\"ax\",@progbits\n\t"
74*06c3fb27SDimitry Andric "call __do_init\n\t"
75*06c3fb27SDimitry Andric ".popsection");
76*06c3fb27SDimitry Andric #else
77*06c3fb27SDimitry Andric #error "crtbegin without .init_fini array unimplemented for this architecture"
78*06c3fb27SDimitry Andric #endif // CRT_HAS_INITFINI_ARRAY
79*06c3fb27SDimitry Andric
80*06c3fb27SDimitry Andric #ifndef CRT_HAS_INITFINI_ARRAY
81*06c3fb27SDimitry Andric static fp __DTOR_LIST__[]
82*06c3fb27SDimitry Andric __attribute__((section(".dtors"), aligned(sizeof(fp)))) = {(fp)-1};
83*06c3fb27SDimitry Andric extern fp __DTOR_LIST_END__[];
84*06c3fb27SDimitry Andric #endif
85*06c3fb27SDimitry Andric
__do_fini(void)86*06c3fb27SDimitry Andric static void __attribute__((used)) __do_fini(void) {
87*06c3fb27SDimitry Andric static _Bool __finalized;
88*06c3fb27SDimitry Andric if (__builtin_expect(__finalized, 0))
89*06c3fb27SDimitry Andric return;
90*06c3fb27SDimitry Andric __finalized = 1;
91*06c3fb27SDimitry Andric
92*06c3fb27SDimitry Andric if (__cxa_finalize)
93*06c3fb27SDimitry Andric __cxa_finalize(__dso_handle);
94*06c3fb27SDimitry Andric
95*06c3fb27SDimitry Andric #ifndef CRT_HAS_INITFINI_ARRAY
96*06c3fb27SDimitry Andric const size_t n = __DTOR_LIST_END__ - __DTOR_LIST__ - 1;
97*06c3fb27SDimitry Andric for (size_t i = 1; i <= n; i++) __DTOR_LIST__[i]();
98*06c3fb27SDimitry Andric #endif
99*06c3fb27SDimitry Andric #ifdef EH_USE_FRAME_REGISTRY
100*06c3fb27SDimitry Andric if (__deregister_frame_info)
101*06c3fb27SDimitry Andric __deregister_frame_info(__EH_FRAME_LIST__);
102*06c3fb27SDimitry Andric #endif
103*06c3fb27SDimitry Andric }
104*06c3fb27SDimitry Andric
105*06c3fb27SDimitry Andric #ifdef CRT_HAS_INITFINI_ARRAY
106*06c3fb27SDimitry Andric __attribute__((section(".fini_array"),
107*06c3fb27SDimitry Andric used)) static void (*__fini)(void) = __do_fini;
108*06c3fb27SDimitry Andric #elif defined(__i386__) || defined(__x86_64__)
109*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
110*06c3fb27SDimitry Andric "call __do_fini\n\t"
111*06c3fb27SDimitry Andric ".popsection");
112*06c3fb27SDimitry Andric #elif defined(__arm__) || defined(__aarch64__)
113*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",%progbits\n\t"
114*06c3fb27SDimitry Andric "bl __do_fini\n\t"
115*06c3fb27SDimitry Andric ".popsection");
116*06c3fb27SDimitry Andric #elif defined(__mips__)
117*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
118*06c3fb27SDimitry Andric "jal __do_fini\n\t"
119*06c3fb27SDimitry Andric ".popsection");
120*06c3fb27SDimitry Andric #elif defined(__powerpc__) || defined(__powerpc64__)
121*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
122*06c3fb27SDimitry Andric "bl __do_fini\n\t"
123*06c3fb27SDimitry Andric "nop\n\t"
124*06c3fb27SDimitry Andric ".popsection");
125*06c3fb27SDimitry Andric #elif defined(__riscv)
126*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
127*06c3fb27SDimitry Andric "call __do_fini\n\t"
128*06c3fb27SDimitry Andric ".popsection");
129*06c3fb27SDimitry Andric #elif defined(__sparc__)
130*06c3fb27SDimitry Andric __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
131*06c3fb27SDimitry Andric "call __do_fini\n\t"
132*06c3fb27SDimitry Andric ".popsection");
133*06c3fb27SDimitry Andric #else
134*06c3fb27SDimitry Andric #error "crtbegin without .init_fini array unimplemented for this architecture"
135*06c3fb27SDimitry Andric #endif // CRT_HAS_INIT_FINI_ARRAY
136