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:
parent
f4c8b1eb40
commit
b8000952ca
|
@ -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
|
||||
;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue