Commit 285dc330bd28aa0e097106875bb184e2707bbed5
1 parent
baf8ebf0
update
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@417 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
47 additions
and
320 deletions
Changelog
| 1 | -version 0.4.4: | 1 | +version 0.5.0: |
| 2 | 2 | ||
| 3 | - full hardware level VGA emulation | 3 | - full hardware level VGA emulation |
| 4 | - graphical display with SDL | 4 | - graphical display with SDL |
| @@ -16,8 +16,9 @@ version 0.4.4: | @@ -16,8 +16,9 @@ version 0.4.4: | ||
| 16 | - preliminary SPARC target support (Thomas M. Ogrisegg) | 16 | - preliminary SPARC target support (Thomas M. Ogrisegg) |
| 17 | - tun-fd option (Rusty Russell) | 17 | - tun-fd option (Rusty Russell) |
| 18 | - automatic IDE geometry detection | 18 | - automatic IDE geometry detection |
| 19 | - - renamed 'vl' to qemu and user qemu to qemu-{cpu}. | 19 | + - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}. |
| 20 | - added man page | 20 | - added man page |
| 21 | + - added full soft mmy mode to launch unpatched OSes. | ||
| 21 | 22 | ||
| 22 | version 0.4.3: | 23 | version 0.4.3: |
| 23 | 24 |
README
| @@ -6,35 +6,17 @@ INSTALLATION | @@ -6,35 +6,17 @@ INSTALLATION | ||
| 6 | 6 | ||
| 7 | Type | 7 | Type |
| 8 | 8 | ||
| 9 | - ./configure --interp-prefix=/usr/local/qemu-i386 | 9 | + ./configure |
| 10 | make | 10 | make |
| 11 | 11 | ||
| 12 | -to build qemu and libqemu.a. | 12 | +to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various |
| 13 | +supported target CPUs). | ||
| 13 | 14 | ||
| 14 | Type | 15 | Type |
| 15 | 16 | ||
| 16 | make install | 17 | make install |
| 17 | 18 | ||
| 18 | -to install QEMU in /usr/local/bin | ||
| 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-XXX-i386-glibc21.tar.gz on the qemu web page). Ensure that | ||
| 27 | -LD_LIBRARY_PATH is not set: | ||
| 28 | - | ||
| 29 | - unset LD_LIBRARY_PATH | ||
| 30 | - | ||
| 31 | -Then you can launch the precompiled 'ls' x86 executable: | ||
| 32 | - | ||
| 33 | - ./qemu /usr/local/qemu-i386/bin/ls-i386 | ||
| 34 | - | ||
| 35 | -You can look at /usr/local/qemu-i386/bin/qemu-conf.sh so that QEMU is | ||
| 36 | -automatically launched by the Linux kernel when you try to launch x86 | ||
| 37 | -executables. | 19 | +to install QEMU in /usr/local |
| 38 | 20 | ||
| 39 | Tested tool versions | 21 | Tested tool versions |
| 40 | -------------------- | 22 | -------------------- |
README.distrib
| @@ -6,11 +6,11 @@ x86 binary distribution: | @@ -6,11 +6,11 @@ x86 binary distribution: | ||
| 6 | 6 | ||
| 7 | * wine-20020411 tarball | 7 | * wine-20020411 tarball |
| 8 | 8 | ||
| 9 | - ./configure --prefix=/usr/local/qemu-i386/wine | 9 | + ./configure --prefix=/usr/local/wine-i386 |
| 10 | 10 | ||
| 11 | All exe and libs were stripped. Some compile time tools and the | 11 | All exe and libs were stripped. Some compile time tools and the |
| 12 | includes were deleted. | 12 | includes were deleted. |
| 13 | 13 | ||
| 14 | * ldconfig was launched to build the library links: | 14 | * ldconfig was launched to build the library links: |
| 15 | 15 | ||
| 16 | - ./qemu /usr/local/qemu-i386/bin/ldconfig-i386 -C /usr/local/qemu-i386/etc/ld.so.cache | 16 | + qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C /usr/gnemul/qemu-i386/etc/ld.so.cache |
TODO
| 1 | +- tests for each target CPU | ||
| 2 | +- ppc qemu test | ||
| 1 | - optimize FPU operations (evaluate x87 stack pointer statically) and | 3 | - optimize FPU operations (evaluate x87 stack pointer statically) and |
| 2 | fix cr0.TS emulation | 4 | fix cr0.TS emulation |
| 5 | +- fix some 16 bit sp push/pop overflow | ||
| 6 | +- sysenter/sysexit emulation | ||
| 7 | +- finish segment ops (call far, ret far, load_seg suppressed) | ||
| 3 | - fix CCOP optimisation | 8 | - fix CCOP optimisation |
| 4 | - fix all remaining thread lock issues (must put TBs in a specific invalid | 9 | - fix all remaining thread lock issues (must put TBs in a specific invalid |
| 5 | state, find a solution for tb_flush()). | 10 | state, find a solution for tb_flush()). |
| 6 | - cpu loop optimisation (optimise ret case as the cpu state does not change) | 11 | - cpu loop optimisation (optimise ret case as the cpu state does not change) |
| 7 | - fix arm fpu rounding (at least for float->integer conversions) | 12 | - fix arm fpu rounding (at least for float->integer conversions) |
| 8 | -- add IPC syscalls | ||
| 9 | 13 | ||
| 10 | lower priority: | 14 | lower priority: |
| 11 | -------------- | 15 | -------------- |
| 12 | -- sysenter/sysexit emulation | 16 | +- add IPC syscalls |
| 13 | - SMP support | 17 | - SMP support |
| 14 | -- finish segment ops (call far, ret far, load_seg suppressed) | ||
| 15 | - use -msoft-float on ARM | 18 | - use -msoft-float on ARM |
| 16 | - use kernel traps for unaligned accesses on ARM ? | 19 | - use kernel traps for unaligned accesses on ARM ? |
| 17 | - handle rare page fault cases (in particular if page fault in heplers or | 20 | - handle rare page fault cases (in particular if page fault in heplers or |
VERSION
qemu-doc.texi
| @@ -72,7 +72,7 @@ QEMU user mode emulation features: | @@ -72,7 +72,7 @@ QEMU user mode emulation features: | ||
| 72 | 72 | ||
| 73 | QEMU full system emulation features: | 73 | QEMU full system emulation features: |
| 74 | @itemize | 74 | @itemize |
| 75 | -@item Using mmap() system calls to simulate the MMU | 75 | +@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU. |
| 76 | @end itemize | 76 | @end itemize |
| 77 | 77 | ||
| 78 | @section x86 emulation | 78 | @section x86 emulation |
| @@ -110,14 +110,7 @@ memory access. | @@ -110,14 +110,7 @@ memory access. | ||
| 110 | 10 byte @code{long double}s of x86 for floating point emulation to get | 110 | 10 byte @code{long double}s of x86 for floating point emulation to get |
| 111 | maximum performances. | 111 | maximum performances. |
| 112 | 112 | ||
| 113 | -@item Full system emulation only works if no data are mapped above the virtual address | ||
| 114 | -0xc0000000 (yet). | ||
| 115 | - | ||
| 116 | -@item Some priviledged instructions or behaviors are missing. Only the ones | ||
| 117 | -needed for proper Linux kernel operation are emulated. | ||
| 118 | - | ||
| 119 | -@item No memory separation between the kernel and the user processes is done. | ||
| 120 | -It will be implemented very soon. | 113 | +@item Some priviledged instructions or behaviors are missing, especially for segment protection testing (yet). |
| 121 | 114 | ||
| 122 | @end itemize | 115 | @end itemize |
| 123 | 116 | ||
| @@ -177,9 +170,9 @@ unset LD_LIBRARY_PATH | @@ -177,9 +170,9 @@ unset LD_LIBRARY_PATH | ||
| 177 | Then you can launch the precompiled @file{ls} x86 executable: | 170 | Then you can launch the precompiled @file{ls} x86 executable: |
| 178 | 171 | ||
| 179 | @example | 172 | @example |
| 180 | -qemu-i386 /usr/local/qemu-i386/bin/ls-i386 | 173 | +qemu-i386 tests/i386/ls |
| 181 | @end example | 174 | @end example |
| 182 | -You can look at @file{/usr/local/qemu-i386/bin/qemu-conf.sh} so that | 175 | +You can look at @file{qemu-binfmt-conf.sh} so that |
| 183 | QEMU is automatically launched by the Linux kernel when you try to | 176 | QEMU is automatically launched by the Linux kernel when you try to |
| 184 | launch x86 executables. It requires the @code{binfmt_misc} module in the | 177 | launch x86 executables. It requires the @code{binfmt_misc} module in the |
| 185 | Linux kernel. | 178 | Linux kernel. |
| @@ -258,16 +251,15 @@ available: | @@ -258,16 +251,15 @@ available: | ||
| 258 | @enumerate | 251 | @enumerate |
| 259 | 252 | ||
| 260 | @item | 253 | @item |
| 261 | -@code{qemu} uses the host Memory Management Unit (MMU) to simulate | 254 | +@code{qemu-fast} uses the host Memory Management Unit (MMU) to simulate |
| 262 | the x86 MMU. It is @emph{fast} but has limitations because the whole 4 GB | 255 | the x86 MMU. It is @emph{fast} but has limitations because the whole 4 GB |
| 263 | address space cannot be used and some memory mapped peripherials | 256 | address space cannot be used and some memory mapped peripherials |
| 264 | cannot be emulated accurately yet. Therefore, a specific Linux kernel | 257 | cannot be emulated accurately yet. Therefore, a specific Linux kernel |
| 265 | must be used (@xref{linux_compile}). | 258 | must be used (@xref{linux_compile}). |
| 266 | 259 | ||
| 267 | @item | 260 | @item |
| 268 | -@code{qemu-softmmu} uses a software MMU. It is about @emph{two times | ||
| 269 | -slower} but gives a more accurate emulation. (XXX: Linux cannot be ran | ||
| 270 | -unpatched yet). | 261 | +@code{qemu} uses a software MMU. It is about @emph{two times |
| 262 | +slower} but gives a more accurate emulation. | ||
| 271 | 263 | ||
| 272 | @end enumerate | 264 | @end enumerate |
| 273 | 265 | ||
| @@ -296,10 +288,10 @@ CMOS memory | @@ -296,10 +288,10 @@ CMOS memory | ||
| 296 | 288 | ||
| 297 | @section Quick Start | 289 | @section Quick Start |
| 298 | 290 | ||
| 299 | -Download the linux image (@file{linux.img}) and type: | 291 | +Download and uncompress the linux image (@file{linux.img}) and type: |
| 300 | 292 | ||
| 301 | @example | 293 | @example |
| 302 | -qemu-softmmu linux.img | 294 | +qemu linux.img |
| 303 | @end example | 295 | @end example |
| 304 | 296 | ||
| 305 | Linux should boot and give you a prompt. | 297 | Linux should boot and give you a prompt. |
| @@ -627,8 +619,10 @@ the real one. To know it, use the @code{ls -ls} command. | @@ -627,8 +619,10 @@ the real one. To know it, use the @code{ls -ls} command. | ||
| 627 | @node linux_compile | 619 | @node linux_compile |
| 628 | @section Linux Kernel Compilation | 620 | @section Linux Kernel Compilation |
| 629 | 621 | ||
| 630 | -You should be able to use any kernel with QEMU provided you make the | ||
| 631 | -following changes (only 2.4.x and 2.5.x were tested): | 622 | +You can use any linux kernel with QEMU. However, if you want to use |
| 623 | +@code{qemu-fast} to get maximum performances, you should make the | ||
| 624 | +following changes to the Linux kernel (only 2.4.x and 2.5.x were | ||
| 625 | +tested): | ||
| 632 | 626 | ||
| 633 | @enumerate | 627 | @enumerate |
| 634 | @item | 628 | @item |
| @@ -723,8 +717,6 @@ Then you can use gdb normally. For example, type 'c' to launch the kernel: | @@ -723,8 +717,6 @@ Then you can use gdb normally. For example, type 'c' to launch the kernel: | ||
| 723 | (gdb) c | 717 | (gdb) c |
| 724 | @end example | 718 | @end example |
| 725 | 719 | ||
| 726 | -WARNING: breakpoints and single stepping are not yet supported. | ||
| 727 | - | ||
| 728 | Here are some useful tips in order to use gdb on system code: | 720 | Here are some useful tips in order to use gdb on system code: |
| 729 | 721 | ||
| 730 | @enumerate | 722 | @enumerate |
| @@ -1019,16 +1011,6 @@ The new Plex86 project. | @@ -1019,16 +1011,6 @@ The new Plex86 project. | ||
| 1019 | In the directory @file{tests/}, various interesting testing programs | 1011 | In the directory @file{tests/}, various interesting testing programs |
| 1020 | are available. There are used for regression testing. | 1012 | are available. There are used for regression testing. |
| 1021 | 1013 | ||
| 1022 | -@section @file{hello-i386} | ||
| 1023 | - | ||
| 1024 | -Very simple statically linked x86 program, just to test QEMU during a | ||
| 1025 | -port to a new host CPU. | ||
| 1026 | - | ||
| 1027 | -@section @file{hello-arm} | ||
| 1028 | - | ||
| 1029 | -Very simple statically linked ARM program, just to test QEMU during a | ||
| 1030 | -port to a new host CPU. | ||
| 1031 | - | ||
| 1032 | @section @file{test-i386} | 1014 | @section @file{test-i386} |
| 1033 | 1015 | ||
| 1034 | This program executes most of the 16 bit and 32 bit x86 instructions and | 1016 | This program executes most of the 16 bit and 32 bit x86 instructions and |
| @@ -1044,6 +1026,22 @@ The Linux system call @code{vm86()} is used to test vm86 emulation. | @@ -1044,6 +1026,22 @@ The Linux system call @code{vm86()} is used to test vm86 emulation. | ||
| 1044 | Various exceptions are raised to test most of the x86 user space | 1026 | Various exceptions are raised to test most of the x86 user space |
| 1045 | exception reporting. | 1027 | exception reporting. |
| 1046 | 1028 | ||
| 1029 | +@section @file{linux-test} | ||
| 1030 | + | ||
| 1031 | +This program tests various Linux system calls. It is used to verify | ||
| 1032 | +that the system call parameters are correctly converted between target | ||
| 1033 | +and host CPUs. | ||
| 1034 | + | ||
| 1035 | +@section @file{hello-i386} | ||
| 1036 | + | ||
| 1037 | +Very simple statically linked x86 program, just to test QEMU during a | ||
| 1038 | +port to a new host CPU. | ||
| 1039 | + | ||
| 1040 | +@section @file{hello-arm} | ||
| 1041 | + | ||
| 1042 | +Very simple statically linked ARM program, just to test QEMU during a | ||
| 1043 | +port to a new host CPU. | ||
| 1044 | + | ||
| 1047 | @section @file{sha1} | 1045 | @section @file{sha1} |
| 1048 | 1046 | ||
| 1049 | It is a simple benchmark. Care must be taken to interpret the results | 1047 | It is a simple benchmark. Care must be taken to interpret the results |
tests/linux-test.c
| @@ -71,7 +71,7 @@ int __chk_error(const char *filename, int line, int ret) | @@ -71,7 +71,7 @@ int __chk_error(const char *filename, int line, int ret) | ||
| 71 | 71 | ||
| 72 | #define FILE_BUF_SIZE 300 | 72 | #define FILE_BUF_SIZE 300 |
| 73 | 73 | ||
| 74 | -void file_test(void) | 74 | +void test_file(void) |
| 75 | { | 75 | { |
| 76 | int fd, i, len, ret; | 76 | int fd, i, len, ret; |
| 77 | uint8_t buf[FILE_BUF_SIZE]; | 77 | uint8_t buf[FILE_BUF_SIZE]; |
| @@ -499,7 +499,7 @@ void test_signal(void) | @@ -499,7 +499,7 @@ void test_signal(void) | ||
| 499 | 499 | ||
| 500 | int main(int argc, char **argv) | 500 | int main(int argc, char **argv) |
| 501 | { | 501 | { |
| 502 | - file_test(); | 502 | + test_file(); |
| 503 | test_fork(); | 503 | test_fork(); |
| 504 | test_time(); | 504 | test_time(); |
| 505 | test_socket(); | 505 | test_socket(); |
| @@ -507,4 +507,3 @@ int main(int argc, char **argv) | @@ -507,4 +507,3 @@ int main(int argc, char **argv) | ||
| 507 | test_signal(); | 507 | test_signal(); |
| 508 | return 0; | 508 | return 0; |
| 509 | } | 509 | } |
| 510 | - |
tests/testclone.c deleted
100644 โ 0
| 1 | -#include <stdlib.h> | ||
| 2 | -#include <stdio.h> | ||
| 3 | -#include <string.h> | ||
| 4 | -#include <signal.h> | ||
| 5 | -#include <unistd.h> | ||
| 6 | -#include <inttypes.h> | ||
| 7 | -#include <pthread.h> | ||
| 8 | -#include <sys/wait.h> | ||
| 9 | -#include <sched.h> | ||
| 10 | - | ||
| 11 | -int thread1_func(void *arg) | ||
| 12 | -{ | ||
| 13 | - int i; | ||
| 14 | - char buf[512]; | ||
| 15 | - | ||
| 16 | - for(i=0;i<10;i++) { | ||
| 17 | - snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); | ||
| 18 | - write(1, buf, strlen(buf)); | ||
| 19 | - usleep(100 * 1000); | ||
| 20 | - } | ||
| 21 | - return 0; | ||
| 22 | -} | ||
| 23 | - | ||
| 24 | -int thread2_func(void *arg) | ||
| 25 | -{ | ||
| 26 | - int i; | ||
| 27 | - char buf[512]; | ||
| 28 | - for(i=0;i<20;i++) { | ||
| 29 | - snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); | ||
| 30 | - write(1, buf, strlen(buf)); | ||
| 31 | - usleep(120 * 1000); | ||
| 32 | - } | ||
| 33 | - return 0; | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | -#define STACK_SIZE 16384 | ||
| 37 | - | ||
| 38 | -void test_clone(void) | ||
| 39 | -{ | ||
| 40 | - uint8_t *stack1, *stack2; | ||
| 41 | - int pid1, pid2, status1, status2; | ||
| 42 | - | ||
| 43 | - stack1 = malloc(STACK_SIZE); | ||
| 44 | - pid1 = clone(thread1_func, stack1 + STACK_SIZE, | ||
| 45 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"); | ||
| 46 | - | ||
| 47 | - stack2 = malloc(STACK_SIZE); | ||
| 48 | - pid2 = clone(thread2_func, stack2 + STACK_SIZE, | ||
| 49 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"); | ||
| 50 | - | ||
| 51 | - while (waitpid(pid1, &status1, 0) != pid1); | ||
| 52 | - while (waitpid(pid2, &status2, 0) != pid2); | ||
| 53 | - printf("status1=0x%x\n", status1); | ||
| 54 | - printf("status2=0x%x\n", status2); | ||
| 55 | - printf("End of clone test.\n"); | ||
| 56 | -} | ||
| 57 | - | ||
| 58 | -int main(int argc, char **argv) | ||
| 59 | -{ | ||
| 60 | - test_clone(); | ||
| 61 | - return 0; | ||
| 62 | -} |
tests/testsig.c deleted
100644 โ 0
| 1 | -#define _GNU_SOURCE | ||
| 2 | -#include <stdlib.h> | ||
| 3 | -#include <stdio.h> | ||
| 4 | -#include <string.h> | ||
| 5 | -#include <signal.h> | ||
| 6 | -#include <unistd.h> | ||
| 7 | -#include <setjmp.h> | ||
| 8 | -#include <sys/ucontext.h> | ||
| 9 | - | ||
| 10 | -jmp_buf jmp_env; | ||
| 11 | - | ||
| 12 | -void alarm_handler(int sig) | ||
| 13 | -{ | ||
| 14 | - printf("alarm signal=%d\n", sig); | ||
| 15 | - alarm(1); | ||
| 16 | -} | ||
| 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 | -#define REG_TRAPNO TRAPNO | ||
| 30 | -#define REG_ERR ERR | ||
| 31 | -#endif | ||
| 32 | - | ||
| 33 | -void dump_regs(struct ucontext *uc) | ||
| 34 | -{ | ||
| 35 | - printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" | ||
| 36 | - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" | ||
| 37 | - "EFL=%08x EIP=%08x trapno=%02x err=%08x\n", | ||
| 38 | - uc->uc_mcontext.gregs[REG_EAX], | ||
| 39 | - uc->uc_mcontext.gregs[REG_EBX], | ||
| 40 | - uc->uc_mcontext.gregs[REG_ECX], | ||
| 41 | - uc->uc_mcontext.gregs[REG_EDX], | ||
| 42 | - uc->uc_mcontext.gregs[REG_ESI], | ||
| 43 | - uc->uc_mcontext.gregs[REG_EDI], | ||
| 44 | - uc->uc_mcontext.gregs[REG_EBP], | ||
| 45 | - uc->uc_mcontext.gregs[REG_ESP], | ||
| 46 | - uc->uc_mcontext.gregs[REG_EFL], | ||
| 47 | - uc->uc_mcontext.gregs[REG_EIP], | ||
| 48 | - uc->uc_mcontext.gregs[REG_TRAPNO], | ||
| 49 | - uc->uc_mcontext.gregs[REG_ERR]); | ||
| 50 | -} | ||
| 51 | - | ||
| 52 | -void sig_handler(int sig, siginfo_t *info, void *puc) | ||
| 53 | -{ | ||
| 54 | - struct ucontext *uc = puc; | ||
| 55 | - | ||
| 56 | - printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n", | ||
| 57 | - strsignal(info->si_signo), | ||
| 58 | - info->si_signo, info->si_errno, info->si_code, | ||
| 59 | - (unsigned long)info->si_addr); | ||
| 60 | - dump_regs(uc); | ||
| 61 | - longjmp(jmp_env, 1); | ||
| 62 | -} | ||
| 63 | - | ||
| 64 | -int v1; | ||
| 65 | -int tab[2]; | ||
| 66 | - | ||
| 67 | -int main(int argc, char **argv) | ||
| 68 | -{ | ||
| 69 | - struct sigaction act; | ||
| 70 | - volatile int val; | ||
| 71 | - | ||
| 72 | - act.sa_sigaction = sig_handler; | ||
| 73 | - sigemptyset(&act.sa_mask); | ||
| 74 | - act.sa_flags = SA_SIGINFO; | ||
| 75 | - sigaction(SIGFPE, &act, NULL); | ||
| 76 | - sigaction(SIGILL, &act, NULL); | ||
| 77 | - sigaction(SIGSEGV, &act, NULL); | ||
| 78 | - sigaction(SIGTRAP, &act, NULL); | ||
| 79 | - | ||
| 80 | - /* test division by zero reporting */ | ||
| 81 | - if (setjmp(jmp_env) == 0) { | ||
| 82 | - /* now divide by zero */ | ||
| 83 | - v1 = 0; | ||
| 84 | - v1 = 2 / v1; | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - /* test illegal instruction reporting */ | ||
| 88 | - if (setjmp(jmp_env) == 0) { | ||
| 89 | - /* now execute an invalid instruction */ | ||
| 90 | - asm volatile("ud2"); | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - /* test SEGV reporting */ | ||
| 94 | - if (setjmp(jmp_env) == 0) { | ||
| 95 | - /* now store in an invalid address */ | ||
| 96 | - *(char *)0x1234 = 1; | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | - /* test SEGV reporting */ | ||
| 100 | - if (setjmp(jmp_env) == 0) { | ||
| 101 | - /* read from an invalid address */ | ||
| 102 | - v1 = *(char *)0x1234; | ||
| 103 | - } | ||
| 104 | - | ||
| 105 | - printf("segment GPF exception:\n"); | ||
| 106 | - if (setjmp(jmp_env) == 0) { | ||
| 107 | - /* load an invalid segment */ | ||
| 108 | - asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); | ||
| 109 | - } | ||
| 110 | - | ||
| 111 | - printf("INT exception:\n"); | ||
| 112 | - if (setjmp(jmp_env) == 0) { | ||
| 113 | - asm volatile ("int $0xfd"); | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - printf("INT3 exception:\n"); | ||
| 117 | - if (setjmp(jmp_env) == 0) { | ||
| 118 | - asm volatile ("int3"); | ||
| 119 | - } | ||
| 120 | - | ||
| 121 | - printf("CLI exception:\n"); | ||
| 122 | - if (setjmp(jmp_env) == 0) { | ||
| 123 | - asm volatile ("cli"); | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - printf("STI exception:\n"); | ||
| 127 | - if (setjmp(jmp_env) == 0) { | ||
| 128 | - asm volatile ("cli"); | ||
| 129 | - } | ||
| 130 | - | ||
| 131 | - printf("INTO exception:\n"); | ||
| 132 | - if (setjmp(jmp_env) == 0) { | ||
| 133 | - /* overflow exception */ | ||
| 134 | - asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - printf("BOUND exception:\n"); | ||
| 138 | - if (setjmp(jmp_env) == 0) { | ||
| 139 | - /* bound exception */ | ||
| 140 | - tab[0] = 1; | ||
| 141 | - tab[1] = 10; | ||
| 142 | - asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); | ||
| 143 | - } | ||
| 144 | - | ||
| 145 | - printf("OUTB exception:\n"); | ||
| 146 | - if (setjmp(jmp_env) == 0) { | ||
| 147 | - asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); | ||
| 148 | - } | ||
| 149 | - | ||
| 150 | - printf("INB exception:\n"); | ||
| 151 | - if (setjmp(jmp_env) == 0) { | ||
| 152 | - asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); | ||
| 153 | - } | ||
| 154 | - | ||
| 155 | - printf("REP OUTSB exception:\n"); | ||
| 156 | - if (setjmp(jmp_env) == 0) { | ||
| 157 | - asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - printf("REP INSB exception:\n"); | ||
| 161 | - if (setjmp(jmp_env) == 0) { | ||
| 162 | - asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | - printf("HLT exception:\n"); | ||
| 166 | - if (setjmp(jmp_env) == 0) { | ||
| 167 | - asm volatile ("hlt"); | ||
| 168 | - } | ||
| 169 | - | ||
| 170 | - printf("single step exception:\n"); | ||
| 171 | - val = 0; | ||
| 172 | - if (setjmp(jmp_env) == 0) { | ||
| 173 | - asm volatile ("pushf\n" | ||
| 174 | - "orl $0x00100, (%%esp)\n" | ||
| 175 | - "popf\n" | ||
| 176 | - "movl $0xabcd, %0\n" : "=m" (val) : : "cc", "memory"); | ||
| 177 | - } | ||
| 178 | - printf("val=0x%x\n", val); | ||
| 179 | - | ||
| 180 | -#if 1 | ||
| 181 | - { | ||
| 182 | - int i; | ||
| 183 | - act.sa_handler = alarm_handler; | ||
| 184 | - sigemptyset(&act.sa_mask); | ||
| 185 | - act.sa_flags = 0; | ||
| 186 | - sigaction(SIGALRM, &act, NULL); | ||
| 187 | - alarm(1); | ||
| 188 | - for(i = 0;i < 2; i++) { | ||
| 189 | - sleep(1); | ||
| 190 | - } | ||
| 191 | - } | ||
| 192 | -#endif | ||
| 193 | - return 0; | ||
| 194 | -} |