diff options
-rw-r--r-- | libddekit/Makefile | 2 | ||||
-rw-r--r-- | libddekit/include/ddekit/initcall.h | 42 | ||||
-rw-r--r-- | libddekit/initcall.c | 27 |
3 files changed, 70 insertions, 1 deletions
diff --git a/libddekit/Makefile b/libddekit/Makefile index 4d5d58fa..958e67d3 100644 --- a/libddekit/Makefile +++ b/libddekit/Makefile @@ -21,7 +21,7 @@ makemode := library libname = libddekit SRCS= condvar.c init.c interrupt.c lock.c malloc.c memory.c \ pci.c pgtab.c printf.c resources.c list.c panic.c \ - thread.c timer.c kmem.c + thread.c timer.c kmem.c initcall.c LCLHDRS = include/ddekit/condvar.h include/ddekit/lock.h \ include/ddekit/semaphore.h include/ddekit/debug.h \ include/ddekit/inline.h include/ddekit/panic.h \ diff --git a/libddekit/include/ddekit/initcall.h b/libddekit/include/ddekit/initcall.h new file mode 100644 index 00000000..b503cc6a --- /dev/null +++ b/libddekit/include/ddekit/initcall.h @@ -0,0 +1,42 @@ +#ifndef _ddekit_initcall_h +#define _ddekit_initcall_h + +// from l4/sys/compiler.h +#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4 +#define L4_STICKY(x) __attribute__((used)) x +#else +#define L4_STICKY(x) __attribute__((unused)) x +#endif + +#define l4str(s) #s + +// from dde_linux/ARCH-x86/ctor.h +typedef void (*l4ddekit_initcall_t)(void); + +#define __l4ddekit_initcall(p) \ + __attribute__ ((__section__ (".l4dde_ctors." #p))) + +/** Define a function to be a DDEKit initcall. + * + * Define a function to be a DDEKit initcall. This function will then be placed + * in a separate linker section of the binary (called .l4dde_ctors). The L4Env + * construction mechanism will execute all constructors in this section during + * application startup. + * + * This is the right place to place Linux' module_init functions & Co. + * + * \param fn function + */ +#define DDEKIT_INITCALL(fn) DDEKIT_CTOR(fn, 1) + +#define DDEKIT_CTOR(fn, prio) \ + static l4ddekit_initcall_t \ + L4_STICKY(__l4ddekit_initcall_##fn) \ + __l4ddekit_initcall(prio) = (void *)fn + +/** + * Runs all registered initcalls. + */ +void ddekit_do_initcalls(void); + +#endif diff --git a/libddekit/initcall.c b/libddekit/initcall.c new file mode 100644 index 00000000..78c24146 --- /dev/null +++ b/libddekit/initcall.c @@ -0,0 +1,27 @@ +#include <ddekit/initcall.h> + +#define BEG { (crt0_hook) ~1U } +#define END { (crt0_hook) 0 } + +#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ >= 4 +#define SECTION(x) __attribute__((used, section( x ))) +#else +#define SECTION(x) __attribute__((section( x ))) +#endif + +typedef void (*const crt0_hook)(void); + +static crt0_hook __L4DDE_CTOR_BEG__[1] SECTION(".mark_beg_l4dde_ctors") = BEG; +static crt0_hook __l4DDE_CTOR_END__[1] SECTION(".mark_end_l4dde_ctors") = END; + +void ddekit_do_initcalls() { + crt0_hook *list = __L4DDE_CTOR_BEG__; + + list++; + while (*list) + { + (**list)(); + list++; + } +} + |