Added support for integrating dynamic linker into libc
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#include "__heap.h"
|
||||
#include "__fio.h"
|
||||
|
||||
#define DYLD_PARENT_IMAGE
|
||||
|
||||
/* maximum of 32 handles can be received sent as arguments */
|
||||
#define MAX_HANDLE_ARGS 32
|
||||
|
||||
@@ -40,8 +42,13 @@ static void dbg_log(const char *format, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DYLD_PARENT_IMAGE
|
||||
extern mx_vaddr_t dyld_load_exec(int argc, const char **argv);
|
||||
#endif
|
||||
|
||||
static const char **environ = NULL;
|
||||
static char arg_msg_buf[MAX_MSG_SIZE];
|
||||
static mx_bootstrap_handle_t arg_handles[MAX_HANDLE_ARGS];
|
||||
|
||||
const char **__crt_environ()
|
||||
{
|
||||
@@ -213,7 +220,7 @@ static void init_stdio(mx_bootstrap_handle_t *handles, size_t nhandles)
|
||||
dbg_log("** photon: stdio init finished\n");
|
||||
}
|
||||
|
||||
int __crt_init(mx_handle_t bootstrap)
|
||||
static int do_init(mx_handle_t bootstrap, bool enable_fs, bool enable_stdio, int *out_argc, const char ***out_argv)
|
||||
{
|
||||
dbg_log("reading bootstrap message from %x\n", bootstrap);
|
||||
mx_signals_t sig = 0;
|
||||
@@ -228,8 +235,6 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
|
||||
mx_handle_t handles[MAX_HANDLE_ARGS + 1];
|
||||
|
||||
mx_bootstrap_handle_t handle_info[MAX_HANDLE_ARGS + 1];
|
||||
|
||||
dbg_log("receiving message from handle %lx\n", bootstrap);
|
||||
mx_status_t err = mx_tunnel_read(bootstrap,
|
||||
arg_msg_buf, MAX_MSG_SIZE,
|
||||
@@ -245,12 +250,15 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
mx_bootstrap_msg_t *msg = (mx_bootstrap_msg_t *)arg_msg_buf;
|
||||
|
||||
dbg_log("extracting handles\n");
|
||||
extract_arg_handles(msg, handles, nr_handles, handle_info);
|
||||
handle_info[nr_handles].handle = bootstrap;
|
||||
handle_info[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0);
|
||||
extract_arg_handles(msg, handles, nr_handles, arg_handles);
|
||||
#if 0
|
||||
arg_handles[nr_handles].handle = bootstrap;
|
||||
arg_handles[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0);
|
||||
nr_handles++;
|
||||
#endif
|
||||
|
||||
mx_bootstrap_handle_init(handle_info, nr_handles);
|
||||
dbg_log("extracted %zu handles\n", nr_handles);
|
||||
mx_bootstrap_handle_init(arg_handles, nr_handles);
|
||||
|
||||
const char **argv = NULL, **envp = NULL, **namep = NULL;
|
||||
|
||||
@@ -264,14 +272,25 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
|
||||
parse_args(msg, argv, envp, namep);
|
||||
|
||||
init_stdio(handle_info, nr_handles);
|
||||
*out_argc = msg->args_num;
|
||||
*out_argv = argv;
|
||||
|
||||
if (enable_stdio) {
|
||||
init_stdio(arg_handles, nr_handles);
|
||||
} else {
|
||||
__fio_init(-1, -1, -1);
|
||||
}
|
||||
|
||||
if (!enable_fs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mio_namespace *ns = mio_namespace_create();
|
||||
|
||||
if (msg->names_num > 0) {
|
||||
for (size_t i = 0; i < nr_handles; i++) {
|
||||
int type = MX_B_HND_TYPE(handle_info[i].info);
|
||||
int arg = MX_B_HND_ARG(handle_info[i].info);
|
||||
int type = MX_B_HND_TYPE(arg_handles[i].info);
|
||||
int arg = MX_B_HND_ARG(arg_handles[i].info);
|
||||
|
||||
if (type != MX_B_NS_DIR && type != MX_B_TUNNEL_CWD) {
|
||||
continue;
|
||||
@@ -280,17 +299,69 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
const char *path = namep[arg];
|
||||
|
||||
if (type == MX_B_TUNNEL_CWD) {
|
||||
mio_set_cwd(handle_info[i].handle, path);
|
||||
mio_set_cwd(arg_handles[i].handle, path);
|
||||
} else {
|
||||
mio_namespace_add_entry(ns, path, handle_info[i].handle);
|
||||
mio_namespace_add_entry(ns, path, arg_handles[i].handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mio_set_global_namespace(ns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbg_log("calling main\n");
|
||||
int ret = main(msg->args_num, argv);
|
||||
static int do_run(mx_handle_t bootstrap)
|
||||
{
|
||||
int argc;
|
||||
const char **argv;
|
||||
|
||||
int err = do_init(bootstrap, true, true, &argc, &argv);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return main(argc, argv);
|
||||
}
|
||||
|
||||
#ifdef DYLD_PARENT_IMAGE
|
||||
static int do_load_and_run(mx_handle_t bootstrap)
|
||||
{
|
||||
int argc;
|
||||
const char **argv;
|
||||
|
||||
int err = do_init(bootstrap, false, false, &argc, &argv);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mx_vaddr_t main_ptr = dyld_load_exec(argc, argv);
|
||||
if (!main_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mx_bootstrap_handle_cleanup();
|
||||
|
||||
err = do_init(bootstrap, true, true, &argc, &argv);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
int(*main_func)(int, const char **) = (int(*)(int, const char **))main_ptr;
|
||||
if (!main_func) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return main_func(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
int __crt_init(mx_handle_t bootstrap, mx_vaddr_t arg2)
|
||||
{
|
||||
#ifndef DYLD_PARENT_IMAGE
|
||||
int ret = do_run(bootstrap);
|
||||
#else
|
||||
int ret = do_load_and_run(bootstrap);
|
||||
#endif
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.global pthread_self
|
||||
.type pthread_self, @function
|
||||
.global __pthread_self
|
||||
.type __pthread_self, @function
|
||||
|
||||
pthread_self:
|
||||
__pthread_self:
|
||||
push %rbp
|
||||
mov %rsp, %rbp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user