diff --git a/src/kernel/glue/Jamfile b/src/kernel/glue/Jamfile index 016ab0accd..e8a2a6097b 100755 --- a/src/kernel/glue/Jamfile +++ b/src/kernel/glue/Jamfile @@ -1,4 +1,8 @@ SubDir OBOS_TOP src kernel glue ; -KernelObjects lib0.c crt0.c ; +KernelObjects + crt0.c + init_term_dyn.c + start_dyn.c + ; diff --git a/src/kernel/glue/crt0.c b/src/kernel/glue/crt0.c index 2ced87a515..9d8d8ff36f 100755 --- a/src/kernel/glue/crt0.c +++ b/src/kernel/glue/crt0.c @@ -1,58 +1,23 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. */ -#include -#include -#include -extern int __stdio_init(void); -extern int __stdio_deinit(void); +#include "init_term_dyn.h" -extern void sys_exit(int retcode); +void _init(int id, void *args) __attribute__((section(".init"))); +void _fini(int id, void *args) __attribute__((section(".fini"))); + +// constructor/destructor lists as defined in the ld-script extern void (*__ctor_list)(void); extern void (*__ctor_end)(void); - -extern int main(int argc,char **argv); - -int _start(struct uspace_program_args *); -void _call_ctors(void); - -static char empty[1]; -char *__progname = empty; - -char **environ = NULL; +extern void (*__dtor_list)(void); +extern void (*__dtor_end)(void); -int -_start(struct uspace_program_args *args) -{ - int retcode; - register char *ap; - _call_ctors(); - -// __stdio_init(); - - if ((ap = args->argv[0])) { - if ((__progname = strrchr(ap, '/')) == NULL) - __progname = ap; - else - ++__progname; - } - - environ = args->envp; - retcode = main(args->argc, args->argv); - -// __stdio_deinit(); - - sys_exit(retcode); - return 0; -} - - -void +static void _call_ctors(void) { void (**f)(void); @@ -62,3 +27,36 @@ _call_ctors(void) } } + +static void +_call_dtors(void) +{ + void (**f)(void); + + for (f = &__dtor_list; f < &__dtor_end; f++) { + (**f)(); + } +} + + +void +_init(int id, void *args) +{ + _init_before(id, args); + + _call_ctors(); + + _init_after(id, args); +} + + +void +_fini(int id, void *args) +{ + _term_before(id, args); + + _call_dtors(); + + _term_after(id, args); +} + diff --git a/src/kernel/glue/init_term_dyn.c b/src/kernel/glue/init_term_dyn.c new file mode 100644 index 0000000000..d9e7d70aff --- /dev/null +++ b/src/kernel/glue/init_term_dyn.c @@ -0,0 +1,59 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include +#include + +#include "init_term_dyn.h" + + +/* These functions are called from _init()/_fini() (in crti.S, crtn.S) + * _init/fini_before() is called before crtbegin/end code is executed, + * _init/fini_after() after this. + * crtbegin contains code to initialize all global constructors and + * probably other GCC related things. + */ + + +void +_init_before(image_id id, struct uspace_program_args *args) +{ + void (*before)(image_id, struct uspace_program_args *); + + if (args->rld_export->get_image_symbol(id, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) + before(id, args); +} + + +void +_init_after(image_id id, struct uspace_program_args *args) +{ + void (*after)(image_id, struct uspace_program_args *); + + if (args->rld_export->get_image_symbol(id, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) + after(id, args); +} + + +void +_term_before(image_id id, struct uspace_program_args *args) +{ + void (*before)(image_id, struct uspace_program_args *); + + if (args->rld_export->get_image_symbol(id, B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) + before(id, args); +} + + +void +_term_after(image_id id, struct uspace_program_args *args) +{ + void (*after)(image_id, struct uspace_program_args *); + + if (args->rld_export->get_image_symbol(id, B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) + after(id, args); +} + diff --git a/src/kernel/glue/init_term_dyn.h b/src/kernel/glue/init_term_dyn.h new file mode 100644 index 0000000000..f84fd712a4 --- /dev/null +++ b/src/kernel/glue/init_term_dyn.h @@ -0,0 +1,19 @@ +#ifndef INIT_TERM_DYN_H +#define INIT_TERM_DYN_H +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include + + +struct uspace_program_args; + +void _init_before(image_id id, struct uspace_program_args *args); +void _init_after(image_id id, struct uspace_program_args *args); +void _term_before(image_id id, struct uspace_program_args *args); +void _term_after(image_id id, struct uspace_program_args *args); + +#endif /* INIT_TERM_DYN_H */ diff --git a/src/kernel/glue/lib0.c b/src/kernel/glue/lib0.c deleted file mode 100755 index 24e5804d2b..0000000000 --- a/src/kernel/glue/lib0.c +++ /dev/null @@ -1,61 +0,0 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Copyright 2002, Manuel J. Petit. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - - -#include -#include -#include - - -extern void sys_exit(int retcode); - -extern void (*__ctor_list)(void); -extern void (*__ctor_end)(void); - -int _start(image_id image_id, struct uspace_program_args *); -static void _call_ctors(void); - - -int -_start(image_id imageID, struct uspace_program_args *args) -{ -// int i; -// int retcode; - void *initBefore = NULL; - void *initAfter = NULL; - - args->rld_export->get_image_symbol(imageID, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&initBefore); - args->rld_export->get_image_symbol(imageID, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&initAfter); - - if (initBefore) - ((libinit_f *)(initBefore))(imageID, args); - - _call_ctors(); - - if (initAfter) - ((libinit_f *)(initAfter))(imageID, args); - - return 0; -} - - -static -void _call_ctors(void) -{ - void (**f)(void); - - for(f = &__ctor_list; f < &__ctor_end; f++) { - (**f)(); - } -} - -int __gxx_personality_v0(void); - -// XXX hack to make gcc 3.x happy until we get libstdc++ working -int __gxx_personality_v0(void) -{ - return 0; -} diff --git a/src/kernel/glue/start_dyn.c b/src/kernel/glue/start_dyn.c new file mode 100644 index 0000000000..357e5bb2d8 --- /dev/null +++ b/src/kernel/glue/start_dyn.c @@ -0,0 +1,39 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#include +#include + +#include +#include + + +extern int main(int argc, char **argv); + +int _start(int argc, char **argv, char **, struct uspace_program_args *); + +//static char empty[1]; +//char *__progname = empty; + +extern char **environ; + + +/* The argument list is redundant, but that is for keeping BeOS compatibility. + * BeOS doesn't have the last pointer, though. + */ + +int +_start(int argc, char **argv, char **_environ, struct uspace_program_args *args) +{ + int retcode; + + environ = args->envp; + + retcode = main(args->argc, args->argv); + + exit(retcode); + return 0; +} +