X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglwrap.c;h=c121e22709c819eb3e9040245818e419023bd49e;hb=6d297b506314c07bff3d77c2853a5f59380cfcb0;hp=4c17edfca772755f16a983253e96d37cf3ef0de6;hpb=4aba13fc7690cf79e949d9765b371e85e7530207;p=gldbg.git diff --git a/source/glwrap.c b/source/glwrap.c index 4c17edf..c121e22 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -11,19 +11,24 @@ Distributed under the GPL #include #include #include -#include +#include +#include "breakpoint.h" +#include "functions.h" +#include "packet.h" -#define INTERNAL __attribute__((visibility("internal"))) +static unsigned char breakpoints[N_FUNCS] = { }; +static char break_any = 0; +static char hold = 0; -INTERNAL inline const char *get_lib_names(void) +static const char *get_lib_names(void) { const char *env = getenv("GLWRAP_LIBS"); if(env) return env; - return "libGL.so"; + return "libGL.so.1"; } -INTERNAL inline void *glsym(const char *name) +void *glsym(const char *name) { static void **gl_libs = NULL; unsigned i; @@ -77,151 +82,121 @@ INTERNAL inline void *glsym(const char *name) return NULL; } -INTERNAL char *buffer = 0; -INTERNAL char *write_pos; -INTERNAL struct iovec *iovecs = 0; -INTERNAL struct iovec *cur_vec; -INTERNAL unsigned length; - -INTERNAL inline void next_vec(void) +int get_out_fd(void) { - if(write_pos!=cur_vec->iov_base) + static int fd = -1; + + if(fd<0) { - 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 *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; + } } -} - -INTERNAL inline void write_bytes(const char *ptr, unsigned size) -{ - unsigned i; - for(i=0; iiov_base = (void *)data; - cur_vec->iov_len = size; - length += size; - ++cur_vec; - cur_vec->iov_base = write_pos; + breakpoints[func] &= ~flags_clr; + breakpoints[func] |= flags_set; } else - write_int(0); -} - -INTERNAL inline void write_string(const char *s) -{ - write_data(s, strlen(s)+1); + break_any = flags_set; } -INTERNAL inline void write_string_array(const char **sa, unsigned size) +static void receive_gldHold(GlPacket *pkt __attribute__((unused))) { - unsigned i; - size /= sizeof(const char *); - write_int(size); - for(i=0; iiov_base = write_pos; - length = 0; - - write_int(0); - write_short(func); -} + GlPacket *pkt; -INTERNAL inline int get_out_fd(void) -{ - static int fd = -1; - - if(fd<0) + while((pkt = packet_receive(get_in_fd()))) { - const char *var = getenv("GLWRAP_FD"); - if(var) - fd = strtol(var, NULL, 0); - else - fd = 2; - } + unsigned short func; - return fd; + packet_read_short(pkt, (short *)&func); + switch(func) + { + case FUNC_GLDBREAK: receive_gldBreak(pkt); break; + case FUNC_GLDHOLD: receive_gldHold(pkt); break; + default:; + } + } } -INTERNAL inline void send_partial_packet(void) +void tracepoint(unsigned short func, int flag) { - next_vec(); - write_pos = buffer; - write_int(length|0x80000000); - writev(get_out_fd(), iovecs, cur_vec-iovecs); + int breakpoint; - write_pos = buffer; - cur_vec = iovecs; - cur_vec->iov_base = write_pos; - length = 0; + receive(); - write_int(0); -} + breakpoint = (breakpoints[func]|break_any)&flag; + if(breakpoint || hold) + { + GlPacket *pkt; -INTERNAL inline void send_packet(void) -{ - next_vec(); - write_pos = buffer; - write_int(length); - writev(get_out_fd(), iovecs, cur_vec-iovecs); + if(breakpoint) + { + pkt = packet_begin(FUNC_GLDBREAK); + packet_write_short(pkt, func); + packet_write_char(pkt, flag); + packet_send(pkt, get_out_fd()); + } + + break_any = 0; + + while(1) + { + hold = 0; + raise(SIGTRAP); + receive(); + if(!hold) + break; + } + } }