Commit d691f66983c0b36689400e9e9137d72bd3be8e72

Authored by bellard
1 parent 386405f7

glibc2.2 fixes - more command line options - misc doc fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@46 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
  1 +version 0.1.1:
  2 +
  3 + - glibc 2.2 compilation fixes
  4 + - added -s and -L options
  5 + - binary distribution of x86 glibc and wine
  6 +
1 7 version 0.1:
2 8  
3 9 - initial public release.
... ...
Makefile
... ... @@ -118,6 +118,15 @@ tar:
118 118 ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) )
119 119 rm -rf /tmp/$(FILE)
120 120  
  121 +# generate a binary distribution including the test binary environnment
  122 +BINPATH=/usr/local/qemu-i386
  123 +
  124 +tarbin:
  125 + tar zcvf /tmp/qemu-i386-glibc21.tar.gz \
  126 + $(BINPATH)/etc $(BINPATH)/lib $(BINPATH)/bin
  127 + tar zcvf /tmp/qemu-i386-wine.tar.gz \
  128 + $(BINPATH)/X11R6 $(BINPATH)/wine
  129 +
121 130 ifneq ($(wildcard .depend),)
122 131 include .depend
123 132 endif
... ...
... ... @@ -15,8 +15,22 @@ Type
15 15  
16 16 make install
17 17  
18   -to install qemu in /usr/local/bin
  18 +to install QEMU in /usr/local/bin
19 19  
  20 +* On x86 you should be able to launch any program by using the
  21 +libraries installed on your PC. For example:
  22 +
  23 + ./qemu -L / /bin/ls
  24 +
  25 +* On non x86 CPUs, you need first to download at least an x86 glibc
  26 +(qemu-i386-glibc21.tar.gz on the qemu web page). Then you can launch
  27 +the precompiled 'ls' x86 executable:
  28 +
  29 + ./qemu /usr/local/qemu-i386/bin/ls
  30 +
  31 +You can look at /usr/local/qemu-i386/bin/qemu-conf.sh so that QEMU is
  32 +automatically launched by the Linux kernel when you try to launch x86
  33 +executables.
20 34  
21 35 Documentation
22 36 -------------
... ...
1   -0.1
2 1 \ No newline at end of file
  2 +0.1.1
... ...
cpu-i386.h
... ... @@ -406,7 +406,7 @@ void cpu_x86_close(CPUX86State *s);
406 406 /* needed to load some predefinied segment registers */
407 407 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
408 408  
409   -/* you can call these signal handler from you SIGBUS and SIGSEGV
  409 +/* you can call this signal handler from your SIGBUS and SIGSEGV
410 410 signal handlers to inform the virtual CPU of exceptions. non zero
411 411 is returned if the signal was handled by the virtual CPU. */
412 412 struct siginfo;
... ...
exec-i386.c
... ... @@ -485,6 +485,10 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
485 485 unsigned long pc;
486 486 sigset_t *pold_set;
487 487  
  488 +#ifndef REG_EIP
  489 +/* for glibc 2.1 */
  490 +#define REG_EIP EIP
  491 +#endif
488 492 pc = uc->uc_mcontext.gregs[EIP];
489 493 pold_set = &uc->uc_sigmask;
490 494 return handle_cpu_signal(pc, pold_set);
... ...
linux-user/elfload.c
... ... @@ -42,8 +42,7 @@
42 42 #define DLINFO_ITEMS 12
43 43  
44 44 /* Where we find X86 libraries... */
45   -//#define X86_DEFAULT_LIB_DIR "/usr/x86/"
46   -#define X86_DEFAULT_LIB_DIR "/"
  45 +
47 46  
48 47 //extern void * mmap4k();
49 48 #define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
... ... @@ -638,7 +637,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
638 637 * is an a.out format binary
639 638 */
640 639  
641   - elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+strlen(X86_DEFAULT_LIB_DIR));
  640 + elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+
  641 + strlen(bprm->interp_prefix));
