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:
@@ -1,4 +1,8 @@
|
|||||||
SubDir OBOS_TOP src kernel glue ;
|
SubDir OBOS_TOP src kernel glue ;
|
||||||
|
|
||||||
KernelObjects lib0.c crt0.c ;
|
KernelObjects
|
||||||
|
crt0.c
|
||||||
|
init_term_dyn.c
|
||||||
|
start_dyn.c
|
||||||
|
;
|
||||||
|
|
||||||
|
|||||||
+44
-46
@@ -1,58 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
** Distributed under the terms of the NewOS License.
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <user_runtime.h>
|
|
||||||
#include <syscalls.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
extern int __stdio_init(void);
|
#include "init_term_dyn.h"
|
||||||
extern int __stdio_deinit(void);
|
|
||||||
|
|
||||||
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_list)(void);
|
||||||
extern void (*__ctor_end)(void);
|
extern void (*__ctor_end)(void);
|
||||||
|
extern void (*__dtor_list)(void);
|
||||||
extern int main(int argc,char **argv);
|
extern void (*__dtor_end)(void);
|
||||||
|
|
||||||
int _start(struct uspace_program_args *);
|
|
||||||
void _call_ctors(void);
|
|
||||||
|
|
||||||
static char empty[1];
|
|
||||||
char *__progname = empty;
|
|
||||||
|
|
||||||
char **environ = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
int
|
static void
|
||||||
_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
|
|
||||||
_call_ctors(void)
|
_call_ctors(void)
|
||||||
{
|
{
|
||||||
void (**f)(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, [email protected]. 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, [email protected]. 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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user