1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// This file is part of Gear.
//
// Copyright (C) 2025 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Global constructors and destructors.
use crate::;
use ArrayVec;
use ;
pub use paste;
static mut DTORS: = new_const;
// a symbol that forces the linker to retain `.init_array` entries
// so that the linker does not garbage-collect constructors
static __gcore_pull_in_symbol: u8 = 0;
type Dtor = unsafe extern "C" fn;
/// Defines a global constructor.
///
/// The function is executed at the start of **every entrypoint** invocation.
///
/// # Examples
///
/// ```rust,no_run
/// gcore::ctor! {
/// unsafe extern "C" fn() {
/// // your global constructor
/// }
/// }
/// ```
///
/// # Priority
///
/// Constructors are ordered by a numeric priority: **the lower the priority,
/// the earlier it runs**.
///
/// Priorities `0..=999` are reserved for internal/runtime usage.
///
/// ```rust,no_run
/// // runs first
/// gcore::ctor! {
/// unsafe extern "C" fn 50000() {
/// // your global constructor
/// }
/// }
///
/// // runs second
/// gcore::ctor! {
/// unsafe extern "C" fn 50001() {
/// // your global constructor
/// }
/// }
/// ```
;
}
};
};
=> ;
}
/// Defines a global destructor.
///
/// The function is executed at the **end of every entrypoint** invocation.
///
/// This is a thin wrapper around [`ctor!`] that registers the body via
/// [`atexit()`], so the same priority rules and limits apply.
///
/// **Note:** because the wrapper always calls [`atexit()`], the destructor
/// is always registered for any entrypoint.
///
/// # Examples
///
/// ```rust,no_run
/// gcore::dtor! {
/// unsafe extern "C" fn() {
/// // your global destructor
/// }
/// }
/// ```
///
/// # Priority and ordering
///
/// See the [priority](ctor#priority) docs on [`ctor!`]. Because destructors
/// are executed in reverse registration order (LIFO), a destructor associated
/// with a **higher** constructor priority (runs later at start) will run
/// **earlier** at shutdown.
///
/// ```rust,no_run
/// // registered earlier → runs second (later) at shutdown
/// gcore::dtor! {
/// unsafe extern "C" fn 50000() {
/// // your global destructor
/// }
/// }
///
/// // registered later → runs first (earlier) at shutdown
/// gcore::dtor! {
/// unsafe extern "C" fn 50001() {
/// // your global destructor
/// }
/// }
/// ```
};
}
/// Registers a function to be executed at entry point termination.
///
/// Returns `0` on success, or `-1` if the registration limit has been reached.
///
/// Registered functions:
/// - are executed in **reverse order of registration** (LIFO) at the end of the
/// current entry point;
/// - remain registered until that point (they are not automatically
/// unregistered before then);
/// - are limited to a maximum of **32** slots total. Core libraries such as
/// `gcore`, `gstd`, and `galloc` may consume some of these slots, reducing
/// what is available to user code.
///
/// # Examples
///
/// ```rust,no_run
/// fn cleanup() {
/// /* ... */
/// }
///
/// let rc = gcore::atexit(cleanup);
/// assert_eq!(rc, 0, "atexit registry is full");
/// ```
unsafe extern "C"
ctor!
pub unsafe extern "C"
pub unsafe extern "C"