diff --git a/lib/liblaunch/include/launch.h b/lib/liblaunch/include/launch.h index 1beb86d..f504b1b 100644 --- a/lib/liblaunch/include/launch.h +++ b/lib/liblaunch/include/launch.h @@ -45,7 +45,9 @@ struct launch_ctx { struct launch_parameters { kern_handle_t p_parent_task; kern_handle_t p_local_address_space; - kern_handle_t p_executable; + + const char *p_exec_path; + kern_handle_t p_exec_image; const char *p_task_name; diff --git a/lib/liblaunch/launch.c b/lib/liblaunch/launch.c index d5d8e91..0463843 100644 --- a/lib/liblaunch/launch.c +++ b/lib/liblaunch/launch.c @@ -38,6 +38,7 @@ static kern_handle_t get_library( static virt_addr_t write_bootstrap_data( struct stack_writer *stack, + const char *interpreter, const struct launch_parameters *params) { virt_addr_t bs_remote; @@ -51,9 +52,15 @@ static virt_addr_t write_bootstrap_data( bs->bs_handles_count = params->p_handle_count; bs->bs_channels_count = params->p_channel_count; + if (interpreter) { + /* two extra args: interpreter path and path to executable */ + bs->bs_argc += 2; + } + const char **argv, **envp; if (bs->bs_argc > 0) { + int argc = bs->bs_argc; virt_addr_t remote_argv; argv = stack_writer_put( stack, @@ -73,13 +80,22 @@ static virt_addr_t write_bootstrap_data( bs->bs_envp = (const char **)remote_envp; } - for (size_t i = 0; i < params->p_argc; i++) { + size_t i = 0, j = 0; + if (interpreter) { virt_addr_t arg_ptr; - stack_writer_put_string(stack, params->p_argv[i], &arg_ptr); + stack_writer_put_string(stack, interpreter, &arg_ptr); + argv[i++] = (const char *)arg_ptr; + stack_writer_put_string(stack, params->p_exec_path, &arg_ptr); + argv[i++] = (const char *)arg_ptr; + } + + for (; i < bs->bs_argc; i++, j++) { + virt_addr_t arg_ptr; + stack_writer_put_string(stack, params->p_argv[j], &arg_ptr); argv[i] = (const char *)arg_ptr; } - for (size_t i = 0; i < params->p_envc; i++) { + for (size_t i = 0; i < bs->bs_envc; i++) { virt_addr_t env_ptr; stack_writer_put_string(stack, params->p_envp[i], &env_ptr); envp[i] = (const char *)env_ptr; @@ -118,16 +134,20 @@ enum launch_status launch_ctx_execute( return LAUNCH_ERR_TASK_CREATION_FAILED; } + char interp_path[4096]; + interp_path[0] = 0; + struct elf_image image; elf_image_init(&image); enum launch_status status = elf_image_load( &image, - params->p_executable, + params->p_exec_image, params->p_local_address_space, remote_address_space); if (status == LAUNCH_ERR_INTERPRETER_REQUIRED) { + snprintf(interp_path, sizeof interp_path, "%s", image.e_interp); kern_handle_t interp = get_library( ctx, image.e_interp, @@ -187,7 +207,7 @@ enum launch_status launch_ctx_execute( &stack, local_stack_buf + STACK_SIZE, remote_stack_buf + STACK_SIZE); - virt_addr_t bsdata = write_bootstrap_data(&stack, params); + virt_addr_t bsdata = write_bootstrap_data(&stack, interp_path, params); virt_addr_t ip = image.e_hdr.e_entry + image.e_remote_base;