Save registers via local variables instead of simple "push", so that gcc become aware of this operation and avoid stack disorder. opengl calling (in call_opengl_qemu) includes 4 steps: 1. prepare opengl parameters on stack 2. save some "input" register by push 3. load "input" register with parameters on stack via same index as step 1 4. issue "int 0x99" to trap into qemu, who will get parameter in the registers New gcc uses "%esp" rather than "%ebp" to index local variable in stack, which leads wrong index in step 3, as push decrease "%esp" automatically. Saving registers via local variables to fix it. Upstream-Status: Pending Signed-off-by: Zhai Edwin Index: git/opengl_client.c =================================================================== --- git.orig/opengl_client.c 2011-09-19 19:44:51.000000000 +0800 +++ git/opengl_client.c 2011-09-22 10:11:04.000000000 +0800 @@ -1076,23 +1076,29 @@ { #if defined(__i386__) int ret; + int bx, cx, dx, si; #ifdef WIN32 __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (win32_sigsegv_handler)); #endif - __asm__ ("push %ebx"); - __asm__ ("push %ecx"); - __asm__ ("push %edx"); - __asm__ ("push %esi"); + /* save registers before opengl call */ + __asm__ ("mov %%ebx, %0"::"m"(bx)); + __asm__ ("mov %%ecx, %0"::"m"(cx)); + __asm__ ("mov %%edx, %0"::"m"(dx)); + __asm__ ("mov %%esi, %0"::"m"(si)); + __asm__ ("mov %0, %%eax"::"m"(func_number)); __asm__ ("mov %0, %%ebx"::"m"(pid)); __asm__ ("mov %0, %%ecx"::"m"(ret_string)); __asm__ ("mov %0, %%edx"::"m"(args)); __asm__ ("mov %0, %%esi"::"m"(args_size)); __asm__ ("int $0x99"); - __asm__ ("pop %esi"); - __asm__ ("pop %edx"); - __asm__ ("pop %ecx"); - __asm__ ("pop %ebx"); + + /* restore registers */ + __asm__ ("mov %0, %%ebx"::"m"(bx)); + __asm__ ("mov %0, %%ecx"::"m"(cx)); + __asm__ ("mov %0, %%edx"::"m"(dx)); + __asm__ ("mov %0, %%esi"::"m"(si)); + __asm__ ("mov %%eax, %0"::"m"(ret)); #ifdef WIN32 __asm__ ("movl (%%esp),%%ecx;movl %%ecx,%%fs:0;addl $8,%%esp;" : : : "%ecx");