Made our glue code compatible to BeOS again. IOW executables compiled for Haiku will
now run under BeOS as well (as long as they don't use any functions that are not available under R5). The solution is a bit messy, but we have to live with it :-) The runtime loader now patches the __gRuntimeLoader symbol in libroot.so to point to its exported structure instead of passing it to the init functions as an argument. (Hax0red by axeld and bonefish on stippi's assimilated machine -- resistence is futile) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15848 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected].
|
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -15,6 +15,15 @@
|
|||||||
|
|
||||||
#define MAGIC_APP_NAME "_APP_"
|
#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 {
|
struct rld_export {
|
||||||
// runtime linker API export
|
// runtime linker API export
|
||||||
image_id (*load_add_on)(char const *path, uint32 flags);
|
image_id (*load_add_on)(char const *path, uint32 flags);
|
||||||
@@ -25,20 +34,10 @@ struct rld_export {
|
|||||||
int32 *nameLength, int32 *symbolType, void **_location);
|
int32 *nameLength, int32 *symbolType, void **_location);
|
||||||
status_t (*test_executable)(const char *path, uid_t user, gid_t group,
|
status_t (*test_executable)(const char *path, uid_t user, gid_t group,
|
||||||
char *starter);
|
char *starter);
|
||||||
|
|
||||||
|
const struct uspace_program_args *program_args;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uspace_program_args {
|
extern struct rld_export *__gRuntimeLoader;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* KERNEL_USER_RUNTIME_H_ */
|
#endif /* KERNEL_USER_RUNTIME_H_ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2005, Axel Dörfler, [email protected].
|
* Copyright 2004-2006, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef LIBROOT_PRIVATE_H
|
#ifndef LIBROOT_PRIVATE_H
|
||||||
@@ -15,8 +15,6 @@ struct real_time_data;
|
|||||||
status_t __parse_invoke_line(char *invoker, char ***_newArgs,
|
status_t __parse_invoke_line(char *invoker, char ***_newArgs,
|
||||||
char * const **_oldArgs, int32 *_argCount);
|
char * const **_oldArgs, int32 *_argCount);
|
||||||
status_t __test_executable(const char *path, char *invoker);
|
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_env(const struct uspace_program_args *args);
|
||||||
void __init_heap(void);
|
void __init_heap(void);
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,8 +23,9 @@
|
|||||||
FUNCTION(_init):
|
FUNCTION(_init):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl 0xc(%ebp) // program args
|
pushl %ebx
|
||||||
pushl 0x8(%ebp) // image ID
|
// BeOS unfortunately puts the image ID into %ebx instead of
|
||||||
|
// just passing it over the stack
|
||||||
call _init_before
|
call _init_before
|
||||||
// crtbegin.o stuff comes here
|
// crtbegin.o stuff comes here
|
||||||
|
|
||||||
@@ -32,7 +33,6 @@ FUNCTION(_init):
|
|||||||
FUNCTION(_fini):
|
FUNCTION(_fini):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl 0xc(%ebp) // program args
|
pushl %ebx
|
||||||
pushl 0x8(%ebp) // image ID
|
|
||||||
call _term_before
|
call _term_before
|
||||||
// crtbegin.o stuff comes here
|
// crtend.o stuff comes here
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,14 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
// the image ID and program args are still on the stack
|
// the image ID is still on the stack
|
||||||
call _init_after
|
call _init_after
|
||||||
movl %ebp, %esp
|
movl %ebp, %esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section .fini
|
.section .fini
|
||||||
// the image ID and program args are still on the stack
|
// the image ID is still on the stack
|
||||||
call _term_after
|
call _term_after
|
||||||
movl %ebp, %esp
|
movl %ebp, %esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -19,41 +19,41 @@
|
|||||||
|
|
||||||
|
|
||||||
void
|
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)
|
if (get_image_symbol(id, B_INIT_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK)
|
||||||
before(id, args);
|
before(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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)
|
if (get_image_symbol(id, B_INIT_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK)
|
||||||
after(id, args);
|
after(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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)
|
if (get_image_symbol(id, B_TERM_BEFORE_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&before) == B_OK)
|
||||||
before(id, args);
|
before(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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)
|
if (get_image_symbol(id, B_TERM_AFTER_FUNCTION_NAME, B_SYMBOL_TYPE_TEXT, (void **)&after) == B_OK)
|
||||||
after(id, args);
|
after(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef INIT_TERM_DYN_H
|
#ifndef INIT_TERM_DYN_H
|
||||||
#define 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>
|
#include <image.h>
|
||||||
|
|
||||||
|
|
||||||
struct uspace_program_args;
|
void _init_before(image_id id);
|
||||||
|
void _init_after(image_id id);
|
||||||
void _init_before(image_id id, struct uspace_program_args *args);
|
void _term_before(image_id id);
|
||||||
void _init_after(image_id id, struct uspace_program_args *args);
|
void _term_after(image_id id);
|
||||||
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 */
|
#endif /* INIT_TERM_DYN_H */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
@@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
|
|
||||||
extern int main(int argc, char **argv, char **env);
|
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
|
// these are part of libroot.so, and initialized here
|
||||||
extern char **argv_save;
|
extern char **argv_save;
|
||||||
@@ -23,19 +25,20 @@ extern thread_id __main_thread_id;
|
|||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
|
|
||||||
/* The argument list is redundant, but that is for keeping BeOS compatibility.
|
|
||||||
* BeOS doesn't have the last pointer, though.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_start(int argc, char **argv, char **_environ, struct uspace_program_args *args)
|
_start(int argc, char **argv, char **environment)
|
||||||
{
|
{
|
||||||
int returnCode;
|
int returnCode;
|
||||||
|
|
||||||
argv_save = args->argv;
|
argv_save = argv;
|
||||||
__main_thread_id = find_thread(NULL);
|
__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);
|
exit(returnCode);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected].
|
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,11 +7,16 @@
|
|||||||
#include <libroot_private.h>
|
#include <libroot_private.h>
|
||||||
#include <user_runtime.h>
|
#include <user_runtime.h>
|
||||||
#include <fork.h>
|
#include <fork.h>
|
||||||
|
#include <image.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
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;
|
char *__progname = NULL;
|
||||||
int __libc_argc;
|
int __libc_argc;
|
||||||
@@ -30,9 +35,9 @@ int _data_offset_main_;
|
|||||||
|
|
||||||
|
|
||||||
void
|
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 (programPath) {
|
||||||
if ((__progname = strrchr(programPath, '/')) == NULL)
|
if ((__progname = strrchr(programPath, '/')) == NULL)
|
||||||
__progname = programPath;
|
__progname = programPath;
|
||||||
@@ -40,15 +45,13 @@ initialize_before(image_id imageID, struct uspace_program_args const *args)
|
|||||||
__progname++;
|
__progname++;
|
||||||
}
|
}
|
||||||
|
|
||||||
__libc_argc = args->argc;
|
__libc_argc = __gRuntimeLoader->program_args->argc;
|
||||||
__libc_argv = args->argv;
|
__libc_argv = __gRuntimeLoader->program_args->argv;
|
||||||
|
|
||||||
__init_time();
|
__init_time();
|
||||||
__init_image(args);
|
|
||||||
__init_dlfcn(args);
|
|
||||||
__init_fork();
|
__init_fork();
|
||||||
__init_heap();
|
__init_heap();
|
||||||
__init_env(args);
|
__init_env(__gRuntimeLoader->program_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -14,9 +14,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
static struct rld_export const *sRuntimeLinker;
|
|
||||||
|
|
||||||
|
|
||||||
thread_id
|
thread_id
|
||||||
load_image(int32 argCount, const char **args, const char **environ)
|
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
|
image_id
|
||||||
load_add_on(char const *name)
|
load_add_on(char const *name)
|
||||||
{
|
{
|
||||||
return sRuntimeLinker->load_add_on(name, 0);
|
return __gRuntimeLoader->load_add_on(name, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
unload_add_on(image_id id)
|
unload_add_on(image_id id)
|
||||||
{
|
{
|
||||||
return sRuntimeLinker->unload_add_on(id);
|
return __gRuntimeLoader->unload_add_on(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
get_image_symbol(image_id id, char const *symbolName, int32 symbolType, void **_location)
|
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,
|
get_nth_image_symbol(image_id id, int32 num, char *nameBuffer, int32 *_nameLength,
|
||||||
int32 *_symbolType, void **_location)
|
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
|
status_t
|
||||||
__test_executable(const char *path, char *invoker)
|
__test_executable(const char *path, char *invoker)
|
||||||
{
|
{
|
||||||
return sRuntimeLinker->test_executable(path, geteuid(), getegid(), invoker);
|
return __gRuntimeLoader->test_executable(path, geteuid(), getegid(), invoker);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
__init_image(const struct uspace_program_args *args)
|
|
||||||
{
|
|
||||||
sRuntimeLinker = args->rld_export;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
** Distributed under the terms of the Haiku License.
|
* Distributed under the terms of the MIT License.
|
||||||
**
|
*
|
||||||
** Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
** Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <libroot_private.h>
|
#include <libroot_private.h>
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
static struct rld_export const *sRuntimeLinker;
|
|
||||||
static status_t sStatus;
|
static status_t sStatus;
|
||||||
// Note, this is not thread-safe
|
// Note, this is not thread-safe
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ dlopen(char const *name, int mode)
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
name = MAGIC_APP_NAME;
|
name = MAGIC_APP_NAME;
|
||||||
|
|
||||||
status = sRuntimeLinker->load_add_on(name, mode);
|
status = __gRuntimeLoader->load_add_on(name, mode);
|
||||||
sStatus = status;
|
sStatus = status;
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@@ -43,7 +42,7 @@ dlsym(void *handle, char const *name)
|
|||||||
status_t status;
|
status_t status;
|
||||||
void *location;
|
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;
|
sStatus = status;
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@@ -56,7 +55,7 @@ dlsym(void *handle, char const *name)
|
|||||||
int
|
int
|
||||||
dlclose(void *handle)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
__init_dlfcn(const struct uspace_program_args *args)
|
|
||||||
{
|
|
||||||
sRuntimeLinker = args->rld_export;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
SubDir HAIKU_TOP src system runtime_loader ;
|
SubDir HAIKU_TOP src system runtime_loader ;
|
||||||
|
|
||||||
SubDirHdrs [ FDirName $(SUBDIR) arch ] ;
|
|
||||||
UsePrivateHeaders runtime_loader ;
|
UsePrivateHeaders runtime_loader ;
|
||||||
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||||
|
|
||||||
@@ -54,17 +53,21 @@ StaticLibrary librld.a :
|
|||||||
SEARCH on [ FGristFiles kernel_vsprintf.c ]
|
SEARCH on [ FGristFiles kernel_vsprintf.c ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel lib ] ;
|
= [ FDirName $(HAIKU_TOP) src system kernel lib ] ;
|
||||||
|
|
||||||
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
|
||||||
|
|
||||||
Objects
|
Objects
|
||||||
rld.c
|
rld.c
|
||||||
rldexport.c
|
rldexport.c
|
||||||
rldelf.c
|
rldelf.c
|
||||||
rldheap.c
|
rldheap.c
|
||||||
rldaux.c
|
rldaux.c
|
||||||
|
arch_relocate.c
|
||||||
|
arch_call_init_term.c
|
||||||
;
|
;
|
||||||
|
|
||||||
Ld rld.so :
|
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
|
librld.a
|
||||||
$(TARGET_GCC_LIBGCC)
|
$(TARGET_GCC_LIBGCC)
|
||||||
: $(SUBDIR)/arch/$(TARGET_ARCH)/rld.ld
|
: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/rld.ld
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
* Ingo Weinhold, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
+17
-1
@@ -3,6 +3,22 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <runtime_loader.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "rld_priv.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define TRACE_RLD
|
||||||
|
#ifdef TRACE_RLD
|
||||||
|
# define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
relocate_rel(image_t *image, struct Elf32_Rel *rel, int rel_len)
|
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)
|
arch_relocate_image(image_t *image)
|
||||||
{
|
{
|
||||||
status_t status = B_NO_ERROR;
|
status_t status = B_NO_ERROR;
|
||||||
@@ -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
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
* Ingo Weinhold, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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));
|
||||||
|
}
|
||||||
|
|
||||||
+25
-9
@@ -1,8 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de
|
||||||
** Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Distributed under the terms of the MIT License.
|
||||||
** Distributed under the terms of the NewOS 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 <runtime_loader.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "rld_priv.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define TRACE_RLD
|
||||||
|
#ifdef TRACE_RLD
|
||||||
|
# define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -93,11 +113,7 @@ relocate_rel(image_t *image, struct Elf32_Rel *rel, int rel_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
status_t
|
||||||
* rldelf.c requires this function to be implemented on a per-cpu basis
|
|
||||||
*/
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
arch_relocate_image(image_t *image)
|
arch_relocate_image(image_t *image)
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -302,6 +302,6 @@ runtime_loader(void *_args)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// call the program entry point (usually _start())
|
// call the program entry point (usually _start())
|
||||||
return ((int (*)(int, void *, void *, const void *))entry)(gProgramArgs->argc,
|
return ((int (*)(int, void *, void *))entry)(gProgramArgs->argc,
|
||||||
gProgramArgs->argv, gProgramArgs->envp, gProgramArgs);
|
gProgramArgs->argv, gProgramArgs->envp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005, Axel Dörfler, [email protected].
|
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <user_runtime.h>
|
#include <user_runtime.h>
|
||||||
|
#include <runtime_loader.h>
|
||||||
|
|
||||||
int runtime_loader(void *arg);
|
int runtime_loader(void *arg);
|
||||||
int open_executable(char *name, image_type type, const char *rpath);
|
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 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);
|
image_id load_program(char const *path, void **entry);
|
||||||
status_t unload_library(image_id imageID, bool addOn);
|
status_t unload_library(image_id imageID, bool addOn);
|
||||||
image_id load_library(char const *path, uint32 flags, 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);
|
int32 *_type, void **_location);
|
||||||
status_t get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
status_t get_symbol(image_id imageID, char const *symbolName, int32 symbolType,
|
||||||
void **_location);
|
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);
|
status_t elf_verify_header(void *header, int32 length);
|
||||||
void rldelf_init(void);
|
void rldelf_init(void);
|
||||||
@@ -34,6 +36,12 @@ void rldheap_init(void);
|
|||||||
void *rldalloc(size_t);
|
void *rldalloc(size_t);
|
||||||
void rldfree(void *p);
|
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 uspace_program_args *gProgramArgs;
|
||||||
|
extern struct rld_export gRuntimeLoader;
|
||||||
|
|
||||||
#endif /* RUN_TIME_LINKER_H */
|
#endif /* RUN_TIME_LINKER_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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
* Copyright 2002, Manuel J. Petit. All rights reserved.
|
||||||
@@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
|
|
||||||
// ToDo: implement better locking strategy
|
// ToDo: implement better locking strategy
|
||||||
// ToDo: implement unload_program()
|
|
||||||
// ToDo: implement lazy binding
|
// ToDo: implement lazy binding
|
||||||
|
|
||||||
#define PAGE_MASK (B_PAGE_SIZE - 1)
|
#define PAGE_MASK (B_PAGE_SIZE - 1)
|
||||||
@@ -55,6 +54,7 @@ enum {
|
|||||||
RFLAG_RW = 0x0001,
|
RFLAG_RW = 0x0001,
|
||||||
RFLAG_ANON = 0x0002,
|
RFLAG_ANON = 0x0002,
|
||||||
|
|
||||||
|
RFLAG_TERMINATED = 0x0200,
|
||||||
RFLAG_INITIALIZED = 0x0400,
|
RFLAG_INITIALIZED = 0x0400,
|
||||||
RFLAG_SYMBOLIC = 0x0800,
|
RFLAG_SYMBOLIC = 0x0800,
|
||||||
RFLAG_RELOCATED = 0x1000,
|
RFLAG_RELOCATED = 0x1000,
|
||||||
@@ -73,12 +73,11 @@ enum {
|
|||||||
| IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE))
|
| IMAGE_TYPE_TO_MASK(B_LIBRARY_IMAGE))
|
||||||
|
|
||||||
|
|
||||||
typedef void (libinit_f)(unsigned, struct uspace_program_args const *);
|
static image_queue_t sLoadedImages = {0, 0};
|
||||||
|
static image_queue_t sLoadingImages = {0, 0};
|
||||||
static image_queue_t gLoadedImages = {0, 0};
|
static image_queue_t sDisposableImages = {0, 0};
|
||||||
static image_queue_t gLoadingImages = {0, 0};
|
static uint32 sLoadedImageCount = 0;
|
||||||
static image_queue_t gDisposableImages = {0, 0};
|
static image_t *sProgramImage;
|
||||||
static uint32 gLoadedImageCount = 0;
|
|
||||||
|
|
||||||
// a recursive lock
|
// a recursive lock
|
||||||
static sem_id rld_sem;
|
static sem_id rld_sem;
|
||||||
@@ -211,10 +210,10 @@ find_image(char const *name, uint32 typeMask)
|
|||||||
bool isPath = (strchr(name, '/') != NULL);
|
bool isPath = (strchr(name, '/') != NULL);
|
||||||
image_t *image;
|
image_t *image;
|
||||||
|
|
||||||
image = find_image_in_queue(&gLoadedImages, name, isPath, typeMask);
|
image = find_image_in_queue(&sLoadedImages, name, isPath, typeMask);
|
||||||
|
|
||||||
if (!image)
|
if (!image)
|
||||||
image = find_image_in_queue(&gLoadingImages, name, isPath, typeMask);
|
image = find_image_in_queue(&sLoadingImages, name, isPath, typeMask);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -225,7 +224,7 @@ find_loaded_image_by_id(image_id id)
|
|||||||
{
|
{
|
||||||
image_t *image;
|
image_t *image;
|
||||||
|
|
||||||
for (image = gLoadedImages.head; image; image = image->next) {
|
for (image = sLoadedImages.head; image; image = image->next) {
|
||||||
if (image->id == id)
|
if (image->id == id)
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -496,7 +495,7 @@ remap_images(void)
|
|||||||
image_t *image;
|
image_t *image;
|
||||||
uint32 i;
|
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++) {
|
for (i = 0; i < image->num_regions; i++) {
|
||||||
if ((image->regions[i].flags & RFLAG_RW) == 0
|
if ((image->regions[i].flags & RFLAG_RW) == 0
|
||||||
&& (image->regions[i].flags & RFLAG_REMAPPED) == 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;
|
image_t *image;
|
||||||
|
|
||||||
for (image = gLoadedImages.head; image; image = image->next) {
|
for (image = sLoadedImages.head; image; image = image->next) {
|
||||||
struct Elf32_Sym *symbol;
|
struct Elf32_Sym *symbol;
|
||||||
|
|
||||||
if (image->dynamic_ptr == NULL)
|
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)
|
resolve_symbol(image_t *image, struct Elf32_Sym *sym, addr_t *sym_addr)
|
||||||
{
|
{
|
||||||
struct Elf32_Sym *sym2;
|
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
|
static void
|
||||||
register_image(image_t *image, int fd, const char *path)
|
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);
|
_kern_close(fd);
|
||||||
|
|
||||||
enqueue_image(&gLoadedImages, image);
|
enqueue_image(&sLoadedImages, image);
|
||||||
|
|
||||||
*_image = image;
|
*_image = image;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -1031,6 +1027,7 @@ load_dependencies(image_t *image)
|
|||||||
switch (d[i].d_tag) {
|
switch (d[i].d_tag) {
|
||||||
case DT_NEEDED:
|
case DT_NEEDED:
|
||||||
neededOffset = d[i].d_un.d_val;
|
neededOffset = d[i].d_un.d_val;
|
||||||
|
|
||||||
status = load_container(STRING(image, neededOffset),
|
status = load_container(STRING(image, neededOffset),
|
||||||
B_LIBRARY_IMAGE, rpath, &image->needed[j]);
|
B_LIBRARY_IMAGE, rpath, &image->needed[j]);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@@ -1040,9 +1037,7 @@ load_dependencies(image_t *image)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
// ignore any other tag
|
||||||
* ignore any other tag
|
|
||||||
*/
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1079,12 +1074,12 @@ get_sorted_image_list(image_t *image, image_t ***_list, uint32 sortFlag)
|
|||||||
{
|
{
|
||||||
image_t **list;
|
image_t **list;
|
||||||
|
|
||||||
list = rldalloc(gLoadedImageCount * sizeof(image_t *));
|
list = rldalloc(sLoadedImageCount * sizeof(image_t *));
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
FATAL("memory shortage in get_sorted_image_list()");
|
FATAL("memory shortage in get_sorted_image_list()");
|
||||||
return 0; // B_NO_MEMORY
|
return 0; // B_NO_MEMORY
|
||||||
}
|
}
|
||||||
memset(list, 0, gLoadedImageCount * sizeof(image_t *));
|
memset(list, 0, sLoadedImageCount * sizeof(image_t *));
|
||||||
|
|
||||||
*_list = list;
|
*_list = list;
|
||||||
return topological_sort(image, 0, list, sortFlag);
|
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)));
|
TRACE(("%ld: init dependencies\n", find_thread(NULL)));
|
||||||
for (i = 0; i < count; i++) {
|
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));
|
TRACE(("%ld: init: %s\n", find_thread(NULL), initList[i]->name));
|
||||||
if (initf)
|
arch_call_init(initList[i]);
|
||||||
initf(initList[i]->id, gProgramArgs);
|
|
||||||
}
|
}
|
||||||
TRACE(("%ld: init done.\n", find_thread(NULL)));
|
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) {
|
if (atomic_add(&image->ref_count, -1) == 1) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
dequeue_image(&gLoadedImages, image);
|
dequeue_image(&sLoadedImages, image);
|
||||||
enqueue_image(&gDisposableImages, image);
|
enqueue_image(&sDisposableImages, image);
|
||||||
|
|
||||||
for (i = 0; i < image->num_needed; i++) {
|
for (i = 0; i < image->num_needed; i++) {
|
||||||
put_image(image->needed[i]);
|
put_image(image->needed[i]);
|
||||||
@@ -1169,42 +1160,50 @@ load_program(char const *path, void **_entry)
|
|||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
image_t *image;
|
image_t *image;
|
||||||
image_t *iter;
|
|
||||||
|
|
||||||
rld_lock();
|
rld_lock();
|
||||||
// for now, just do stupid simple global locking
|
// for now, just do stupid simple global locking
|
||||||
|
|
||||||
TRACE(("rld: load %s\n", path));
|
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) {
|
if (status < B_OK) {
|
||||||
_kern_loading_app_failed(status);
|
_kern_loading_app_failed(status);
|
||||||
rld_unlock();
|
rld_unlock();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iter = gLoadedImages.head; iter; iter = iter->next) {
|
for (image = sLoadedImages.head; image != NULL; image = image->next) {
|
||||||
status = load_dependencies(iter);
|
status = load_dependencies(image);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = relocate_dependencies(image);
|
status = relocate_dependencies(sProgramImage);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
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();
|
remap_images();
|
||||||
// ToDo: once setup_system_time() is fixed, move this one line higher!
|
// ToDo: once setup_system_time() is fixed, move this one line higher!
|
||||||
|
|
||||||
*_entry = (void *)(image->entry_point);
|
*_entry = (void *)(sProgramImage->entry_point);
|
||||||
|
|
||||||
rld_unlock();
|
rld_unlock();
|
||||||
return image->id;
|
return sProgramImage->id;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
_kern_loading_app_failed(status);
|
_kern_loading_app_failed(status);
|
||||||
delete_image(image);
|
delete_image(sProgramImage);
|
||||||
rld_unlock();
|
rld_unlock();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1240,7 @@ load_library(char const *path, uint32 flags, bool addOn)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iter = gLoadedImages.head; iter; iter = iter->next) {
|
for (iter = sLoadedImages.head; iter; iter = iter->next) {
|
||||||
status = load_dependencies(iter);
|
status = load_dependencies(iter);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1269,7 +1268,7 @@ unload_library(image_id imageID, bool addOn)
|
|||||||
{
|
{
|
||||||
status_t status = B_BAD_IMAGE_ID;
|
status_t status = B_BAD_IMAGE_ID;
|
||||||
image_t *image;
|
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();
|
rld_lock();
|
||||||
// for now, just do stupid simple global locking
|
// 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
|
* 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) {
|
if (image->id == imageID) {
|
||||||
/*
|
/*
|
||||||
* do the unloading
|
* do the unloading
|
||||||
@@ -1293,12 +1292,12 @@ unload_library(image_id imageID, bool addOn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
while ((image = gDisposableImages.head) != NULL) {
|
while ((image = sDisposableImages.head) != NULL) {
|
||||||
// call image fini here...
|
// call image fini here...
|
||||||
if (image->term_routine)
|
if (image->term_routine)
|
||||||
((libinit_f *)image->term_routine)(image->id, gProgramArgs);
|
arch_call_term(image);
|
||||||
|
|
||||||
dequeue_image(&gDisposableImages, image);
|
dequeue_image(&sDisposableImages, image);
|
||||||
unmap_image(image);
|
unmap_image(image);
|
||||||
|
|
||||||
delete_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
|
void
|
||||||
rldelf_init(void)
|
rldelf_init(void)
|
||||||
{
|
{
|
||||||
@@ -1425,6 +1446,6 @@ rldelf_init(void)
|
|||||||
_kern_loading_app_failed(areaID);
|
_kern_loading_app_failed(areaID);
|
||||||
}
|
}
|
||||||
|
|
||||||
area->loaded_images = &gLoadedImages;
|
area->loaded_images = &sLoadedImages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,17 +49,18 @@ export_test_executable(const char *path, uid_t user, gid_t group, char *starter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
rldexport_init(void)
|
rldexport_init(void)
|
||||||
{
|
{
|
||||||
static struct rld_export exports = {
|
gRuntimeLoader.program_args = gProgramArgs;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user