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#ifndef __has_feature
12# define __has_feature(x) 0
13#endif
14
15#if __has_feature(ptrauth_init_fini)
16#include <ptrauth.h>
17#endif
18
19__attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle;
20
21#ifdef EH_USE_FRAME_REGISTRY
22__extension__ static void *__EH_FRAME_LIST__[]
23 __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {};
24
25extern void __register_frame_info(const void *, void *) __attribute__((weak));
26extern void *__deregister_frame_info(const void *) __attribute__((weak));
27#endif
28
29#ifndef CRT_HAS_INITFINI_ARRAY
30typedef void (*fp)(void);
31
32static fp __CTOR_LIST__[]
33 __attribute__((section(".ctors"), aligned(sizeof(fp)))) = {(fp)-1};
34extern fp __CTOR_LIST_END__[];
35#endif
36
37extern void __cxa_finalize(void *) __attribute__((weak));
38
39static void __attribute__((used)) __do_init(void) {
40 static _Bool __initialized;
41 if (__builtin_expect(__initialized, 0))
42 return;
43 __initialized = 1;
44
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);
49#endif
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]();
53#endif
54}
55
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));
64#else
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);
68#endif
69#else
70__attribute__((section(".init_array"),
71 used)) static void (*__init)(void) = __do_init;
72#endif
73#elif defined(__i386__) || defined(__x86_64__)
74__asm__(".pushsection .init,\"ax\",@progbits\n\t"
75 "call __do_init\n\t"
76 ".popsection");
77#elif defined(__riscv)
78__asm__(".pushsection .init,\"ax\",%progbits\n\t"
79 "call __do_init\n\t"
80 ".popsection");
81#elif defined(__arm__) || defined(__aarch64__)
82__asm__(".pushsection .init,\"ax\",%progbits\n\t"
83 "bl __do_init\n\t"
84 ".popsection");
85#elif defined(__mips__)
86__asm__(".pushsection .init,\"ax\",@progbits\n\t"
87 "jal __do_init\n\t"
88 ".popsection");
89#elif defined(__powerpc__) || defined(__powerpc64__)
90__asm__(".pushsection .init,\"ax\",@progbits\n\t"
91 "bl __do_init\n\t"
92 "nop\n\t"
93 ".popsection");
94#elif defined(__sparc__)
95__asm__(".pushsection .init,\"ax\",@progbits\n\t"
96 "call __do_init\n\t"
97 ".popsection");
98#else
99#error "crtbegin without .init_fini array unimplemented for this architecture"
100#endif // CRT_HAS_INITFINI_ARRAY
101
102#ifndef CRT_HAS_INITFINI_ARRAY
103static fp __DTOR_LIST__[]
104 __attribute__((section(".dtors"), aligned(sizeof(fp)))) = {(fp)-1};
105extern fp __DTOR_LIST_END__[];
106#endif
107
108static void __attribute__((used)) __do_fini(void) {
109 static _Bool __finalized;
110 if (__builtin_expect(__finalized, 0))
111 return;
112 __finalized = 1;
113
114 if (__cxa_finalize)
115 __cxa_finalize(__dso_handle);
116
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]();
120#endif
121#ifdef EH_USE_FRAME_REGISTRY
122 if (__deregister_frame_info)
123 __deregister_frame_info(__EH_FRAME_LIST__);
124#endif
125}
126
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));
135#else
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);
139#endif
140#else
141__attribute__((section(".fini_array"),
142 used)) static void (*__fini)(void) = __do_fini;
143#endif
144#elif defined(__i386__) || defined(__x86_64__)
145__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
146 "call __do_fini\n\t"
147 ".popsection");
148#elif defined(__arm__) || defined(__aarch64__)
149__asm__(".pushsection .fini,\"ax\",%progbits\n\t"
150 "bl __do_fini\n\t"
151 ".popsection");
152#elif defined(__mips__)
153__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
154 "jal __do_fini\n\t"
155 ".popsection");
156#elif defined(__powerpc__) || defined(__powerpc64__)
157__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
158 "bl __do_fini\n\t"
159 "nop\n\t"
160 ".popsection");
161#elif defined(__riscv)
162__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
163 "call __do_fini\n\t"
164 ".popsection");
165#elif defined(__sparc__)
166__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
167 "call __do_fini\n\t"
168 ".popsection");
169#else
170#error "crtbegin without .init_fini array unimplemented for this architecture"
171#endif // CRT_HAS_INIT_FINI_ARRAY
172

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of compiler-rt/lib/builtins/crtbegin.c