Initialize
[sdk/emulator/qemu.git] / target-i386 / helper_opengl.c
1 /*
2  *  Host-side implementation of GL/GLX API
3  * 
4  *  Copyright (c) 2006,2007 Even Rouault
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 #ifdef _WIN32
26 #ifndef _GNU_SOURCE
27     #define _GNU_SOURCE
28 #endif
29 #endif
30
31 #define _XOPEN_SOURCE 600
32
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <assert.h>
37 #include <string.h>
38 #include "exec.h"
39
40 #ifndef _WIN32
41 #include <X11/Xlib.h>
42 #include <X11/Xutil.h>
43 #else
44 #include <windows.h>
45
46 typedef HDC GLDisplay;
47 HWND displayHWND;
48 #endif
49
50 //## remove GCC warning
51 //#include "qemu-common.h"
52 //#include "opengl_func.h"
53 #include "helper_opengl.h"
54
55 #define ENABLE_GL_LOG
56
57 //#ifdef _WIN32
58 //extern int do_function_call(Display dpy, int func_number, int pid, int* args, char* ret_string);
59 //#else
60 //extern int do_function_call(Display* dpy, int func_number, int pid, int* args, char* ret_string);
61 //#endif
62 extern int last_process_id;
63
64 #ifndef _WIN32
65 extern void sdl_set_opengl_window(int x, int y, int width, int height);
66 #endif
67
68 #ifdef _WIN32
69 static GLDisplay CreateDisplay(void)
70 {
71   HWND        hWnd;
72   WNDCLASS    wc;
73   LPCSTR       ClassName ="DISPLAY";
74   HINSTANCE hInstance = 0;
75
76   /* only register the window class once - use hInstance as a flag. */
77   hInstance = GetModuleHandle(NULL);
78   wc.style         = CS_OWNDC;
79   wc.lpfnWndProc   = (WNDPROC)DefWindowProc;
80   wc.cbClsExtra    = 0;
81   wc.cbWndExtra    = 0;
82   wc.hInstance     = hInstance;
83   wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
84   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
85   wc.hbrBackground = NULL;
86   wc.lpszMenuName  = NULL;
87   wc.lpszClassName = ClassName;
88
89   RegisterClass(&wc);
90
91   displayHWND = CreateWindow(ClassName, ClassName, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU ),
92   0, 0, 10, 10, NULL, (HMENU)NULL, hInstance, NULL);
93
94
95   ShowWindow(hWnd, SW_HIDE);
96
97   return GetDC(displayHWND);
98 }
99 #endif
100
101 static int must_save = 0;
102
103 static inline void* get_phys_mem_addr(const CPUState *env, target_ulong addr)
104 {
105 #if 1
106   void *ret;
107   ret = qemu_get_ram_ptr(addr);  
108
109   return ret;
110 #endif
111 #if 0
112   int is_user, index;
113   index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
114   is_user = ((env->hflags & HF_CPL_MASK) == 3);
115   if (is_user == 0)
116   {
117     fprintf(stderr, "not in userland !!!\n");
118     return NULL;
119   }
120   if (__builtin_expect(env->tlb_table[is_user][index].addr_code != 
121       (addr & TARGET_PAGE_MASK), 0))
122   {
123     target_ulong ret = cpu_get_phys_page_debug((CPUState *)env, addr);
124     if (ret == -1)
125     {
126       fprintf(stderr, "cpu_get_phys_page_debug(env, %x) == %x\n", addr, ret);
127       fprintf(stderr, "not in phys mem %x (%x %x)\n", addr, env->tlb_table[is_user][index].addr_code, addr & TARGET_PAGE_MASK);
128       fprintf(stderr, "cpu_x86_handle_mmu_fault = %d\n",
129               cpu_x86_handle_mmu_fault((CPUState*)env, addr, 0, 1, 1));
130       return NULL;
131     }
132     else
133     {
134       if (ret + TARGET_PAGE_SIZE <= ldl_phys(0))
135       {
136         //return phys_ram_base + ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1));
137         //return qemu_get_buffer(ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1)));
138                 //return ldl_phys(0) + ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1));
139         return qemu_get_ram_ptr(ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1)));
140       }
141       else
142       {
143         fprintf(stderr, "cpu_get_phys_page_debug(env, %x) == %xp\n", addr, ret);
144         //fprintf(stderr, "ret=%x phys_ram_size=%x\n", ret, phys_ram_size);
145         fprintf(stderr, "ret=%x ldl_phys(0)=%x\n", ret, ldl_phys(0));
146         return NULL;
147       }
148     }
149   }
150   else
151   {
152     return (void*)(addr + env->tlb_table[is_user][index].addend);
153   }
154 #endif    
155 }
156 #ifndef MIN
157 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
158 #endif
159
160 enum
161 {
162   NOT_MAPPED,
163   MAPPED_CONTIGUOUS,
164   MAPPED_NOT_CONTIGUOUS
165 };
166
167 #define TARGET_ADDR_LOW_ALIGN(x)  ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1))
168
169 /* Return NOT_MAPPED if a page is not mapped into target physical memory */
170 /*        MAPPED_CONTIGUOUS if all pages are mapped into target physical memory and contiguous */
171 /*        MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physical memory but not contiguous */
172 static int get_target_mem_state(const CPUState *env, target_ulong target_addr, int len)
173 {
174   target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr);
175   int to_end_page = (long)aligned_target_addr + TARGET_PAGE_SIZE - (long)target_addr;
176   int ret = MAPPED_CONTIGUOUS;
177   
178   if (aligned_target_addr != target_addr)
179   {
180     void* phys_addr = get_phys_mem_addr(env, aligned_target_addr);
181     void* last_phys_addr = phys_addr;
182     if (phys_addr == 0)
183     {
184       return NOT_MAPPED;
185     }
186     if (len > to_end_page)
187     {
188       len -= to_end_page;
189       aligned_target_addr += TARGET_PAGE_SIZE;
190       int i;
191       for(i=0;i<len;i+=TARGET_PAGE_SIZE)
192       {
193         void* phys_addr = get_phys_mem_addr(env, aligned_target_addr + i);
194         if (phys_addr == 0)
195         {
196           return NOT_MAPPED;
197         }
198         if (phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
199           ret = MAPPED_NOT_CONTIGUOUS;
200         last_phys_addr = phys_addr;
201       }
202     }
203   }
204   else
205   {
206     void* last_phys_addr = NULL;
207     int i;
208     for(i=0;i<len;i+=TARGET_PAGE_SIZE)
209     {
210       void* phys_addr = get_phys_mem_addr(env, target_addr + i);
211       if (phys_addr == 0)
212       {
213         return NOT_MAPPED;
214       }
215       if (i != 0 && phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
216           ret = MAPPED_NOT_CONTIGUOUS;
217       last_phys_addr = phys_addr;
218     }
219   }
220   return ret;
221 }
222
223 /* copy len bytes from host memory at addr host_addr to target memory at logical addr target_addr */
224 /* Returns 1 if successfull, 0 if some target pages are not mapped into target physical memory */
225 static int memcpy_host_to_target(const CPUState *env, target_ulong target_addr, const void* host_addr, int len)
226 {
227   int i;
228   target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr);
229   int to_end_page = (long)aligned_target_addr + TARGET_PAGE_SIZE - (long)target_addr;
230   int ret = get_target_mem_state(env, target_addr, len);
231   if (ret == NOT_MAPPED)
232   {
233     return 0;
234   }
235   
236   if (ret == MAPPED_CONTIGUOUS)
237   {
238     void *phys_addr = get_phys_mem_addr(env, target_addr);
239     memcpy(phys_addr, host_addr, len);
240   }
241   else
242   {
243     if (aligned_target_addr != target_addr)
244     {
245       void* phys_addr = get_phys_mem_addr(env, target_addr);
246       memcpy(phys_addr, host_addr, MIN(len, to_end_page));
247       if (len <= to_end_page)
248       {
249         return 1;
250       }
251       len -= to_end_page;
252       host_addr += to_end_page;
253       target_addr = aligned_target_addr + TARGET_PAGE_SIZE;
254     }
255     for(i=0;i<len;i+=TARGET_PAGE_SIZE)
256     {
257       void *phys_addr = get_phys_mem_addr(env, target_addr + i);
258       memcpy(phys_addr, host_addr + i, (i + TARGET_PAGE_SIZE <= len) ? TARGET_PAGE_SIZE : len & (TARGET_PAGE_SIZE - 1));
259     }
260   }
261   
262   return 1;
263 }
264
265 static int memcpy_target_to_host(const CPUState *env, void* host_addr, target_ulong target_addr, int len)
266 {
267   int i;
268   target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr);
269   int to_end_page = (long)aligned_target_addr + TARGET_PAGE_SIZE - (long)target_addr;
270   int ret = get_target_mem_state(env, target_addr, len);
271   if (ret == NOT_MAPPED)
272   {
273     return 0;
274   }
275   
276   if (ret == MAPPED_CONTIGUOUS)
277   {
278     void *phys_addr = get_phys_mem_addr(env, target_addr);
279     memcpy(host_addr, phys_addr, len);
280   }
281   else
282   {
283     if (aligned_target_addr != target_addr)
284     {
285       void* phys_addr = get_phys_mem_addr(env, target_addr);
286       memcpy(host_addr, phys_addr, MIN(len, to_end_page));
287       if (len <= to_end_page)
288       {
289         return 1;
290       }
291       len -= to_end_page;
292       host_addr += to_end_page;
293       target_addr = aligned_target_addr + TARGET_PAGE_SIZE;
294     }
295     for(i=0;i<len;i+=TARGET_PAGE_SIZE)
296     {
297       void *phys_addr = get_phys_mem_addr(env, target_addr + i);
298       memcpy(host_addr + i, phys_addr, (i + TARGET_PAGE_SIZE <= len) ? TARGET_PAGE_SIZE : len & (TARGET_PAGE_SIZE - 1));
299     }
300   }
301   
302   return 1;
303 }
304
305 static int host_offset = 0;
306 static void reset_host_offset(void)
307 {
308   host_offset = 0;
309 }
310
311 /* Return a host pointer with the content of [target_addr, target_addr + len bytes[ */
312 /* Do not free or modify */
313 static const void* get_host_read_pointer(const CPUState *env, const target_ulong target_addr, int len)
314 {
315   int ret = get_target_mem_state(env, target_addr, len);
316   if (ret == NOT_MAPPED)
317   {
318     return NULL;
319   }
320   else if (ret == MAPPED_CONTIGUOUS)
321   {
322     return get_phys_mem_addr(env, target_addr);
323   }
324   else
325   {
326     static int host_mem_size = 0;
327     static void* host_mem = NULL;
328     static void* ret;
329     if (host_mem_size < host_offset + len)
330     {
331       host_mem_size = 2 * host_mem_size + host_offset + len;
332       host_mem = realloc(host_mem, host_mem_size);
333     }
334     ret = host_mem + host_offset;
335     assert(memcpy_target_to_host(env, ret, target_addr, len));
336     host_offset += len;
337     return ret;
338   }
339 }
340  
341 int doing_opengl = 0;
342 static int last_func_number = -1;
343 static size_t (*my_strlen)(const char*) = NULL;
344
345 #ifdef ENABLE_GL_LOG
346 static FILE* f = NULL;
347
348 #define write_gl_debug_init() do { if (f == NULL) f = fopen("/tmp/debug_gl.bin", "wb"); } while(0)
349
350 static int write_gl_debug_cmd_int(int my_int)
351 {
352   int r;
353   write_gl_debug_init();
354   r = fwrite(&my_int, sizeof(int), 1, f);
355   fflush(f);
356   return r;
357 }
358
359 static int write_gl_debug_cmd_short(int my_int)
360 {
361   int r;
362   write_gl_debug_init();
363   r = fwrite(&my_int, sizeof(short), 1, f);
364   fflush(f);
365   return r;
366 }
367
368 inline static int write_gl_debug_cmd_buffer_with_size(int size, void* buffer)
369 {
370   int r;
371   write_gl_debug_init();
372   r = fwrite(&size, sizeof(int), 1, f);
373   if (size)
374     r += fwrite(buffer, size, 1, f);
375   return r;
376 }
377
378 inline static int write_gl_debug_cmd_buffer_without_size(int size, void* buffer)
379 {
380   int r = 0;
381   write_gl_debug_init();
382   if (size)
383     r = fwrite(buffer, size, 1, f);
384   return r;
385 }
386
387 static void write_gl_debug_end(void)
388 {
389   write_gl_debug_init();
390   fclose(f);
391   f = NULL;
392 }
393
394 #endif
395
396
397 #if !defined( _WIN32 )   /* by    12.Nov.2009 */
398 #include <dlfcn.h>
399 #include <signal.h>
400
401 static void (*anticrash_handler)(void*) = NULL;
402 static void (*show_stack_from_signal_handler)(int, int, int) = NULL;
403
404 static void my_anticrash_sigsegv_handler(int signum, siginfo_t* info, void* ptr)
405 {
406   static int counter = 0;
407   counter++;
408   
409   printf("oops\n");
410   
411   /*if (show_stack_from_signal_handler && counter == 1)
412   {
413     struct ucontext* ctxt = (struct ucontext*)ptr;
414     show_stack_from_signal_handler(10, ctxt->uc_mcontext.gregs[REG_EBP], ctxt->uc_mcontext.gregs[REG_ESP]);
415   }*/
416   anticrash_handler(ptr);
417
418   counter--;
419 }
420 #endif
421
422 #ifdef _WIN32
423
424 static int decode_call_int(CPUState *env, int func_number, int pid, target_ulong target_ret_string,
425                            target_ulong in_args, target_ulong in_args_size)
426 {
427   Signature* signature = (Signature*)tab_opengl_calls[func_number];
428   int ret_type = signature->ret_type;
429   //int has_out_parameters = signature->has_out_parameters;
430   int nb_args = signature->nb_args;
431   int* args_type = signature->args_type;
432   int i;
433   int ret;
434   int* args_size = NULL;
435   target_ulong saved_out_ptr[50];
436   static char* ret_string = NULL;
437   static target_ulong args[50];
438   static GLDisplay dpy = 0;
439
440   if (last_func_number == _exit_process_func && func_number == _exit_process_func)
441   {
442     last_func_number = -1;
443     return 0;
444   }
445
446 #if 0
447   if (last_process_id == 0)
448   {
449     last_process_id = pid;
450   }
451   else if (last_process_id != pid)
452   {
453     fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n");
454     return 0;
455   }
456 #else
457   last_process_id = pid;
458 #endif
459
460   if (dpy == NULL)
461   {
462     dpy = CreateDisplay();
463     //init_process_tab();
464     create_process_tab(NULL);
465
466     ret_string = malloc(32768);
467     my_strlen = strlen;
468   }
469
470   reset_host_offset();
471
472   if (nb_args)
473   {
474     if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0)
475     {
476       fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
477       fprintf(stderr, "cannot get call parameters\n");
478       last_process_id = 0;
479       return 0;
480     }
481
482     args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args);
483     if (args_size == NULL)
484     {
485       fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
486       fprintf(stderr, "cannot get call parameters size\n");
487       last_process_id = 0;
488       return 0;
489     }
490   }
491
492   if (func_number == _serialized_calls_func)
493   {
494     int command_buffer_size = args_size[0];
495     const void* command_buffer = get_host_read_pointer(env, args[0], command_buffer_size);
496     int commmand_buffer_offset = 0;
497     args_size = NULL;
498 #ifdef ENABLE_GL_LOG
499     if (must_save) write_gl_debug_cmd_short(_serialized_calls_func);
500 #endif
501
502     while(commmand_buffer_offset < command_buffer_size)
503     {
504       func_number = *(short*)(command_buffer + commmand_buffer_offset);
505       if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
506       {
507         fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed at "
508                         "commmand_buffer_offset=%d (command_buffer_size=%d)\n",
509                         commmand_buffer_offset, command_buffer_size);
510         return 0;
511       }
512       commmand_buffer_offset += sizeof(short);
513 #ifdef ENABLE_GL_LOG
514       if (must_save) write_gl_debug_cmd_short(func_number);
515 #endif
516
517       signature = (Signature*)tab_opengl_calls[func_number];
518       ret_type = signature->ret_type;
519       assert(ret_type == TYPE_NONE);
520       nb_args = signature->nb_args;
521       args_type = signature->args_type;
522
523       for(i=0;i<nb_args;i++)
524       {
525         switch(args_type[i])
526         {
527           case TYPE_UNSIGNED_INT:
528           case TYPE_INT:
529           case TYPE_UNSIGNED_CHAR:
530           case TYPE_CHAR:
531           case TYPE_UNSIGNED_SHORT:
532           case TYPE_SHORT:
533           case TYPE_FLOAT:
534           {
535             args[i] = *(int*)(command_buffer + commmand_buffer_offset);
536 #ifdef ENABLE_GL_LOG
537             if (must_save) write_gl_debug_cmd_int(args[i]);
538 #endif
539             commmand_buffer_offset += sizeof(int);
540             break;
541           }
542
543           case TYPE_NULL_TERMINATED_STRING:
544           CASE_IN_UNKNOWN_SIZE_POINTERS:
545           {
546             int arg_size = *(int*)(command_buffer + commmand_buffer_offset);
547             commmand_buffer_offset += sizeof(int);
548
549             if (arg_size == 0)
550             {
551               args[i] = 0;
552             }
553             else
554             {
555               args[i] = (long)(command_buffer + commmand_buffer_offset);
556             }
557
558             if (args[i] == 0)
559             {
560               if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
561               {
562                 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
563                 last_process_id = 0;
564                 return 0;
565               }
566             }
567             else
568             {
569               if (arg_size == 0)
570               {
571                 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
572                 fprintf(stderr, "args_size[i] == 0 !!\n");
573                 last_process_id = 0;
574                 return 0;
575               }
576             }
577 #ifdef ENABLE_GL_LOG
578             if (must_save) write_gl_debug_cmd_buffer_with_size(arg_size, (void*)args[i]);
579 #endif
580             commmand_buffer_offset += arg_size;
581
582             break;
583           }
584
585           CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
586           {
587             int arg_size = compute_arg_length(stderr, func_number, i, args);
588             args[i] = (arg_size) ? (long)(command_buffer + commmand_buffer_offset) : 0;
589 #ifdef ENABLE_GL_LOG
590             if (must_save) write_gl_debug_cmd_buffer_without_size(arg_size, (void*)args[i]);
591 #endif
592             commmand_buffer_offset += arg_size;
593             break;
594           }
595
596           CASE_OUT_POINTERS:
597           {
598             fprintf(stderr, "shouldn't happen TYPE_OUT_xxxx : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
599             last_process_id = 0;
600             return 0;
601             break;
602           }
603
604         case TYPE_DOUBLE:
605         CASE_IN_KNOWN_SIZE_POINTERS:
606             args[i] = (long)(command_buffer + commmand_buffer_offset);
607 #ifdef ENABLE_GL_LOG
608             if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
609 #endif
610             commmand_buffer_offset += tab_args_type_length[args_type[i]];
611             break;
612
613           case TYPE_IN_IGNORED_POINTER:
614             args[i] = 0;
615             break;
616
617           default:
618             fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
619             last_process_id = 0;
620             return 0;
621             break;
622         }
623       }
624       do_function_call(dpy, func_number, pid, args, ret_string);
625     }
626
627     ret = 0;
628   }
629   else
630   {
631 #ifdef ENABLE_GL_LOG
632     if (must_save) write_gl_debug_cmd_short(func_number);
633 #endif
634
635     for(i=0;i<nb_args;i++)
636     {
637       switch(args_type[i])
638       {
639         case TYPE_UNSIGNED_INT:
640         case TYPE_INT:
641         case TYPE_UNSIGNED_CHAR:
642         case TYPE_CHAR:
643         case TYPE_UNSIGNED_SHORT:
644         case TYPE_SHORT:
645         case TYPE_FLOAT:
646 #ifdef ENABLE_GL_LOG
647           if (must_save) write_gl_debug_cmd_int(args[i]);
648 #endif
649           break;
650
651         case TYPE_NULL_TERMINATED_STRING:
652         CASE_IN_UNKNOWN_SIZE_POINTERS:
653           if (args[i] == 0 && args_size[i] == 0)
654           {
655             if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
656             {
657               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
658               last_process_id = 0;
659               return 0;
660             }
661           }
662           else if (args[i] == 0 && args_size[i] != 0)
663           {
664             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
665             fprintf(stderr, "args[i] == 0 && args_size[i] != 0 !!\n");
666             last_process_id = 0;
667             return 0;
668           }
669           else if (args[i] != 0 && args_size[i] == 0)
670           {
671             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
672             fprintf(stderr, "args[i] != 0 && args_size[i] == 0 !!\n");
673             last_process_id = 0;
674             return 0;
675           }
676           if (args[i])
677           {
678             args[i] = (target_ulong)get_host_read_pointer(env, args[i], args_size[i]);
679             if (args[i] == 0)
680             {
681               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
682               fprintf(stderr, "can not get %d bytes\n", args_size[i]);
683               last_process_id = 0;
684               return 0;
685             }
686           }
687 #ifdef ENABLE_GL_LOG
688           if (must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]);
689 #endif
690           break;
691
692         CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
693         {
694           args_size[i] = compute_arg_length(stderr, func_number, i, args);
695           args[i] = (args_size[i]) ? (target_ulong)get_host_read_pointer(env, args[i], args_size[i]) : 0;
696           if (args[i] == 0 && args_size[i] != 0)
697           {
698             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
699             fprintf(stderr, "can not get %d bytes\n", args_size[i]);
700             last_process_id = 0;
701             return 0;
702           }
703 #ifdef ENABLE_GL_LOG
704           if (must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]);
705 #endif
706           break;
707         }
708
709         CASE_OUT_POINTERS:
710         {
711           int mem_state;
712 #ifdef ENABLE_GL_LOG
713           if (must_save)
714           {
715             switch(args_type[i])
716             {
717               CASE_OUT_UNKNOWN_SIZE_POINTERS:
718                 write_gl_debug_cmd_int(args_size[i]);
719                 break;
720
721               default:
722                 break;
723             }
724           }
725 #endif
726
727           if (func_number == glXQueryExtension_func && args[i] == 0)
728           {
729             saved_out_ptr[i] = 0;
730             continue;
731           }
732           if (args[i] == 0 && args_size[i] == 0)
733           {
734             if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
735             {
736               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
737               last_process_id = 0;
738               return 0;
739             }
740             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
741             last_process_id = 0;
742             return 0;
743           }
744           else if (args[i] == 0 && args_size[i] != 0)
745           {
746             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
747             fprintf(stderr, "args[i] == 0 && args_size[i] != 0 !!\n");
748             last_process_id = 0;
749             return 0;
750           }
751           else if (args[i] != 0 && args_size[i] == 0)
752           {
753             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
754             fprintf(stderr, "args[i] != 0 && args_size[i] == 0 !!\n");
755             last_process_id = 0;
756             return 0;
757           }
758           if (args[i])
759           {
760             mem_state = get_target_mem_state(env, args[i], args_size[i]);
761             if (mem_state == NOT_MAPPED)
762             {
763               fprintf(stderr, "call %s arg %d pid=%d addr=%x size=%d NOT_MAPPED\n", tab_opengl_calls_name[func_number], i, pid, args[i], args_size[i]);
764               last_process_id = 0;
765               return 0;
766             }
767             else if (mem_state == MAPPED_CONTIGUOUS)
768             {
769               saved_out_ptr[i] = 0;
770               args[i] = (target_ulong)get_phys_mem_addr(env, args[i]);
771             }
772             else
773             {
774               saved_out_ptr[i] = args[i];
775               args[i] = (target_ulong)malloc(args_size[i]);
776             }
777           }
778           else
779           {
780             saved_out_ptr[i] = 0;
781           }
782           break;
783         }
784
785         case TYPE_DOUBLE:
786         CASE_IN_KNOWN_SIZE_POINTERS:
787           if (args[i] == 0)
788           {
789             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
790             fprintf(stderr, "can not get %d bytes\n", tab_args_type_length[args_type[i]]);
791             last_process_id = 0;
792             return 0;
793           }
794           args[i] = (int)get_host_read_pointer(env, args[i], tab_args_type_length[args_type[i]]);
795           if (args[i] == 0)
796           {
797             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
798             fprintf(stderr, "can not get %d bytes\n", tab_args_type_length[args_type[i]]);
799             last_process_id = 0;
800             return 0;
801           }
802 #ifdef ENABLE_GL_LOG
803           if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
804 #endif
805           break;
806
807         case TYPE_IN_IGNORED_POINTER:
808           args[i] = 0;
809           break;
810
811         default:
812           fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
813           last_process_id = 0;
814           return 0;
815           break;
816       }
817     }
818
819     if (ret_type == TYPE_CONST_CHAR)
820     {
821       ret_string[0] = 0;
822     }
823
824     /*if (func_number == glDrawElements_func)
825     {
826       fprintf(stderr, "glDrawElements_func %d %d %d %X\n", args[0], args[1], args[2], args[3]);
827     }*/
828
829     if (func_number == _init_func)
830     {
831        must_save = args[0];
832 #if 0
833 #ifdef USE_KQEMU
834        if (env->kqemu_enabled)
835          *(int*)args[1] = 2;
836        else
837 #endif
838 #endif
839          *(int*)args[1] = 1;
840        ret = 0;
841     }
842     else
843     {
844       ret = do_function_call(dpy, func_number, pid, args, ret_string);
845     }
846 #ifdef ENABLE_GL_LOG
847     if (must_save && func_number == glXGetVisualFromFBConfig_func)
848     {
849       write_gl_debug_cmd_int(ret);
850     }
851 #endif
852     for(i=0;i<nb_args;i++)
853     {
854       switch(args_type[i])
855       {
856         CASE_OUT_POINTERS:
857         {
858           if (saved_out_ptr[i])
859           {
860             if (memcpy_host_to_target(env, saved_out_ptr[i], (void*)args[i], args_size[i]) == 0)
861             {
862               fprintf(stderr, "cannot copy out parameters back to user space\n");
863               last_process_id = 0;
864               return 0;
865             }
866             free((void*)args[i]);
867           }
868           break;
869         }
870
871         default:
872           break;
873       }
874     }
875
876     if (ret_type == TYPE_CONST_CHAR)
877     {
878       if (target_ret_string)
879       {
880         /* the my_strlen stuff is a hack to workaround a GCC bug if using directly strlen... */
881         if (memcpy_host_to_target(env, target_ret_string, ret_string, my_strlen(ret_string) + 1) == 0)
882         {
883           fprintf(stderr, "cannot copy out parameters back to user space\n");
884           last_process_id = 0;
885           return 0;
886         }
887       }
888     }
889   }
890
891 #ifdef ENABLE_GL_LOG
892   if (must_save && func_number == _exit_process_func)
893   {
894     write_gl_debug_end();
895   }
896 #endif
897
898   return ret;
899 }
900
901 #else
902
903 static int decode_call_int(CPUState *env, int func_number, int pid, target_ulong target_ret_string,
904                            target_ulong in_args, target_ulong in_args_size)
905 {
906   Signature* signature = (Signature*)tab_opengl_calls[func_number];
907   int ret_type = signature->ret_type;
908   //int has_out_parameters = signature->has_out_parameters;
909   int nb_args = signature->nb_args;
910   int* args_type = signature->args_type;
911   int i;
912   int ret;
913   int* args_size = NULL;
914   target_ulong saved_out_ptr[50];
915   static char* ret_string = NULL;
916   static target_ulong args[50];
917   static Display* dpy = NULL;
918
919   if (last_func_number == _exit_process_func && func_number == _exit_process_func)
920   {
921     last_func_number = -1;
922     return 0;
923   }
924   
925   #if 0
926   if (last_process_id == 0)
927   {
928     last_process_id = pid;
929   }
930   else if (last_process_id != pid)
931   {
932     fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n");
933     return 0;
934   }
935   #else
936   last_process_id = pid;
937   #endif
938       
939   if (dpy == NULL)
940   {
941     void *handle = dlopen("libanticrash.so", RTLD_LAZY);
942     if (handle)
943     {
944       anticrash_handler = dlsym(handle, "anticrash_handler");
945       if (anticrash_handler)
946       {
947         fprintf(stderr, "anticrash handler enabled\n");
948         struct sigaction sigsegv_action;
949         struct sigaction old_sigsegv_action;
950       
951         sigsegv_action.sa_sigaction = my_anticrash_sigsegv_handler;
952         sigemptyset(&(sigsegv_action.sa_mask));
953         sigsegv_action.sa_flags = SA_SIGINFO | SA_NOMASK;
954         sigaction(SIGSEGV, &sigsegv_action, &old_sigsegv_action);
955       }
956     }
957     handle = dlopen("libgetstack.so", RTLD_LAZY);
958     if (handle)
959     {
960       show_stack_from_signal_handler = dlsym(handle, "show_stack_from_signal_handler");
961     }
962     
963     dpy = XOpenDisplay(NULL);
964     /*init_process_tab();*/
965     create_process_tab(NULL);
966
967     ret_string = malloc(32768);
968     my_strlen = strlen;
969   }
970   
971   reset_host_offset();
972   
973   if (nb_args)
974   {
975     if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0)
976     {
977       fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
978       fprintf(stderr, "cannot get call parameters\n");
979       last_process_id = 0;
980       return 0;
981     }
982     
983     args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args);
984     if (args_size == NULL)
985     {
986       fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
987       fprintf(stderr, "cannot get call parameters size\n");
988       last_process_id = 0;
989       return 0;
990     }
991   }
992   if (func_number == _serialized_calls_func)
993   {
994     int command_buffer_size = args_size[0];
995     const void* command_buffer = get_host_read_pointer(env, args[0], command_buffer_size);
996     int commmand_buffer_offset = 0;
997     args_size = NULL;
998 #ifdef ENABLE_GL_LOG
999     if (must_save) write_gl_debug_cmd_short(_serialized_calls_func);
1000 #endif
1001
1002     while(commmand_buffer_offset < command_buffer_size)
1003     {
1004       func_number = *(short*)(command_buffer + commmand_buffer_offset);
1005       if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
1006       {
1007         fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed at "
1008                         "commmand_buffer_offset=%d (command_buffer_size=%d)\n",
1009                         commmand_buffer_offset, command_buffer_size);
1010         return 0;
1011       }
1012       commmand_buffer_offset += sizeof(short);
1013 #ifdef ENABLE_GL_LOG
1014       if (must_save) write_gl_debug_cmd_short(func_number);
1015 #endif
1016
1017       signature = (Signature*)tab_opengl_calls[func_number];
1018       ret_type = signature->ret_type;
1019       assert(ret_type == TYPE_NONE);
1020       nb_args = signature->nb_args;
1021       args_type = signature->args_type;
1022       for(i=0;i<nb_args;i++)
1023       {
1024         switch(args_type[i])
1025         {
1026           case TYPE_UNSIGNED_INT:
1027           case TYPE_INT:
1028           case TYPE_UNSIGNED_CHAR:
1029           case TYPE_CHAR:
1030           case TYPE_UNSIGNED_SHORT:
1031           case TYPE_SHORT:
1032           case TYPE_FLOAT:
1033           {
1034             args[i] = *(int*)(command_buffer + commmand_buffer_offset);
1035 #ifdef ENABLE_GL_LOG
1036             if (must_save) write_gl_debug_cmd_int(args[i]);
1037 #endif
1038             commmand_buffer_offset += sizeof(int);
1039             break;
1040           }
1041           
1042           case TYPE_NULL_TERMINATED_STRING:
1043           CASE_IN_UNKNOWN_SIZE_POINTERS:
1044           {
1045             int arg_size = *(int*)(command_buffer + commmand_buffer_offset);
1046             commmand_buffer_offset += sizeof(int);
1047             
1048             if (arg_size == 0)
1049             {
1050               args[i] = 0;
1051             }
1052             else
1053             {
1054               args[i] = (long)(command_buffer + commmand_buffer_offset);
1055             }
1056
1057             if (args[i] == 0)
1058             {
1059               if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1060               {
1061                 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1062                 last_process_id = 0;
1063                 return 0;
1064               }
1065             }
1066             else
1067             {
1068               if (arg_size == 0)
1069               {
1070                 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1071                 fprintf(stderr, "args_size[i] == 0 !!\n");
1072                 last_process_id = 0;
1073                 return 0;
1074               }
1075             }
1076 #ifdef ENABLE_GL_LOG
1077             if (must_save) write_gl_debug_cmd_buffer_with_size(arg_size, (void*)args[i]);
1078 #endif
1079             commmand_buffer_offset += arg_size;
1080
1081             break;
1082           }
1083           
1084           CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
1085           {
1086             int arg_size = compute_arg_length(stderr, func_number, i, (void*)args);
1087             args[i] = (arg_size) ? (long)(command_buffer + commmand_buffer_offset) : 0;
1088 #ifdef ENABLE_GL_LOG
1089             if (must_save) write_gl_debug_cmd_buffer_without_size(arg_size, (void*)args[i]);
1090 #endif
1091             commmand_buffer_offset += arg_size;
1092             break;
1093           }
1094             
1095           CASE_OUT_POINTERS:
1096           {
1097             fprintf(stderr, "shouldn't happen TYPE_OUT_xxxx : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1098             last_process_id = 0;
1099             return 0;
1100             break;
1101           }
1102
1103         case TYPE_DOUBLE:
1104         CASE_IN_KNOWN_SIZE_POINTERS:
1105             args[i] = (long)(command_buffer + commmand_buffer_offset);
1106 #ifdef ENABLE_GL_LOG
1107             if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
1108 #endif
1109             commmand_buffer_offset += tab_args_type_length[args_type[i]];
1110             break;
1111             
1112           case TYPE_IN_IGNORED_POINTER:
1113             args[i] = 0;
1114             break;
1115               
1116           default:
1117             fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1118             last_process_id = 0;
1119             return 0;
1120             break;
1121         }
1122       }
1123       do_function_call(dpy, func_number, pid, (void*)args, ret_string);
1124     }
1125     
1126     ret = 0;
1127   }
1128   else
1129   {
1130 #ifdef ENABLE_GL_LOG
1131     if (must_save) write_gl_debug_cmd_short(func_number);
1132 #endif
1133
1134     for(i=0;i<nb_args;i++)
1135     {
1136       switch(args_type[i])
1137       {
1138         case TYPE_UNSIGNED_INT:
1139         case TYPE_INT:
1140         case TYPE_UNSIGNED_CHAR:
1141         case TYPE_CHAR:
1142         case TYPE_UNSIGNED_SHORT:
1143         case TYPE_SHORT:
1144         case TYPE_FLOAT:
1145 #ifdef ENABLE_GL_LOG
1146           if (must_save) write_gl_debug_cmd_int(args[i]);
1147 #endif
1148           break;
1149
1150         case TYPE_NULL_TERMINATED_STRING:
1151         CASE_IN_UNKNOWN_SIZE_POINTERS:
1152           if (args[i] == 0 && args_size[i] == 0)
1153           {
1154             if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1155             {
1156               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1157               last_process_id = 0;
1158               return 0;
1159             }
1160           }
1161           else if (args[i] == 0 && args_size[i] != 0)
1162           {
1163             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1164             fprintf(stderr, "args[i] == 0 && args_size[i] != 0 !!\n");
1165             last_process_id = 0;
1166             return 0;
1167           }
1168           else if (args[i] != 0 && args_size[i] == 0)
1169           {
1170             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1171             fprintf(stderr, "args[i] != 0 && args_size[i] == 0 !!\n");
1172             last_process_id = 0;
1173             return 0;
1174           }
1175           if (args[i])
1176           {
1177             args[i] = (target_ulong)get_host_read_pointer(env, args[i], args_size[i]);
1178             if (args[i] == 0)
1179             {
1180               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1181               fprintf(stderr, "can not get %d bytes\n", args_size[i]);
1182               last_process_id = 0;
1183               return 0;
1184             }
1185           }
1186 #ifdef ENABLE_GL_LOG
1187           if (must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]);
1188 #endif
1189           break;
1190           
1191         CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
1192         {
1193           args_size[i] = compute_arg_length(stderr, func_number, i, (void*)args);
1194           args[i] = (args_size[i]) ? (target_ulong)get_host_read_pointer(env, args[i], args_size[i]) : 0;
1195           if (args[i] == 0 && args_size[i] != 0)
1196           {
1197             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1198             fprintf(stderr, "can not get %d bytes\n", args_size[i]);
1199             last_process_id = 0;
1200             return 0;
1201           }
1202 #ifdef ENABLE_GL_LOG
1203           if (must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]);
1204 #endif
1205           break;
1206         }
1207           
1208         CASE_OUT_POINTERS:
1209         {
1210           int mem_state;
1211 #ifdef ENABLE_GL_LOG
1212           if (must_save) 
1213           {
1214             switch(args_type[i])
1215             {
1216               CASE_OUT_UNKNOWN_SIZE_POINTERS:
1217                 write_gl_debug_cmd_int(args_size[i]);
1218                 break;
1219                 
1220               default:
1221                 break;
1222             }
1223           }
1224 #endif
1225
1226           if (func_number == glXQueryExtension_func && args[i] == 0)
1227           {
1228             saved_out_ptr[i] = 0;
1229             continue;
1230           }
1231           if (args[i] == 0 && args_size[i] == 0)
1232           {
1233             if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1234             {
1235               fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1236               last_process_id = 0;
1237               return 0;
1238             }
1239             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1240             last_process_id = 0;
1241             return 0;
1242           }
1243           else if (args[i] == 0 && args_size[i] != 0)
1244           {
1245             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1246             fprintf(stderr, "args[i] == 0 && args_size[i] != 0 !!\n");
1247             last_process_id = 0;
1248             return 0;
1249           }
1250           else if (args[i] != 0 && args_size[i] == 0)
1251           {
1252             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1253             fprintf(stderr, "args[i] != 0 && args_size[i] == 0 !!\n");
1254             last_process_id = 0;
1255             return 0;
1256           }
1257           if (args[i])
1258           {
1259             mem_state = get_target_mem_state(env, args[i], args_size[i]);
1260             if (mem_state == NOT_MAPPED)
1261             {
1262               fprintf(stderr, "call %s arg %d pid=%d addr=%x size=%d NOT_MAPPED\n", tab_opengl_calls_name[func_number], i, pid, args[i], args_size[i]);
1263               last_process_id = 0;
1264               return 0;
1265             }
1266             else if (mem_state == MAPPED_CONTIGUOUS)
1267             {
1268               saved_out_ptr[i] = 0;
1269               args[i] = (target_ulong)get_phys_mem_addr(env, args[i]); 
1270             }
1271             else
1272             {
1273               saved_out_ptr[i] = args[i];
1274               args[i] = (target_ulong)malloc(args_size[i]);
1275             }
1276           }
1277           else
1278           {
1279             saved_out_ptr[i] = 0;
1280           }
1281           break;
1282         }
1283
1284         case TYPE_DOUBLE:
1285         CASE_IN_KNOWN_SIZE_POINTERS:
1286           if (args[i] == 0)
1287           {
1288             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1289             fprintf(stderr, "can not get %d bytes\n", tab_args_type_length[args_type[i]]);
1290             last_process_id = 0;
1291             return 0;
1292           }
1293           args[i] = (int)get_host_read_pointer(env, args[i], tab_args_type_length[args_type[i]]);
1294           if (args[i] == 0)
1295           {
1296             fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1297             fprintf(stderr, "can not get %d bytes\n", tab_args_type_length[args_type[i]]);
1298             last_process_id = 0;
1299             return 0;
1300           }
1301 #ifdef ENABLE_GL_LOG
1302           if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
1303 #endif
1304           break;
1305
1306         case TYPE_IN_IGNORED_POINTER:
1307           args[i] = 0;
1308           break;
1309
1310         default:
1311           fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1312           last_process_id = 0;
1313           return 0;
1314           break;
1315       }
1316     }
1317     
1318     if (ret_type == TYPE_CONST_CHAR)
1319     {
1320       ret_string[0] = 0;
1321     }
1322     
1323     /*if (func_number == glDrawElements_func)
1324     {
1325       fprintf(stderr, "glDrawElements_func %d %d %d %X\n", args[0], args[1], args[2], args[3]);
1326     }*/
1327   
1328     if (func_number == _init_func)
1329     {
1330        must_save = args[0];
1331 #if 0
1332 #ifdef USE_KQEMU
1333        if (env->kqemu_enabled)
1334          *(int*)args[1] = 2;
1335        else
1336 #endif
1337 #endif
1338          *(int*)args[1] = 1;
1339        ret = 0;
1340     }
1341     else
1342     {
1343
1344       ret = do_function_call(dpy, func_number, pid, (void*)args, ret_string);
1345     }
1346 #ifdef ENABLE_GL_LOG
1347     if (must_save && func_number == glXGetVisualFromFBConfig_func)
1348     {
1349       write_gl_debug_cmd_int(ret);
1350     }
1351 #endif
1352     for(i=0;i<nb_args;i++)
1353     {
1354       switch(args_type[i])
1355       {
1356         CASE_OUT_POINTERS:
1357         {
1358           if (saved_out_ptr[i])
1359           {
1360             if (memcpy_host_to_target(env, saved_out_ptr[i], (void*)args[i], args_size[i]) == 0)
1361             {
1362               fprintf(stderr, "cannot copy out parameters back to user space\n");
1363               last_process_id = 0;
1364               return 0;
1365             }
1366             free((void*)args[i]);
1367           }
1368           break;
1369         }
1370         
1371         default:
1372           break;
1373       }
1374     }
1375     
1376     if (ret_type == TYPE_CONST_CHAR)
1377     {
1378       if (target_ret_string)
1379       {
1380         /* the my_strlen stuff is a hack to workaround a GCC bug if using directly strlen... */
1381         if (memcpy_host_to_target(env, target_ret_string, ret_string, my_strlen(ret_string) + 1) == 0)
1382         {
1383           fprintf(stderr, "cannot copy out parameters back to user space\n");
1384           last_process_id = 0;
1385           return 0;
1386         }
1387       }
1388     }
1389   }
1390   
1391 #ifdef ENABLE_GL_LOG
1392   if (must_save && func_number == _exit_process_func)
1393   {
1394     write_gl_debug_end();
1395   }
1396 #endif
1397
1398   return ret;
1399 }
1400
1401 #endif
1402
1403 extern int decode_call(CPUState *env, int func_number, int pid, target_ulong target_ret_string,
1404                        target_ulong in_args, target_ulong in_args_size)
1405 {
1406   int ret;
1407   //fprintf(stderr, "cr3 = %d\n", env->cr[3]);
1408   if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
1409   {
1410     fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed(%d)\n", func_number);
1411     return 0;
1412   }
1413   ret = decode_call_int(env, func_number, pid, target_ret_string, in_args, in_args_size);
1414   if (func_number == glXCreateContext_func)
1415   {
1416     fprintf(stderr, "ret of glXCreateContext_func = %d\n", ret);
1417   }
1418   return ret;
1419 }
1420
1421 //void helper_opengl()
1422 void helper_opengl(CPUState *env)
1423 {
1424   doing_opengl = 1;
1425
1426   env->regs[R_EAX] = decode_call(env,
1427                                  env->regs[R_EAX],
1428                                  env->regs[R_EBX],
1429                                  env->regs[R_ECX],
1430                                  env->regs[R_EDX],
1431                                  env->regs[R_ESI]);
1432   
1433   doing_opengl = 0;
1434 }