From 5a9afc5f8f00e9f1d1f99159e3943240400bdfbd Mon Sep 17 00:00:00 2001 From: "shuai.fu" Date: Mon, 5 Sep 2016 14:35:50 +0800 Subject: [PATCH] Add the qemu-arm-binfmt (qemu-arm64-binfmt) Change-Id: Iee417992cebbba47c5155aaf1f4a47de77ec5a72 Signed-off-by: shuai.fu --- Makefile.target | 10 +++++ linux-user/binfmt.c | 71 ++++++++++++++++++++++++++++++++++ packaging/qemu-arm-static.spec | 2 + 3 files changed, 83 insertions(+) create mode 100644 linux-user/binfmt.c diff --git a/Makefile.target b/Makefile.target index 9a4985213..a2319e124 100644 --- a/Makefile.target +++ b/Makefile.target @@ -31,6 +31,10 @@ PROGS+=$(QEMU_PROGW) endif STPFILES= +ifdef CONFIG_LINUX_USER +PROGS+=$(QEMU_PROG)-binfmt +endif + config-target.h: config-target.h-timestamp config-target.h-timestamp: config-target.mak @@ -166,6 +170,12 @@ $(QEMU_PROG): $(all-obj-y) ../libqemuutil.a ../libqemustub.a $(call LINK,$^) endif +$(QEMU_PROG)-binfmt: + #pwd + #$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o ./linux-user/$@.o $(BUILD_DIR)/linux-user/binfmt.c + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) $($@-cflags) -c -o ./linux-user/$@.o $(BUILD_DIR)/linux-user/binfmt.c + $(call LINK,./linux-user/$@.o) + gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@") diff --git a/linux-user/binfmt.c b/linux-user/binfmt.c new file mode 100644 index 000000000..d55941aa2 --- /dev/null +++ b/linux-user/binfmt.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +#ifdef __x86_64__ +#define ARCH_NAME "x86_64" +#elif defined __i386__ +#define ARCH_NAME "i586" +#endif + +int main(int argc, char **argv, char **envp) +{ + char *binfmt; + char **new_argv; + + /* + * Check if our file name ends with -binfmt + */ + binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt"); + if (strcmp(binfmt, "-binfmt")) { + fprintf(stderr, "%s: Invalid executable name\n", argv[0]); + exit(1); + } + if (argc < 3) { + fprintf(stderr, "%s: Please use me through binfmt with P flag\n", + argv[0]); + exit(1); + } + + //binfmt[0] = '\0'; + strcpy(binfmt, "-static"); + /* Now argv[0] is the real qemu binary name */ + +#ifdef ARCH_NAME + { + char *hostbin; + char *guestarch; + int r; + + guestarch = strrchr(argv[0], '-') ; + if (!guestarch) { + goto skip; + } + guestarch++; + r = asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]); + if (!access(hostbin, X_OK) && (r > 0)) { + /* + * 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)); + } + new_argv[0] = argv[0]; + new_argv[1] = (char *)"-0"; + new_argv[2] = argv[2]; + new_argv[3] = argv[1]; + new_argv[argc + 1] = NULL; + + return execve(new_argv[0], new_argv, envp); +} diff --git a/packaging/qemu-arm-static.spec b/packaging/qemu-arm-static.spec index 4e265f0d6..ed2e4881d 100644 --- a/packaging/qemu-arm-static.spec +++ b/packaging/qemu-arm-static.spec @@ -105,6 +105,8 @@ rm -rf ${RPM_BUILD_ROOT} %defattr(-, root, root) %{_bindir}/qemu-arm-static %{_bindir}/qemu-arm64-static +%{_bindir}/qemu-arm-binfmt +%{_bindir}/qemu-arm64-binfmt %{_sbindir}/* %changelog -- 2.34.1