tizen 2.3.1 release
[external/qemu.git] / packaging / 0011-linux-user-add-binfmt-wrapper-for-argv-0-handling.patch
1 From: Alexander Graf <agraf@suse.de>
2 Date: Fri, 30 Sep 2011 19:40:36 +0200
3 Subject: linux-user: add binfmt wrapper for argv[0] handling
4 MIME-Version: 1.0
5 Content-Type: text/plain; charset="utf-8"
6 Content-Transfer-Encoding: 8bit
7
8 When using qemu's linux-user binaries through binfmt, argv[0] gets lost
9 along the execution because qemu only gets passed in the full file name
10 to the executable while argv[0] can be something completely different.
11
12 This breaks in some subtile situations, such as the grep and make test
13 suites.
14
15 This patch adds a wrapper binary called qemu-$TARGET-binfmt that can be
16 used with binfmt's P flag which passes the full path _and_ argv[0] to
17 the binfmt handler.
18
19 The binary would be smart enough to be versatile and only exist in the
20 system once, creating the qemu binary path names from its own argv[0].
21 However, this seemed like it didn't fit the make system too well, so
22 we're currently creating a new binary for each target archictecture.
23
24 CC: Reinhard Max <max@suse.de>
25 Signed-off-by: Alexander Graf <agraf@suse.de>
26 [AF: Rebased onto new Makefile infrastructure]
27 Signed-off-by: Andreas Färber <afaerber@suse.de>
28 ---
29  Makefile.target             | 12 ++++++++++++
30  linux-user/Makefile.objs    |  2 ++
31  linux-user/binfmt.c         | 42 ++++++++++++++++++++++++++++++++++++++++++
32  scripts/qemu-binfmt-conf.sh | 34 +++++++++++++++++-----------------
33  4 files changed, 73 insertions(+), 17 deletions(-)
34  create mode 100644 linux-user/binfmt.c
35
36 diff --git a/Makefile.target b/Makefile.target
37 index 9a49852..58e7a22 100644
38 --- a/Makefile.target
39 +++ b/Makefile.target
40 @@ -31,6 +31,10 @@ PROGS+=$(QEMU_PROGW)
41  endif
42  STPFILES=
43  
44 +ifdef CONFIG_LINUX_USER
45 +PROGS+=$(QEMU_PROG)-binfmt
46 +endif
47 +
48  config-target.h: config-target.h-timestamp
49  config-target.h-timestamp: config-target.mak
50  
51 @@ -96,6 +100,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
52  obj-y += linux-user/
53  obj-y += gdbstub.o thunk.o user-exec.o
54  
55 +obj-binfmt-y += linux-user/
56 +
57  endif #CONFIG_LINUX_USER
58  
59  #########################################################
60 @@ -144,6 +150,9 @@ endif # CONFIG_SOFTMMU
61  %/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
62  
63  nested-vars += obj-y
64 +ifdef CONFIG_LINUX_USER
65 +nested-vars += obj-binfmt-y
66 +endif
67  
68  # This resolves all nested paths, so it must come last
69  include $(SRC_PATH)/Makefile.objs
70 @@ -166,6 +175,9 @@ $(QEMU_PROG): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
71         $(call LINK,$^)
72  endif
73  
74 +$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
75 +       $(call LINK,$^)
76 +
77  gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
78         $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   $(TARGET_DIR)$@")
79  
80 diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
81 index 5899d72..18212a2 100644
82 --- a/linux-user/Makefile.objs
83 +++ b/linux-user/Makefile.objs
84 @@ -5,3 +5,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
85  obj-$(TARGET_I386) += vm86.o
86  obj-$(TARGET_ARM) += arm/nwfpe/
87  obj-$(TARGET_M68K) += m68k-sim.o
88 +
89 +obj-binfmt-y = binfmt.o
90 diff --git a/linux-user/binfmt.c b/linux-user/binfmt.c
91 new file mode 100644
92 index 0000000..cd1f513
93 --- /dev/null
94 +++ b/linux-user/binfmt.c
95 @@ -0,0 +1,42 @@
96 +#include <stdio.h>
97 +#include <stdarg.h>
98 +#include <unistd.h>
99 +#include <libgen.h>
100 +#include <string.h>
101 +#include <stdlib.h>
102 +
103 +
104 +int main(int argc, char **argv, char **envp)
105 +{
106 +    char *binfmt;
107 +    char **new_argv;
108 +
109 +    /*
110 +     * Check if our file name ends with -binfmt
111 +     */
112 +    binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt");
113 +    if (strcmp(binfmt, "-binfmt")) {
114 +        fprintf(stderr, "%s: Invalid executable name\n", argv[0]);
115 +        exit(1);
116 +    }
117 +    if (argc < 3) {
118 +        fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
119 +                argv[0]);
120 +        exit(1);
121 +    }
122 +
123 +    binfmt[0] = '\0';
124 +    /* Now argv[0] is the real qemu binary name */
125 +
126 +    new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
127 +    if (argc > 3) {
128 +        memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));
129 +    }
130 +    new_argv[0] = argv[0];
131 +    new_argv[1] = (char *)"-0";
132 +    new_argv[2] = argv[2];
133 +    new_argv[3] = argv[1];
134 +    new_argv[argc + 1] = NULL;
135 +
136 +    return execve(new_argv[0], new_argv, envp);
137 +}
138 diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
139 index dc652f0..37d03f3 100644
140 --- a/scripts/qemu-binfmt-conf.sh
141 +++ b/scripts/qemu-binfmt-conf.sh
142 @@ -34,39 +34,39 @@ esac
143  
144  # register the interpreter for each cpu except for the native one
145  if [ $cpu != "i386" ] ; then
146 -    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
147 -    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
148 +    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
149 +    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
150  fi
151  if [ $cpu != "alpha" ] ; then
152 -    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
153 +    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register
154  fi
155  if [ $cpu != "arm" ] ; then
156 -    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
157 -    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
158 +    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register
159 +    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
160  fi
161  if [ $cpu != "sparc" ] ; then
162 -    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
163 +    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
164  fi
165  if [ $cpu != "ppc" ] ; then
166 -    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
167 +    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
168  fi
169  if [ $cpu != "m68k" ] ; then
170      echo   'Please check cpu value and header information for m68k!'
171 -    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
172 +    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register
173  fi
174  if [ $cpu != "mips" ] ; then
175      # FIXME: We could use the other endianness on a MIPS host.
176 -    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
177 -    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
178 -    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
179 -    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
180 -    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
181 -    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
182 +    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register
183 +    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register
184 +    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register
185 +    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
186 +    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register
187 +    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
188  fi
189  if [ $cpu != "sh" ] ; then
190 -    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
191 -    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
192 +    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register
193 +    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
194  fi
195  if [ $cpu != "s390x" ] ; then
196 -    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
197 +    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register
198  fi