Skip to content

Commit 0995aed

Browse files
committed
automatically spawn child processes inside QEMU instance
1 parent 2780fdf commit 0995aed

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

linux-user/main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4781,6 +4781,10 @@ static int parse_args(int argc, char **argv)
47814781
return optind;
47824782
}
47834783

4784+
// args to pass to child instances of QEMU when spawning a child process
4785+
int qemu_argc;
4786+
char **qemu_argv;
4787+
47844788
int main(int argc, char **argv, char **envp)
47854789
{
47864790
struct target_pt_regs regs1, *regs = &regs1;
@@ -5407,6 +5411,10 @@ int main(int argc, char **argv, char **envp)
54075411
}
54085412
gdb_handlesig(cpu, 0);
54095413
}
5414+
5415+
qemu_argc = optind;
5416+
qemu_argv = argv;
5417+
54105418
cpu_loop(env);
54115419
/* never exits */
54125420
return 0;

linux-user/qemu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@ void mmap_fork_end(int child);
467467

468468
/* main.c */
469469
extern unsigned long guest_stack_size;
470+
extern int qemu_argc;
471+
extern char **qemu_argv;
470472

471473
/* user access */
472474

linux-user/syscall.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8290,6 +8290,38 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask,
82908290
}
82918291
#endif
82928292

8293+
// executes the specified program in a QEMU VM
8294+
static int qemu_execve(const char *filename, char **argv, char **envp)
8295+
{
8296+
int target_argc = 0;
8297+
char **exec_argv;
8298+
int i;
8299+
const char *fname = path(filename);
8300+
8301+
// count number of arguments the target program is passing
8302+
while (argv[target_argc] != NULL)
8303+
target_argc++;
8304+
8305+
exec_argv = g_malloc((qemu_argc + target_argc + 1) * sizeof(*exec_argv));
8306+
8307+
// add qemu args
8308+
for (i = 0; i < qemu_argc; i++)
8309+
exec_argv[i] = qemu_argv[i];
8310+
8311+
// add target program args
8312+
exec_argv[qemu_argc + 0] = (char *)fname;
8313+
for (i = 1; i < target_argc; i++)
8314+
exec_argv[qemu_argc + i] = argv[i];
8315+
8316+
// end with a null pointer
8317+
exec_argv[qemu_argc + target_argc] = NULL;
8318+
8319+
int ret = safe_execve(exec_argv[0], exec_argv, envp);
8320+
8321+
g_free(exec_argv);
8322+
return ret;
8323+
}
8324+
82938325
/* do_syscall() should always have a single exit point at the end so
82948326
that actions, such as logging of syscall results, can be performed.
82958327
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,
86248656
* before the execve completes and makes it the other
86258657
* program's problem.
86268658
*/
8627-
ret = get_errno(safe_execve(path(p), argp, envp));
8659+
ret = get_errno(qemu_execve(p, argp, envp));
86288660
unlock_user(p, arg1, 0);
86298661

86308662
goto execve_end;

0 commit comments

Comments
 (0)