From 29fa1af29768c3d069a4b96dc5719a0214a9ed03 Mon Sep 17 00:00:00 2001 From: Andreas Grapentin Date: Tue, 20 Mar 2018 20:54:00 +0100 Subject: [PATCH] add binfmt wrapper --- Makefile.target | 9 ++++++++ binfmt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ scripts/qemu-binfmt-conf.sh | 10 ++++----- 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 binfmt.c diff --git a/Makefile.target b/Makefile.target index 6549481096..3edb4cc832 100644 --- a/Makefile.target +++ b/Makefile.target @@ -36,6 +36,10 @@ endif PROGS=$(QEMU_PROG) $(QEMU_PROGW) STPFILES= +ifdef CONFIG_LINUX_USER +PROGS+=$(QEMU_PROG)-binfmt +endif + config-target.h: config-target.h-timestamp config-target.h-timestamp: config-target.mak @@ -114,6 +118,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \ obj-y += linux-user/ obj-y += gdbstub.o thunk.o +obj-binfmt-y += binfmt.o + endif #CONFIG_LINUX_USER ######################################################### @@ -196,6 +202,9 @@ ifdef CONFIG_DARWIN $(call quiet-command,SetFile -a C $@,"SETFILE","$(TARGET_DIR)$@") endif +$(QEMU_PROG)-binfmt: $(obj-binfmt-y) + $(call LINK,$^) + 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/binfmt.c b/binfmt.c new file mode 100644 index 0000000000..9b19436ee5 --- /dev/null +++ b/binfmt.c @@ -0,0 +1,55 @@ + +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "%s: please use me through binfmt\n", argv[0]); + return 1; + } + + char **nargv = malloc(sizeof(*argv) * (argc + 2)); + if (NULL == nargv) + { + perror("malloc"); + return 1; + } + + nargv[0] = strdup(argv[0]); + if (NULL == nargv[0]) + { + perror("strdup"); + return 1; + } + + // argv0 is qemu-$cpu-binfmt, and we want to change that to qemu-$cpu-static + char *dest = strstr(nargv[0], "-binfmt"); + if (NULL == dest) + { + fprintf(stderr, "%s: -binfmt not found in invocation name\n", argv[0]); + return 1; + } + strncpy(dest, "-static", 7); + + nargv[1] = strdup("-0"); + if (NULL == nargv[1]) + { + perror("strdup"); + return 1; + } + + nargv[2] = argv[2]; + nargv[3] = argv[1]; + + memcpy(&nargv[4], &argv[3], (argc - 3 + 1) * sizeof(*argv)); + + int ret = execv(nargv[0], nargv); + perror("exec"); + return ret; +} diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index f39ad344fc..c36b1abd43 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -274,9 +274,9 @@ qemu_set_binfmts() { continue fi - qemu="$QEMU_PATH/qemu-$cpu" + qemu="$QEMU_PATH/qemu-$cpu-binfmt" if [ "$cpu" = "i486" ] ; then - qemu="$QEMU_PATH/qemu-i386" + qemu="$QEMU_PATH/qemu-i386-binfmt" fi if [ "$host_family" != "$family" ] ; then @@ -292,7 +292,7 @@ SYSTEMDDIR="/etc/binfmt.d" DEBIANDIR="/usr/share/binfmts" QEMU_PATH=/usr/local/bin -FLAGS="" +FLAGS="P" options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@") eval set -- "$options" @@ -341,9 +341,7 @@ while true ; do -c|--credential) shift if [ "$1" = "yes" ] ; then - FLAGS="OC" - else - FLAGS="" + FLAGS+="OC" fi ;; *) -- 2.16.2