Skip to content

Commit 40afd69

Browse files
committed
Add support for .preinit_array / .init_array / .fini_array sections
1 parent b9d39d4 commit 40afd69

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

mintlib/crtinit.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,58 @@ char **__libc_argv = __libc_argv_default;
8686

8787
static long parseargs(BASEPAGE *);
8888

89+
#ifdef __ELF__
90+
91+
/*
92+
* Support for the init/fini initialization mechanism.
93+
* Inspired from glibc's csu/libc-start.c.
94+
* https://sourceware.org/git/?p=glibc.git;f=csu/libc-start.c;hb=refs/heads/master
95+
*/
96+
97+
/* These magic symbols are provided by the linker. */
98+
extern void (*__preinit_array_start [])(int, char **, char **);
99+
extern void (*__preinit_array_end [])(int, char **, char **);
100+
extern void (*__init_array_start [])(int, char **, char **);
101+
extern void (*__init_array_end [])(int, char **, char **);
102+
extern void (*__fini_array_start [])(void);
103+
extern void (*__fini_array_end [])(void);
104+
105+
/* Call global initializers/constructors. */
106+
static void
107+
call_init(int argc, char **argv, char **envp)
108+
{
109+
/* Preinitializers come from the .preinit_array sections. */
110+
{
111+
const size_t size = __preinit_array_end - __preinit_array_start;
112+
size_t i;
113+
for (i = 0; i < size; i++)
114+
(*__preinit_array_start [i])(argc, argv, envp);
115+
}
116+
117+
/* Modern systems don't require the .init section. */
118+
/*_init();*/
119+
120+
/* Initializers come from the .init_array sections. */
121+
const size_t size = __init_array_end - __init_array_start;
122+
for (size_t i = 0; i < size; i++)
123+
(*__init_array_start [i])(argc, argv, envp);
124+
}
125+
126+
/* Call global finalizers/destructors. */
127+
static void
128+
call_fini(void)
129+
{
130+
/* Finalizers come from the .fini_array sections. */
131+
size_t i = __fini_array_end - __fini_array_start;
132+
while (i-- > 0)
133+
(*__fini_array_start [i])();
134+
135+
/* Modern systems don't require the .fini section. */
136+
/*_fini();*/
137+
}
138+
139+
#endif /* __ELF__ */
140+
89141
/*
90142
* accessories start here:
91143
*/
@@ -114,6 +166,12 @@ _acc_main(void)
114166
/* this is an accessory */
115167
_app = 0;
116168

169+
#ifdef __ELF__
170+
/* main() won't call __main() for global constructors, so do it here. */
171+
atexit(call_fini);
172+
call_init(1L, acc_argv, acc_argv);
173+
#endif
174+
117175
_main(1L, acc_argv, acc_argv);
118176
/*NOTREACHED*/
119177
}
@@ -196,6 +254,12 @@ _crtinit(void)
196254
/* start profiling, if we were linked with gcrt0.o */
197255
_monstartup((void *)bp->p_tbase, (void *)((long)etext - 1));
198256

257+
#ifdef __ELF__
258+
/* main() won't call __main() for global constructors, so do it here. */
259+
atexit(call_fini);
260+
call_init(__libc_argc, __libc_argv, environ);
261+
#endif
262+
199263
_main(__libc_argc, __libc_argv, environ);
200264
/* not reached normally */
201265

0 commit comments

Comments
 (0)