Skip to content

Commit f81c82f

Browse files
committed
[VCSTARTUP] Implement atexit and _onexit
These must use a local table and cannot use the one from ucrtbase. The table is initialized with a .CRT section initializer.
1 parent fce48c3 commit f81c82f

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

sdk/lib/vcruntime/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ list(APPEND VCRT_STARTUP_SOURCES
3535
__acrt_initialize_stub.cpp
3636
__scrt_uninitialize_crt.cpp
3737
__vcrt_init_stubs.c
38+
_onexit.c
39+
atexit.c
3840
mainCRTStartup.cpp
3941
wmainCRTStartup.cpp
4042
)

sdk/lib/vcruntime/_onexit.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// _onexit.c
3+
//
4+
// Copyright (c) 2024 Timo Kreuzer
5+
//
6+
// Implementation of _onexit.
7+
//
8+
// SPDX-License-Identifier: MIT
9+
//
10+
11+
#include <stdlib.h>
12+
#include <internal_shared.h>
13+
#include <corecrt_startup.h>
14+
#include <assert.h>
15+
16+
_onexit_table_t module_local_atexit_table;
17+
int module_local_atexit_table_initialized = 0;
18+
19+
int __cdecl __scrt_initialize_onexit(void)
20+
{
21+
_initialize_onexit_table(&module_local_atexit_table);
22+
module_local_atexit_table_initialized = 1;
23+
return 0;
24+
}
25+
26+
// CRT startup initializer
27+
_CRTALLOC(".CRT$XIAA") _PIFV const __scrt_onexit_initializer = __scrt_initialize_onexit;
28+
29+
_onexit_t __cdecl _onexit(_In_opt_ _onexit_t _Func)
30+
{
31+
assert(module_local_atexit_table_initialized == 1);
32+
int result = _register_onexit_function(&module_local_atexit_table, _Func);
33+
return (result == 0) ? _Func : NULL;
34+
}

sdk/lib/vcruntime/atexit.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// atexit.c
3+
//
4+
// Copyright (c) 2024 Timo Kreuzer
5+
//
6+
// Implementation of atexit.
7+
//
8+
// SPDX-License-Identifier: MIT
9+
//
10+
11+
#include <stdlib.h>
12+
13+
int __cdecl atexit(void (__cdecl* _Func)(void))
14+
{
15+
// Go through _onexit, so that the initializer is pulled in.
16+
_onexit_t result = _onexit((_onexit_t)_Func);
17+
return (result == NULL) ? -1 : 0;
18+
}

sdk/lib/vcruntime/inc/internal_shared.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern "C" {
3131
#pragma section(".CRT$XPXA", long, read)
3232

3333
#pragma section(".CRT$XIA", long, read)
34+
#pragma section(".CRT$XIAA", long, read) // CRT startup
3435
#pragma section(".CRT$XIZ", long, read)
3536
#pragma section(".CRT$XCA", long, read)
3637
#pragma section(".CRT$XCZ", long, read)

0 commit comments

Comments
 (0)