X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglwrap.c;h=c70b308384b339888dc4ab4527fc7a86df4fa4dc;hb=ea3d851aa52e999b1c5a5fa52c97ff5019756c0e;hp=68351143d31aca0567dca79c1d7051a885ced85c;hpb=27a82684df128955f6c4e1467935be14ff9bb816;p=gldbg.git diff --git a/source/glwrap.c b/source/glwrap.c index 6835114..c70b308 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -1,260 +1,195 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ #include #include #include +#include #include -#include -#include -#include -#include -#include "arraysize.h" +#include +#include +#include "breakpoint.h" #include "functions.h" +#include "packet.h" -static inline void *glsym(const char *sym) -{ - static void *libgl = NULL; - if(!libgl) - { - const char *libgl_name = getenv("GLWRAP_LIBGL"); - if(!libgl_name) - libgl_name = "libGL.so"; - libgl = dlopen(libgl_name, RTLD_NOW); - if(!libgl) - { - fprintf(stderr, "Could not open %s: %s\n", libgl_name, dlerror()); - abort(); - } - } +static unsigned char breakpoints[N_FUNCS] = { }; +static char break_any = 0; +static char hold = 0; - return dlsym(libgl, sym); -} - -static char *buffer = 0; -static char *write_pos; -static struct iovec *iovecs = 0; -static struct iovec *cur_vec; -static unsigned length; - -static inline void next_vec() +static const char *get_lib_names(void) { - if(write_pos!=cur_vec->iov_base) - { - cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base; - length += cur_vec->iov_len; - ++cur_vec; - cur_vec->iov_base = write_pos; - } + const char *env = getenv("GLWRAP_LIBS"); + if(env) + return env; + return "libGL.so.1"; } -static inline void write_bytes(const char *ptr, unsigned size) +void *glsym(const char *name) { + static void **gl_libs = NULL; unsigned i; - for(i=0; iiov_base = (void *)data; - cur_vec->iov_len = size; - length += size; - ++cur_vec; - cur_vec->iov_base = write_pos; + const char *var = getenv("GLWRAP_FD"); + if(var) + fd = strtol(var, NULL, 0); + else + { + var = getenv("GLWRAP_FILE"); + if(var) + { + fd = open(var, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if(fd==-1) + { + fprintf(stderr, "Couldn't open dumpfile %s for output: %s", var, strerror(errno)); + abort(); + } + } + else + fd = 2; + } } - else - write_int(0); -} - -static inline void write_string(const char *s) -{ - write_data(s, strlen(s)+1); -} - -static inline void write_string_array(const char **sa, unsigned size) -{ - unsigned i; - size /= sizeof(const char *); - write_int(size); - for(i=0; iiov_base = write_pos; - length = 0; - write_int(0); - write_short(func); + return fd; } -static inline void send_packet() +int get_in_fd(void) { static int fd = -1; + if(fd<0) { - const char *var = getenv("GLWRAP_FD"); + const char *var = getenv("GLWRAP_CTRL_FD"); if(var) fd = strtol(var, NULL, 0); else - fd = 2; + fd = 0; } - next_vec(); - write_pos = buffer; - write_int(length); - writev(fd, iovecs, cur_vec-iovecs); -} -int in_begin_block = 0; -GLenum cur_error = GL_NO_ERROR; + return fd; +} -static void check_error() +static void receive_gldBreak(GlPacket *pkt) { - GLenum (*orig_glGetError)() = 0; - GLenum code; - - if(in_begin_block) - return; + unsigned short func; + unsigned char flags_set; + unsigned char flags_clr; - if(!orig_glGetError) - orig_glGetError = glsym("glGetError"); + packet_read_short(pkt, (short *)&func); + packet_read_char(pkt, (char *)&flags_set); + packet_read_char(pkt, (char *)&flags_clr); - code = orig_glGetError(); - if(code!=GL_NO_ERROR) + if(func) { - begin_packet(FUNC_GLDERROR); - write_int(code); - send_packet(); - - if(cur_error==GL_NO_ERROR) - cur_error = code; + breakpoints[func] &= ~flags_clr; + breakpoints[func] |= flags_set; } + else + break_any = flags_set; } -void APIENTRY glBegin(GLenum mode) +static void receive_gldHold(GlPacket *pkt __attribute__((unused))) { - static void (*orig)(GLenum); - if(!orig) - orig = glsym("glBegin"); - orig(mode); - - begin_packet(FUNC_GLBEGIN); - write_int(mode); - send_packet(); - - in_begin_block = 1; + hold = 1; } -void APIENTRY glEnd() +static void receive(void) { - static void (*orig)(); - if(!orig) - orig = glsym("glEnd"); - orig(); + GlPacket *pkt; - begin_packet(FUNC_GLEND); - send_packet(); + while((pkt = packet_receive(get_in_fd()))) + { + unsigned short func; - in_begin_block = 0; - check_error(); + packet_read_short(pkt, (short *)&func); + switch(func) + { + case FUNC_GLDBREAK: receive_gldBreak(pkt); break; + case FUNC_GLDHOLD: receive_gldHold(pkt); break; + default:; + } + } } -GLenum APIENTRY glGetError() +void tracepoint(unsigned short func, int flag) { - GLenum ret = GL_NO_ERROR; + receive(); - if(in_begin_block) + if((breakpoints[func]|break_any)&flag) { - if(cur_error==GL_NO_ERROR) - cur_error = GL_INVALID_OPERATION; - } - else - { - ret = cur_error; - cur_error = GL_NO_ERROR; - } + GlPacket *pkt; - begin_packet(FUNC_GLGETERROR); - write_int(ret); - send_packet(); + pkt = packet_begin(FUNC_GLDBREAK); + packet_write_short(pkt, func); + packet_send(pkt, get_out_fd()); - return ret; -} - -void (*glXGetProcAddress(const GLubyte *procname))(void) -{ - void *handle = 0; - void (*ret)() = 0; + break_any = 0; - if(glsym((const char *)procname)) - { - handle = dlopen(NULL, RTLD_LAZY); - ret = dlsym(handle, (const char *)procname); + while(1) + { + hold = 0; + raise(SIGTRAP); + receive(); + if(!hold) + break; + } } - - begin_packet(FUNC_GLXGETPROCADDRESS); - write_pointer(ret); - write_string((const char *)procname); - send_packet(); - - return ret; } - -void (*glXGetProcAddressARB(const GLubyte *))(void) __attribute__((alias("glXGetProcAddress"))); - -#include "glwrap.funcs"