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