lib: launch: implement alternate argument handling to support interpreters

This commit is contained in:
2026-03-21 10:53:38 +00:00
parent 5d9a3fa54d
commit 88f8d4f18a
2 changed files with 28 additions and 6 deletions

View File

@@ -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;

View File

@@ -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;