642 642  
643 643 if (elf_interpreter == NULL) {
644 644 free (elf_phdata);
... ... @@ -646,11 +646,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
646 646 return -ENOMEM;
647 647 }
648 648  
649   - strcpy(elf_interpreter, X86_DEFAULT_LIB_DIR);
  649 + strcpy(elf_interpreter, bprm->interp_prefix);
650 650 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
651 651 if(retval >= 0) {
652 652 retval = read(bprm->fd,
653   - elf_interpreter+strlen(X86_DEFAULT_LIB_DIR),
  653 + elf_interpreter+strlen(bprm->interp_prefix),
654 654 elf_ppnt->p_filesz);
655 655 }
656 656 if(retval < 0) {
... ... @@ -911,7 +911,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
911 911  
912 912  
913 913  
914   -int elf_exec(const char * filename, char ** argv, char ** envp,
  914 +int elf_exec(const char *interp_prefix,
  915 + const char * filename, char ** argv, char ** envp,
915 916 struct target_pt_regs * regs, struct image_info *infop)
916 917 {
917 918 struct linux_binprm bprm;
... ... @@ -930,6 +931,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp,
930 931 else {
931 932 bprm.fd = retval;
932 933 }
  934 + bprm.interp_prefix = (char *)interp_prefix;
933 935 bprm.filename = (char *)filename;
934 936 bprm.sh_bang = 0;
935 937 bprm.loader = 0;
... ...
linux-user/main.c
... ... @@ -32,6 +32,7 @@
32 32  
33 33 FILE *logfile = NULL;
34 34 int loglevel;
  35 +const char *interp_prefix = CONFIG_QEMU_PREFIX "/qemu-i386";
35 36  
36 37 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
37 38 we allocate a bigger stack. Need a better solution, for example
... ... @@ -172,9 +173,16 @@ void cpu_loop(struct CPUX86State *env)
172 173 void usage(void)
173 174 {
174 175 printf("qemu version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
175   - "usage: qemu [-d] program [arguments...]\n"
  176 + "usage: qemu [-h] [-d] [-L path] [-s size] program [arguments...]\n"
176 177 "Linux x86 emulator\n"
177   - );
  178 + "\n"
  179 + "-h print this help\n"
  180 + "-d activate log (logfile=%s)\n"
  181 + "-L path set the x86 elf interpreter prefix (default=%s)\n"
  182 + "-s size set the x86 stack size in bytes (default=%ld)\n",
  183 + DEBUG_LOGFILE,
  184 + interp_prefix,
  185 + x86_stack_size);
178 186 exit(1);
179 187 }
180 188  
... ... @@ -188,15 +196,41 @@ int main(int argc, char **argv)
188 196 struct image_info info1, *info = &info1;
189 197 CPUX86State *env;
190 198 int optind;
191   -
  199 + const char *r;
  200 +
192 201 if (argc <= 1)
193 202 usage();
194 203 loglevel = 0;
195 204 optind = 1;
196   - if (argv[optind] && !strcmp(argv[optind], "-d")) {
197   - loglevel = 1;
  205 + for(;;) {
  206 + if (optind >= argc)
  207 + break;
  208 + r = argv[optind];
  209 + if (r[0] != '-')
  210 + break;
198 211 optind++;
  212 + r++;
  213 + if (!strcmp(r, "-")) {
  214 + break;
  215 + } else if (!strcmp(r, "d")) {
  216 + loglevel = 1;
  217 + } else if (!strcmp(r, "s")) {
  218 + r = argv[optind++];
  219 + x86_stack_size = strtol(r, (char **)&r, 0);
  220 + if (x86_stack_size <= 0)
  221 + usage();
  222 + if (*r == 'M')
  223 + x86_stack_size *= 1024 * 1024;
  224 + else if (*r == 'k' || *r == 'K')
  225 + x86_stack_size *= 1024;
  226 + } else if (!strcmp(r, "L")) {
  227 + interp_prefix = argv[optind++];
  228 + } else {
  229 + usage();
  230 + }
199 231 }
  232 + if (optind >= argc)
  233 + usage();
200 234 filename = argv[optind];
201 235  
202 236 /* init debug */
... ... @@ -215,7 +249,7 @@ int main(int argc, char **argv)
215 249 /* Zero out image_info */
216 250 memset(info, 0, sizeof(struct image_info));
217 251  
218   - if(elf_exec(filename, argv+optind, environ, regs, info) != 0) {
  252 + if(elf_exec(interp_prefix, filename, argv+optind, environ, regs, info) != 0) {
219 253 printf("Error loading %s\n", filename);
220 254 exit(1);
221 255 }
... ...
linux-user/qemu.h
... ... @@ -33,7 +33,8 @@ struct image_info {
33 33 int personality;
34 34 };
35 35  
36   -int elf_exec(const char * filename, char ** argv, char ** envp,
  36 +int elf_exec(const char *interp_prefix,
  37 + const char * filename, char ** argv, char ** envp,
37 38 struct target_pt_regs * regs, struct image_info *infop);
38 39  
39 40 void target_set_brk(char *new_brk);
... ...
opreg_template.h
1   -/* templates for various register related operations */
2   -
  1 +/*
  2 + * i386 micro operations (templates for various register related
  3 + * operations)
  4 + *
  5 + * Copyright (c) 2003 Fabrice Bellard
  6 + *
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
  11 + *
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 + */
3 21 void OPPROTO glue(op_movl_A0,REGNAME)(void)
4 22 {
5 23 A0 = REG;
... ...
ops_template.h
... ... @@ -4,21 +4,20 @@
4 4 *
5 5 * Copyright (c) 2003 Fabrice Bellard
6 6 *
7   - * This program is free software; you can redistribute it and/or modify
8   - * it under the terms of the GNU General Public License as published by
9   - * the Free Software Foundation; either version 2 of the License, or
10   - * (at your option) any later version.
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
11 11 *
12   - * This program is distributed in the hope that it will be useful,
13   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   - * GNU General Public License for more details.
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
16 16 *
17   - * You should have received a copy of the GNU General Public License
18   - * along with this program; if not, write to the Free Software
19   - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 20 */
21   -
22 21 #define DATA_BITS (1 << (3 + SHIFT))
23 22 #define SHIFT_MASK (DATA_BITS - 1)
24 23 #define SIGN_MASK (1 << (DATA_BITS - 1))
... ...
qemu-doc.texi
... ... @@ -73,26 +73,53 @@ maximum performances.
73 73  
74 74 @chapter Invocation
75 75  
  76 +@section Quick Start
  77 +
76 78 In order to launch a Linux process, QEMU needs the process executable
77   -itself and all the target (x86) dynamic libraries used by it. Currently,
78   -QEMU is not distributed with the necessary packages so that you can test
79   -it easily on non x86 CPUs.
  79 +itself and all the target (x86) dynamic libraries used by it.
  80 +
  81 +@itemize
80 82  
81   -However, the statically x86 binary 'tests/hello' can be used to do a
82   -first test:
  83 +@item On x86, you can just try to launch any process by using the native
  84 +libraries:
83 85  
84 86 @example
85   -qemu tests/hello
  87 +qemu -L / /bin/ls
86 88 @end example
87 89  
88   -@code{Hello world} should be printed on the terminal.
  90 +@code{-L /} tells that the x86 dynamic linker must be searched with a
  91 +@file{/} prefix.
89 92  
90   -If you are testing it on a x86 CPU, then you can test it on any process:
91 93  
92   -@example
93   -qemu /bin/ls -l
  94 +@item On non x86 CPUs, you need first to download at least an x86 glibc
  95 +(@file{qemu-i386-glibc21.tar.gz} on the QEMU web page). Then you can
  96 +launch the precompiled @file{ls} x86 executable:
  97 +@example
  98 +qemu /usr/local/qemu-i386/bin/ls
  99 +@end example
  100 +You can look at @file{/usr/local/qemu-i386/bin/qemu-conf.sh} so that QEMU is automatically
  101 +launched by the Linux kernel when you try to launch x86 executables. It
  102 +requires the @code{binfmt_misc} module in the Linux kernel.
  103 +
  104 +@end itemize
  105 +
  106 +@section Command line options
  107 +
  108 +@example
  109 +usage: qemu [-h] [-d] [-L path] [-s size] program [arguments...]
94 110 @end example
95 111  
  112 +@table @samp
  113 +@item -h
  114 +Print the help
  115 +@item -d
  116 +Activate log (logfile=/tmp/qemu.log)
  117 +@item -L path
  118 +Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
  119 +@item -s size
  120 +Set the x86 stack size in bytes (default=524288)
  121 +@end table
  122 +
96 123 @chapter QEMU Internals
97 124  
98 125 @section QEMU compared to other emulators
... ...
tests/Makefile
... ... @@ -28,7 +28,7 @@ testthread: testthread.c
28 28 # i386 emulation test (test various opcodes) */
29 29 test-i386: test-i386.c test-i386-code16.S \
30 30 test-i386.h test-i386-shift.h test-i386-muldiv.h
31   - $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c test-i386-code16.S -lm
  31 + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ test-i386.c test-i386-code16.S -lm
32 32  
33 33 test: test-i386
34 34 ifeq ($(ARCH),i386)
... ...
tests/testsig.c
... ... @@ -15,21 +15,34 @@ void alarm_handler(int sig)
15 15 alarm(1);
16 16 }
17 17  
  18 +#ifndef REG_EAX
  19 +#define REG_EAX EAX
  20 +#define REG_EBX EBX
  21 +#define REG_ECX ECX
  22 +#define REG_EDX EDX
  23 +#define REG_ESI ESI
  24 +#define REG_EDI EDI
  25 +#define REG_EBP EBP
  26 +#define REG_ESP ESP
  27 +#define REG_EIP EIP
  28 +#define REG_EFL EFL
  29 +#endif
  30 +
18 31 void dump_regs(struct ucontext *uc)
19 32 {
20 33 printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
21 34 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
22 35 "EFL=%08x EIP=%08x\n",
23   - uc->uc_mcontext.gregs[EAX],
24   - uc->uc_mcontext.gregs[EBX],
25   - uc->uc_mcontext.gregs[ECX],
26   - uc->uc_mcontext.gregs[EDX],
27   - uc->uc_mcontext.gregs[ESI],
28   - uc->uc_mcontext.gregs[EDI],
29   - uc->uc_mcontext.gregs[EBP],
30   - uc->uc_mcontext.gregs[ESP],
31   - uc->uc_mcontext.gregs[EFL],
32   - uc->uc_mcontext.gregs[EIP]);
  36 + uc->uc_mcontext.gregs[REG_EAX],
  37 + uc->uc_mcontext.gregs[REG_EBX],
  38 + uc->uc_mcontext.gregs[REG_ECX],
  39 + uc->uc_mcontext.gregs[REG_EDX],
  40 + uc->uc_mcontext.gregs[REG_ESI],
  41 + uc->uc_mcontext.gregs[REG_EDI],
  42 + uc->uc_mcontext.gregs[REG_EBP],
  43 + uc->uc_mcontext.gregs[REG_ESP],
  44 + uc->uc_mcontext.gregs[REG_EFL],
  45 + uc->uc_mcontext.gregs[REG_EIP]);
33 46 }
34 47  
35 48 void sig_handler(int sig, siginfo_t *info, void *puc)
... ...