2 * Host-side implementation of GL/GLX API
4 * Copyright (c) 2006,2007 Even Rouault
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
31 #define _XOPEN_SOURCE 600
42 #include <X11/Xutil.h>
46 typedef HDC GLDisplay;
50 //## remove GCC warning
51 //#include "qemu-common.h"
52 //#include "opengl_func.h"
53 #include "helper_opengl.h"
58 //extern int do_function_call(Display dpy, int func_number, int pid, int* args, char* ret_string);
60 //extern int do_function_call(Display* dpy, int func_number, int pid, int* args, char* ret_string);
62 extern int last_process_id;
65 extern void sdl_set_opengl_window(int x, int y, int width, int height);
69 static GLDisplay CreateDisplay(void)
73 LPCSTR ClassName ="DISPLAY";
74 HINSTANCE hInstance = 0;
76 /* only register the window class once - use hInstance as a flag. */
77 hInstance = GetModuleHandle(NULL);
79 wc.lpfnWndProc = (WNDPROC)DefWindowProc;
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;
91 displayHWND = CreateWindow(ClassName, ClassName, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU ),
92 0, 0, 10, 10, NULL, (HMENU)NULL, hInstance, NULL);
95 ShowWindow(hWnd, SW_HIDE);
97 return GetDC(displayHWND);
101 static int must_save = 0;
103 static inline void* get_phys_mem_addr(const CPUState *env, target_ulong addr)
107 ret = qemu_get_ram_ptr(addr);
113 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
114 is_user = ((env->hflags & HF_CPL_MASK) == 3);
117 fprintf(stderr, "not in userland !!!\n");
120 if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
121 (addr & TARGET_PAGE_MASK), 0))
123 target_ulong ret = cpu_get_phys_page_debug((CPUState *)env, addr);
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));
134 if (ret + TARGET_PAGE_SIZE <= ldl_phys(0))
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)));
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));
152 return (void*)(addr + env->tlb_table[is_user][index].addend);
157 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
164 MAPPED_NOT_CONTIGUOUS
167 #define TARGET_ADDR_LOW_ALIGN(x) ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1))
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)
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;
178 if (aligned_target_addr != target_addr)
180 void* phys_addr = get_phys_mem_addr(env, aligned_target_addr);
181 void* last_phys_addr = phys_addr;
186 if (len > to_end_page)
189 aligned_target_addr += TARGET_PAGE_SIZE;
191 for(i=0;i<len;i+=TARGET_PAGE_SIZE)
193 void* phys_addr = get_phys_mem_addr(env, aligned_target_addr + i);
198 if (phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
199 ret = MAPPED_NOT_CONTIGUOUS;
200 last_phys_addr = phys_addr;
206 void* last_phys_addr = NULL;
208 for(i=0;i<len;i+=TARGET_PAGE_SIZE)
210 void* phys_addr = get_phys_mem_addr(env, target_addr + i);
215 if (i != 0 && phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
216 ret = MAPPED_NOT_CONTIGUOUS;
217 last_phys_addr = phys_addr;
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)
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)
236 if (ret == MAPPED_CONTIGUOUS)
238 void *phys_addr = get_phys_mem_addr(env, target_addr);
239 memcpy(phys_addr, host_addr, len);
243 if (aligned_target_addr != target_addr)
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)
252 host_addr += to_end_page;
253 target_addr = aligned_target_addr + TARGET_PAGE_SIZE;
255 for(i=0;i<len;i+=TARGET_PAGE_SIZE)
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));
265 static int memcpy_target_to_host(const CPUState *env, void* host_addr, target_ulong target_addr, int len)
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)
276 if (ret == MAPPED_CONTIGUOUS)
278 void *phys_addr = get_phys_mem_addr(env, target_addr);
279 memcpy(host_addr, phys_addr, len);
283 if (aligned_target_addr != target_addr)
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)
292 host_addr += to_end_page;
293 target_addr = aligned_target_addr + TARGET_PAGE_SIZE;
295 for(i=0;i<len;i+=TARGET_PAGE_SIZE)
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));
305 static int host_offset = 0;
306 static void reset_host_offset(void)
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)
315 int ret = get_target_mem_state(env, target_addr, len);
316 if (ret == NOT_MAPPED)
320 else if (ret == MAPPED_CONTIGUOUS)
322 return get_phys_mem_addr(env, target_addr);
326 static int host_mem_size = 0;
327 static void* host_mem = NULL;
329 if (host_mem_size < host_offset + len)
331 host_mem_size = 2 * host_mem_size + host_offset + len;
332 host_mem = realloc(host_mem, host_mem_size);
334 ret = host_mem + host_offset;
335 assert(memcpy_target_to_host(env, ret, target_addr, len));
341 int doing_opengl = 0;
342 static int last_func_number = -1;
343 static size_t (*my_strlen)(const char*) = NULL;
346 static FILE* f = NULL;
348 #define write_gl_debug_init() do { if (f == NULL) f = fopen("/tmp/debug_gl.bin", "wb"); } while(0)
350 static int write_gl_debug_cmd_int(int my_int)
353 write_gl_debug_init();
354 r = fwrite(&my_int, sizeof(int), 1, f);
359 static int write_gl_debug_cmd_short(int my_int)
362 write_gl_debug_init();
363 r = fwrite(&my_int, sizeof(short), 1, f);
368 inline static int write_gl_debug_cmd_buffer_with_size(int size, void* buffer)
371 write_gl_debug_init();
372 r = fwrite(&size, sizeof(int), 1, f);
374 r += fwrite(buffer, size, 1, f);
378 inline static int write_gl_debug_cmd_buffer_without_size(int size, void* buffer)
381 write_gl_debug_init();
383 r = fwrite(buffer, size, 1, f);
387 static void write_gl_debug_end(void)
389 write_gl_debug_init();
397 #if !defined( _WIN32 ) /* by 12.Nov.2009 */
401 static void (*anticrash_handler)(void*) = NULL;
402 static void (*show_stack_from_signal_handler)(int, int, int) = NULL;
404 static void my_anticrash_sigsegv_handler(int signum, siginfo_t* info, void* ptr)
406 static int counter = 0;
411 /*if (show_stack_from_signal_handler && counter == 1)
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]);
416 anticrash_handler(ptr);
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)
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;
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;
440 if (last_func_number == _exit_process_func && func_number == _exit_process_func)
442 last_func_number = -1;
447 if (last_process_id == 0)
449 last_process_id = pid;
451 else if (last_process_id != pid)
453 fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n");
457 last_process_id = pid;
462 dpy = CreateDisplay();
463 //init_process_tab();
464 create_process_tab(NULL);
466 ret_string = malloc(32768);
474 if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0)
476 fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
477 fprintf(stderr, "cannot get call parameters\n");
482 args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args);
483 if (args_size == NULL)
485 fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
486 fprintf(stderr, "cannot get call parameters size\n");
492 if (func_number == _serialized_calls_func)
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;
499 if (must_save) write_gl_debug_cmd_short(_serialized_calls_func);
502 while(commmand_buffer_offset < command_buffer_size)
504 func_number = *(short*)(command_buffer + commmand_buffer_offset);
505 if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
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);
512 commmand_buffer_offset += sizeof(short);
514 if (must_save) write_gl_debug_cmd_short(func_number);
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;
523 for(i=0;i<nb_args;i++)
527 case TYPE_UNSIGNED_INT:
529 case TYPE_UNSIGNED_CHAR:
531 case TYPE_UNSIGNED_SHORT:
535 args[i] = *(int*)(command_buffer + commmand_buffer_offset);
537 if (must_save) write_gl_debug_cmd_int(args[i]);
539 commmand_buffer_offset += sizeof(int);
543 case TYPE_NULL_TERMINATED_STRING:
544 CASE_IN_UNKNOWN_SIZE_POINTERS:
546 int arg_size = *(int*)(command_buffer + commmand_buffer_offset);
547 commmand_buffer_offset += sizeof(int);
555 args[i] = (long)(command_buffer + commmand_buffer_offset);
560 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
562 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
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");
578 if (must_save) write_gl_debug_cmd_buffer_with_size(arg_size, (void*)args[i]);
580 commmand_buffer_offset += arg_size;
585 CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
587 int arg_size = compute_arg_length(stderr, func_number, i, args);
588 args[i] = (arg_size) ? (long)(command_buffer + commmand_buffer_offset) : 0;
590 if (must_save) write_gl_debug_cmd_buffer_without_size(arg_size, (void*)args[i]);
592 commmand_buffer_offset += arg_size;
598 fprintf(stderr, "shouldn't happen TYPE_OUT_xxxx : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
605 CASE_IN_KNOWN_SIZE_POINTERS:
606 args[i] = (long)(command_buffer + commmand_buffer_offset);
608 if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
610 commmand_buffer_offset += tab_args_type_length[args_type[i]];
613 case TYPE_IN_IGNORED_POINTER:
618 fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
624 do_function_call(dpy, func_number, pid, args, ret_string);
632 if (must_save) write_gl_debug_cmd_short(func_number);
635 for(i=0;i<nb_args;i++)
639 case TYPE_UNSIGNED_INT:
641 case TYPE_UNSIGNED_CHAR:
643 case TYPE_UNSIGNED_SHORT:
647 if (must_save) write_gl_debug_cmd_int(args[i]);
651 case TYPE_NULL_TERMINATED_STRING:
652 CASE_IN_UNKNOWN_SIZE_POINTERS:
653 if (args[i] == 0 && args_size[i] == 0)
655 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
657 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
662 else if (args[i] == 0 && args_size[i] != 0)
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");
669 else if (args[i] != 0 && args_size[i] == 0)
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");
678 args[i] = (target_ulong)get_host_read_pointer(env, args[i], args_size[i]);
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]);
688 if (must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]);
692 CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
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)
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]);
704 if (must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]);
717 CASE_OUT_UNKNOWN_SIZE_POINTERS:
718 write_gl_debug_cmd_int(args_size[i]);
727 if (func_number == glXQueryExtension_func && args[i] == 0)
729 saved_out_ptr[i] = 0;
732 if (args[i] == 0 && args_size[i] == 0)
734 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
736 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
740 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
744 else if (args[i] == 0 && args_size[i] != 0)
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");
751 else if (args[i] != 0 && args_size[i] == 0)
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");
760 mem_state = get_target_mem_state(env, args[i], args_size[i]);
761 if (mem_state == NOT_MAPPED)
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]);
767 else if (mem_state == MAPPED_CONTIGUOUS)
769 saved_out_ptr[i] = 0;
770 args[i] = (target_ulong)get_phys_mem_addr(env, args[i]);
774 saved_out_ptr[i] = args[i];
775 args[i] = (target_ulong)malloc(args_size[i]);
780 saved_out_ptr[i] = 0;
786 CASE_IN_KNOWN_SIZE_POINTERS:
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]]);
794 args[i] = (int)get_host_read_pointer(env, args[i], tab_args_type_length[args_type[i]]);
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]]);
803 if (must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]);
807 case TYPE_IN_IGNORED_POINTER:
812 fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
819 if (ret_type == TYPE_CONST_CHAR)
824 /*if (func_number == glDrawElements_func)
826 fprintf(stderr, "glDrawElements_func %d %d %d %X\n", args[0], args[1], args[2], args[3]);
829 if (func_number == _init_func)
834 if (env->kqemu_enabled)
844 ret = do_function_call(dpy, func_number, pid, args, ret_string);
847 if (must_save && func_number == glXGetVisualFromFBConfig_func)
849 write_gl_debug_cmd_int(ret);
852 for(i=0;i<nb_args;i++)
858 if (saved_out_ptr[i])
860 if (memcpy_host_to_target(env, saved_out_ptr[i], (void*)args[i], args_size[i]) == 0)
862 fprintf(stderr, "cannot copy out parameters back to user space\n");
866 free((void*)args[i]);
876 if (ret_type == TYPE_CONST_CHAR)
878 if (target_ret_string)
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)
883 fprintf(stderr, "cannot copy out parameters back to user space\n");
892 if (must_save && func_number == _exit_process_func)
894 write_gl_debug_end();
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)
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;
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;
919 if (last_func_number == _exit_process_func && func_number == _exit_process_func)
921 last_func_number = -1;
926 if (last_process_id == 0)
928 last_process_id = pid;
930 else if (last_process_id != pid)
932 fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n");
936 last_process_id = pid;
941 void *handle = dlopen("libanticrash.so", RTLD_LAZY);
944 anticrash_handler = dlsym(handle, "anticrash_handler");
945 if (anticrash_handler)
947 fprintf(stderr, "anticrash handler enabled\n");
948 struct sigaction sigsegv_action;
949 struct sigaction old_sigsegv_action;
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);
957 handle = dlopen("libgetstack.so", RTLD_LAZY);
960 show_stack_from_signal_handler = dlsym(handle, "show_stack_from_signal_handler");
963 dpy = XOpenDisplay(NULL);
964 /*init_process_tab();*/
965 create_process_tab(NULL);
967 ret_string = malloc(32768);
975 if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0)
977 fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
978 fprintf(stderr, "cannot get call parameters\n");
983 args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args);
984 if (args_size == NULL)
986 fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid);
987 fprintf(stderr, "cannot get call parameters size\n");
992 if (func_number == _serialized_calls_func)
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;
999 if (must_save) write_gl_debug_cmd_short(_serialized_calls_func);
1002 while(commmand_buffer_offset < command_buffer_size)
1004 func_number = *(short*)(command_buffer + commmand_buffer_offset);
1005 if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
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);
1012 commmand_buffer_offset += sizeof(short);
1013 #ifdef ENABLE_GL_LOG
1014 if (must_save) write_gl_debug_cmd_short(func_number);
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++)
1024 switch(args_type[i])
1026 case TYPE_UNSIGNED_INT:
1028 case TYPE_UNSIGNED_CHAR:
1030 case TYPE_UNSIGNED_SHORT:
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]);
1038 commmand_buffer_offset += sizeof(int);
1042 case TYPE_NULL_TERMINATED_STRING:
1043 CASE_IN_UNKNOWN_SIZE_POINTERS:
1045 int arg_size = *(int*)(command_buffer + commmand_buffer_offset);
1046 commmand_buffer_offset += sizeof(int);
1054 args[i] = (long)(command_buffer + commmand_buffer_offset);
1059 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1061 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1062 last_process_id = 0;
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;
1076 #ifdef ENABLE_GL_LOG
1077 if (must_save) write_gl_debug_cmd_buffer_with_size(arg_size, (void*)args[i]);
1079 commmand_buffer_offset += arg_size;
1084 CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
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]);
1091 commmand_buffer_offset += arg_size;
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;
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]);
1109 commmand_buffer_offset += tab_args_type_length[args_type[i]];
1112 case TYPE_IN_IGNORED_POINTER:
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;
1123 do_function_call(dpy, func_number, pid, (void*)args, ret_string);
1130 #ifdef ENABLE_GL_LOG
1131 if (must_save) write_gl_debug_cmd_short(func_number);
1134 for(i=0;i<nb_args;i++)
1136 switch(args_type[i])
1138 case TYPE_UNSIGNED_INT:
1140 case TYPE_UNSIGNED_CHAR:
1142 case TYPE_UNSIGNED_SHORT:
1145 #ifdef ENABLE_GL_LOG
1146 if (must_save) write_gl_debug_cmd_int(args[i]);
1150 case TYPE_NULL_TERMINATED_STRING:
1151 CASE_IN_UNKNOWN_SIZE_POINTERS:
1152 if (args[i] == 0 && args_size[i] == 0)
1154 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1156 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1157 last_process_id = 0;
1161 else if (args[i] == 0 && args_size[i] != 0)
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;
1168 else if (args[i] != 0 && args_size[i] == 0)
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;
1177 args[i] = (target_ulong)get_host_read_pointer(env, args[i], args_size[i]);
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;
1186 #ifdef ENABLE_GL_LOG
1187 if (must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]);
1191 CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS:
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)
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;
1202 #ifdef ENABLE_GL_LOG
1203 if (must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]);
1211 #ifdef ENABLE_GL_LOG
1214 switch(args_type[i])
1216 CASE_OUT_UNKNOWN_SIZE_POINTERS:
1217 write_gl_debug_cmd_int(args_size[i]);
1226 if (func_number == glXQueryExtension_func && args[i] == 0)
1228 saved_out_ptr[i] = 0;
1231 if (args[i] == 0 && args_size[i] == 0)
1233 if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number))
1235 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1236 last_process_id = 0;
1239 fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid);
1240 last_process_id = 0;
1243 else if (args[i] == 0 && args_size[i] != 0)
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;
1250 else if (args[i] != 0 && args_size[i] == 0)
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;
1259 mem_state = get_target_mem_state(env, args[i], args_size[i]);
1260 if (mem_state == NOT_MAPPED)
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;
1266 else if (mem_state == MAPPED_CONTIGUOUS)
1268 saved_out_ptr[i] = 0;
1269 args[i] = (target_ulong)get_phys_mem_addr(env, args[i]);
1273 saved_out_ptr[i] = args[i];
1274 args[i] = (target_ulong)malloc(args_size[i]);
1279 saved_out_ptr[i] = 0;
1285 CASE_IN_KNOWN_SIZE_POINTERS:
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;
1293 args[i] = (int)get_host_read_pointer(env, args[i], tab_args_type_length[args_type[i]]);
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;
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]);
1306 case TYPE_IN_IGNORED_POINTER:
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;
1318 if (ret_type == TYPE_CONST_CHAR)
1323 /*if (func_number == glDrawElements_func)
1325 fprintf(stderr, "glDrawElements_func %d %d %d %X\n", args[0], args[1], args[2], args[3]);
1328 if (func_number == _init_func)
1330 must_save = args[0];
1333 if (env->kqemu_enabled)
1344 ret = do_function_call(dpy, func_number, pid, (void*)args, ret_string);
1346 #ifdef ENABLE_GL_LOG
1347 if (must_save && func_number == glXGetVisualFromFBConfig_func)
1349 write_gl_debug_cmd_int(ret);
1352 for(i=0;i<nb_args;i++)
1354 switch(args_type[i])
1358 if (saved_out_ptr[i])
1360 if (memcpy_host_to_target(env, saved_out_ptr[i], (void*)args[i], args_size[i]) == 0)
1362 fprintf(stderr, "cannot copy out parameters back to user space\n");
1363 last_process_id = 0;
1366 free((void*)args[i]);
1376 if (ret_type == TYPE_CONST_CHAR)
1378 if (target_ret_string)
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)
1383 fprintf(stderr, "cannot copy out parameters back to user space\n");
1384 last_process_id = 0;
1391 #ifdef ENABLE_GL_LOG
1392 if (must_save && func_number == _exit_process_func)
1394 write_gl_debug_end();
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)
1407 //fprintf(stderr, "cr3 = %d\n", env->cr[3]);
1408 if( ! (func_number >= 0 && func_number < GL_N_CALLS) )
1410 fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed(%d)\n", func_number);
1413 ret = decode_call_int(env, func_number, pid, target_ret_string, in_args, in_args_size);
1414 if (func_number == glXCreateContext_func)
1416 fprintf(stderr, "ret of glXCreateContext_func = %d\n", ret);
1421 //void helper_opengl()
1422 void helper_opengl(CPUState *env)
1426 env->regs[R_EAX] = decode_call(env,