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
|
#include <stdio.h>
// flush so that:
// (1) if we segfault, we'll see the output
// (2) we get ordered correctly with Haskell output, which uses
// different buffers
static void initArray1(void) { printf("initArray1\n"); fflush(stdout); }
static void initArray2(void) { printf("initArray2\n"); fflush(stdout); }
static void ctors1(void) { printf("ctors1\n"); fflush(stdout); }
static void ctors2(void) { printf("ctors2\n"); fflush(stdout); }
static void modInitFunc1(void) { printf("modInitFunc1\n"); fflush(stdout); }
static void modInitFunc2(void) { printf("modInitFunc2\n"); fflush(stdout); }
#if defined(mingw32_HOST_OS)
static void (*ctors[2])(void) __attribute__((
section(".ctors"),
used,
aligned(sizeof(void*))))
= {ctors2, ctors1}; // ctors run in reverse
#elif defined(darwin_HOST_OS)
static void (*mod_init_func[2])(void) __attribute__((
// Mac OS X sections are in two parts: the segment name and
// the section name. The third part is the flag which says
// that this section is a list of module initialization
// functions.
section("__DATA,__mod_init_func,mod_init_funcs"),
used,
aligned(sizeof(void*))))
= {modInitFunc1, modInitFunc2};
#else /* ELF */
#if LOAD_CONSTR == 0
static void (*const init_array[2])(void) __attribute__((
section(".init_array"), // put it in the right section
used, // prevent GCC from optimizing this away
aligned(sizeof(void*)) // avoid slop between GCC's preloaded initializers and ours
))
= {initArray1, initArray2};
#else
static void (*ctors[2])(void) __attribute__((
section(".ctors"),
used,
aligned(sizeof(void*))))
= {ctors2, ctors1}; // ctors run in reverse
#endif
#endif
|