Skip to content

Commit 2caa7b6

Browse files
committed
Adding code for early init and late deinitialiation functions.
The early initialization functions are called before main() is called. They correspond to early constructor calls in C++. The deinitialization functions are the mirror image. They are called after main exits.
1 parent 5e43b3e commit 2caa7b6

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

earlyinit/earlyinit.h

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* RLIB - Convenience library for useful things
2+
* Copyright (C) 2015-2016 Haakon Sporsheim <[email protected]>
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 3.0 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library.
16+
* See the COPYING file at the root of the source repository.
17+
*/
18+
19+
20+
/*
21+
* Modified by Kyle Hayes. I just want the early init stuff.
22+
*/
23+
24+
#ifndef __R_MACROS_H__
25+
#define __R_MACROS_H__
26+
27+
#if defined(__GNUC__)
28+
#define R_INITIALIZER(f) static void __attribute__((constructor)) f (void)
29+
#define R_DEINITIALIZER(f) static void __attribute__((destructor)) f (void)
30+
#elif defined(_MSC_VER)
31+
#define R_INITIALIZER(f) \
32+
static void __cdecl f (void); \
33+
__pragma(section(".CRT$XCU",read)) \
34+
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
35+
static void __cdecl f (void)
36+
#define R_DEINITIALIZER(f) \
37+
static void __cdecl f (void); \
38+
static void __cdecl f##_atexit (void) { atexit (f); } \
39+
__pragma(section(".CRT$XCU",read)) \
40+
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f##_atexit; \
41+
static void __cdecl f (void)
42+
#else
43+
#error Your compiler does not support initializers/deinitializers
44+
#endif
45+
46+
47+
#endif /* __R_MACROS_H__ */

earlyinit/test_earlyinit.c

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include "earlyinit.h"
5+
6+
7+
static int test_val = 4;
8+
static void *test_allocation = NULL;
9+
10+
R_INITIALIZER(test_initializer)
11+
{
12+
printf("Test initializer called.\n");
13+
14+
test_val = 42;
15+
16+
test_allocation = malloc(1024);
17+
}
18+
19+
R_DEINITIALIZER(test_deinitializer)
20+
{
21+
printf("Test deinitializer called.\n");
22+
23+
test_val = 4;
24+
25+
free(test_allocation);
26+
}
27+
28+
29+
30+
31+
int main(int argc, char **argv)
32+
{
33+
printf("test_val = %d\n",test_val);
34+
35+
printf("test_allocation=%p\n",test_allocation);
36+
37+
return 0;
38+
}
39+
40+

0 commit comments

Comments
 (0)