1 // This is a tiny wrapper that converts the extra arv[0] argument
2 // from binfmt-misc with the P flag enabled to QEMU parameters.
3 // It also prevents LD_* environment variables from being applied
12 #error "Define TARGET_QEMU to be the path to the qemu-user binary (e.g., -DTARGET_QEMU=\"/full/path/to/qemu-riscv64\")"
15 extern char **environ
;
17 int main(int argc
, char *argv
[]) {
19 fprintf(stderr
, "%s: This should be run as the binfmt interpreter with the P flag\n", argv
[0]);
20 fprintf(stderr
, "%s: My preconfigured qemu-user binary: %s\n", argv
[0], TARGET_QEMU
);
24 size_t environ_count
= 0;
25 for (char **cur
= environ
; *cur
!= NULL
; ++cur
) {
30 size_t new_argv_alloc
= argc
+ 2 * environ_count
+ 2; // [ "-E", env ] for each LD_* env + [ "-0", argv0 ]
31 char **new_argv
= (char**)malloc((new_argv_alloc
+ 1) * sizeof(char*));
33 fprintf(stderr
, "FATAL: Failed to allocate new argv array\n");
37 new_argv
[0] = TARGET_QEMU
;
39 new_argv
[2] = argv
[2];
41 // Pass all LD_ env variables as -E and strip them in `new_environ`
42 size_t new_environc
= 0;
43 char **new_environ
= (char**)malloc((environ_count
+ 1) * sizeof(char*));
45 fprintf(stderr
, "FATAL: Failed to allocate new environ array\n");
49 for (char **cur
= environ
; *cur
!= NULL
; ++cur
) {
50 if (strncmp("LD_", *cur
, 3) == 0) {
51 new_argv
[new_argc
++] = "-E";
52 new_argv
[new_argc
++] = *cur
;
54 new_environ
[new_environc
++] = *cur
;
57 new_environ
[new_environc
] = NULL
;
59 size_t new_arg_start
= new_argc
;
60 new_argc
+= argc
- 3 + 2; // [ "--", full_binary_path ]
63 memcpy(&new_argv
[new_arg_start
+ 2], &argv
[3], (argc
- 3) * sizeof(char**));
66 new_argv
[new_arg_start
] = "--";
67 new_argv
[new_arg_start
+ 1] = argv
[1];
68 new_argv
[new_argc
] = NULL
;
71 for (size_t i
= 0; i
< new_argc
; ++i
) {
72 fprintf(stderr
, "argv[%zu] = %s\n", i
, new_argv
[i
]);
76 return execve(new_argv
[0], new_argv
, new_environ
);