From 973b8255aefa2f10a70e0ac8a0cda0cbd37aaa28 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 22 May 2022 21:31:04 +0100 Subject: [PATCH] Added support for integrating dynamic linker into libc --- photon/libc/sys/horizon/init.c | 99 ++++++++++++++++--- .../libc/sys/horizon/machine/x86_64/pthread.s | 6 +- 2 files changed, 88 insertions(+), 17 deletions(-) diff --git a/photon/libc/sys/horizon/init.c b/photon/libc/sys/horizon/init.c index bc55766..9f2d03e 100644 --- a/photon/libc/sys/horizon/init.c +++ b/photon/libc/sys/horizon/init.c @@ -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); diff --git a/photon/libc/sys/horizon/machine/x86_64/pthread.s b/photon/libc/sys/horizon/machine/x86_64/pthread.s index 5dfb86f..a0c6148 100644 --- a/photon/libc/sys/horizon/machine/x86_64/pthread.s +++ b/photon/libc/sys/horizon/machine/x86_64/pthread.s @@ -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