Message ID | 20150209075530.4252.76551.stgit@PASHA-ISP |
---|---|
State | New |
Headers | show |
Am 09.02.2015 um 08:55 schrieb Pavel Dovgalyuk: > On w64, setjmp is implemented by _setjmp which needs a second parameter. > This parameter should be NULL to allow using longjump from generated code. > This patch replaces all usages of setjmp.h with new header files which > replaces setjmp with _setjmp function on win64 platform. > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > --- > Please have a look at include/sysemu/os-win32.h. I think that your patch is not needed because the current code already uses _setjmp. Regards Stefan
> From: Stefan Weil [mailto:sw@weilnetz.de] > Am 09.02.2015 um 08:55 schrieb Pavel Dovgalyuk: > > On w64, setjmp is implemented by _setjmp which needs a second parameter. > > This parameter should be NULL to allow using longjump from generated code. > > This patch replaces all usages of setjmp.h with new header files which > > replaces setjmp with _setjmp function on win64 platform. > > > > Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > > Please have a look at include/sysemu/os-win32.h. I think that your patch > is not needed because the current code already uses _setjmp. Right, but some of the files (e.g. include/qom/cpu.h) include setjmp.h directly. Then we have the following for compiling cpu-exec.c: cpu-exec.c: ... os-win32.h ... setjmp.h ... In this situation cpu-exec will call incorrect setjmp function. Pavel Dovgalyuk
Am 09.02.2015 um 09:07 schrieb Pavel Dovgaluk: >> From: Stefan Weil [mailto:sw@weilnetz.de] >> Am 09.02.2015 um 08:55 schrieb Pavel Dovgalyuk: >>> On w64, setjmp is implemented by _setjmp which needs a second parameter. >>> This parameter should be NULL to allow using longjump from generated code. >>> This patch replaces all usages of setjmp.h with new header files which >>> replaces setjmp with _setjmp function on win64 platform. >>> >>> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> >> Please have a look at include/sysemu/os-win32.h. I think that your patch >> is not needed because the current code already uses _setjmp. > Right, but some of the files (e.g. include/qom/cpu.h) include setjmp.h directly. > Then we have the following for compiling cpu-exec.c: > > cpu-exec.c: > ... > os-win32.h > ... > setjmp.h > ... > > In this situation cpu-exec will call incorrect setjmp function. > > Pavel Dovgalyuk It won't call the wrong setjmp function, at least not in my tests. cpu-exec.c gets the setjmp declaration from os-win32.h. Without it, QEMU would be unusable because it would crash very soon during the emulation. Do you see problems caused by a wrong setjmp with latest QEMU? If yes: which build environment do you use (host, compiler, version of MinGW*)?
> From: Stefan Weil [mailto:sw@weilnetz.de] > Am 09.02.2015 um 09:07 schrieb Pavel Dovgaluk: > >> From: Stefan Weil [mailto:sw@weilnetz.de] > >> Am 09.02.2015 um 08:55 schrieb Pavel Dovgalyuk: > >>> On w64, setjmp is implemented by _setjmp which needs a second parameter. > >>> This parameter should be NULL to allow using longjump from generated code. > >>> This patch replaces all usages of setjmp.h with new header files which > >>> replaces setjmp with _setjmp function on win64 platform. > >>> > >>> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> > >> Please have a look at include/sysemu/os-win32.h. I think that your patch > >> is not needed because the current code already uses _setjmp. > > Right, but some of the files (e.g. include/qom/cpu.h) include setjmp.h directly. > > Then we have the following for compiling cpu-exec.c: > > > > cpu-exec.c: > > ... > > os-win32.h > > ... > > setjmp.h > > ... > > > > In this situation cpu-exec will call incorrect setjmp function. > > > > Pavel Dovgalyuk > > > It won't call the wrong setjmp function, at least not in my tests. > cpu-exec.c gets the setjmp declaration from os-win32.h. Without it, QEMU > would be unusable because it would crash very soon during the emulation. > > Do you see problems caused by a wrong setjmp with latest QEMU? If yes: > which build environment do you use (host, compiler, version of MinGW*)? Yes, I've got the problems. To verify the correctness of the call I disassembled cpu-exec.o and found that setjmp is called with second parameter not equal to zero. I'm using Cygwin environment and packages from here: http://win-builds.org/ My host OS is Windows 7x64 and the compiler is x86_64-w64-mingw32-gcc.exe (GCC) 4.8.3 Pavel Dovgalyuk
diff --git a/coroutine-sigaltstack.c b/coroutine-sigaltstack.c index 63519ff..c890496 100644 --- a/coroutine-sigaltstack.c +++ b/coroutine-sigaltstack.c @@ -26,7 +26,7 @@ #undef _FORTIFY_SOURCE #endif #include <stdlib.h> -#include <setjmp.h> +#include "sysemu/setjmp.h" #include <stdint.h> #include <pthread.h> #include <signal.h> diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c index 259fcb4..12e2826 100644 --- a/coroutine-ucontext.c +++ b/coroutine-ucontext.c @@ -23,7 +23,7 @@ #undef _FORTIFY_SOURCE #endif #include <stdlib.h> -#include <setjmp.h> +#include "sysemu/setjmp.h" #include <stdint.h> #include <ucontext.h> #include "qemu-common.h" diff --git a/disas/i386.c b/disas/i386.c index 00ceca9..fdb1ec6 100644 --- a/disas/i386.c +++ b/disas/i386.c @@ -153,7 +153,7 @@ /* opcodes/i386-dis.c r1.126 */ #include "qemu-common.h" -#include <setjmp.h> +#include "sysemu/setjmp.h" static int fetch_data2(struct disassemble_info *, bfd_byte *); static int fetch_data(struct disassemble_info *, bfd_byte *); diff --git a/disas/m68k.c b/disas/m68k.c index cc0db96..312351e 100644 --- a/disas/m68k.c +++ b/disas/m68k.c @@ -616,7 +616,7 @@ static const char *const reg_half_names[] = /* Maximum length of an instruction. */ #define MAXLEN 22 -#include <setjmp.h> +#include "sysemu/setjmp.h" struct private { diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 2098f1c..16dc2f7 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -21,7 +21,7 @@ #define QEMU_CPU_H #include <signal.h> -#include <setjmp.h> +#include "sysemu/setjmp.h" #include "hw/qdev-core.h" #include "exec/hwaddr.h" #include "qemu/queue.h" diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h index af3fbc4..0387313 100644 --- a/include/sysemu/os-win32.h +++ b/include/sysemu/os-win32.h @@ -55,23 +55,6 @@ # define EWOULDBLOCK WSAEWOULDBLOCK #endif -#if defined(_WIN64) -/* On w64, setjmp is implemented by _setjmp which needs a second parameter. - * If this parameter is NULL, longjump does no stack unwinding. - * That is what we need for QEMU. Passing the value of register rsp (default) - * lets longjmp try a stack unwinding which will crash with generated code. */ -# undef setjmp -# define setjmp(env) _setjmp(env, NULL) -#endif -/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify - * "longjmp and don't touch the signal masks". Since we know that the - * savemask parameter will always be zero we can safely define these - * in terms of setjmp/longjmp on Win32. - */ -#define sigjmp_buf jmp_buf -#define sigsetjmp(env, savemask) setjmp(env) -#define siglongjmp(env, val) longjmp(env, val) - /* Declaration of ffs() is missing in MinGW's strings.h. */ int ffs(int i); diff --git a/include/sysemu/setjmp.h b/include/sysemu/setjmp.h new file mode 100755 index 0000000..ffd804a --- /dev/null +++ b/include/sysemu/setjmp.h @@ -0,0 +1,35 @@ +/* + * setjmp.h + * + * Copyright (c) 2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#ifndef QEMU_SETJMP_H +#define QEMU_SETJMP_H + +#include <setjmp.h> + +#if defined(_WIN32) +#if defined(_WIN64) +/* On w64, setjmp is implemented by _setjmp which needs a second parameter. + * If this parameter is NULL, longjump does no stack unwinding. + * That is what we need for QEMU. Passing the value of register rsp (default) + * lets longjmp try a stack unwinding which will crash with generated code. */ +# undef setjmp +# define setjmp(env) _setjmp(env, NULL) +#endif +/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify + * "longjmp and don't touch the signal masks". Since we know that the + * savemask parameter will always be zero we can safely define these + * in terms of setjmp/longjmp on Win32. + */ +#define sigjmp_buf jmp_buf +#define sigsetjmp(env, savemask) setjmp(env) +#define siglongjmp(env, val) longjmp(env, val) +#endif + +#endif diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 16fcec2..23b7af8 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -59,7 +59,7 @@ extern int daemon(int, int); #include "qemu/sockets.h" #include <sys/mman.h> #include <libgen.h> -#include <setjmp.h> +#include "sysemu/setjmp.h" #include <sys/signal.h> #ifdef CONFIG_LINUX
On w64, setjmp is implemented by _setjmp which needs a second parameter. This parameter should be NULL to allow using longjump from generated code. This patch replaces all usages of setjmp.h with new header files which replaces setjmp with _setjmp function on win64 platform. Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> --- coroutine-sigaltstack.c | 2 +- coroutine-ucontext.c | 2 +- disas/i386.c | 2 +- disas/m68k.c | 2 +- include/qom/cpu.h | 2 +- include/sysemu/os-win32.h | 17 ----------------- include/sysemu/setjmp.h | 35 +++++++++++++++++++++++++++++++++++ util/oslib-posix.c | 2 +- 8 files changed, 41 insertions(+), 23 deletions(-) create mode 100755 include/sysemu/setjmp.h