Merge commit 'origin/master' into maemo-test
[qemu] / linux-user / main.c
index 6e2984c..724387a 100644 (file)
@@ -1004,7 +1004,7 @@ void cpu_loop (CPUSPARCState *env)
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
             cpu_dump_state(env, stderr, fprintf, 0);
-            exit (1);
+            _exit (1);
         }
         process_pending_signals (env);
     }
@@ -1933,7 +1933,7 @@ void cpu_loop (CPUState *env)
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
             cpu_dump_state(env, stderr, fprintf, 0);
-            exit (1);
+            _exit (1);
         }
         process_pending_signals (env);
     }
@@ -2193,6 +2193,7 @@ static void usage(void)
            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
            "-E var=value      sets/modifies targets environment variable(s)\n"
            "-U var            unsets targets environment variable(s)\n"
+           "-0 argv0          forces target process argv[0] to be argv0\n"
            "\n"
            "Debug options:\n"
            "-d options   activate log (logfile=%s)\n"
@@ -2233,7 +2234,7 @@ void init_task_state(TaskState *ts)
  
 int main(int argc, char **argv, char **envp)
 {
-    const char *filename;
+    char *filename = NULL;
     const char *cpu_model;
     struct target_pt_regs regs1, *regs = &regs1;
     struct image_info info1, *info = &info1;
@@ -2243,7 +2244,12 @@ int main(int argc, char **argv, char **envp)
     const char *r;
     int gdbstub_port = 0;
     char **target_environ, **wrk;
+    char **target_argv;
+    int target_argc;
+    int drop_ld_preload = 0;
     envlist_t *envlist = NULL;
+    const char *argv0 = NULL;
+    int i;
 
     if (argc <= 1)
         usage();
@@ -2289,7 +2295,7 @@ int main(int argc, char **argv, char **envp)
                 for(item = cpu_log_items; item->mask != 0; item++) {
                     printf("%-10s %s\n", item->name, item->help);
                 }
-                exit(1);
+                _exit(1);
             }
             cpu_set_log(mask);
         } else if (!strcmp(r, "E")) {
@@ -2300,6 +2306,13 @@ int main(int argc, char **argv, char **envp)
             r = argv[optind++];
             if (envlist_unsetenv(envlist, r) != 0)
                 usage();
+        } else if (!strcmp(r, "0")) {
+            r = argv[optind++];
+            argv0 = r;
+        } else if (!strcmp(r,"-sbox-call")) {
+           r = argv[optind++];
+           filename = r;
+           exec_path = r;
         } else if (!strcmp(r, "s")) {
             if (optind >= argc)
                 break;
@@ -2320,7 +2333,7 @@ int main(int argc, char **argv, char **envp)
             if (qemu_host_page_size == 0 ||
                 (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
                 fprintf(stderr, "page size must be a power of two\n");
-                exit(1);
+                _exit(1);
             }
         } else if (!strcmp(r, "g")) {
             if (optind >= argc)
@@ -2338,7 +2351,9 @@ int main(int argc, char **argv, char **envp)
                 exit(1);
             }
         } else if (!strcmp(r, "drop-ld-preload")) {
-            (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+            drop_ld_preload = 1;
+        } else if (!strcmp(r, "keep-ld-preload")) {
+            drop_ld_preload = 0;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
         } else
@@ -2348,8 +2363,15 @@ int main(int argc, char **argv, char **envp)
     }
     if (optind >= argc)
         usage();
-    filename = argv[optind];
-    exec_path = argv[optind];
+    if (filename == NULL) {
+        filename = argv[optind];
+        exec_path = argv[optind];
+    } else {
+        argv0 = argv[optind];
+    }
+    if (drop_ld_preload) {
+        (void) envlist_unsetenv(envlist, "LD_PRELOAD");
+    }
 
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
@@ -2368,7 +2390,7 @@ int main(int argc, char **argv, char **envp)
         cpu_model = "qemu32";
 #endif
 #elif defined(TARGET_ARM)
-        cpu_model = "arm926";
+        cpu_model = "any";
 #elif defined(TARGET_M68K)
         cpu_model = "any";
 #elif defined(TARGET_SPARC)
@@ -2410,11 +2432,39 @@ int main(int argc, char **argv, char **envp)
     target_environ = envlist_to_environ(envlist, NULL);
     envlist_free(envlist);
 
-    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+    /*
+     * Prepare copy of argv vector for target.
+     */
+    target_argc = argc - optind;
+    target_argv = calloc(target_argc + 1, sizeof (char *));
+    if (target_argv == NULL) {
+       (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
+       exit(1);
+    }
+
+    /*
+     * If argv0 is specified (using '-0' switch) we replace
+     * argv[0] pointer with the given one.
+     */
+    i = 0;
+    if (argv0 != NULL) {
+        target_argv[i++] = strdup(argv0);
+    }
+    for (; i < target_argc; i++) {
+        target_argv[i] = strdup(argv[optind + i]);
+    }
+    target_argv[target_argc] = NULL;
+
+    if (loader_exec(filename, target_argv, target_environ, regs, info) != 0) {
         printf("Error loading %s\n", filename);
         _exit(1);
     }
 
+    for (i = 0; i < target_argc; i++) {
+        free(target_argv[i]);
+    }
+    free(target_argv);
+
     for (wrk = target_environ; *wrk; wrk++) {
         free(*wrk);
     }