summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-02-02 18:02:33 +0100
committerJunfeng Dong <junfeng.dong@intel.com>2013-11-19 18:50:32 +0800
commit1c3a8097c0916dba8afaed7d4542bb2cf16416f2 (patch)
treee16850787311ace53acb8467e089bebed9c894e0
parent8dbf3a54099df78d5eaf23415129c6a59b4ebc1a (diff)
downloadqemu-1c3a8097c0916dba8afaed7d4542bb2cf16416f2.tar.gz
qemu-1c3a8097c0916dba8afaed7d4542bb2cf16416f2.tar.bz2
qemu-1c3a8097c0916dba8afaed7d4542bb2cf16416f2.zip
linux-user: binfmt: support host binaries
When we have a working host binary equivalent for the guest binary we're trying to run, let's just use that instead as it will be a lot faster. Change-Id: I7ae3bd8dbf8e5562affe0e6921e15a32e2d3e0a1 Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--linux-user/binfmt.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/linux-user/binfmt.c b/linux-user/binfmt.c
index cd1f513b3..87dc4c672 100644
--- a/linux-user/binfmt.c
+++ b/linux-user/binfmt.c
@@ -5,6 +5,9 @@
#include <string.h>
#include <stdlib.h>
+#ifdef __x86_64__
+#define ARCH_NAME "x86_64"
+#endif
int main(int argc, char **argv, char **envp)
{
@@ -28,6 +31,28 @@ int main(int argc, char **argv, char **envp)
binfmt[0] = '\0';
/* Now argv[0] is the real qemu binary name */
+#ifdef ARCH_NAME
+ {
+ char *hostbin;
+ char *guestarch;
+
+ guestarch = strrchr(argv[0], '-') ;
+ if (!guestarch) {
+ goto skip;
+ }
+ guestarch++;
+ asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
+ if (!access(hostbin, X_OK)) {
+ /*
+ * We found a host binary replacement for the non-host binary. Let's
+ * use that instead!
+ */
+ return execve(hostbin, &argv[2], envp);
+ }
+ }
+skip:
+#endif
+
new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
if (argc > 3) {
memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));