summaryrefslogtreecommitdiffstats
path: root/meta/recipes-graphics/mesa/qemugl/call_opengl_fix.patch
blob: 342f49b717000d1bfc096965b101b83bf3dde9b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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 <edwin.zhai@intel.com>
Index: git/opengl_client.c
===================================================================
--- git.orig/opengl_client.c	2012-02-28 15:26:28.000000000 +0800
+++ git/opengl_client.c	2012-02-28 15:29:18.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");
@@ -1100,20 +1106,27 @@
   return ret;
 #elif defined(__x86_64__)
   int ret;
-  __asm__ ("push %rbx");
-  __asm__ ("push %rcx");
-  __asm__ ("push %rdx");
-  __asm__ ("push %rsi");
+  long bx, cx, dx, si;
+
+  /* save registers before opengl call */
+  __asm__ ("mov %%rbx, %0"::"m"(bx));
+  __asm__ ("mov %%rcx, %0"::"m"(cx));
+  __asm__ ("mov %%rdx, %0"::"m"(dx));
+  __asm__ ("mov %%rsi, %0"::"m"(si));
+
   __asm__ ("mov %0, %%eax"::"m"(func_number));
   __asm__ ("mov %0, %%ebx"::"m"(pid));
   __asm__ ("mov %0, %%rcx"::"m"(ret_string));
   __asm__ ("mov %0, %%rdx"::"m"(args));
   __asm__ ("mov %0, %%rsi"::"m"(args_size));
   __asm__ ("int $0x99");
-  __asm__ ("pop %rsi");
-  __asm__ ("pop %rdx");
-  __asm__ ("pop %rcx");
-  __asm__ ("pop %rbx");
+
+  /* restore registers */
+  __asm__ ("mov %0, %%rbx"::"m"(bx));
+  __asm__ ("mov %0, %%rcx"::"m"(cx));
+  __asm__ ("mov %0, %%rdx"::"m"(dx));
+  __asm__ ("mov %0, %%rsi"::"m"(si));
+
   __asm__ ("mov %%eax, %0"::"m"(ret));
   return ret;
 #else