]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/crtn/lib/src/construction.c
update
[l4.git] / l4 / pkg / crtn / lib / src / construction.c
1 /*
2  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *               Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU Lesser General Public License 2.1.
7  * Please see the COPYING-LGPL-2.1 file for details.
8  */
9 #include <l4/crtn/crt0.h>
10
11 //#define DEBUG
12
13 #ifdef DEBUG
14 #include <l4/sys/kdebug.h>
15 #endif
16
17 int __cxa_atexit(void (*function)(void*), void *arg, void *dso_handle);
18
19 #define BEG             { (crt0_hook) ~1UL }
20 #define END             { (crt0_hook)  0UL }
21
22 // make sure that unused symbols are not discarded
23 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4
24 #define SECTION(x)      __attribute__((used, section( x )))
25 #else
26 #define SECTION(x)      __attribute__((section( x )))
27 #endif
28
29 typedef void (*const crt0_hook)(void);
30
31 static crt0_hook const __CTOR_BEG__[1]   SECTION(".mark_beg_ctors")   = BEG;
32 static crt0_hook const __CTOR_END__[1]   SECTION(".mark_end_ctors")   = END;
33 static crt0_hook const __C_CTOR_BEG__[1] SECTION(".mark_beg_c_ctors") = BEG;
34 static crt0_hook const __C_CTOR_END__[1] SECTION(".mark_end_c_ctors") = END;
35 static crt0_hook const __DTOR_BEG__[1]   SECTION(".mark_beg_dtors")   = BEG;
36 static crt0_hook const __DTOR_END__[1]   SECTION(".mark_end_dtors")   = END;
37 static crt0_hook const __C_DTOR_BEG__[1] SECTION(".mark_beg_c_dtors") = BEG;
38 static crt0_hook const __C_DTOR_END__[1] SECTION(".mark_end_c_dtors") = END;
39
40
41 static void
42 run_hooks_forward(crt0_hook *list, const char *name)
43 {
44   (void)name;
45 #ifdef DEBUG
46   outstring("list (forward) ");
47   outstring(name);
48   outstring(" @ ");
49   outhex32((unsigned)list);
50   outchar('\n');
51 #endif
52   list++;
53   while (*list)
54     {
55 #ifdef DEBUG
56       outstring("  calling ");
57       outhex32((unsigned)*list);
58       outchar('\n');
59 #endif
60       (**list)();
61       list++;
62     }
63 }
64
65 static void
66 run_hooks_backward(crt0_hook *list, const char *name)
67 {
68   (void)name;
69 #ifdef DEBUG
70   outstring("list (backward) ");
71   outstring(name);
72   outstring(" @ ");
73   outhex32((unsigned)list);
74   outchar('\n');
75 #endif
76   list--;
77   while (*list != (crt0_hook)~1UL)
78     {
79 #ifdef DEBUG
80       outstring("  calling ");
81       outhex32((unsigned)*list);
82       outchar('\n');
83 #endif
84       (**list)();
85       list--;
86     }
87 }
88
89 static void
90 static_construction(void)
91 {
92   /* call constructors made with L4_C_CTOR */
93   run_hooks_forward(__C_CTOR_BEG__, "__C_CTOR_BEG__");
94
95   /* call constructors made with __attribute__((constructor))
96    * and static C++ constructors */
97   run_hooks_backward(__CTOR_END__, "__CTOR_END__");
98 }
99
100 static void
101 static_destruction(void)
102 {
103   /* call destructors made with __attribute__((destructor))
104    * and static C++ destructors */
105   run_hooks_forward(__DTOR_BEG__, "__DTOR_BEG__");
106
107   /* call destructors made with L4_C_DTOR except system destructors */
108   run_hooks_backward(__C_DTOR_END__, "__C_DTOR_END__");
109 }
110
111 extern void *__dso_handle __attribute__((weak));
112
113 /* is called by crt0 immediately before calling __main() */
114 void
115 crt0_construction(void)
116 {
117   static_construction();
118   __cxa_atexit((void (*)(void*))&static_destruction, 0,
119       &__dso_handle == 0 ? 0 : __dso_handle);
120 }
121
122 asm (".hidden _init");
123
124 /* this special function is called for initializing static libraries */
125 void _init(void) __attribute__((section(".init")));
126 void
127 _init(void)
128 {
129   static_construction();
130 }