From fc63229d9cd2e5061cab0686aba4d18bc3fb4e4f Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Wed, 5 Oct 2011 12:38:27 -0700 Subject: qemu-0.15: Add recipe and forward port patches from 0.14 Signed-off-by: Khem Raj --- .../qemu/qemu-0.15.0/arm-bgr.patch | 30 + .../qemu/qemu-0.15.0/enable-i386-linux-user.patch | 55 + .../fallback-to-safe-mmap_min_addr.patch | 39 + .../qemu/qemu-0.15.0/fix-configure-checks.patch | 22 + .../qemu/qemu-0.15.0/fix-nogl.patch | 127 + .../qemu/qemu-0.15.0/glflags.patch | 15 + .../qemu/qemu-0.15.0/init-info.patch | 18 + .../qemu/qemu-0.15.0/larger_default_ram_size.patch | 22 + .../qemu/qemu-0.15.0/linker-flags.patch | 25 + .../qemu/qemu-0.15.0/no-strip.patch | 15 + .../qemu/qemu-0.15.0/opengl-sdl-fix.patch | 43 + .../qemu/qemu-0.15.0/powerpc_rom.bin | Bin 0 -> 4096 bytes .../qemu/qemu-0.15.0/qemu-git-qemugl-host.patch | 34368 +++++++++++++++++++ .../qemu/qemu-0.15.0/qemu-vmware-vga-depth.patch | 118 + .../qemugl-allow-glxcontext-release.patch | 65 + .../qemu/qemu-0.15.0/qemugl-fix.patch | 74 + meta/recipes-devtools/qemu/qemu_0.15.0.bb | 45 + 17 files changed, 35081 insertions(+) create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/arm-bgr.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/enable-i386-linux-user.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/fallback-to-safe-mmap_min_addr.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/fix-configure-checks.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/fix-nogl.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/glflags.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/init-info.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/larger_default_ram_size.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/linker-flags.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/no-strip.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/opengl-sdl-fix.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/powerpc_rom.bin create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/qemu-git-qemugl-host.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/qemu-vmware-vga-depth.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/qemugl-allow-glxcontext-release.patch create mode 100644 meta/recipes-devtools/qemu/qemu-0.15.0/qemugl-fix.patch create mode 100644 meta/recipes-devtools/qemu/qemu_0.15.0.bb diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/arm-bgr.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/arm-bgr.patch new file mode 100644 index 0000000000..3b460d04ce --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/arm-bgr.patch @@ -0,0 +1,30 @@ +After kernel commit: + +http://git.yoctoproject.org/cgit/cgit.cgi/linux-yocto-3.0/commit/?h=meta&id=9728c1b6a724daefc413b44e10253cdbb5e06d08 + +It appears that the emulated colours in qemu are incorrect and that +the red and blue channels are reversed. This patch reverses that logic +so the colours are correctly displayed on the versatile platform which +doesn't support the BGR bit. + +RP 16/9/2011 + +Upstream-status: Pending + +Index: qemu-0.14.0/hw/pl110.c +=================================================================== +--- qemu-0.14.0.orig/hw/pl110.c 2011-09-16 14:45:34.228668514 +0100 ++++ qemu-0.14.0/hw/pl110.c 2011-09-16 15:17:22.458671206 +0100 +@@ -141,7 +141,11 @@ + fprintf(stderr, "pl110: Bad color depth\n"); + exit(1); + } +- if (s->cr & PL110_CR_BGR) ++ ++ if (s->versatile && s->bpp == BPP_16) ++ /* Code assumes BPP_16 == 565 and BGR is never set on the versatile in 565 mode */ ++ bpp_offset = 0; ++ else if (s->cr & PL110_CR_BGR) + bpp_offset = 0; + else + bpp_offset = 18; diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/enable-i386-linux-user.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/enable-i386-linux-user.patch new file mode 100644 index 0000000000..bb0d6a3848 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/enable-i386-linux-user.patch @@ -0,0 +1,55 @@ +Enable i386-linux-user + +Signed-off-by: Zhai Edwin + +Upstream-Status: Inappropriate [configuration] + +Index: qemu-0.14.0/Makefile.target +=================================================================== +--- qemu-0.14.0.orig/Makefile.target ++++ qemu-0.14.0/Makefile.target +@@ -78,8 +78,13 @@ ifeq ($(TARGET_BASE_ARCH), i386) + libobj-y += cpuid.o + endif + libobj-$(CONFIG_NEED_MMU) += mmu.o ++ifndef CONFIG_LINUX_USER + libobj-$(TARGET_I386) += helper_opengl.o opengl_exec.o + libobj-$(TARGET_X86_64) += helper_opengl.o opengl_exec.o ++else ++libobj-$(TARGET_I386) += dummygl.o ++libobj-$(TARGET_X86_64) += dummygl.o ++endif #CONFIG_LINUX_USER + libobj-$(TARGET_ARM) += dummygl.o + libobj-$(TARGET_MIPS) += dummygl.o + libobj-$(TARGET_PPC) += dummygl.o +Index: qemu-0.14.0/target-i386/dummygl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/dummygl.c +@@ -0,0 +1,26 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) ++{ ++ ++} ++ ++void opengl_process_enable(void) ++{ ++ ++} ++ ++ ++void mem_opengl(uint64_t ptr) ++{ ++ ++} ++ ++void helper_opengl(void) ++{ ++} diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/fallback-to-safe-mmap_min_addr.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/fallback-to-safe-mmap_min_addr.patch new file mode 100644 index 0000000000..2075386b9f --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/fallback-to-safe-mmap_min_addr.patch @@ -0,0 +1,39 @@ +From c313f89c33217ac0e471554dace2144718f86669 Mon Sep 17 00:00:00 2001 +From: Martin Jansa +Date: Thu, 13 May 2010 12:23:40 +0200 +Subject: [PATCH] linux-user: use default mmap_min_addr 65536 when /proc/sys/vm/mmap_min_addr cannot be read + +* 65536 is default at least for ubuntu and fedora. +--- + linux-user/main.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +Upstream-Status: Pending + +Index: qemu-0.14.0/linux-user/main.c +=================================================================== +--- qemu-0.14.0.orig/linux-user/main.c ++++ qemu-0.14.0/linux-user/main.c +@@ -36,6 +36,7 @@ + #include "envlist.h" + + #define DEBUG_LOGFILE "/tmp/qemu.log" ++#define MMAP_MIN_ADDR_DEFAULT 65536 + + char *exec_path; + +@@ -3010,8 +3011,14 @@ int main(int argc, char **argv, char **e + if (fscanf(fp, "%lu", &tmp) == 1) { + mmap_min_addr = tmp; + qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr); ++ } else { ++ qemu_log("cannot read value from /proc/sys/vm/mmap_min_addr, assuming %d\n", MMAP_MIN_ADDR_DEFAULT); ++ mmap_min_addr = MMAP_MIN_ADDR_DEFAULT; + } + fclose(fp); ++ } else { ++ qemu_log("cannot open /proc/sys/vm/mmap_min_addr for reading, assuming %d\n", MMAP_MIN_ADDR_DEFAULT); ++ mmap_min_addr = MMAP_MIN_ADDR_DEFAULT; + } + } + diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/fix-configure-checks.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/fix-configure-checks.patch new file mode 100644 index 0000000000..96881bb91b --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/fix-configure-checks.patch @@ -0,0 +1,22 @@ +In native builds, qemu can fail to find zlib development files in the native +sysroot and the build machine might not have zlib-dev packages installed. + +Add CFLAGS to qemu's CFLAGS which in the native case means BUILD_CFLAGS are +added and files in the sysroot can be found. + +Patch from Paul Eggleton, Comments by RP 28/11/10 + +Upstream-Status: Inappropriate [embedded specific] + +Index: qemu-0.14.0/configure +=================================================================== +--- qemu-0.14.0.orig/configure ++++ qemu-0.14.0/configure +@@ -229,6 +229,7 @@ QEMU_CFLAGS="-Wstrict-prototypes -Wredun + QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS" + QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS" + QEMU_INCLUDES="-I. -I\$(SRC_PATH)" ++QEMU_CFLAGS="$QEMU_CFLAGS $CFLAGS" + LDFLAGS="-g $LDFLAGS" + + # make source path absolute diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/fix-nogl.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/fix-nogl.patch new file mode 100644 index 0000000000..83b2752589 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/fix-nogl.patch @@ -0,0 +1,127 @@ +Upstream-Status: Inappropriate [configuration] + +Index: qemu-0.14.0/Makefile.target +=================================================================== +--- qemu-0.14.0.orig/Makefile.target ++++ qemu-0.14.0/Makefile.target +@@ -79,6 +79,12 @@ libobj-y += cpuid.o + endif + libobj-$(CONFIG_NEED_MMU) += mmu.o + libobj-$(TARGET_I386) += helper_opengl.o opengl_exec.o ++libobj-$(TARGET_X86_64) += helper_opengl.o opengl_exec.o ++libobj-$(TARGET_ARM) += dummygl.o ++libobj-$(TARGET_MIPS) += dummygl.o ++libobj-$(TARGET_MIPS64) += dummygl.o ++libobj-$(TARGET_PPC) += dummygl.o ++libobj-$(TARGET_SH4) += dummygl.o + libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o + + libobj-y += disas.o +Index: qemu-0.14.0/target-arm/dummygl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-arm/dummygl.c +@@ -0,0 +1,22 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) ++{ ++ ++} ++ ++void opengl_process_enable(void) ++{ ++ ++} ++ ++ ++void mem_opengl(uint64_t ptr) ++{ ++ ++} +Index: qemu-0.14.0/target-mips/dummygl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-mips/dummygl.c +@@ -0,0 +1,22 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) ++{ ++ ++} ++ ++void opengl_process_enable(void) ++{ ++ ++} ++ ++ ++void mem_opengl(uint64_t ptr) ++{ ++ ++} +Index: qemu-0.14.0/target-ppc/dummygl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-ppc/dummygl.c +@@ -0,0 +1,22 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) ++{ ++ ++} ++ ++void opengl_process_enable(void) ++{ ++ ++} ++ ++ ++void mem_opengl(uint64_t ptr) ++{ ++ ++} +Index: qemu-0.14.0/target-sh4/dummygl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-sh4/dummygl.c +@@ -0,0 +1,22 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) ++{ ++ ++} ++ ++void opengl_process_enable(void) ++{ ++ ++} ++ ++ ++void mem_opengl(uint64_t ptr) ++{ ++ ++} diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/glflags.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/glflags.patch new file mode 100644 index 0000000000..0ad5551d47 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/glflags.patch @@ -0,0 +1,15 @@ +Upstream-Status: Inappropriate [configuration] + +Index: qemu-0.14.0/Makefile.target +=================================================================== +--- qemu-0.14.0.orig/Makefile.target 2011-04-04 12:12:19.142871742 +0100 ++++ qemu-0.14.0/Makefile.target 2011-04-04 12:12:21.772871742 +0100 +@@ -362,7 +362,7 @@ + + monitor.o: hmp-commands.h qmp-commands.h + +-LIBS += -lGL -lGLU ++LIBS += -lGL + + $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) + diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/init-info.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/init-info.patch new file mode 100644 index 0000000000..2250444a2b --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/init-info.patch @@ -0,0 +1,18 @@ +# This is a workaround to the crashes seen on Ubuntu. Setting info to zero +# makes info.info.x11.display zero and avoids the calls to +# opengl_exec_set_parent_window, one of which is crashing. + +Upstream-Status: Pending + +Index: qemu-0.14.0/ui/sdl.c +=================================================================== +--- qemu-0.14.0.orig/ui/sdl.c ++++ qemu-0.14.0/ui/sdl.c +@@ -863,6 +863,7 @@ void sdl_display_init(DisplayState *ds, + vi = SDL_GetVideoInfo(); + host_format = *(vi->vfmt); + ++ bzero(&info, sizeof(info)); + SDL_GetWMInfo(&info); + if (info.subsystem == SDL_SYSWM_X11 && info.info.x11.display) + opengl_exec_set_parent_window(info.info.x11.display, diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/larger_default_ram_size.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/larger_default_ram_size.patch new file mode 100644 index 0000000000..711c36071d --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/larger_default_ram_size.patch @@ -0,0 +1,22 @@ +This patch is taken from debian. 128M is too less sometimes if distro +with lot of packages is booted so this patch raises the default to 384M + +It has not been applied to upstream qemu + +Khem Raj + +Upstream-Status: Pending + +Index: qemu-0.14.0/vl.c +=================================================================== +--- qemu-0.14.0.orig/vl.c ++++ qemu-0.14.0/vl.c +@@ -168,7 +168,7 @@ int main(int argc, char **argv) + //#define DEBUG_NET + //#define DEBUG_SLIRP + +-#define DEFAULT_RAM_SIZE 128 ++#define DEFAULT_RAM_SIZE 384 + + #define MAX_VIRTIO_CONSOLES 1 + diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/linker-flags.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/linker-flags.patch new file mode 100644 index 0000000000..c0d1e5541d --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/linker-flags.patch @@ -0,0 +1,25 @@ +Fedora 13 switched the default behaviour of the linker to no longer +indirectly link to required libraries (i.e. dependencies of a library +already linked to). Therefore we need to explicitly pass the depended on +libraries into the linker for building to work on Fedora 13. + +More information is available on the Fedora Wiki: +https://fedoraproject.org/wiki/UnderstandingDSOLinkChange + +JL - 15/06/10 + +Upstream-Status: Inappropriate [configuration] + +Index: qemu-0.14.0/Makefile.target +=================================================================== +--- qemu-0.14.0.orig/Makefile.target ++++ qemu-0.14.0/Makefile.target +@@ -218,7 +218,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p + obj-y += rwhandler.o + obj-$(CONFIG_KVM) += kvm.o kvm-all.o + obj-$(CONFIG_NO_KVM) += kvm-stub.o +-LIBS+=-lz ++LIBS+=-lz -lX11 -ldl + + QEMU_CFLAGS += $(VNC_TLS_CFLAGS) + QEMU_CFLAGS += $(VNC_SASL_CFLAGS) diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/no-strip.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/no-strip.patch new file mode 100644 index 0000000000..d6a4377cd0 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/no-strip.patch @@ -0,0 +1,15 @@ +Upstream-Status: Inappropriate [configuration] + +Index: qemu-0.14.0/Makefile +=================================================================== +--- qemu-0.14.0.orig/Makefile ++++ qemu-0.14.0/Makefile +@@ -235,7 +235,7 @@ install-sysconfig: + install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig + $(INSTALL_DIR) "$(DESTDIR)$(bindir)" + ifneq ($(TOOLS),) +- $(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)" ++ $(INSTALL_PROG) $(TOOLS) "$(DESTDIR)$(bindir)" + endif + ifneq ($(BLOBS),) + $(INSTALL_DIR) "$(DESTDIR)$(datadir)" diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/opengl-sdl-fix.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/opengl-sdl-fix.patch new file mode 100644 index 0000000000..e73bb7bfe9 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/opengl-sdl-fix.patch @@ -0,0 +1,43 @@ +Upstream-Status: Inappropriate [configuration] + +diff -u -r qemu-0.14.0/Makefile.target qemu-0.14.0-fixed/Makefile.target +--- qemu-0.14.0/Makefile.target 2011-04-26 21:22:17.627637741 -0700 ++++ qemu-0.14.0-fixed/Makefile.target 2011-04-26 21:23:02.767637747 -0700 +@@ -82,8 +82,10 @@ + libobj-$(TARGET_I386) += helper_opengl.o opengl_exec.o + libobj-$(TARGET_X86_64) += helper_opengl.o opengl_exec.o + else ++ifdef CONFIG_SDL + libobj-$(TARGET_I386) += dummygl.o + libobj-$(TARGET_X86_64) += dummygl.o ++endif + endif #CONFIG_LINUX_USER + libobj-$(TARGET_ARM) += dummygl.o + libobj-$(TARGET_MIPS) += dummygl.o +Only in qemu-0.14.0-fixed: config.log +diff -u -r qemu-0.14.0/target-i386/helper.h qemu-0.14.0-fixed/target-i386/helper.h +--- qemu-0.14.0/target-i386/helper.h 2011-04-26 21:22:11.418637742 -0700 ++++ qemu-0.14.0-fixed/target-i386/helper.h 2011-04-26 21:23:02.539637747 -0700 +@@ -217,6 +217,9 @@ + DEF_HELPER_2(rcrq, tl, tl, tl) + #endif + ++#ifdef CONFIG_SDL + DEF_HELPER_0(opengl, void) ++#endif ++ + + #include "def-helper.h" +diff -u -r qemu-0.14.0/target-i386/translate.c qemu-0.14.0-fixed/target-i386/translate.c +--- qemu-0.14.0/target-i386/translate.c 2011-04-26 21:22:21.600637743 -0700 ++++ qemu-0.14.0-fixed/target-i386/translate.c 2011-04-26 21:23:02.538637747 -0700 +@@ -2659,7 +2659,7 @@ + static void gen_interrupt(DisasContext *s, int intno, + target_ulong cur_eip, target_ulong next_eip) + { +-#if !defined(CONFIG_USER_ONLY) ++#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_SDL) + if (enable_gl && intno == 0x99) { + gen_helper_opengl(); + return; + diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/powerpc_rom.bin b/meta/recipes-devtools/qemu/qemu-0.15.0/powerpc_rom.bin new file mode 100644 index 0000000000..c4044296c5 Binary files /dev/null and b/meta/recipes-devtools/qemu/qemu-0.15.0/powerpc_rom.bin differ diff --git a/meta/recipes-devtools/qemu/qemu-0.15.0/qemu-git-qemugl-host.patch b/meta/recipes-devtools/qemu/qemu-0.15.0/qemu-git-qemugl-host.patch new file mode 100644 index 0000000000..bbc9c9eaf9 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu-0.15.0/qemu-git-qemugl-host.patch @@ -0,0 +1,34368 @@ +Upstream-Status: Inappropriate [other] - qemugl patch need huge changes for upstream + +Index: qemu-0.14.0/Makefile.target +=================================================================== +--- qemu-0.14.0.orig/Makefile.target ++++ qemu-0.14.0/Makefile.target +@@ -78,6 +78,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) + libobj-y += cpuid.o + endif + libobj-$(CONFIG_NEED_MMU) += mmu.o ++libobj-$(TARGET_I386) += helper_opengl.o opengl_exec.o + libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o + + libobj-y += disas.o +@@ -100,6 +101,21 @@ op_helper.o cpu-exec.o: QEMU_CFLAGS += $ + # cpu_signal_handler() in cpu-exec.c. + signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS) + ++parse_gl_h: parse_gl_h.c ++ $(HOST_CC) -g -o $@ $< ++server_stub.c: parse_gl_h ++ ./parse_gl_h ++gl_func.h: parse_gl_h ++ ./parse_gl_h ++GL_CFLAGS := -Wall -g -O2 -fno-strict-aliasing ++opengl_func.h: gl_func.h ++helper_opengl.o: helper_opengl.c opengl_func.h server_stub.c ++ $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< -I.. -I. -I../fpu -I../target-i386 -DNEED_CPU_H ++gl_beginend.h: ../target-i386/beginend_funcs.sh ++ $< > $@ ++opengl_exec.o : opengl_exec.c server_stub.c gl_func.h opengl_func.h gl_beginend.h ++ $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< -I. -I../target-i386 ++ + ######################################################### + # Linux user emulator target + +@@ -221,6 +237,10 @@ obj-i386-y += debugcon.o multiboot.o + obj-i386-y += pc_piix.o + obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o + ++ifeq ($(TARGET_BASE_ARCH), i386) ++QEMU_CFLAGS += -DTARGET_OPENGL_OK ++endif ++ + # shared objects + obj-ppc-y = ppc.o + obj-ppc-y += vga.o +@@ -331,6 +351,8 @@ main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) + + monitor.o: hmp-commands.h qmp-commands.h + ++LIBS += -lGL -lGLU ++ + $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) + + obj-y += $(addprefix ../, $(common-obj-y)) +Index: qemu-0.14.0/hw/pixel_ops.h +=================================================================== +--- qemu-0.14.0.orig/hw/pixel_ops.h ++++ qemu-0.14.0/hw/pixel_ops.h +@@ -4,6 +4,12 @@ static inline unsigned int rgb_to_pixel8 + return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6); + } + ++static inline unsigned int rgb_to_pixel8bgr(unsigned int r, unsigned int g, ++ unsigned int b) ++{ ++ return ((b >> 5) << 5) | ((g >> 5) << 2) | (r >> 6); ++} ++ + static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, + unsigned int b) + { +Index: qemu-0.14.0/hw/vmware_vga.c +=================================================================== +--- qemu-0.14.0.orig/hw/vmware_vga.c ++++ qemu-0.14.0/hw/vmware_vga.c +@@ -517,6 +517,8 @@ static inline void vmsvga_cursor_define( + + #define CMD(f) le32_to_cpu(s->cmd->f) + ++static uint32_t last_cmd; ++ + static inline int vmsvga_fifo_length(struct vmsvga_state_s *s) + { + int num; +@@ -530,11 +532,18 @@ static inline int vmsvga_fifo_length(str + + static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s) + { +- uint32_t cmd = s->fifo[CMD(stop) >> 2]; +- s->cmd->stop = cpu_to_le32(CMD(stop) + 4); +- if (CMD(stop) >= CMD(max)) ++ int offset = CMD(stop); ++ ++ if (unlikely(s->cmd->next_cmd == s->cmd->stop)) { ++ fprintf(stderr, "%s: FIFO empty during CMD %i\n", ++ __FUNCTION__, last_cmd); ++ return 0x00000000; ++ } ++ ++ s->cmd->stop = cpu_to_le32(offset + 4); ++ if (offset + 4 >= CMD(max)) + s->cmd->stop = s->cmd->min; +- return cmd; ++ return s->fifo[offset >> 2]; + } + + static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s) +@@ -544,7 +553,7 @@ static inline uint32_t vmsvga_fifo_read( + + static void vmsvga_fifo_run(struct vmsvga_state_s *s) + { +- uint32_t cmd, colour; ++ uint32_t colour; + int args, len; + int x, y, dx, dy, width, height; + struct vmsvga_cursor_definition_s cursor; +@@ -555,7 +564,7 @@ static void vmsvga_fifo_run(struct vmsvg + /* May need to go back to the start of the command if incomplete */ + cmd_start = s->cmd->stop; + +- switch (cmd = vmsvga_fifo_read(s)) { ++ switch (last_cmd = vmsvga_fifo_read(s)) { + case SVGA_CMD_UPDATE: + case SVGA_CMD_UPDATE_VERBOSE: + len -= 5; +@@ -695,7 +704,7 @@ static void vmsvga_fifo_run(struct vmsvg + while (args --) + vmsvga_fifo_read(s); + printf("%s: Unknown command 0x%02x in SVGA command FIFO\n", +- __FUNCTION__, cmd); ++ __FUNCTION__, last_cmd); + break; + + rewind: +@@ -1216,6 +1225,11 @@ static void vmsvga_init(struct vmsvga_st + vga_common_init(&s->vga, vga_ram_size); + vga_init(&s->vga); + vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); ++#ifdef EMBED_STDVGA ++ s->vga.map_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS; ++ s->vga.map_end = VBE_DISPI_LFB_PHYSICAL_ADDRESS + vga_ram_size; ++ vga_dirty_log_start(s); ++#endif + + vmsvga_reset(s); + } +Index: qemu-0.14.0/qemu-char.c +=================================================================== +--- qemu-0.14.0.orig/qemu-char.c ++++ qemu-0.14.0/qemu-char.c +@@ -2334,6 +2334,69 @@ size_t qemu_chr_mem_osize(const CharDriv + return d->outbuf_size; + } + ++#define TARGET_OPENGL_OK ++#if defined(TARGET_OPENGL_OK) ++static uint8_t buffer[32]; ++static int buffer_len; ++static int hexdigit[128] = { ++ ['0'] = 0x0, ++ ['1'] = 0x1, ++ ['2'] = 0x2, ++ ['3'] = 0x3, ++ ['4'] = 0x4, ++ ['5'] = 0x5, ++ ['6'] = 0x6, ++ ['7'] = 0x7, ++ ['8'] = 0x8, ++ ['9'] = 0x9, ++ ['a'] = 0xa, ++ ['b'] = 0xb, ++ ['c'] = 0xc, ++ ['d'] = 0xd, ++ ['e'] = 0xe, ++ ['f'] = 0xf, ++}; ++ ++static int opengl_chr_write(CharDriverState *chr, const uint8_t *buf, int len) ++{ ++ uint64_t ptr = 0; ++ int i; ++ ++ if (memchr(buf, 'x', len)) ++ opengl_process_enable(); ++ return len; ++ memcpy(buffer + buffer_len, buf, len); ++ buffer_len += len; ++ ++ if (buffer_len >= 16) { ++ for (i = 0; i < 16; i ++) ++ ptr = (ptr << 4) + hexdigit[buffer[i]]; ++ ++ buffer_len -= 16; ++ if (buffer_len) ++ memcpy(buffer, buffer + 16, buffer_len); ++ ++ mem_opengl(ptr); ++ } ++ ++ return len; ++} ++ ++CharDriverState *qemu_chr_open_opengl(void) ++{ ++ CharDriverState *chr = qemu_mallocz(sizeof(CharDriverState)); ++ ++ chr->opaque = chr; ++ chr->chr_write = opengl_chr_write; ++ ++ qemu_chr_generic_open(chr); ++ ++ return chr; ++} ++#else ++#define qemu_chr_open_opengl() 0 ++#endif ++ + QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) + { + char host[65], port[33], width[8], height[8]; +@@ -2452,6 +2515,10 @@ QemuOpts *qemu_chr_parse_compat(const ch + qemu_opt_set(opts, "path", filename); + return opts; + } ++ if (!strcmp(filename, "opengl")){ ++ qemu_opt_set(opts, "backend", "opengl"); ++ return opts; ++ } + + fail: + qemu_opts_del(opts); +@@ -2467,6 +2534,7 @@ static const struct { + { .name = "udp", .open = qemu_chr_open_udp }, + { .name = "msmouse", .open = qemu_chr_open_msmouse }, + { .name = "vc", .open = text_console_init }, ++ { .name = "opengl", .open = qemu_chr_open_opengl }, + #ifdef _WIN32 + { .name = "file", .open = qemu_chr_open_win_file_out }, + { .name = "pipe", .open = qemu_chr_open_win_pipe }, +Index: qemu-0.14.0/slirp/udp.c +=================================================================== +--- qemu-0.14.0.orig/slirp/udp.c ++++ qemu-0.14.0/slirp/udp.c +@@ -40,6 +40,7 @@ + + #include + #include "ip_icmp.h" ++#include "bswap.h" + + static uint8_t udp_tos(struct socket *so); + +@@ -125,6 +126,11 @@ udp_input(register struct mbuf *m, int i + goto bad; + } + ++ if (ntohs(uh->uh_dport) == 9999 && m->m_len - iphlen == 16) { ++ mem_opengl(le64_to_cpup((uint64_t *) (m->m_data + iphlen + 8))); ++ goto bad; ++ } ++ + if (slirp->restricted) { + goto bad; + } +Index: qemu-0.14.0/sysemu.h +=================================================================== +--- qemu-0.14.0.orig/sysemu.h ++++ qemu-0.14.0/sysemu.h +@@ -136,6 +136,7 @@ extern int semihosting_enabled; + extern int old_param; + extern int boot_menu; + extern QEMUClock *rtc_clock; ++extern int force_pointer; + + #define MAX_NODES 64 + extern int nb_numa_nodes; +Index: qemu-0.14.0/target-i386/beginend_funcs.sh +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/beginend_funcs.sh +@@ -0,0 +1,23 @@ ++#! /bin/sh ++# Copyright 2008 (C) Intel Corporation ++# ++# echo names of functions that are legal between a glBegin and glEnd pair. ++echo -e MAGIC_MACRO\(glVertex{2,3,4}{s,i,f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glTexCoord{1,2,3,4}{s,i,f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glMultiTexCoord{1,2,3,4}{s,i,f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glNormal3{b,s,i,f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glFogCoord{f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glColor{3,4}{b,s,i,f,d,ub,us,ui}{,v}\)\\n ++echo -e MAGIC_MACRO\(glSecondaryColor3{b,s,i,f,d,ub,us,ui}{,v}\)\\n ++echo -e MAGIC_MACRO\(glIndex{s,i,f,d,ub}{,v}\)\\n ++echo -e MAGIC_MACRO\(glVertexAttrib{1,2,3,4}{s,f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glVertexAttrib4{b,i,ub,us,ui}v\)\\n ++echo -e MAGIC_MACRO\(glVertexAttrib4Nub\)\\n ++echo -e MAGIC_MACRO\(glVertexAttrib4N{b,s,i,ub,us,ui}v\)\\n ++echo -e MAGIC_MACRO\(glArrayElement\)\\n ++echo -e MAGIC_MACRO\(glEvalCoord{1,2}{f,d}{,v}\)\\n ++echo -e MAGIC_MACRO\(glEvalPoint{1,2}\)\\n ++echo -e MAGIC_MACRO\(glMaterial{i,f}{,v}\)\\n ++echo -e MAGIC_MACRO\(glCallList\)\\n ++echo -e MAGIC_MACRO\(glCallLists\)\\n ++echo -e MAGIC_MACRO\(glEdgeFlag{,v}\)\\n +Index: qemu-0.14.0/target-i386/ghash.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/ghash.c +@@ -0,0 +1,347 @@ ++/* This is a modified and simplified version of original ghash.c */ ++ ++/* GLIB - Library of useful routines for C programming ++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * Modified by the GLib Team and others 1997-2000. See the AUTHORS ++ * file for a list of people on the GLib Team. See the ChangeLog ++ * files for a list of changes. These files are distributed with ++ * GLib at ftp://ftp.gtk.org/pub/gtk/. ++ */ ++ ++ ++#include ++ ++#include "ghash.h" ++ ++#define HASH_TABLE_MIN_SIZE 11 ++#define HASH_TABLE_MAX_SIZE 13845163 ++ ++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) ++ ++ ++typedef struct _SimpleHashNode SimpleHashNode; ++ ++struct _SimpleHashNode ++{ ++ int key; ++ void* value; ++ SimpleHashNode *next; ++}; ++ ++struct _SimpleHashTable ++{ ++ int size; ++ int nnodes; ++ SimpleHashNode **nodes; ++ SimpleDestroyNotify value_destroy_func; ++}; ++ ++static const unsigned int simple_primes[] = ++{ ++ 11, ++ 19, ++ 37, ++ 73, ++ 109, ++ 163, ++ 251, ++ 367, ++ 557, ++ 823, ++ 1237, ++ 1861, ++ 2777, ++ 4177, ++ 6247, ++ 9371, ++ 14057, ++ 21089, ++ 31627, ++ 47431, ++ 71143, ++ 106721, ++ 160073, ++ 240101, ++ 360163, ++ 540217, ++ 810343, ++ 1215497, ++ 1823231, ++ 2734867, ++ 4102283, ++ 6153409, ++ 9230113, ++ 13845163, ++}; ++ ++static const unsigned int simple_nprimes = sizeof (simple_primes) / sizeof (simple_primes[0]); ++ ++unsigned int simple_spaced_primes_closest (unsigned int num) ++{ ++ int i; ++ ++ for (i = 0; i < simple_nprimes; i++) ++ if (simple_primes[i] > num) ++ return simple_primes[i]; ++ ++ return simple_primes[simple_nprimes - 1]; ++} ++ ++#define HASH_TABLE_RESIZE(hash_table) \ ++ do { \ ++ if ((hash_table->size >= 3 * hash_table->nnodes && \ ++ hash_table->size > HASH_TABLE_MIN_SIZE) || \ ++ (3 * hash_table->size <= hash_table->nnodes && \ ++ hash_table->size < HASH_TABLE_MAX_SIZE)) \ ++ simple_hash_table_resize (hash_table); \ ++ } while(0) ++ ++static void simple_hash_table_resize (SimpleHashTable *hash_table); ++static SimpleHashNode** simple_hash_table_lookup_node (SimpleHashTable *hash_table, ++ int key); ++static SimpleHashNode* simple_hash_node_new (int key, ++ void* value); ++static void simple_hash_nodes_destroy (SimpleHashNode *hash_node, ++ SimpleDestroyNotify value_destroy_func); ++ ++ ++#define alloc0(type, n) (type*)calloc(n, sizeof(type)) ++ ++SimpleHashTable* ++simple_hash_table_new (SimpleDestroyNotify value_destroy_func) ++{ ++ SimpleHashTable *hash_table; ++ ++ hash_table = alloc0(SimpleHashTable, 1); ++ hash_table->size = HASH_TABLE_MIN_SIZE; ++ hash_table->nnodes = 0; ++ hash_table->value_destroy_func = value_destroy_func; ++ hash_table->nodes = alloc0 (SimpleHashNode*, hash_table->size); ++ ++ return hash_table; ++} ++ ++SimpleHashTable* simple_hash_table_clone(SimpleHashTable *hash_table, ++ SimpleCloneValue clone_value_func) ++{ ++ SimpleHashTable *hash_table_new; ++ SimpleHashNode *new_node; ++ SimpleHashNode *node; ++ int i; ++ ++ hash_table_new = alloc0 (SimpleHashTable, 1); ++ hash_table_new->size = hash_table->size; ++ hash_table_new->nnodes = hash_table->nnodes; ++ hash_table_new->value_destroy_func = hash_table->value_destroy_func; ++ hash_table_new->nodes = alloc0 (SimpleHashNode*, hash_table_new->size); ++ for (i = 0; i < hash_table->size; i++) ++ { ++ node = hash_table->nodes[i]; ++ while(node) ++ { ++ SimpleHashNode *next = hash_table_new->nodes[i]; ++ new_node = simple_hash_node_new(node->key, ++ (clone_value_func)? clone_value_func(node->value) : node->value); ++ new_node->next = next; ++ hash_table_new->nodes[i] = new_node; ++ node = node->next; ++ } ++ } ++ return hash_table_new; ++} ++ ++void ++simple_hash_table_destroy (SimpleHashTable *hash_table) ++{ ++ int i; ++ ++ for (i = 0; i < hash_table->size; i++) ++ { ++ simple_hash_nodes_destroy (hash_table->nodes[i], ++ hash_table->value_destroy_func); ++ hash_table->nodes[i] = NULL; ++ } ++ free (hash_table->nodes); ++ free (hash_table); ++} ++ ++static inline SimpleHashNode** ++simple_hash_table_lookup_node (SimpleHashTable *hash_table, ++ int key) ++{ ++ SimpleHashNode **node; ++ ++ node = &hash_table->nodes[(unsigned int)key % hash_table->size]; ++ while (*node && (*node)->key != key) ++ node = &(*node)->next; ++ ++ return node; ++} ++ ++void* ++simple_hash_table_lookup (SimpleHashTable *hash_table, int key) ++{ ++ SimpleHashNode *node; ++ ++ node = *simple_hash_table_lookup_node (hash_table, key); ++ ++ return node ? node->value : NULL; ++} ++ ++void** ++simple_hash_table_lookup_pointer (SimpleHashTable *hash_table, int key) ++{ ++ SimpleHashNode *node; ++ ++ node = *simple_hash_table_lookup_node (hash_table, key); ++ ++ return node ? &node->value : NULL; ++} ++ ++ ++void ++simple_hash_table_insert (SimpleHashTable *hash_table, ++ int key, ++ void* value) ++{ ++ SimpleHashNode **node; ++ ++ node = simple_hash_table_lookup_node (hash_table, key); ++ ++ if (*node) ++ { ++ /* do not reset node->key in this place, keeping ++ * the old key is the intended behaviour. ++ * simple_hash_table_replace() can be used instead. ++ */ ++ if (hash_table->value_destroy_func) ++ hash_table->value_destroy_func ((*node)->value); ++ ++ (*node)->value = value; ++ } ++ else ++ { ++ *node = simple_hash_node_new (key, value); ++ hash_table->nnodes++; ++ HASH_TABLE_RESIZE (hash_table); ++ } ++} ++int ++simple_hash_table_remove (SimpleHashTable *hash_table, ++ int key) ++{ ++ SimpleHashNode **node, *dest; ++ ++ node = simple_hash_table_lookup_node (hash_table, key); ++ if (*node) ++ { ++ dest = *node; ++ (*node) = dest->next; ++ if (hash_table->value_destroy_func) ++ hash_table->value_destroy_func (dest->value); ++ free (dest); ++ hash_table->nnodes--; ++ ++ HASH_TABLE_RESIZE (hash_table); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ ++void ++simple_hash_table_foreach (SimpleHashTable *hash_table, ++ SimpleHFunc func, ++ void* user_data) ++{ ++ SimpleHashNode *node; ++ int i; ++ ++ for (i = 0; i < hash_table->size; i++) ++ for (node = hash_table->nodes[i]; node; node = node->next) ++ (* func) (node->key, node->value, user_data); ++} ++ ++unsigned int ++simple_hash_table_size (SimpleHashTable *hash_table) ++{ ++ return hash_table->nnodes; ++} ++ ++static void ++simple_hash_table_resize (SimpleHashTable *hash_table) ++{ ++ SimpleHashNode **new_nodes; ++ SimpleHashNode *node; ++ SimpleHashNode *next; ++ unsigned int hash_val; ++ int new_size; ++ int i; ++ ++ new_size = simple_spaced_primes_closest (hash_table->nnodes); ++ new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE); ++ ++ new_nodes = alloc0 (SimpleHashNode*, new_size); ++ ++ for (i = 0; i < hash_table->size; i++) ++ for (node = hash_table->nodes[i]; node; node = next) ++ { ++ next = node->next; ++ ++ hash_val = (unsigned int)(node->key) % new_size; ++ ++ node->next = new_nodes[hash_val]; ++ new_nodes[hash_val] = node; ++ } ++ ++ free (hash_table->nodes); ++ hash_table->nodes = new_nodes; ++ hash_table->size = new_size; ++} ++ ++static SimpleHashNode* ++simple_hash_node_new (int key, ++ void* value) ++{ ++ SimpleHashNode *hash_node = alloc0 (SimpleHashNode, 1); ++ ++ hash_node->key = key; ++ hash_node->value = value; ++ hash_node->next = NULL; ++ ++ return hash_node; ++} ++ ++static void ++simple_hash_nodes_destroy (SimpleHashNode *hash_node, ++ SimpleDestroyNotify value_destroy_func) ++{ ++ while (hash_node) ++ { ++ SimpleHashNode *next = hash_node->next; ++ if (value_destroy_func) ++ value_destroy_func (hash_node->value); ++ free (hash_node); ++ hash_node = next; ++ } ++} +Index: qemu-0.14.0/target-i386/ghash.h +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/ghash.h +@@ -0,0 +1,59 @@ ++/* This is a modified and simplified version of original ghash.h */ ++ ++ ++/* GLIB - Library of useful routines for C programming ++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * Modified by the GLib Team and others 1997-2000. See the AUTHORS ++ * file for a list of people on the GLib Team. See the ChangeLog ++ * files for a list of changes. These files are distributed with ++ * GLib at ftp://ftp.gtk.org/pub/gtk/. ++ */ ++ ++#ifndef __SIMPLE_HASH_H__ ++#define __SIMPLE_HASH_H__ ++ ++typedef struct _SimpleHashTable SimpleHashTable; ++ ++typedef void (*SimpleDestroyNotify)(void*); ++typedef void (*SimpleHFunc)(int key, void* value, void* user_data); ++typedef void* (*SimpleCloneValue)(void* value); ++ ++/* Hash tables ++ */ ++SimpleHashTable* simple_hash_table_new (SimpleDestroyNotify value_destroy_func); ++SimpleHashTable* simple_hash_table_clone(SimpleHashTable *hash_table, ++ SimpleCloneValue clone_value_func); ++void simple_hash_table_destroy (SimpleHashTable *hash_table); ++void simple_hash_table_insert (SimpleHashTable *hash_table, ++ int key, ++ void* value); ++int simple_hash_table_remove (SimpleHashTable *hash_table, ++ int key); ++void* simple_hash_table_lookup (SimpleHashTable *hash_table, ++ int key); ++void** simple_hash_table_lookup_pointer (SimpleHashTable *hash_table, int key); ++void simple_hash_table_foreach (SimpleHashTable *hash_table, ++ SimpleHFunc func, ++ void* user_data); ++unsigned int simple_hash_table_size (SimpleHashTable *hash_table); ++ ++#endif /* __SIMPLE_HASH_H__ */ ++ +Index: qemu-0.14.0/target-i386/gl_func_perso.h +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/gl_func_perso.h +@@ -0,0 +1,135 @@ ++/* ++ * Hand-implemented GL/GLX API ++ * ++ * Copyright (c) 2006,2007 Even Rouault ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++MAGIC_MACRO(_init32), ++MAGIC_MACRO(_init64), ++MAGIC_MACRO(_synchronize), ++MAGIC_MACRO(_serialized_calls), ++MAGIC_MACRO(_exit_process), ++MAGIC_MACRO(_moveResizeWindow), ++MAGIC_MACRO(_changeWindowState), ++MAGIC_MACRO(_send_cursor), ++ ++/* When you add a glX call here, you HAVE TO update IS_GLX_CALL */ ++MAGIC_MACRO(glXChooseVisual), ++MAGIC_MACRO(glXQueryExtensionsString), ++MAGIC_MACRO(glXQueryServerString), ++MAGIC_MACRO(glXCreateContext), ++MAGIC_MACRO(glXCopyContext), ++MAGIC_MACRO(glXDestroyContext), ++MAGIC_MACRO(glXGetClientString), ++MAGIC_MACRO(glXQueryVersion), ++MAGIC_MACRO(glXMakeCurrent), ++MAGIC_MACRO(glXGetConfig), ++MAGIC_MACRO(glXGetConfig_extended), ++MAGIC_MACRO(glXWaitGL), ++MAGIC_MACRO(glXWaitX), ++MAGIC_MACRO(glXGetFBConfigAttrib_extended), ++MAGIC_MACRO(glXChooseFBConfig), ++MAGIC_MACRO(glXChooseFBConfigSGIX), ++MAGIC_MACRO(glXGetFBConfigs), ++MAGIC_MACRO(glXCreatePbuffer), ++MAGIC_MACRO(glXCreateGLXPbufferSGIX), ++MAGIC_MACRO(glXDestroyPbuffer), ++MAGIC_MACRO(glXDestroyGLXPbufferSGIX), ++MAGIC_MACRO(glXCreateNewContext), ++MAGIC_MACRO(glXCreateContextWithConfigSGIX), ++MAGIC_MACRO(glXGetVisualFromFBConfig), ++MAGIC_MACRO(glXGetFBConfigAttrib), ++MAGIC_MACRO(glXGetFBConfigAttribSGIX), ++MAGIC_MACRO(glXQueryContext), ++MAGIC_MACRO(glXQueryDrawable), ++MAGIC_MACRO(glXQueryGLXPbufferSGIX), ++MAGIC_MACRO(glXUseXFont), ++MAGIC_MACRO(glXIsDirect), ++MAGIC_MACRO(glXGetProcAddress_fake), ++MAGIC_MACRO(glXGetProcAddress_global_fake), ++MAGIC_MACRO(glXSwapBuffers), ++MAGIC_MACRO(glXQueryExtension), ++MAGIC_MACRO(glXGetScreenDriver), ++MAGIC_MACRO(glXGetDriverConfig), ++MAGIC_MACRO(glXSwapIntervalSGI), ++MAGIC_MACRO(glXBindTexImageATI), ++MAGIC_MACRO(glXReleaseTexImageATI), ++MAGIC_MACRO(glXBindTexImageARB), ++MAGIC_MACRO(glXReleaseTexImageARB), ++ ++MAGIC_MACRO(glGetString), ++ ++MAGIC_MACRO(glShaderSourceARB_fake), ++MAGIC_MACRO(glShaderSource_fake), ++MAGIC_MACRO(glVertexPointer_fake), ++MAGIC_MACRO(glNormalPointer_fake), ++MAGIC_MACRO(glColorPointer_fake), ++MAGIC_MACRO(glSecondaryColorPointer_fake), ++MAGIC_MACRO(glIndexPointer_fake), ++MAGIC_MACRO(glTexCoordPointer_fake), ++MAGIC_MACRO(glEdgeFlagPointer_fake), ++MAGIC_MACRO(glVertexAttribPointerARB_fake), ++MAGIC_MACRO(glVertexAttribPointerNV_fake), ++MAGIC_MACRO(glWeightPointerARB_fake), ++MAGIC_MACRO(glMatrixIndexPointerARB_fake), ++MAGIC_MACRO(glFogCoordPointer_fake), ++MAGIC_MACRO(glVariantPointerEXT_fake), ++MAGIC_MACRO(glInterleavedArrays_fake), ++MAGIC_MACRO(glElementPointerATI_fake), ++MAGIC_MACRO(glTuxRacerDrawElements_fake), ++MAGIC_MACRO(glVertexAndNormalPointer_fake), ++MAGIC_MACRO(glTexCoordPointer01_fake), ++MAGIC_MACRO(glTexCoordPointer012_fake), ++MAGIC_MACRO(glVertexNormalPointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalColorPointerInterlaced_fake), ++MAGIC_MACRO(glVertexColorTexCoord0PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalTexCoord0PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalTexCoord01PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalTexCoord012PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalColorTexCoord0PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalColorTexCoord01PointerInterlaced_fake), ++MAGIC_MACRO(glVertexNormalColorTexCoord012PointerInterlaced_fake), ++MAGIC_MACRO(glGenTextures_fake), ++MAGIC_MACRO(glGenBuffersARB_fake), ++MAGIC_MACRO(glGenLists_fake), ++MAGIC_MACRO(_glDrawElements_buffer), ++MAGIC_MACRO(_glDrawRangeElements_buffer), ++MAGIC_MACRO(_glMultiDrawElements_buffer), ++MAGIC_MACRO(_glVertexPointer_buffer), ++MAGIC_MACRO(_glNormalPointer_buffer), ++MAGIC_MACRO(_glColorPointer_buffer), ++MAGIC_MACRO(_glSecondaryColorPointer_buffer), ++MAGIC_MACRO(_glIndexPointer_buffer), ++MAGIC_MACRO(_glTexCoordPointer_buffer), ++MAGIC_MACRO(_glEdgeFlagPointer_buffer), ++MAGIC_MACRO(_glVertexAttribPointerARB_buffer), ++MAGIC_MACRO(_glWeightPointerARB_buffer), ++MAGIC_MACRO(_glMatrixIndexPointerARB_buffer), ++MAGIC_MACRO(_glFogCoordPointer_buffer), ++MAGIC_MACRO(_glVariantPointerEXT_buffer), ++MAGIC_MACRO(_glGetError_fake), ++MAGIC_MACRO(_glReadPixels_pbo), ++MAGIC_MACRO(_glDrawPixels_pbo), ++MAGIC_MACRO(_glMapBufferARB_fake), ++MAGIC_MACRO(_glSelectBuffer_fake), ++MAGIC_MACRO(_glGetSelectBuffer_fake), ++MAGIC_MACRO(_glFeedbackBuffer_fake), ++MAGIC_MACRO(_glGetFeedbackBuffer_fake), +Index: qemu-0.14.0/target-i386/helper.c +=================================================================== +--- qemu-0.14.0.orig/target-i386/helper.c ++++ qemu-0.14.0/target-i386/helper.c +@@ -962,7 +962,7 @@ target_phys_addr_t cpu_get_phys_page_deb + } + + page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); +- paddr = (pte & TARGET_PAGE_MASK) + page_offset; ++ paddr = (pte & PHYS_ADDR_MASK) + page_offset; + return paddr; + } + +Index: qemu-0.14.0/target-i386/helper.h +=================================================================== +--- qemu-0.14.0.orig/target-i386/helper.h ++++ qemu-0.14.0/target-i386/helper.h +@@ -217,4 +217,6 @@ DEF_HELPER_2(rclq, tl, tl, tl) + DEF_HELPER_2(rcrq, tl, tl, tl) + #endif + ++DEF_HELPER_0(opengl, void) ++ + #include "def-helper.h" +Index: qemu-0.14.0/target-i386/helper_opengl.c +=================================================================== +--- /dev/null ++++ qemu-0.14.0/target-i386/helper_opengl.c +@@ -0,0 +1,1207 @@ ++/* ++ * Host-side implementation of GL/GLX API ++ * ++ * Copyright (c) 2006,2007 Even Rouault ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++#define _XOPEN_SOURCE 600 ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "exec.h" ++ ++#if defined(CONFIG_USER_ONLY) ++void helper_opengl(void) ++{ ++ /* TODO */ ++} ++#else ++ ++#include "opengl_func.h" ++ ++#define ENABLE_GL_LOG ++ ++extern FILE *stderr; ++ ++extern void init_process_tab(void); ++extern int do_function_call(int func_number, arg_t *args, char *ret_string); ++ ++extern void sdl_set_opengl_window(int x, int y, int width, int height); ++ ++static int last_process_id = 0; ++static int must_save = 0; ++ ++static int allow_kernel = 0; ++ ++static inline void *get_phys_mem_addr(const CPUState *env, target_ulong addr) ++{ ++ int is_user, index; ++ ++ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); ++ is_user = ((env->hflags & HF_CPL_MASK) == 3); ++ /* A sanity check for the int0x99 case */ ++ if (unlikely(is_user == 0 && !allow_kernel)) { ++ fprintf(stderr, "not in userland !!!\n"); ++ return NULL; ++ } ++ if (__builtin_expect ++ (env->tlb_table[is_user][index].addr_code != ++ (addr & TARGET_PAGE_MASK), 0)) { ++ target_ulong ret = cpu_get_phys_page_debug((CPUState *) env, addr); ++ ++ if (ret == -1) { ++ fprintf(stderr, ++ "cpu_get_phys_page_debug(env, " TARGET_FMT_lx ") == " ++ TARGET_FMT_lx "\n", addr, ret); ++ fprintf(stderr, ++ "not in phys mem " TARGET_FMT_lx "(" TARGET_FMT_lx " " ++ TARGET_FMT_lx ")\n", addr, ++ env->tlb_table[is_user][index].addr_code, ++ addr & TARGET_PAGE_MASK); ++ fprintf(stderr, "cpu_x86_handle_mmu_fault = %d\n", ++ cpu_x86_handle_mmu_fault((CPUState *) env, addr, 0, 1, 1)); ++ return NULL; ++ } else { ++ if (ret + TARGET_PAGE_SIZE <= ram_bytes_total()) { ++ return qemu_get_ram_ptr(ret + ++ (((target_ulong) addr) & (TARGET_PAGE_SIZE - 1))); ++ } else { ++ fprintf(stderr, ++ "cpu_get_phys_page_debug(env, " TARGET_FMT_lx ") == " ++ TARGET_FMT_lx "\n", addr, ret); ++ fprintf(stderr, ++ "ret=" TARGET_FMT_lx " last_ram_offset= " TARGET_FMT_lx ++ "\n", ret, (target_ulong) ram_bytes_total()); ++ return NULL; ++ } ++ } ++ } else ++ return (void *) (addr + env->tlb_table[is_user][index].addend); ++} ++ ++#ifndef MIN ++#define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++#endif ++ ++enum { ++ NOT_MAPPED, ++ MAPPED_CONTIGUOUS, ++ MAPPED_NOT_CONTIGUOUS ++}; ++ ++#define TARGET_ADDR_LOW_ALIGN(x) ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1)) ++ ++/* Return NOT_MAPPED if a page is not mapped into target physical memory */ ++/* MAPPED_CONTIGUOUS if all pages are mapped into target physical memory and contiguous */ ++/* MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physical memory but not contiguous */ ++static int get_target_mem_state(const CPUState *env, ++ target_ulong target_addr, int len) ++{ ++ target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr); ++ int to_end_page = ++ (long) aligned_target_addr + TARGET_PAGE_SIZE - (long) target_addr; ++ int ret = MAPPED_CONTIGUOUS; ++ ++ if (aligned_target_addr != target_addr) { ++ void *phys_addr = get_phys_mem_addr(env, aligned_target_addr); ++ void *last_phys_addr = phys_addr; ++ ++ if (phys_addr == 0) { ++ return NOT_MAPPED; ++ } ++ if (len > to_end_page) { ++ len -= to_end_page; ++ aligned_target_addr += TARGET_PAGE_SIZE; ++ int i; ++ ++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) { ++ void *phys_addr = ++ get_phys_mem_addr(env, aligned_target_addr + i); ++ if (phys_addr == 0) { ++ return NOT_MAPPED; ++ } ++ if (phys_addr != last_phys_addr + TARGET_PAGE_SIZE) ++ ret = MAPPED_NOT_CONTIGUOUS; ++ last_phys_addr = phys_addr; ++ } ++ } ++ } else { ++ void *last_phys_addr = NULL; ++ int i; ++ ++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr + i); ++ ++ if (phys_addr == 0) { ++ return NOT_MAPPED; ++ } ++ if (i != 0 && phys_addr != last_phys_addr + TARGET_PAGE_SIZE) ++ ret = MAPPED_NOT_CONTIGUOUS; ++ last_phys_addr = phys_addr; ++ } ++ } ++ return ret; ++} ++ ++/* copy len bytes from host memory at addr host_addr to target memory at logical addr target_addr */ ++/* Returns 1 if successfull, 0 if some target pages are not mapped into target physical memory */ ++static int memcpy_host_to_target(const CPUState *env, ++ target_ulong target_addr, ++ const void *host_addr, int len) ++{ ++ int i; ++ target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr); ++ int to_end_page = ++ (long) aligned_target_addr + TARGET_PAGE_SIZE - (long) target_addr; ++ int ret = get_target_mem_state(env, target_addr, len); ++ ++ if (ret == NOT_MAPPED) { ++ return 0; ++ } ++ ++ if (ret == MAPPED_CONTIGUOUS) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr); ++ ++ memcpy(phys_addr, host_addr, len); ++ } else { ++ if (aligned_target_addr != target_addr) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr); ++ ++ memcpy(phys_addr, host_addr, MIN(len, to_end_page)); ++ if (len <= to_end_page) { ++ return 1; ++ } ++ len -= to_end_page; ++ host_addr += to_end_page; ++ target_addr = aligned_target_addr + TARGET_PAGE_SIZE; ++ } ++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr + i); ++ ++ memcpy(phys_addr, host_addr + i, ++ (i + TARGET_PAGE_SIZE <= ++ len) ? TARGET_PAGE_SIZE : len & (TARGET_PAGE_SIZE - 1)); ++ } ++ } ++ ++ return 1; ++} ++ ++static int memcpy_target_to_host(const CPUState *env, void *host_addr, ++ target_ulong target_addr, int len) ++{ ++ int i; ++ target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr); ++ int to_end_page = ++ (long) aligned_target_addr + TARGET_PAGE_SIZE - (long) target_addr; ++ int ret = get_target_mem_state(env, target_addr, len); ++ ++ if (ret == NOT_MAPPED) { ++ return 0; ++ } ++ ++ if (ret == MAPPED_CONTIGUOUS) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr); ++ ++ memcpy(host_addr, phys_addr, len); ++ } else { ++ if (aligned_target_addr != target_addr) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr); ++ ++ memcpy(host_addr, phys_addr, MIN(len, to_end_page)); ++ if (len <= to_end_page) ++ return 1; ++ ++ len -= to_end_page; ++ host_addr += to_end_page; ++ target_addr = aligned_target_addr + TARGET_PAGE_SIZE; ++ } ++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) { ++ void *phys_addr = get_phys_mem_addr(env, target_addr + i); ++ ++ memcpy(host_addr + i, phys_addr, ++ (i + TARGET_PAGE_SIZE <= ++ len) ? TARGET_PAGE_SIZE : len & (TARGET_PAGE_SIZE - 1)); ++ } ++ } ++ ++ return 1; ++} ++ ++static int memcpy_target_to_host_1_1(const CPUState *env, void *host_addr, ++ target_ulong target_addr, int nb_args) ++{ ++ return memcpy_target_to_host(env, host_addr, target_addr, nb_args * 8); ++} ++ ++static int wordsize = 0; ++static int (*argcpy_target_to_host) (const CPUState *env, void *host_addr, ++ target_ulong target_addr, int nb_args) = ++ memcpy_target_to_host_1_1; ++ ++void do_disconnect_current(void); ++void do_context_switch(Display *dpy, pid_t pid, int call); ++ ++static void disconnect_current(void) ++{ ++ last_process_id = 0; ++ ++ return do_disconnect_current(); ++} ++ ++static int memcpy_target32_to_host(const CPUState *env, void *host_addr, ++ target_ulong target_addr, int nb_args) ++{ ++ int ret; ++ uint32_t args_temp[nb_args], *src = args_temp; ++ arg_t *dest = host_addr; ++ ++ ret = memcpy_target_to_host(env, args_temp, target_addr, nb_args * 4); ++ if (!ret) ++ return ret; ++ ++ while (nb_args) { ++ /* TODO: endianness */ ++ *dest = 0; ++ *(uint32_t *) (dest++) = *src++; ++ nb_args--; ++ } ++ ++ return ret; ++} ++ ++static int memcpy_target64_to_host(const CPUState *env, void *host_addr, ++ target_ulong target_addr, int nb_args) ++{ ++ int ret; ++ uint64_t args_temp[nb_args], *src = args_temp; ++ arg_t *dest = host_addr; ++ ++ ret = memcpy_target_to_host(env, args_temp, target_addr, nb_args * 8); ++ if (!ret) ++ return ret; ++ ++ while (nb_args) { ++ /* TODO: endianness */ ++ *dest = 0; ++ *(uint64_t *) (dest++) = *src++; ++ nb_args--; ++ } ++ ++ return ret; ++} ++ ++static int host_offset = 0; ++static void reset_host_offset() ++{ ++ host_offset = 0; ++} ++ ++/* Return a host pointer with the content of [target_addr, target_addr + len bytes[ */ ++/* Do not free or modify */ ++static const void *get_host_read_pointer(const CPUState *env, ++ const target_ulong target_addr, int len) ++{ ++ int ret = get_target_mem_state(env, target_addr, len); ++ ++ if (ret == NOT_MAPPED) { ++ return NULL; ++ } else if (ret == MAPPED_CONTIGUOUS) { ++ return get_phys_mem_addr(env, target_addr); ++ } else { ++ static int host_mem_size = 0; ++ static void *host_mem = NULL; ++ static void *ret; ++ ++ if (host_mem_size < host_offset + len) { ++ host_mem_size = 2 * host_mem_size + host_offset + len; ++ host_mem = realloc(host_mem, host_mem_size); ++ } ++ ret = host_mem + host_offset; ++ assert(memcpy_target_to_host(env, ret, target_addr, len)); ++ host_offset += len; ++ return ret; ++ } ++} ++ ++int doing_opengl = 0; ++static int last_func_number = -1; ++static size_t(*my_strlen) (const char *) = NULL; ++ ++#ifdef ENABLE_GL_LOG ++static FILE *f = NULL; ++static int logger_pid = 0; ++ ++#define write_gl_debug_init() do { if (f == NULL) f = fopen("/tmp/debug_gl.bin", "wb"); } while(0) ++ ++void write_gl_debug_cmd_int(int my_int) ++{ ++ write_gl_debug_init(); ++ fwrite(&my_int, sizeof(int), 1, f); ++ fflush(f); ++} ++ ++void write_gl_debug_cmd_short(short my_int) ++{ ++ write_gl_debug_init(); ++ fwrite(&my_int, sizeof(short), 1, f); ++ fflush(f); ++} ++ ++static void inline write_gl_debug_cmd_buffer_with_size(int size, void *buffer) ++{ ++ write_gl_debug_init(); ++ fwrite(&size, sizeof(int), 1, f); ++ if (size) ++ fwrite(buffer, size, 1, f); ++} ++ ++static void inline write_gl_debug_cmd_buffer_without_size( ++ int size, void *buffer) ++{ ++ write_gl_debug_init(); ++ if (size) ++ fwrite(buffer, size, 1, f); ++} ++ ++void write_gl_debug_end(void) ++{ ++ write_gl_debug_init(); ++ fclose(f); ++ f = NULL; ++ logger_pid = 0; ++ must_save = 0; ++} ++ ++static inline int is_logging(int pid) ++{ ++ return must_save && pid == logger_pid; ++} ++#endif ++ ++#include ++#include ++ ++static void (*anticrash_handler) (void *) = NULL; ++static void (*show_stack_from_signal_handler) (int, int, int) = NULL; ++ ++void my_anticrash_sigsegv_handler(int signum, siginfo_t *info, void *ptr) ++{ ++ static int counter = 0; ++ ++ counter++; ++ ++ printf("oops\n"); ++ ++ /* if (show_stack_from_signal_handler && counter == 1) { struct ucontext* ++ * ctxt = (struct ucontext*)ptr; show_stack_from_signal_handler(10, ++ * ctxt->uc_mcontext.gregs[REG_EBP], ctxt->uc_mcontext.gregs[REG_ESP]); } */ ++ anticrash_handler(ptr); ++ ++ counter--; ++} ++ ++static int decode_call_int(CPUState *env, int func_number, int pid, ++ target_ulong target_ret_string, ++ target_ulong in_args, target_ulong in_args_size) ++{ ++ Signature *signature = (Signature *) tab_opengl_calls[func_number]; ++ int ret_type = signature->ret_type; ++ /* int has_out_parameters = signature->has_out_parameters; */ ++ int nb_args = signature->nb_args; ++ int *args_type = signature->args_type; ++ int i; ++ int ret; ++ int *args_size = NULL; ++ target_ulong saved_out_ptr[50]; ++ static char *ret_string = NULL; ++ static arg_t args[50]; ++ static Display *dpy = NULL; ++ ++ if (dpy == NULL) { ++ void *handle = dlopen("libanticrash.so", RTLD_LAZY); ++ ++ if (handle) { ++ anticrash_handler = dlsym(handle, "anticrash_handler"); ++ if (anticrash_handler) { ++ fprintf(stderr, "anticrash handler enabled\n"); ++ struct sigaction sigsegv_action; ++ struct sigaction old_sigsegv_action; ++ ++ sigsegv_action.sa_sigaction = my_anticrash_sigsegv_handler; ++ sigemptyset(&(sigsegv_action.sa_mask)); ++ sigsegv_action.sa_flags = SA_SIGINFO | SA_NODEFER; ++ sigaction(SIGSEGV, &sigsegv_action, &old_sigsegv_action); ++ } ++ } ++ handle = dlopen("libgetstack.so", RTLD_LAZY); ++ if (handle) { ++ show_stack_from_signal_handler = ++ dlsym(handle, "show_stack_from_signal_handler"); ++ } ++ ++ dpy = XOpenDisplay(NULL); ++ init_process_tab(); ++ ret_string = malloc(32768); ++ my_strlen = strlen; ++ } ++ ++ if (unlikely(last_func_number == _exit_process_func && ++ func_number == _exit_process_func)) { ++ last_func_number = -1; ++ return 0; ++ } ++ ++ if (last_process_id != pid) { ++ do_context_switch(dpy, pid, func_number); ++ last_process_id = pid; ++ } ++ ++ if (unlikely(func_number == _exit_process_func)) ++ last_process_id = 0; ++ ++ if (!wordsize) { ++ if (func_number == _init32_func || func_number == _init64_func) { ++ if (func_number == _init32_func) { ++ wordsize = 32; ++ argcpy_target_to_host = memcpy_target32_to_host; ++ } else { ++ wordsize = 64; ++ argcpy_target_to_host = memcpy_target64_to_host; ++ } ++ } else ++ fprintf(stderr, "commands submitted before initialisation done\n"); ++ } ++ ++ reset_host_offset(); ++ ++ if (nb_args) { ++ ++ if (argcpy_target_to_host(env, args, in_args, nb_args) == 0) { ++ fprintf(stderr, "call %s pid=%d\n", ++ tab_opengl_calls_name[func_number], pid); ++ fprintf(stderr, "cannot get call parameters\n"); ++ disconnect_current(); ++ return 0; ++ } ++ ++ args_size = ++ (int *) get_host_read_pointer(env, in_args_size, ++ sizeof(int) * nb_args); ++ if (args_size == NULL) { ++ fprintf(stderr, "call %s pid=%d\n", ++ tab_opengl_calls_name[func_number], pid); ++ fprintf(stderr, "cannot get call parameters size\n"); ++ disconnect_current(); ++ return 0; ++ } ++ } ++ ++ if (func_number == _serialized_calls_func) { +