automatically spawn child processes inside QEMU instance

This commit is contained in:
Cameron Hall 2018-04-20 19:22:28 -05:00
parent 2780fdfdbb
commit 0995aedb78
3 changed files with 43 additions and 1 deletions

View File

@ -4781,6 +4781,10 @@ static int parse_args(int argc, char **argv)
return optind; return optind;
} }
// args to pass to child instances of QEMU when spawning a child process
int qemu_argc;
char **qemu_argv;
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)
{ {
struct target_pt_regs regs1, *regs = &regs1; struct target_pt_regs regs1, *regs = &regs1;
@ -5407,6 +5411,10 @@ int main(int argc, char **argv, char **envp)
} }
gdb_handlesig(cpu, 0); gdb_handlesig(cpu, 0);
} }
qemu_argc = optind;
qemu_argv = argv;
cpu_loop(env); cpu_loop(env);
/* never exits */ /* never exits */
return 0; return 0;

View File

@ -467,6 +467,8 @@ void mmap_fork_end(int child);
/* main.c */ /* main.c */
extern unsigned long guest_stack_size; extern unsigned long guest_stack_size;
extern int qemu_argc;
extern char **qemu_argv;
/* user access */ /* user access */

View File

@ -8290,6 +8290,38 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask,
} }
#endif #endif
// executes the specified program in a QEMU VM
static int qemu_execve(const char *filename, char **argv, char **envp)
{
int target_argc = 0;
char **exec_argv;
int i;
const char *fname = path(filename);
// count number of arguments the target program is passing
while (argv[target_argc] != NULL)
target_argc++;
exec_argv = g_malloc((qemu_argc + target_argc + 1) * sizeof(*exec_argv));
// add qemu args
for (i = 0; i < qemu_argc; i++)
exec_argv[i] = qemu_argv[i];
// add target program args
exec_argv[qemu_argc + 0] = (char *)fname;
for (i = 1; i < target_argc; i++)
exec_argv[qemu_argc + i] = argv[i];
// end with a null pointer
exec_argv[qemu_argc + target_argc] = NULL;
int ret = safe_execve(exec_argv[0], exec_argv, envp);
g_free(exec_argv);
return ret;
}
/* do_syscall() should always have a single exit point at the end so /* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed. that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */ All errnos that do_syscall() returns must be -TARGET_<errcode>. */
@ -8624,7 +8656,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
* before the execve completes and makes it the other * before the execve completes and makes it the other
* program's problem. * program's problem.
*/ */
ret = get_errno(safe_execve(path(p), argp, envp)); ret = get_errno(qemu_execve(p, argp, envp));
unlock_user(p, arg1, 0); unlock_user(p, arg1, 0);
goto execve_end; goto execve_end;