Implemented BeOS compatible startup code.

This has almost the same layout as in BeOS - the only difference is crt0.o which
is what is usually provided by crti.o/crtbegin.o/crtend.o/crtn.o. When we want to
move to GCC's crtbegin/end code, we have to introduce crti.o and crtn.o. This is
required because the crtbegin/end stuff assumes to be inserted between a function
start (crti.o) and a function end (crtn.o) - which can only be achieved with assembly,
and is therefore platform dependent.
start_dyn.c is used for executables and calls main() (among other).
init_term_dyn.c functions are called from the .init/.fini sections and search
for B_INIT/TERM_BEFORE/AFTER_FUNCTION_NAME, and execute them if they are present.
Both use BeOS compatible call scheme but add parameters to the end.
lib0.c is no longer needed, because init_term.c/crt0.c replace its functionality.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2448 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2003-01-13 11:18:01 +00:00
parent f4c8b1eb40
commit b8000952ca
6 changed files with 166 additions and 108 deletions

View File

@ -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
;

View File

@ -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 <user_runtime.h>
#include <syscalls.h>
#include <string.h>
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);
}

View File

@ -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 <user_runtime.h>
#include <image.h>
#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);
}

View File

@ -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 <image.h>
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 */

View File

@ -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 <user_runtime.h>
#include <image.h>
#include <syscalls.h>
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;
}

View File

@ -0,0 +1,39 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <user_runtime.h>
#include <syscalls.h>
#include <string.h>
#include <stdlib.h>
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;
}