* Added a mechanism to retrieve a BMessage with eventual error descriptions

for _kern_load_image().
* Added KMessage to the runtime_loader (a bit hacky, though) - it will use
  it to deliver the above mentioned functionality.
* load_dependencies() did return the wrong status code in case a library
  was missing; now it returns B_MISSING_LIBRARY.
* load_dependencies() will now try to load all dependencies when a report
  message is requested; therefore, all missing libraries are listed.
* Renamed uspace_program_args to user_space_program_args.
* The kernel filled in various members of the user_space_program_args structure
  unsafely, ie. was not using user_memcpy().
* Renamed some local variables in team.c to better fit our style guide (ie.
  uargs to userArgs).
* Changed Tracker to use the new _kern_load_image() variant on Haiku to retrieve
  and report all missing libraries. This fixes bug #1324.
* Adapted kernel_cpp.cpp to the runtime loader as well; the latter will now
  compile with _LOADER_MODE defined.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21715 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-07-27 02:32:19 +00:00
parent d6dfbc4de5
commit 74c0424a43
19 changed files with 323 additions and 136 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2006, Haiku Inc. All rights reserved.
* Copyright 2004-2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_SYSCALLS_H
@@ -73,7 +73,7 @@ extern status_t _kern_set_sem_owner(sem_id id, team_id proc);
extern thread_id _kern_load_image(int32 argCount, const char **args,
int32 envCount, const char **envp, int32 priority,
uint32 flags);
uint32 flags, port_id errorPort, uint32 errorToken);
extern void _kern_exit_team(status_t returnValue);
extern status_t _kern_kill_team(team_id team);
extern team_id _kern_get_current_team();
+20 -13
View File
@@ -6,7 +6,6 @@
#define _TEAM_H
#include <OS.h>
#include <thread_types.h>
@@ -15,37 +14,44 @@ extern "C" {
#endif
status_t team_init(struct kernel_args *args);
team_id team_create_team(const char *path, const char *name, char **args, int argc,
char **envp, int envc, int priority);
team_id team_create_team(const char *path, const char *name, char **args,
int argc, char **envp, int envc, int priority);
status_t wait_for_team(team_id id, status_t *returnCode);
void team_remove_team(struct team *team, struct process_group **_freeGroup);
void team_delete_team(struct team *team);
struct process_group *team_get_process_group_locked(struct process_session *session, pid_t id);
struct process_group *team_get_process_group_locked(
struct process_session *session, pid_t id);
void team_delete_process_group(struct process_group *group);
struct team *team_get_kernel_team(void);
team_id team_get_kernel_team_id(void);
team_id team_get_current_team_id(void);
status_t team_get_address_space(team_id id, struct vm_address_space **_addressSpace);
status_t team_get_address_space(team_id id,
struct vm_address_space **_addressSpace);
char **user_team_get_arguments(void);
int user_team_get_arg_count(void);
status_t team_get_death_entry(struct team *team, thread_id child,
struct death_entry *death, struct death_entry **_freeDeath);
struct death_entry *death, struct death_entry **_freeDeath);
bool team_is_valid(team_id id);
struct team *team_get_team_struct_locked(team_id id);
int32 team_max_teams(void);
int32 team_used_teams(void);
status_t start_watching_team(team_id team, void (*hook)(team_id, void *), void *data);
status_t stop_watching_team(team_id team, void (*hook)(team_id, void *), void *data);
status_t start_watching_team(team_id team, void (*hook)(team_id, void *),
void *data);
status_t stop_watching_team(team_id team, void (*hook)(team_id, void *),
void *data);
// used in syscalls.c
thread_id _user_load_image(int32 argCount, const char **args, int32 envCount,
const char **envp, int32 priority, uint32 flags);
const char **env, int32 priority, uint32 flags,
port_id errorPort, uint32 errorToken);
status_t _user_wait_for_team(team_id id, status_t *_returnCode);
void _user_exit_team(status_t returnValue);
status_t _user_kill_team(thread_id thread);
thread_id _user_wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode);
status_t _user_exec(const char *path, int32 argc, char * const *argv, int32 envCount, char * const *environment);
thread_id _user_wait_for_child(thread_id child, uint32 flags, int32 *_reason,
status_t *_returnCode);
status_t _user_exec(const char *path, int32 argc, char * const *argv,
int32 envCount, char * const *environment);
thread_id _user_fork(void);
team_id _user_get_current_team(void);
pid_t _user_process_info(pid_t process, int32 which);
@@ -54,10 +60,11 @@ pid_t _user_setsid(void);
status_t _user_get_team_info(team_id id, team_info *info);
status_t _user_get_next_team_info(int32 *cookie, team_info *info);
status_t _user_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size);
status_t _user_get_team_usage_info(team_id team, int32 who,
team_usage_info *info, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* _TIME_H */
#endif /* _TEAM_H */
+11 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2006, Axel Dörfler, [email protected].
* Copyright 2003-2007, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -15,13 +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 user_space_program_args {
char program_name[B_OS_NAME_LENGTH];
char program_path[B_PATH_NAME_LENGTH];
port_id error_port;
uint32 error_token;
int arg_count;
int env_count;
char **args;
char **env;
};
struct rld_export {
@@ -37,7 +39,7 @@ struct rld_export {
status_t (*get_next_image_dependency)(image_id id, uint32 *cookie,
const char **_name);
const struct uspace_program_args *program_args;
const struct user_space_program_args *program_args;
};
extern struct rld_export *__gRuntimeLoader;
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2006, Axel Dörfler, [email protected].
* Copyright 2004-2007, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef LIBROOT_PRIVATE_H
@@ -10,7 +10,7 @@
#include <image.h>
struct uspace_program_args;
struct user_space_program_args;
struct real_time_data;
extern char _single_threaded;
@@ -26,7 +26,7 @@ status_t __parse_invoke_line(char *invoker, char ***_newArgs,
status_t __get_next_image_dependency(image_id id, uint32 *cookie,
const char **_name);
status_t __test_executable(const char *path, char *invoker);
void __init_env(const struct uspace_program_args *args);
void __init_env(const struct user_space_program_args *args);
void __init_heap(void);
void __init_time(void);
+2 -2
View File
@@ -17,8 +17,8 @@ if $(RUN_WITHOUT_APP_SERVER) != 0 {
SubDirC++Flags $(defines) ;
}
UsePrivateHeaders [ FDirName kernel util ] ; # For KMessage.h
UsePrivateHeaders syslog_daemon ; # For syslog.cpp
UsePrivateHeaders [ FDirName kernel ] # For KMessage.h
UsePrivateHeaders syslog_daemon ; # For syslog.cpp
# Build our libbe.so
+72 -8
View File
@@ -2890,12 +2890,19 @@ _TrackerLaunchAppWithDocuments(const entry_ref *appRef, const BMessage *refs, bo
}
extern "C" char** environ;
#ifdef __HAIKU__
extern "C" status_t _kern_load_image(int32 argCount, const char **args,
int32 envCount, const char **env, int32 priority, uint32 flags,
port_id errorPort, uint32 errorToken);
#else
extern "C"
#if !B_BEOS_VERSION_DANO
# if !B_BEOS_VERSION_DANO
_IMPEXP_ROOT
#endif
# endif
status_t _kload_image_etc_(int argc, char **argv, char **envp,
char *buf, int bufsize);
#endif
static status_t
@@ -2903,17 +2910,74 @@ LoaderErrorDetails(const entry_ref *app, BString &details)
{
BPath path;
BEntry appEntry(app, true);
status_t result = appEntry.GetPath(&path);
if (result != B_OK)
return result;
char *argv[2] = { const_cast<char *>(path.Path()), 0};
#ifdef __HAIKU__
// ToDo: do this correctly!
result = load_image(1, (const char **)argv, (const char **)environ);
details.SetTo("ToDo: this is missing from Haiku");
port_id errorPort = create_port(1, "Tracker loader error");
// count environment variables
uint32 envCount = 0;
while (environ[envCount] != NULL)
envCount++;
result = _kern_load_image(1, (const char **)argv, envCount,
(const char **)environ, B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED,
errorPort, 0);
if (result == B_OK) {
// we weren't supposed to be able to start the application...
return B_ERROR;
}
// read error message from port and construct details string
ssize_t bufferSize;
do {
bufferSize = port_buffer_size_etc(errorPort, B_RELATIVE_TIMEOUT, 0);
} while (bufferSize == B_INTERRUPTED);
if (bufferSize <= B_OK) {
delete_port(errorPort);
return bufferSize;
}
uint8 *buffer = (uint8 *)malloc(bufferSize);
if (buffer == NULL) {
delete_port(errorPort);
return B_NO_MEMORY;
}
bufferSize = read_port_etc(errorPort, NULL, buffer, bufferSize,
B_RELATIVE_TIMEOUT, 0);
delete_port(errorPort);
if (bufferSize < B_OK) {
free(buffer);
return bufferSize;
}
BMessage message;
result = message.Unflatten((const char *)buffer);
free(buffer);
if (result != B_OK)
return result;
message.PrintToStream();
const char* library;
for (int32 i = 0; message.FindString("missing library", i,
&library) == B_OK; i++) {
if (i > 0)
details += ", ";
details += library;
}
return B_OK;
#else
result = _kload_image_etc_(1, argv, environ, details.LockBuffer(1024), 1024);
details.UnlockBuffer();
@@ -3048,7 +3112,7 @@ _TrackerLaunchDocuments(const entry_ref */*doNotUse*/, const BMessage *refs,
alertString << "Could not open \"" << documentRef.name << "\" ";
if (openedDocuments)
alertString << "with application \"" << app.name << "\" ";
alertString << "(Missing library: " << loaderErrorString << "). \n";
alertString << "(Missing libraries: " << loaderErrorString << "). \n";
alternative = kFindAlternativeStr;
} else {
alertString << "Could not open \"" << documentRef.name
-1
View File
@@ -3,7 +3,6 @@ SubDir HAIKU_TOP src system kernel messaging ;
UsePrivateHeaders [ FDirName kernel ] ;
#UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
#UsePrivateHeaders [ FDirName kernel fs ] ;
UsePrivateHeaders [ FDirName kernel util ] ; # for <KMessage.h>
UsePrivateHeaders shared ;
UseHeaders [ FDirName $(HAIKU_TOP) src system kernel disk_device_manager ] ;
# for "Locker.h"
+22 -2
View File
@@ -3,7 +3,7 @@
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "KMessage.h"
#include <util/KMessage.h>
#include <stdlib.h>
#include <string.h>
@@ -12,7 +12,7 @@
#include <KernelExport.h>
#include <TypeConstants.h>
#if defined(_BOOT_MODE)
#if defined(_BOOT_MODE) || defined(_LOADER_MODE)
# include <util/kernel_cpp.h>
#else
# include <new>
@@ -32,6 +32,21 @@ using std::nothrow;
# endif
#endif
#ifdef _LOADER_MODE
# include <syscalls.h>
# define KMESSAGE_NO_RECEIVE
# define create_port(capacity, name) _kern_create_port(capacity, name)
# define delete_port(port) _kern_delete_port(port)
# define write_port(port, code, buffer, bufferSize) \
_kern_write_port_etc(port, code, buffer, bufferSize, 0, 0)
# define write_port_etc(port, code, buffer, bufferSize, flags, timeout) \
_kern_write_port_etc(port, code, buffer, bufferSize, flags, timeout)
# define set_port_owner(port, team) _kern_set_port_owner(port, team)
# define _get_port_info(port, info, size) _kern_get_port_info(port, info)
#endif
static const int32 kMessageReallocChunkSize = 64;
// kMessageHeaderMagic
@@ -546,6 +561,9 @@ KMessage::SendReply(KMessage* message, KMessage* reply,
status_t
KMessage::ReceiveFrom(port_id fromPort, bigtime_t timeout)
{
#ifdef KMESSAGE_NO_RECEIVE
return B_NOT_SUPPORTED;
#else
// get the port buffer size
ssize_t size;
if (timeout < 0)
@@ -569,6 +587,7 @@ KMessage::ReceiveFrom(port_id fromPort, bigtime_t timeout)
// init the message
return SetTo(buffer, size, 0,
KMESSAGE_OWNS_BUFFER | KMESSAGE_INIT_FROM_BUFFER);
#endif // !KMESSAGE_NO_RECEIVE
}
#endif // !KMESSAGE_CONTAINER_ONLY
@@ -804,6 +823,7 @@ KMessage::_AllocateSpace(int32 size, bool alignAddress, bool alignSize,
{
if (fBuffer != &fHeader && (fFlags & KMESSAGE_READ_ONLY))
return B_NOT_ALLOWED;
int32 offset = ContentSize();
if (alignAddress)
offset = _Align(offset);
+57 -41
View File
@@ -50,6 +50,8 @@ struct team_arg {
char **args;
uint32 env_count;
char **env;
port_id error_port;
uint32 error_token;
};
struct fork_arg {
@@ -610,7 +612,7 @@ get_arguments_data_size(char **args, int32 argc)
for (count = 0; count < argc; count++)
size += strlen(args[count]) + 1;
return size + (argc + 1) * sizeof(char *) + sizeof(struct uspace_program_args);
return size + (argc + 1) * sizeof(char *) + sizeof(struct user_space_program_args);
}
@@ -626,7 +628,7 @@ free_team_arg(struct team_arg *teamArg)
static status_t
create_team_arg(struct team_arg **_teamArg, int32 argCount, char * const *args,
int32 envCount, char * const *env, bool kernel)
int32 envCount, char * const *env, port_id port, uint32 token, bool kernel)
{
status_t status;
char **argsCopy;
@@ -652,6 +654,8 @@ create_team_arg(struct team_arg **_teamArg, int32 argCount, char * const *args,
teamArg->args = argsCopy;
teamArg->env_count = envCount;
teamArg->env = envCopy;
teamArg->error_port = port;
teamArg->error_token = token;
*_teamArg = teamArg;
return B_OK;
@@ -669,10 +673,10 @@ team_create_thread_start(void *args)
addr_t entry;
char ustack_name[128];
uint32 sizeLeft;
char **uargs;
char **uenv;
char *udest;
struct uspace_program_args *uspa;
char **userArgs;
char **userEnv;
char *userDest;
struct user_space_program_args *programArgs;
uint32 argCount, envCount, i;
t = thread_get_current_thread();
@@ -717,32 +721,32 @@ team_create_thread_start(void *args)
argCount = teamArgs->arg_count;
envCount = teamArgs->env_count;
uspa = (struct uspace_program_args *)(t->user_stack_base + t->user_stack_size
+ TLS_SIZE + ENV_SIZE);
uargs = (char **)(uspa + 1);
udest = (char *)(uargs + argCount + 1);
programArgs = (struct user_space_program_args *)(t->user_stack_base
+ t->user_stack_size + TLS_SIZE + ENV_SIZE);
userArgs = (char **)(programArgs + 1);
userDest = (char *)(userArgs + argCount + 1);
TRACE(("addr: stack base = 0x%lx, uargs = %p, udest = %p, sizeLeft = %lu\n",
t->user_stack_base, uargs, udest, sizeLeft));
TRACE(("addr: stack base = 0x%lx, userArgs = %p, userDest = %p, sizeLeft = %lu\n",
t->user_stack_base, userArgs, userDest, sizeLeft));
sizeLeft = t->user_stack_base + sizeLeft - (addr_t)udest;
sizeLeft = t->user_stack_base + sizeLeft - (addr_t)userDest;
for (i = 0; i < argCount; i++) {
ssize_t length = user_strlcpy(udest, teamArgs->args[i], sizeLeft);
ssize_t length = user_strlcpy(userDest, teamArgs->args[i], sizeLeft);
if (length < B_OK) {
argCount = 0;
break;
}
uargs[i] = udest;
udest += ++length;
userArgs[i] = userDest;
userDest += ++length;
sizeLeft -= length;
}
uargs[argCount] = NULL;
userArgs[argCount] = NULL;
uenv = (char **)(t->user_stack_base + t->user_stack_size + TLS_SIZE);
userEnv = (char **)(t->user_stack_base + t->user_stack_size + TLS_SIZE);
sizeLeft = ENV_SIZE;
udest = (char *)uenv + ENV_SIZE - 1;
userDest = (char *)userEnv + ENV_SIZE - 1;
// the environment variables are copied from back to front
TRACE(("team_create_thread_start: envc: %ld, env: %p\n",
@@ -750,29 +754,37 @@ team_create_thread_start(void *args)
for (i = 0; i < envCount; i++) {
ssize_t length = strlen(teamArgs->env[i]) + 1;
udest -= length;
if (udest < (char *)&uenv[envCount]) {
userDest -= length;
if (userDest < (char *)&userEnv[envCount]) {
envCount = i;
break;
}
uenv[i] = udest;
userEnv[i] = userDest;
if (user_memcpy(udest, teamArgs->env[i], length) < B_OK) {
if (user_memcpy(userDest, teamArgs->env[i], length) < B_OK) {
envCount = 0;
break;
}
sizeLeft -= length;
}
uenv[envCount] = NULL;
userEnv[envCount] = NULL;
path = teamArgs->args[0];
user_memcpy(uspa->program_path, path, sizeof(uspa->program_path));
uspa->argc = argCount;
uspa->argv = uargs;
uspa->envc = envCount;
uspa->envp = uenv;
if (user_memcpy(programArgs->program_path, path,
sizeof(programArgs->program_path)) < B_OK
|| user_memcpy(&programArgs->arg_count, &argCount, sizeof(int32)) < B_OK
|| user_memcpy(&programArgs->args, &userArgs, sizeof(char **)) < B_OK
|| user_memcpy(&programArgs->env_count, &envCount, sizeof(int32)) < B_OK
|| user_memcpy(&programArgs->env, &userEnv, sizeof(char **)) < B_OK
|| user_memcpy(&programArgs->error_port, &teamArgs->error_port,
sizeof(port_id)) < B_OK
|| user_memcpy(&programArgs->error_token, &teamArgs->error_token,
sizeof(uint32)) < B_OK) {
// the team deletion process will clean this mess
return B_BAD_ADDRESS;
}
TRACE(("team_create_thread_start: loading elf binary '%s'\n", path));
@@ -801,7 +813,7 @@ team_create_thread_start(void *args)
team->state = TEAM_STATE_NORMAL;
// jump to the entry point in user space
return arch_thread_enter_userspace(t, entry, uspa, NULL);
return arch_thread_enter_userspace(t, entry, programArgs, NULL);
// only returns in case of error
}
@@ -811,8 +823,9 @@ team_create_thread_start(void *args)
*/
static thread_id
load_image_etc(int32 argCount, char * const *args, int32 envCount, char * const *env,
int32 priority, uint32 flags, bool kernel)
load_image_etc(int32 argCount, char * const *args, int32 envCount,
char * const *env, int32 priority, uint32 flags,
port_id errorPort, uint32 errorToken, bool kernel)
{
struct process_group *group;
struct team *team, *parent;
@@ -853,7 +866,8 @@ load_image_etc(int32 argCount, char * const *args, int32 envCount, char * const
RELEASE_TEAM_LOCK();
restore_interrupts(state);
status = create_team_arg(&teamArgs, argCount, args, envCount, env, kernel);
status = create_team_arg(&teamArgs, argCount, args, envCount, env,
errorPort, errorToken, kernel);
if (status != B_OK)
goto err1;
@@ -879,8 +893,8 @@ load_image_etc(int32 argCount, char * const *args, int32 envCount, char * const
// Create a kernel thread, but under the context of the new team
// The new thread will take over ownership of teamArgs
thread = spawn_kernel_thread_etc(team_create_thread_start, threadName, B_NORMAL_PRIORITY,
teamArgs, team->id, team->id);
thread = spawn_kernel_thread_etc(team_create_thread_start, threadName,
B_NORMAL_PRIORITY, teamArgs, team->id, team->id);
if (thread < 0) {
status = thread;
goto err4;
@@ -1007,9 +1021,8 @@ exec_team(const char *path, int32 argCount, char * const *args,
if (status != B_OK)
return status;
// ToDo: maybe we should make sure upfront that the target path is an app?
status = create_team_arg(&teamArgs, argCount, args, envCount, env, false);
status = create_team_arg(&teamArgs, argCount, args, envCount, env,
-1, 0, false);
if (status != B_OK)
return status;
@@ -1857,7 +1870,8 @@ load_image(int32 argCount, const char **args, const char **env)
envCount++;
return load_image_etc(argCount, (char * const *)args, envCount,
(char * const *)env, B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED, true);
(char * const *)env, B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED,
-1, 0, true);
}
@@ -2393,7 +2407,8 @@ _user_wait_for_team(team_id id, status_t *_userReturnCode)
team_id
_user_load_image(int32 argCount, const char **userArgs, int32 envCount,
const char **userEnv, int32 priority, uint32 flags)
const char **userEnv, int32 priority, uint32 flags, port_id errorPort,
uint32 errorToken)
{
TRACE(("_user_load_image_etc: argc = %ld\n", argCount));
@@ -2404,7 +2419,8 @@ _user_load_image(int32 argCount, const char **userArgs, int32 envCount,
return B_BAD_ADDRESS;
return load_image_etc(argCount, (char * const *)userArgs,
envCount, (char * const *)userEnv, priority, flags, false);
envCount, (char * const *)userEnv, priority, flags, errorPort,
errorToken, false);
}
+21 -9
View File
@@ -1,17 +1,31 @@
/* cpp - C++ in the kernel
**
** Initial version by Axel Dörfler, axeld@pinc-software.de
** This file may be used under the terms of the OpenBeOS License.
*/
/*
* Copyright 2003-2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de.
* Ingo Weinhold, bonefish@users.sf.net.
*/
//! C++ in the kernel
#include "util/kernel_cpp.h"
#ifdef _BOOT_MODE
# include <boot/platform.h>
#elif defined(_KERNEL_MODE)
#else
# include <KernelExport.h>
# include <stdio.h>
#endif
#ifdef _LOADER_MODE
# define panic printf
# define dprintf printf
# define kernel_debugger printf
#endif
// Always define the symbols needed when not linking against libgcc.a --
// we simply override them.
@@ -39,9 +53,7 @@ __cxa_pure_virtual()
#endif
// full C++ support in the kernel
#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
#include <stdio.h>
#if (defined(_KERNEL_MODE) || defined(_LOADER_MODE)) && !defined(_BOOT_MODE)
FILE *stderr = NULL;
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@@ -37,7 +37,7 @@ int _data_offset_main_;
void
initialize_before(image_id imageID)
{
char *programPath = __gRuntimeLoader->program_args->argv[0];
char *programPath = __gRuntimeLoader->program_args->args[0];
if (programPath) {
if ((__progname = strrchr(programPath, '/')) == NULL)
__progname = programPath;
@@ -45,8 +45,8 @@ initialize_before(image_id imageID)
__progname++;
}
__libc_argc = __gRuntimeLoader->program_args->argc;
__libc_argv = __gRuntimeLoader->program_args->argv;
__libc_argc = __gRuntimeLoader->program_args->arg_count;
__libc_argv = __gRuntimeLoader->program_args->args;
__init_time();
__init_fork();
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
@@ -44,7 +44,7 @@ load_image(int32 argCount, const char **args, const char **environ)
envCount++;
thread = _kern_load_image(argCount, args, envCount, environ,
B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED);
B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED, -1, 0);
free(newArgs);
return thread;
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
@@ -148,12 +148,12 @@ environ_fork_hook(void)
void
__init_env(const struct uspace_program_args *args)
__init_env(const struct user_space_program_args *args)
{
// Following POSIX, there is no need to make any of the
// environment functions thread-safe - but we do it anyway
sEnvLock = create_sem(1, "env lock");
environ = args->envp;
environ = args->env;
atfork(environ_fork_hook);
}
+9 -1
View File
@@ -9,11 +9,15 @@ SubDirCcFlags -fno-builtin ;
SubDirC++Flags -fno-builtin -fno-exceptions ;
# default to BeOS style symbol resolution
DEFINES += BEOS_STYLE_SYMBOLS_RESOLUTION ;
DEFINES += BEOS_STYLE_SYMBOLS_RESOLUTION
_LOADER_MODE
;
# needed for "runtime_loader" only
StaticLibrary libruntime_loader.a :
kernel_vsprintf.c
kernel_cpp.cpp
KMessage.cpp
:
<src!system!libroot!os>syscalls.o
<src!system!libroot!os>sem.o
@@ -54,8 +58,12 @@ StaticLibrary libruntime_loader.a :
[ FGristFiles kernel_vsprintf.o ]
;
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles kernel_vsprintf.c ]
= [ FDirName $(HAIKU_TOP) src system kernel lib ] ;
SEARCH on [ FGristFiles KMessage.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel messaging ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;
+47 -16
View File
@@ -76,6 +76,7 @@ static image_queue_t sLoadedImages = {0, 0};
static image_queue_t sDisposableImages = {0, 0};
static uint32 sLoadedImageCount = 0;
static image_t *sProgramImage;
static KMessage sErrorMessage;
#ifdef BEOS_STYLE_SYMBOLS_RESOLUTION
static bool sResolveSymbolsBeOSStyle = true;
@@ -1096,8 +1097,8 @@ static status_t
load_dependencies(image_t *image)
{
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
int neededOffset;
status_t status;
bool reportErrors = gProgramArgs->error_port >= 0;
status_t status = B_OK;
uint32 i, j;
const char *rpath;
@@ -1121,15 +1122,30 @@ load_dependencies(image_t *image)
for (i = 0, j = 0; d[i].d_tag != DT_NULL; i++) {
switch (d[i].d_tag) {
case DT_NEEDED:
neededOffset = d[i].d_un.d_val;
{
int32 neededOffset = d[i].d_un.d_val;
const char *name = STRING(image, neededOffset);
status = load_container(STRING(image, neededOffset),
B_LIBRARY_IMAGE, rpath, &image->needed[j]);
if (status < B_OK)
return status;
status_t loadStatus = load_container(name, B_LIBRARY_IMAGE,
rpath, &image->needed[j]);
if (loadStatus < B_OK) {
status = loadStatus;
// correct error code in case the file could not been found
if (status == B_ENTRY_NOT_FOUND) {
status = B_MISSING_LIBRARY;
if (reportErrors)
sErrorMessage.AddString("missing library", name);
}
// Collect all missing libraries in case we report back
if (!reportErrors)
return status;
}
j += 1;
break;
}
default:
// ignore any other tag
@@ -1137,6 +1153,9 @@ load_dependencies(image_t *image)
}
}
if (status < B_OK)
return status;
if (j != image->num_needed) {
FATAL("Internal error at load_dependencies()");
return B_ERROR;
@@ -1255,8 +1274,7 @@ put_image(image_t *image)
}
// #pragma mark -
// Exported functions (to libroot.so)
// #pragma mark - libroot.so exported functions
image_id
@@ -1271,11 +1289,8 @@ load_program(char const *path, void **_entry)
TRACE(("rld: load %s\n", path));
status = load_container(path, B_APP_IMAGE, NULL, &sProgramImage);
if (status < B_OK) {
_kern_loading_app_failed(status);
rld_unlock();
return status;
}
if (status < B_OK)
goto err;
for (image = sLoadedImages.head; image != NULL; image = image->next) {
status = load_dependencies(image);
@@ -1322,9 +1337,16 @@ load_program(char const *path, void **_entry)
return sProgramImage->id;
err:
_kern_loading_app_failed(status);
delete_image(sProgramImage);
if (gProgramArgs->error_port >= 0) {
sErrorMessage.AddInt32("error", status);
sErrorMessage.SendTo(gProgramArgs->error_port, gProgramArgs->error_token,
-1, 0, 0, find_thread(NULL));
}
_kern_loading_app_failed(status);
rld_unlock();
return status;
}
@@ -1563,7 +1585,7 @@ get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
}
// #pragma mark -
// #pragma mark - runtime_loader private exports
/** Read and verify the ELF header */
@@ -1627,4 +1649,13 @@ rldelf_init(void)
area->loaded_images = &sLoadedImages;
}
// initialize error message if needed
if (gProgramArgs->error_port >= 0) {
void *buffer = malloc(1024);
if (buffer == NULL)
return;
sErrorMessage.SetTo(buffer, 1024, 'Rler');
}
}
+9 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
@@ -236,6 +236,14 @@ dump_chunks(void)
#endif
void *
realloc(void *buffer, size_t newSize)
{
// not implemented
return NULL;
}
void *
malloc(size_t size)
{
+14 -14
View File
@@ -26,7 +26,7 @@
#endif
struct uspace_program_args *gProgramArgs;
struct user_space_program_args *gProgramArgs;
static const char *
@@ -254,12 +254,12 @@ open_executable(char *name, image_type type, const char *rpath)
}
/** Tests if there is an executable file at the provided path. It will
* also test if the file has a valid ELF header or is a shell script.
* Even if the runtime loader does not need to be able to deal with
* both types, the caller will give scripts a proper treatment.
*/
/*!
Tests if there is an executable file at the provided path. It will
also test if the file has a valid ELF header or is a shell script.
Even if the runtime loader does not need to be able to deal with
both types, the caller will give scripts a proper treatment.
*/
status_t
test_executable(const char *name, uid_t user, gid_t group, char *invoker)
{
@@ -339,17 +339,17 @@ out:
}
/** This is the main entry point of the runtime loader as
* specified by its ld-script.
*/
/*!
This is the main entry point of the runtime loader as
specified by its ld-script.
*/
int
runtime_loader(void *_args)
{
void *entry = NULL;
int returnCode;
gProgramArgs = (struct uspace_program_args *)_args;
gProgramArgs = (struct user_space_program_args *)_args;
#if DEBUG_RLD
close(0); open("/dev/console", 0); /* stdin */
@@ -369,8 +369,8 @@ runtime_loader(void *_args)
return -1;
// call the program entry point (usually _start())
returnCode = ((int (*)(int, void *, void *))entry)(gProgramArgs->argc,
gProgramArgs->argv, gProgramArgs->envp);
returnCode = ((int (*)(int, void *, void *))entry)(gProgramArgs->arg_count,
gProgramArgs->args, gProgramArgs->env);
terminate_program();
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2002, Manuel J. Petit. All rights reserved.
@@ -13,7 +13,7 @@
#include <runtime_loader.h>
extern struct uspace_program_args *gProgramArgs;
extern struct user_space_program_args *gProgramArgs;
extern struct rld_export gRuntimeLoader;
extern char *(*gGetEnv)(const char *name);
+23 -3
View File
@@ -24,12 +24,12 @@ extern "C" char *
getenv(const char *name)
{
if (gGetEnv != NULL) {
// Use libroot's getenv() as soon as it is available to us - the environment
// in gProgramArgs is static.
// Use libroot's getenv() as soon as it is available to us - the
// environment in gProgramArgs is static.
return gGetEnv(name);
}
char **environ = gProgramArgs->envp;
char **environ = gProgramArgs->env;
int32 length = strlen(name);
int32 i;
@@ -56,3 +56,23 @@ printf(const char *format, ...)
return length;
}
// Copied from libroot/os/thread.c:
extern "C" status_t
_get_thread_info(thread_id thread, thread_info *info, size_t size)
{
if (info == NULL || size != sizeof(thread_info))
return B_BAD_VALUE;
return _kern_get_thread_info(thread, info);
}
status_t
snooze(bigtime_t timeout)
{
return B_ERROR;
}