1 //===-- crtbegin.c - Start of constructors and destructors ----------------===//
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
7 //===----------------------------------------------------------------------===//
12 # define __has_feature(x) 0
15 #if __has_feature(ptrauth_init_fini)
19 __attribute__((visibility("hidden"))) void *__dso_handle
= &__dso_handle
;
21 #ifdef EH_USE_FRAME_REGISTRY
22 __extension__
static void *__EH_FRAME_LIST__
[]
23 __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {};
25 extern void __register_frame_info(const void *, void *) __attribute__((weak
));
26 extern void *__deregister_frame_info(const void *) __attribute__((weak
));
29 #ifndef CRT_HAS_INITFINI_ARRAY
30 typedef void (*fp
)(void);
32 static fp __CTOR_LIST__
[]
33 __attribute__((section(".ctors"), aligned(sizeof(fp
)))) = {(fp
)-1};
34 extern fp __CTOR_LIST_END__
[];
37 extern void __cxa_finalize(void *) __attribute__((weak
));
39 static void __attribute__((used
)) __do_init(void) {
40 static _Bool __initialized
;
41 if (__builtin_expect(__initialized
, 0))
45 #ifdef EH_USE_FRAME_REGISTRY
46 static struct { void *p
[8]; } __object
;
47 if (__register_frame_info
)
48 __register_frame_info(__EH_FRAME_LIST__
, &__object
);
50 #ifndef CRT_HAS_INITFINI_ARRAY
51 const size_t n
= __CTOR_LIST_END__
- __CTOR_LIST__
- 1;
52 for (size_t i
= n
; i
>= 1; i
--) __CTOR_LIST__
[i
]();
56 #ifdef CRT_HAS_INITFINI_ARRAY
57 #if __has_feature(ptrauth_init_fini)
58 // TODO: use __ptrauth-qualified pointers when they are supported on clang side
59 #if __has_feature(ptrauth_init_fini_address_discrimination)
60 __attribute__((section(".init_array"), used
)) static void *__init
=
61 ptrauth_sign_constant(&__do_init
, ptrauth_key_init_fini_pointer
,
62 ptrauth_blend_discriminator(
63 &__init
, __ptrauth_init_fini_discriminator
));
65 __attribute__((section(".init_array"), used
)) static void *__init
=
66 ptrauth_sign_constant(&__do_init
, ptrauth_key_init_fini_pointer
,
67 __ptrauth_init_fini_discriminator
);
70 __attribute__((section(".init_array"),
71 used
)) static void (*__init
)(void) = __do_init
;
73 #elif defined(__i386__) || defined(__x86_64__)
74 __asm__(".pushsection .init,\"ax\",@progbits\n\t"
77 #elif defined(__riscv)
78 __asm__(".pushsection .init,\"ax\",%progbits\n\t"
81 #elif defined(__arm__) || defined(__aarch64__)
82 __asm__(".pushsection .init,\"ax\",%progbits\n\t"
85 #elif defined(__mips__)
86 __asm__(".pushsection .init,\"ax\",@progbits\n\t"
89 #elif defined(__powerpc__) || defined(__powerpc64__)
90 __asm__(".pushsection .init,\"ax\",@progbits\n\t"
94 #elif defined(__sparc__)
95 __asm__(".pushsection .init,\"ax\",@progbits\n\t"
99 #error "crtbegin without .init_fini array unimplemented for this architecture"
100 #endif // CRT_HAS_INITFINI_ARRAY
102 #ifndef CRT_HAS_INITFINI_ARRAY
103 static fp __DTOR_LIST__
[]
104 __attribute__((section(".dtors"), aligned(sizeof(fp
)))) = {(fp
)-1};
105 extern fp __DTOR_LIST_END__
[];
108 static void __attribute__((used
)) __do_fini(void) {
109 static _Bool __finalized
;
110 if (__builtin_expect(__finalized
, 0))
115 __cxa_finalize(__dso_handle
);
117 #ifndef CRT_HAS_INITFINI_ARRAY
118 const size_t n
= __DTOR_LIST_END__
- __DTOR_LIST__
- 1;
119 for (size_t i
= 1; i
<= n
; i
++) __DTOR_LIST__
[i
]();
121 #ifdef EH_USE_FRAME_REGISTRY
122 if (__deregister_frame_info
)
123 __deregister_frame_info(__EH_FRAME_LIST__
);
127 #ifdef CRT_HAS_INITFINI_ARRAY
128 #if __has_feature(ptrauth_init_fini)
129 // TODO: use __ptrauth-qualified pointers when they are supported on clang side
130 #if __has_feature(ptrauth_init_fini_address_discrimination)
131 __attribute__((section(".fini_array"), used
)) static void *__fini
=
132 ptrauth_sign_constant(&__do_fini
, ptrauth_key_init_fini_pointer
,
133 ptrauth_blend_discriminator(
134 &__fini
, __ptrauth_init_fini_discriminator
));
136 __attribute__((section(".fini_array"), used
)) static void *__fini
=
137 ptrauth_sign_constant(&__do_fini
, ptrauth_key_init_fini_pointer
,
138 __ptrauth_init_fini_discriminator
);
141 __attribute__((section(".fini_array"),
142 used
)) static void (*__fini
)(void) = __do_fini
;
144 #elif defined(__i386__) || defined(__x86_64__)
145 __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
148 #elif defined(__arm__) || defined(__aarch64__)
149 __asm__(".pushsection .fini,\"ax\",%progbits\n\t"
152 #elif defined(__mips__)
153 __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
156 #elif defined(__powerpc__) || defined(__powerpc64__)
157 __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
161 #elif defined(__riscv)
162 __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
165 #elif defined(__sparc__)
166 __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
170 #error "crtbegin without .init_fini array unimplemented for this architecture"
171 #endif // CRT_HAS_INIT_FINI_ARRAY