diff --git a/headers/private/kernel/user_runtime.h b/headers/private/kernel/user_runtime.h index 7fa913ab36..504f2a3b1f 100644 --- a/headers/private/kernel/user_runtime.h +++ b/headers/private/kernel/user_runtime.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2002, Manuel J. Petit. All rights reserved. @@ -15,6 +15,15 @@ #define MAGIC_APP_NAME "_APP_" +struct uspace_program_args { + char program_name[B_OS_NAME_LENGTH]; + char program_path[B_PATH_NAME_LENGTH]; + int argc; + int envc; + char **argv; + char **envp; +}; + struct rld_export { // runtime linker API export image_id (*load_add_on)(char const *path, uint32 flags); @@ -25,20 +34,10 @@ struct rld_export { int32 *nameLength, int32 *symbolType, void **_location); status_t (*test_executable)(const char *path, uid_t user, gid_t group, char *starter); + + const struct uspace_program_args *program_args; }; -struct uspace_program_args { - char program_name[B_OS_NAME_LENGTH]; - char program_path[B_PATH_NAME_LENGTH]; - int argc; - int envc; - char **argv; - char **envp; - - /* - * hooks into rld for POSIX and BeOS library/module loading - */ - struct rld_export *rld_export; -}; +extern struct rld_export *__gRuntimeLoader; #endif /* KERNEL_USER_RUNTIME_H_ */ diff --git a/headers/private/libroot/libroot_private.h b/headers/private/libroot/libroot_private.h index 4bfbb77ca0..e918beefd4 100644 --- a/headers/private/libroot/libroot_private.h +++ b/headers/private/libroot/libroot_private.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef LIBROOT_PRIVATE_H @@ -15,8 +15,6 @@ struct real_time_data; status_t __parse_invoke_line(char *invoker, char ***_newArgs, char * const **_oldArgs, int32 *_argCount); status_t __test_executable(const char *path, char *invoker); -void __init_image(const struct uspace_program_args *args); -void __init_dlfcn(const struct uspace_program_args *args); void __init_env(const struct uspace_program_args *args); void __init_heap(void); diff --git a/src/system/glue/arch/x86/crti.S b/src/system/glue/arch/x86/crti.S index 0fafe1ee27..02c5d4c26c 100644 --- a/src/system/glue/arch/x86/crti.S +++ b/src/system/glue/arch/x86/crti.S @@ -1,5 +1,5 @@ /* - * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -23,8 +23,9 @@ FUNCTION(_init): pushl %ebp movl %esp, %ebp - pushl 0xc(%ebp) // program args - pushl 0x8(%ebp) // image ID + pushl %ebx + // BeOS unfortunately puts the image ID into %ebx instead of + // just passing it over the stack call _init_before // crtbegin.o stuff comes here @@ -32,7 +33,6 @@ FUNCTION(_init): FUNCTION(_fini): pushl %ebp movl %esp, %ebp - pushl 0xc(%ebp) // program args - pushl 0x8(%ebp) // image ID + pushl %ebx call _term_before - // crtbegin.o stuff comes here + // crtend.o stuff comes here diff --git a/src/system/glue/arch/x86/crtn.S b/src/system/glue/arch/x86/crtn.S index 3cf2cb1c10..b6b25d791c 100644 --- a/src/system/glue/arch/x86/crtn.S +++ b/src/system/glue/arch/x86/crtn.S @@ -1,5 +1,5 @@ /* - * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -9,14 +9,14 @@ */ .section .init - // the image ID and program args are still on the stack + // the image ID is still on the stack call _init_after movl %ebp, %esp popl %ebp ret .section .fini - // the image ID and program args are still on the stack + // the image ID is still on the stack call _term_after movl %ebp, %esp popl %ebp diff --git a/src/system/glue/init_term_dyn.c b/src/system/glue/init_term_dyn.c index d19051db4f..5743ab9adc 100644 --- a/src/system/glue/init_term_dyn.c +++ b/src/system/glue/init_term_dyn.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -19,41 +19,41 @@ void -_init_before(image_id id, struct uspace_program_args *args) +_init_before(image_id id) { - void (*before)(image_id, struct uspace_program_args *); + void (*before)(image_id); - if (args->rld_export->get_image_symbol(id, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) - before(id, args); + if (get_image_symbol(id, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) + before(id); } void -_init_after(image_id id, struct uspace_program_args *args) +_init_after(image_id id) { - void (*after)(image_id, struct uspace_program_args *); + void (*after)(image_id); - if (args->rld_export->get_image_symbol(id, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) - after(id, args); + if (get_image_symbol(id, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) + after(id); } void -_term_before(image_id id, struct uspace_program_args *args) +_term_before(image_id id) { - void (*before)(image_id, struct uspace_program_args *); + void (*before)(image_id); - if (args->rld_export->get_image_symbol(id, B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) - before(id, args); + if (get_image_symbol(id, B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK) + before(id); } void -_term_after(image_id id, struct uspace_program_args *args) +_term_after(image_id id) { - void (*after)(image_id, struct uspace_program_args *); + void (*after)(image_id); - if (args->rld_export->get_image_symbol(id, B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) - after(id, args); + if (get_image_symbol(id, B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK) + after(id); } diff --git a/src/system/glue/init_term_dyn.h b/src/system/glue/init_term_dyn.h index f84fd712a4..3b45abef9f 100644 --- a/src/system/glue/init_term_dyn.h +++ b/src/system/glue/init_term_dyn.h @@ -1,19 +1,17 @@ +/* + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ #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); +void _init_before(image_id id); +void _init_after(image_id id); +void _term_before(image_id id); +void _term_after(image_id id); #endif /* INIT_TERM_DYN_H */ diff --git a/src/system/glue/start_dyn.c b/src/system/glue/start_dyn.c index 549e8510d0..f42d459a19 100644 --- a/src/system/glue/start_dyn.c +++ b/src/system/glue/start_dyn.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -14,8 +14,10 @@ extern int main(int argc, char **argv, char **env); +extern void _init_c_library_(void); +extern void _call_init_routines_(void); -int _start(int argc, char **argv, char **env, struct uspace_program_args *args); +int _start(int argc, char **argv, char **env); // these are part of libroot.so, and initialized here extern char **argv_save; @@ -23,19 +25,20 @@ extern thread_id __main_thread_id; 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) +_start(int argc, char **argv, char **environment) { int returnCode; - argv_save = args->argv; + argv_save = argv; __main_thread_id = find_thread(NULL); - returnCode = main(args->argc, args->argv, args->envp); + // These two are called to make our glue code usable under BeOS R5 + // - in Haiku, they are both empty. + _init_c_library_(); + _call_init_routines_(); + + returnCode = main(argc, argv, environment); exit(returnCode); return 0; diff --git a/src/system/runtime_loader/arch/ppc/rld.ld b/src/system/ldscripts/ppc/rld.ld similarity index 100% rename from src/system/runtime_loader/arch/ppc/rld.ld rename to src/system/ldscripts/ppc/rld.ld diff --git a/src/system/runtime_loader/arch/x86/rld.ld b/src/system/ldscripts/x86/rld.ld similarity index 100% rename from src/system/runtime_loader/arch/x86/rld.ld rename to src/system/ldscripts/x86/rld.ld diff --git a/src/system/libroot/libroot_init.c b/src/system/libroot/libroot_init.c index cb6a21772a..4ddc01a306 100644 --- a/src/system/libroot/libroot_init.c +++ b/src/system/libroot/libroot_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -7,11 +7,16 @@ #include #include #include +#include #include -void initialize_before(image_id imageID, struct uspace_program_args const *args); +void initialize_before(image_id imageID); + +struct rld_export *__gRuntimeLoader = NULL; + // This little bugger is set to something meaningful by the runtime loader + // Ugly, eh? char *__progname = NULL; int __libc_argc; @@ -30,9 +35,9 @@ int _data_offset_main_; void -initialize_before(image_id imageID, struct uspace_program_args const *args) +initialize_before(image_id imageID) { - char *programPath = args->argv[0]; + char *programPath = __gRuntimeLoader->program_args->argv[0]; if (programPath) { if ((__progname = strrchr(programPath, '/')) == NULL) __progname = programPath; @@ -40,15 +45,13 @@ initialize_before(image_id imageID, struct uspace_program_args const *args) __progname++; } - __libc_argc = args->argc; - __libc_argv = args->argv; + __libc_argc = __gRuntimeLoader->program_args->argc; + __libc_argv = __gRuntimeLoader->program_args->argv; __init_time(); - __init_image(args); - __init_dlfcn(args); __init_fork(); __init_heap(); - __init_env(args); + __init_env(__gRuntimeLoader->program_args); } diff --git a/src/system/libroot/os/image.c b/src/system/libroot/os/image.c index cc101efa4a..22af19624c 100644 --- a/src/system/libroot/os/image.c +++ b/src/system/libroot/os/image.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -14,9 +14,6 @@ #include -static struct rld_export const *sRuntimeLinker; - - thread_id load_image(int32 argCount, const char **args, const char **environ) { @@ -57,21 +54,21 @@ load_image(int32 argCount, const char **args, const char **environ) image_id load_add_on(char const *name) { - return sRuntimeLinker->load_add_on(name, 0); + return __gRuntimeLoader->load_add_on(name, 0); } status_t unload_add_on(image_id id) { - return sRuntimeLinker->unload_add_on(id); + return __gRuntimeLoader->unload_add_on(id); } status_t get_image_symbol(image_id id, char const *symbolName, int32 symbolType, void **_location) { - return sRuntimeLinker->get_image_symbol(id, symbolName, symbolType, _location); + return __gRuntimeLoader->get_image_symbol(id, symbolName, symbolType, _location); } @@ -79,7 +76,7 @@ status_t get_nth_image_symbol(image_id id, int32 num, char *nameBuffer, int32 *_nameLength, int32 *_symbolType, void **_location) { - return sRuntimeLinker->get_nth_image_symbol(id, num, nameBuffer, _nameLength, _symbolType, _location); + return __gRuntimeLoader->get_nth_image_symbol(id, num, nameBuffer, _nameLength, _symbolType, _location); } @@ -188,14 +185,7 @@ __parse_invoke_line(char *invoker, char ***_newArgs, status_t __test_executable(const char *path, char *invoker) { - return sRuntimeLinker->test_executable(path, geteuid(), getegid(), invoker); -} - - -void -__init_image(const struct uspace_program_args *args) -{ - sRuntimeLinker = args->rld_export; + return __gRuntimeLoader->test_executable(path, geteuid(), getegid(), invoker); } diff --git a/src/system/libroot/posix/dlfcn.c b/src/system/libroot/posix/dlfcn.c index c70e7de86d..3c70dfbb46 100644 --- a/src/system/libroot/posix/dlfcn.c +++ b/src/system/libroot/posix/dlfcn.c @@ -1,10 +1,10 @@ -/* -** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Copyright 2002, Manuel J. Petit. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ +/* + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2002, Manuel J. Petit. All rights reserved. + * Distributed under the terms of the NewOS License. + */ #include @@ -14,7 +14,6 @@ #include -static struct rld_export const *sRuntimeLinker; static status_t sStatus; // Note, this is not thread-safe @@ -27,7 +26,7 @@ dlopen(char const *name, int mode) if (name == NULL) name = MAGIC_APP_NAME; - status = sRuntimeLinker->load_add_on(name, mode); + status = __gRuntimeLoader->load_add_on(name, mode); sStatus = status; if (status < B_OK) @@ -43,7 +42,7 @@ dlsym(void *handle, char const *name) status_t status; void *location; - status = sRuntimeLinker->get_image_symbol((image_id)handle, name, B_SYMBOL_TYPE_ANY, &location); + status = get_image_symbol((image_id)handle, name, B_SYMBOL_TYPE_ANY, &location); sStatus = status; if (status < B_OK) @@ -56,7 +55,7 @@ dlsym(void *handle, char const *name) int dlclose(void *handle) { - return sRuntimeLinker->unload_add_on((image_id)handle); + return unload_add_on((image_id)handle); } @@ -69,9 +68,3 @@ dlerror(void) return NULL; } - -void -__init_dlfcn(const struct uspace_program_args *args) -{ - sRuntimeLinker = args->rld_export; -} diff --git a/src/system/runtime_loader/Jamfile b/src/system/runtime_loader/Jamfile index 8df03b4cc6..30b9646a9d 100644 --- a/src/system/runtime_loader/Jamfile +++ b/src/system/runtime_loader/Jamfile @@ -1,6 +1,5 @@ SubDir HAIKU_TOP src system runtime_loader ; -SubDirHdrs [ FDirName $(SUBDIR) arch ] ; UsePrivateHeaders runtime_loader ; UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; @@ -54,17 +53,21 @@ StaticLibrary librld.a : SEARCH on [ FGristFiles kernel_vsprintf.c ] = [ FDirName $(HAIKU_TOP) src system kernel lib ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ; + Objects rld.c rldexport.c rldelf.c rldheap.c rldaux.c + arch_relocate.c + arch_call_init_term.c ; Ld rld.so : - [ FGristFiles rld.o rldelf.o rldexport.o rldheap.o rldaux.o ] + [ FGristFiles rld.o rldelf.o rldexport.o rldheap.o rldaux.o arch_relocate.o arch_call_init_term.o ] librld.a $(TARGET_GCC_LIBGCC) - : $(SUBDIR)/arch/$(TARGET_ARCH)/rld.ld + : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/rld.ld ; diff --git a/src/system/runtime_loader/arch/ppc/arch_call_init_term.c b/src/system/runtime_loader/arch/ppc/arch_call_init_term.c new file mode 100644 index 0000000000..f1efdb4d17 --- /dev/null +++ b/src/system/runtime_loader/arch/ppc/arch_call_init_term.c @@ -0,0 +1,29 @@ +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * Ingo Weinhold, bonefish@cs.tu-berlin.de + */ + + +#include "rld_priv.h" + + +typedef void (*init_term_function)(image_id); + + +void +arch_call_init(image_t *image) +{ + ((init_term_function *)image->init_routine)(image->id); +} + + +void +arch_call_term(image_t *image) +{ + ((init_term_function *)image->term_routine)(image->id); +} + diff --git a/src/system/runtime_loader/arch/ppc/rldreloc.inc b/src/system/runtime_loader/arch/ppc/arch_relocate.c similarity index 80% rename from src/system/runtime_loader/arch/ppc/rldreloc.inc rename to src/system/runtime_loader/arch/ppc/arch_relocate.c index dd7ee34e4f..69e99c9a47 100644 --- a/src/system/runtime_loader/arch/ppc/rldreloc.inc +++ b/src/system/runtime_loader/arch/ppc/arch_relocate.c @@ -3,6 +3,22 @@ * Distributed under the terms of the MIT License. */ +#include + +#include +#include +#include + +#include "rld_priv.h" + + +//#define TRACE_RLD +#ifdef TRACE_RLD +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + static int relocate_rel(image_t *image, struct Elf32_Rel *rel, int rel_len) @@ -13,7 +29,7 @@ relocate_rel(image_t *image, struct Elf32_Rel *rel, int rel_len) } -static status_t +status_t arch_relocate_image(image_t *image) { status_t status = B_NO_ERROR; diff --git a/src/system/runtime_loader/arch/rldreloc.inc b/src/system/runtime_loader/arch/rldreloc.inc deleted file mode 100644 index 7a91805f51..0000000000 --- a/src/system/runtime_loader/arch/rldreloc.inc +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef ARCH_x86 -#include "x86/rldreloc.inc" -#endif -#ifdef ARCH_alpha -#include "alpha/rldreloc.inc" -#endif -#ifdef ARCH_sh4 -#include "sh4/rldreloc.inc" -#endif -#ifdef ARCH_sparc -#include "sparc/rldreloc.inc" -#endif -#ifdef ARCH_sparc64 -#include "sparc64/rldreloc.inc" -#endif -#ifdef ARCH_mips -#include "mips/rldreloc.inc" -#endif -#ifdef ARCH_ppc -#include "ppc/rldreloc.inc" -#endif diff --git a/src/system/runtime_loader/arch/x86/arch_call_init_term.c b/src/system/runtime_loader/arch/x86/arch_call_init_term.c new file mode 100644 index 0000000000..e0844804d2 --- /dev/null +++ b/src/system/runtime_loader/arch/x86/arch_call_init_term.c @@ -0,0 +1,29 @@ +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * Ingo Weinhold, bonefish@cs.tu-berlin.de + */ + + +#include "rld_priv.h" + + +void +arch_call_init(image_t *image) +{ + // This calls the init code in crti.S (in glue/arch/x86/) + // It would have been too easy to just call this function with its arguments + // on the stack, so Be went the ugly way. Once more. + asm("mov %0, %%ebx; call *%1" : : "g"(image->id), "g"(image->init_routine)); +} + + +void +arch_call_term(image_t *image) +{ + asm("mov %0, %%ebx; call *%1" : : "g"(image->id), "g"(image->term_routine)); +} + diff --git a/src/system/runtime_loader/arch/x86/rldreloc.inc b/src/system/runtime_loader/arch/x86/arch_relocate.c similarity index 82% rename from src/system/runtime_loader/arch/x86/rldreloc.inc rename to src/system/runtime_loader/arch/x86/arch_relocate.c index 4a39fcb1e6..edb97c1387 100644 --- a/src/system/runtime_loader/arch/x86/rldreloc.inc +++ b/src/system/runtime_loader/arch/x86/arch_relocate.c @@ -1,8 +1,28 @@ /* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Copyright 2002, Manuel J. Petit. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de + * Distributed under the terms of the MIT License. + * + * 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 +#include + +#include "rld_priv.h" + + +//#define TRACE_RLD +#ifdef TRACE_RLD +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif static int @@ -93,11 +113,7 @@ relocate_rel(image_t *image, struct Elf32_Rel *rel, int rel_len) } -/* - * rldelf.c requires this function to be implemented on a per-cpu basis - */ - -static status_t +status_t arch_relocate_image(image_t *image) { status_t status; diff --git a/src/system/runtime_loader/rld.c b/src/system/runtime_loader/rld.c index c68f5ce2eb..d4dee6a150 100644 --- a/src/system/runtime_loader/rld.c +++ b/src/system/runtime_loader/rld.c @@ -302,6 +302,6 @@ runtime_loader(void *_args) return -1; // call the program entry point (usually _start()) - return ((int (*)(int, void *, void *, const void *))entry)(gProgramArgs->argc, - gProgramArgs->argv, gProgramArgs->envp, gProgramArgs); + return ((int (*)(int, void *, void *))entry)(gProgramArgs->argc, + gProgramArgs->argv, gProgramArgs->envp); } diff --git a/src/system/runtime_loader/rld_priv.h b/src/system/runtime_loader/rld_priv.h index b3e8c8f504..34e7967084 100644 --- a/src/system/runtime_loader/rld_priv.h +++ b/src/system/runtime_loader/rld_priv.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2002, Manuel J. Petit. All rights reserved. @@ -10,13 +10,13 @@ #include - +#include int runtime_loader(void *arg); int open_executable(char *name, image_type type, const char *rpath); status_t test_executable(const char *path, uid_t user, gid_t group, char *starter); -status_t unload_program(image_id imageID); +void terminate_program(void); image_id load_program(char const *path, void **entry); status_t unload_library(image_id imageID, bool addOn); image_id load_library(char const *path, uint32 flags, bool addOn); @@ -24,6 +24,8 @@ status_t get_nth_symbol(image_id imageID, int32 num, char *nameBuffer, int32 *_n int32 *_type, void **_location); status_t get_symbol(image_id imageID, char const *symbolName, int32 symbolType, void **_location); +int resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr_t *sym_addr); + status_t elf_verify_header(void *header, int32 length); void rldelf_init(void); @@ -34,6 +36,12 @@ void rldheap_init(void); void *rldalloc(size_t); void rldfree(void *p); +// arch dependent prototypes +status_t arch_relocate_image(image_t *image); +void arch_call_init(image_t *image); +void arch_call_term(image_t *image); + extern struct uspace_program_args *gProgramArgs; +extern struct rld_export gRuntimeLoader; #endif /* RUN_TIME_LINKER_H */ diff --git a/src/system/runtime_loader/rldelf.c b/src/system/runtime_loader/rldelf.c index c813396a5c..d546d59b6a 100644 --- a/src/system/runtime_loader/rldelf.c +++ b/src/system/runtime_loader/rldelf.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2002, Manuel J. Petit. All rights reserved. @@ -39,7 +39,6 @@ // ToDo: implement better locking strategy -// ToDo: implement unload_program() // ToDo: implement lazy binding #define PAGE_MASK (B_PAGE_SIZE - 1) @@ -55,6 +54,7 @@ enum { RFLAG_RW = 0x0001, RFLAG_ANON = 0x0002, + RFLAG_TERMINATED = 0x0200, RFLAG_INITIALIZED = 0x0400, RFLAG_SYMBOLIC = 0x0800, RFLAG_RELOCATED = 0x1000, @@ -73,12 +73,11 @@ enum { | IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE)) -typedef void (libinit_f)(unsigned, struct uspace_program_args const *); - -static image_queue_t gLoadedImages = {0, 0}; -static image_queue_t gLoadingImages = {0, 0}; -static image_queue_t gDisposableImages = {0, 0}; -static uint32 gLoadedImageCount = 0; +static image_queue_t sLoadedImages = {0, 0}; +static image_queue_t sLoadingImages = {0, 0}; +static image_queue_t sDisposableImages = {0, 0}; +static uint32 sLoadedImageCount = 0; +static image_t *sProgramImage; // a recursive lock static sem_id rld_sem; @@ -211,10 +210,10 @@ find_image(char const *name, uint32 typeMask) bool isPath = (strchr(name, '/') != NULL); image_t *image; - image = find_image_in_queue(&gLoadedImages, name, isPath, typeMask); + image = find_image_in_queue(&sLoadedImages, name, isPath, typeMask); if (!image) - image = find_image_in_queue(&gLoadingImages, name, isPath, typeMask); + image = find_image_in_queue(&sLoadingImages, name, isPath, typeMask); return image; } @@ -225,7 +224,7 @@ find_loaded_image_by_id(image_id id) { image_t *image; - for (image = gLoadedImages.head; image; image = image->next) { + for (image = sLoadedImages.head; image; image = image->next) { if (image->id == id) return image; } @@ -496,7 +495,7 @@ remap_images(void) image_t *image; uint32 i; - for (image = gLoadedImages.head; image != NULL; image = image->next) { + for (image = sLoadedImages.head; image != NULL; image = image->next) { for (i = 0; i < image->num_regions; i++) { if ((image->regions[i].flags & RFLAG_RW) == 0 && (image->regions[i].flags & RFLAG_REMAPPED) == 0) { @@ -732,7 +731,7 @@ find_symbol_in_loaded_images(image_t **_image, const char *name) { image_t *image; - for (image = gLoadedImages.head; image; image = image->next) { + for (image = sLoadedImages.head; image; image = image->next) { struct Elf32_Sym *symbol; if (image->dynamic_ptr == NULL) @@ -749,7 +748,7 @@ find_symbol_in_loaded_images(image_t **_image, const char *name) } -static int +int resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr_t *sym_addr) { struct Elf32_Sym *sym2; @@ -801,9 +800,6 @@ resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr_t *sym_addr) } -#include "arch/rldreloc.inc" - - static void register_image(image_t *image, int fd, const char *path) { @@ -974,7 +970,7 @@ load_container(char const *name, image_type type, const char *rpath, image_t **_ _kern_close(fd); - enqueue_image(&gLoadedImages, image); + enqueue_image(&sLoadedImages, image); *_image = image; return B_OK; @@ -1031,6 +1027,7 @@ load_dependencies(image_t *image) switch (d[i].d_tag) { case DT_NEEDED: neededOffset = d[i].d_un.d_val; + status = load_container(STRING(image, neededOffset), B_LIBRARY_IMAGE, rpath, &image->needed[j]); if (status < B_OK) @@ -1040,9 +1037,7 @@ load_dependencies(image_t *image) break; default: - /* - * ignore any other tag - */ + // ignore any other tag continue; } } @@ -1079,12 +1074,12 @@ get_sorted_image_list(image_t *image, image_t ***_list, uint32 sortFlag) { image_t **list; - list = rldalloc(gLoadedImageCount * sizeof(image_t *)); + list = rldalloc(sLoadedImageCount * sizeof(image_t *)); if (list == NULL) { FATAL("memory shortage in get_sorted_image_list()"); return 0; // B_NO_MEMORY } - memset(list, 0, gLoadedImageCount * sizeof(image_t *)); + memset(list, 0, sLoadedImageCount * sizeof(image_t *)); *_list = list; return topological_sort(image, 0, list, sortFlag); @@ -1128,12 +1123,8 @@ init_dependencies(image_t *image, bool initHead) TRACE(("%ld: init dependencies\n", find_thread(NULL))); for (i = 0; i < count; i++) { - addr_t _initf = initList[i]->init_routine; - libinit_f *initf = (libinit_f *)(_initf); - TRACE(("%ld: init: %s\n", find_thread(NULL), initList[i]->name)); - if (initf) - initf(initList[i]->id, gProgramArgs); + arch_call_init(initList[i]); } TRACE(("%ld: init done.\n", find_thread(NULL))); @@ -1150,8 +1141,8 @@ put_image(image_t *image) if (atomic_add(&image->ref_count, -1) == 1) { size_t i; - dequeue_image(&gLoadedImages, image); - enqueue_image(&gDisposableImages, image); + dequeue_image(&sLoadedImages, image); + enqueue_image(&sDisposableImages, image); for (i = 0; i < image->num_needed; i++) { put_image(image->needed[i]); @@ -1169,42 +1160,50 @@ load_program(char const *path, void **_entry) { status_t status; image_t *image; - image_t *iter; rld_lock(); // for now, just do stupid simple global locking TRACE(("rld: load %s\n", path)); - status = load_container(path, B_APP_IMAGE, NULL, &image); + status = load_container(path, B_APP_IMAGE, NULL, &sProgramImage); if (status < B_OK) { _kern_loading_app_failed(status); rld_unlock(); return status; } - for (iter = gLoadedImages.head; iter; iter = iter->next) { - status = load_dependencies(iter); + for (image = sLoadedImages.head; image != NULL; image = image->next) { + status = load_dependencies(image); if (status < B_OK) goto err; } - status = relocate_dependencies(image); + status = relocate_dependencies(sProgramImage); if (status < B_OK) goto err; - init_dependencies(gLoadedImages.head, true); + // We patch any exported __gRuntimeLoader symbols to point to our private API + { + struct Elf32_Sym *symbol = find_symbol_in_loaded_images(&image, "__gRuntimeLoader"); + if (symbol != NULL) { + void **_export = (void **)(symbol->st_value + image->regions[0].delta); + *_export = &gRuntimeLoader; + } + } + + init_dependencies(sLoadedImages.head, true); remap_images(); // ToDo: once setup_system_time() is fixed, move this one line higher! - *_entry = (void *)(image->entry_point); + *_entry = (void *)(sProgramImage->entry_point); rld_unlock(); - return image->id; + return sProgramImage->id; err: _kern_loading_app_failed(status); - delete_image(image); + delete_image(sProgramImage); rld_unlock(); return status; } @@ -1241,7 +1240,7 @@ load_library(char const *path, uint32 flags, bool addOn) return status; } - for (iter = gLoadedImages.head; iter; iter = iter->next) { + for (iter = sLoadedImages.head; iter; iter = iter->next) { status = load_dependencies(iter); if (status < B_OK) goto err; @@ -1269,7 +1268,7 @@ unload_library(image_id imageID, bool addOn) { status_t status = B_BAD_IMAGE_ID; image_t *image; - image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE); + image_type type = addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE; rld_lock(); // for now, just do stupid simple global locking @@ -1278,7 +1277,7 @@ unload_library(image_id imageID, bool addOn) * we only check images that have been already initialized */ - for (image = gLoadedImages.head; image; image = image->next) { + for (image = sLoadedImages.head; image; image = image->next) { if (image->id == imageID) { /* * do the unloading @@ -1293,12 +1292,12 @@ unload_library(image_id imageID, bool addOn) } if (status == B_OK) { - while ((image = gDisposableImages.head) != NULL) { + while ((image = sDisposableImages.head) != NULL) { // call image fini here... if (image->term_routine) - ((libinit_f *)image->term_routine)(image->id, gProgramArgs); - - dequeue_image(&gDisposableImages, image); + arch_call_term(image); + + dequeue_image(&sDisposableImages, image); unmap_image(image); delete_image(image); @@ -1405,6 +1404,28 @@ elf_verify_header(void *header, int32 length) } +void +terminate_program(void) +{ + image_t **termList; + uint32 count, i; + + count = get_sorted_image_list(sProgramImage, &termList, RFLAG_TERMINATED); + if (count == 0) + return; + + TRACE(("%ld: terminate dependencies\n", find_thread(NULL))); + for (i = count; i-- > 0;) { + TRACE(("%ld: term: %s\n", find_thread(NULL), termList[i]->name)); + arch_call_term(termList[i]); + } + TRACE(("%ld: term done.\n", find_thread(NULL))); + + rldfree(termList); + +} + + void rldelf_init(void) { @@ -1425,6 +1446,6 @@ rldelf_init(void) _kern_loading_app_failed(areaID); } - area->loaded_images = &gLoadedImages; + area->loaded_images = &sLoadedImages; } } diff --git a/src/system/runtime_loader/rldexport.c b/src/system/runtime_loader/rldexport.c index cda693607c..ced8326906 100644 --- a/src/system/runtime_loader/rldexport.c +++ b/src/system/runtime_loader/rldexport.c @@ -49,17 +49,18 @@ export_test_executable(const char *path, uid_t user, gid_t group, char *starter) } -void +struct rld_export gRuntimeLoader = { + // dynamic loading support API + export_load_add_on, + export_unload_add_on, + export_get_image_symbol, + export_get_nth_image_symbol, + export_test_executable +}; + + +void rldexport_init(void) { - static struct rld_export exports = { - // dynamic loading support API - export_load_add_on, - export_unload_add_on, - export_get_image_symbol, - export_get_nth_image_symbol, - export_test_executable - }; - - gProgramArgs->rld_export = &exports; + gRuntimeLoader.program_args = gProgramArgs; }