#include #include #include #include #include #include #include "sys/handles.h" #include "__init.h" #include "__heap.h" #include "__fio.h" struct handles { mx_handle_t task_self; mx_handle_t task_vmar; mx_handle_t exec_vmar; mx_handle_t stack_vmo; mx_handle_t vdso_vmo; mx_handle_t exec_vmo; mx_handle_t ldsvc; mx_handle_t bootstrap; }; static struct handles rt_handles; extern int main(int, const char **); static void parse_args( mx_bootstrap_msg_t *args, mx_handle_t *handles, const char **argv, const char **envp, int hndc, struct handles *out) { if (args->args_num > 0) { char *arg_buf = (char *)args + args->args_off; int arg_i = 0; int arg_off = 0; for (int i = 0; ; i++) { if (arg_buf[i] == '\0') { argv[arg_i++] = arg_buf + arg_off; arg_off = i + 1; } if (arg_i == (int)args->args_num) { break; } } } if (args->environ_num > 0) { char *env_buf = (char *)args + args->environ_off; int env_i = 0; int env_off = 0; for (int i = 0; ; i++) { if (env_buf[i] == '\0') { envp[env_i++] = env_buf + env_off; env_off = i + 1; } if (env_i == (int)args->environ_num) { break; } } } uint32_t *hent = (uint32_t *)((char *)args + args->handle_info_off); for (int i = 0; i < hndc; i++) { switch (MX_B_HND_TYPE(hent[i])) { case MX_B_TASK_SELF: out->task_self = handles[i]; break; case MX_B_VMO_VDSO: out->vdso_vmo = handles[i]; break; case MX_B_VMO_STACK: out->stack_vmo = handles[i]; break; case MX_B_VMAR_ROOT: out->task_vmar = handles[i]; break; case MX_B_VMAR_EXEC: out->exec_vmar = handles[i]; break; case MX_B_VMO_EXECUTABLE: out->exec_vmo = handles[i]; break; case MX_B_TUNNEL_LDSVC: out->ldsvc = handles[i]; break; #if 0 case MX_B_VMO_BOOTDATA: out->bootfs_vmo = handles[i]; break; #endif default: break; } } } static void hang() { while (1) { mx_nanosleep(mx_deadline_after(MX_SEC(1))); } } int __crt_init(mx_handle_t bootstrap) { size_t msg_size = 0; size_t nr_handles = 0; mx_status_t status = mx_tunnel_read(bootstrap, NULL, 0, NULL, 0, &msg_size, &nr_handles); if (status != MX_OK) { /* TODO replace with a better error handler */ printf("error: cannot read bootstrap message from handle %lx (error %d)\n", bootstrap, status); hang(); } unsigned char msg_buf[msg_size]; mx_handle_t handles[nr_handles]; mx_tunnel_read(bootstrap, msg_buf, msg_size, handles, nr_handles, &msg_size, &nr_handles); mx_bootstrap_msg_t *msg = (mx_bootstrap_msg_t *)msg_buf; const char *argv[msg->args_num]; const char *envp[msg->environ_num]; parse_args(msg, handles, argv, envp, nr_handles, &rt_handles); rt_handles.bootstrap = bootstrap; int ret = main(msg->args_num, argv); mx_task_kill(rt_handles.task_self, ret); /* unreachable */ hang(); return 0; } mx_handle_t m_get_handle(unsigned int type) { switch (type) { case M_HND_VMAR_ROOT: return rt_handles.task_vmar; case M_HND_VMAR_EXEC: return rt_handles.exec_vmar; case M_HND_VMO_EXEC: return rt_handles.exec_vmo; case M_HND_VMO_VDSO: return rt_handles.vdso_vmo; case M_HND_TNL_LDSVC: return rt_handles.ldsvc; case M_HND_TNL_BTSTP: return rt_handles.bootstrap; default: return MX_NULL_HANDLE; } }