lib: launch: implement alternate argument handling to support interpreters
This commit is contained in:
@@ -45,7 +45,9 @@ struct launch_ctx {
|
|||||||
struct launch_parameters {
|
struct launch_parameters {
|
||||||
kern_handle_t p_parent_task;
|
kern_handle_t p_parent_task;
|
||||||
kern_handle_t p_local_address_space;
|
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;
|
const char *p_task_name;
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ static kern_handle_t get_library(
|
|||||||
|
|
||||||
static virt_addr_t write_bootstrap_data(
|
static virt_addr_t write_bootstrap_data(
|
||||||
struct stack_writer *stack,
|
struct stack_writer *stack,
|
||||||
|
const char *interpreter,
|
||||||
const struct launch_parameters *params)
|
const struct launch_parameters *params)
|
||||||
{
|
{
|
||||||
virt_addr_t bs_remote;
|
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_handles_count = params->p_handle_count;
|
||||||
bs->bs_channels_count = params->p_channel_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;
|
const char **argv, **envp;
|
||||||
|
|
||||||
if (bs->bs_argc > 0) {
|
if (bs->bs_argc > 0) {
|
||||||
|
int argc = bs->bs_argc;
|
||||||
virt_addr_t remote_argv;
|
virt_addr_t remote_argv;
|
||||||
argv = stack_writer_put(
|
argv = stack_writer_put(
|
||||||
stack,
|
stack,
|
||||||
@@ -73,13 +80,22 @@ static virt_addr_t write_bootstrap_data(
|
|||||||
bs->bs_envp = (const char **)remote_envp;
|
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;
|
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;
|
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;
|
virt_addr_t env_ptr;
|
||||||
stack_writer_put_string(stack, params->p_envp[i], &env_ptr);
|
stack_writer_put_string(stack, params->p_envp[i], &env_ptr);
|
||||||
envp[i] = (const char *)env_ptr;
|
envp[i] = (const char *)env_ptr;
|
||||||
@@ -118,16 +134,20 @@ enum launch_status launch_ctx_execute(
|
|||||||
return LAUNCH_ERR_TASK_CREATION_FAILED;
|
return LAUNCH_ERR_TASK_CREATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char interp_path[4096];
|
||||||
|
interp_path[0] = 0;
|
||||||
|
|
||||||
struct elf_image image;
|
struct elf_image image;
|
||||||
elf_image_init(&image);
|
elf_image_init(&image);
|
||||||
|
|
||||||
enum launch_status status = elf_image_load(
|
enum launch_status status = elf_image_load(
|
||||||
&image,
|
&image,
|
||||||
params->p_executable,
|
params->p_exec_image,
|
||||||
params->p_local_address_space,
|
params->p_local_address_space,
|
||||||
remote_address_space);
|
remote_address_space);
|
||||||
|
|
||||||
if (status == LAUNCH_ERR_INTERPRETER_REQUIRED) {
|
if (status == LAUNCH_ERR_INTERPRETER_REQUIRED) {
|
||||||
|
snprintf(interp_path, sizeof interp_path, "%s", image.e_interp);
|
||||||
kern_handle_t interp = get_library(
|
kern_handle_t interp = get_library(
|
||||||
ctx,
|
ctx,
|
||||||
image.e_interp,
|
image.e_interp,
|
||||||
@@ -187,7 +207,7 @@ enum launch_status launch_ctx_execute(
|
|||||||
&stack,
|
&stack,
|
||||||
local_stack_buf + STACK_SIZE,
|
local_stack_buf + STACK_SIZE,
|
||||||
remote_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;
|
virt_addr_t ip = image.e_hdr.e_entry + image.e_remote_base;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user