]> git.tdb.fi Git - gldbg.git/blobdiff - source/glwrap.c
Enable bidirectional communication between gldbg and glwrap.so
[gldbg.git] / source / glwrap.c
index 4c17edfca772755f16a983253e96d37cf3ef0de6..c70b308384b339888dc4ab4527fc7a86df4fa4dc 100644 (file)
@@ -11,19 +11,24 @@ Distributed under the GPL
 #include <errno.h>
 #include <dlfcn.h>
 #include <fcntl.h>
-#include <sys/uio.h>
+#include <signal.h>
+#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,114 @@ 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; i<size; ++i)
-               *write_pos++ = *ptr++;
-}
-
-INTERNAL inline void write_char(char v)
-{
-       *write_pos++ = v;
-}
-
-INTERNAL inline void write_short(short v)
-{
-       write_bytes((char *)&v, sizeof(short));
-}
-
-INTERNAL inline void write_int(int v)
-{
-       write_bytes((char *)&v, sizeof(int));
+       return fd;
 }
 
-INTERNAL inline void write_long(long v)
+int get_in_fd(void)
 {
-       write_bytes((char *)&v, sizeof(long));
-}
+       static int fd = -1;
 
-INTERNAL inline void write_long_long(long long v)
-{
-       write_bytes((char *)&v, sizeof(long long));
-}
+       if(fd<0)
+       {
+               const char *var = getenv("GLWRAP_CTRL_FD");
+               if(var)
+                       fd = strtol(var, NULL, 0);
+               else
+                       fd = 0;
+       }
 
-INTERNAL inline void write_float(float v)
-{
-       write_bytes((char *)&v, sizeof(float));
+       return fd;
 }
 
-INTERNAL inline void write_double(double v)
+static void receive_gldBreak(GlPacket *pkt)
 {
-       write_bytes((char *)&v, sizeof(double));
-}
+       unsigned short func;
+       unsigned char flags_set;
+       unsigned char flags_clr;
 
-INTERNAL inline void write_pointer(const void *p)
-{
-       write_bytes((char *)&p, sizeof(void *));
-}
+       packet_read_short(pkt, (short *)&func);
+       packet_read_char(pkt, (char *)&flags_set);
+       packet_read_char(pkt, (char *)&flags_clr);
 
-INTERNAL inline void write_data(const void *data, unsigned size)
-{
-       if(data)
+       if(func)
        {
-               write_int(size);
-               next_vec();
-               cur_vec->iov_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);
+               break_any = flags_set;
 }
 
-INTERNAL inline void write_string(const char *s)
+static void receive_gldHold(GlPacket *pkt __attribute__((unused)))
 {
-       write_data(s, strlen(s)+1);
+       hold = 1;
 }
 
-INTERNAL inline void write_string_array(const char **sa, unsigned size)
+static void receive(void)
 {
-       unsigned i;
-       size /= sizeof(const char *);
-       write_int(size);
-       for(i=0; i<size; ++i)
-               write_string(sa[i]);
-}
-
-INTERNAL inline void begin_packet(int func)
-{
-       if(!buffer)
-               buffer = (char *)malloc(1024);
-       if(!iovecs)
-               iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
-
-       write_pos = buffer;
-       cur_vec = iovecs;
-       cur_vec->iov_base = write_pos;
-       length = 0;
-
-       write_int(0);
-       write_short(func);
-}
-
-INTERNAL inline int get_out_fd(void)
-{
-       static int fd = -1;
+       GlPacket *pkt;
 
-       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);
+       receive();
 
-       write_pos = buffer;
-       cur_vec = iovecs;
-       cur_vec->iov_base = write_pos;
-       length = 0;
+       if((breakpoints[func]|break_any)&flag)
+       {
+               GlPacket *pkt;
 
-       write_int(0);
-}
+               pkt = packet_begin(FUNC_GLDBREAK);
+               packet_write_short(pkt, func);
+               packet_send(pkt, get_out_fd());
 
-INTERNAL inline void send_packet(void)
-{
-       next_vec();
-       write_pos = buffer;
-       write_int(length);
-       writev(get_out_fd(), iovecs, cur_vec-iovecs);
+               break_any = 0;
+
+               while(1)
+               {
+                       hold = 0;
+                       raise(SIGTRAP);
+                       receive();
+                       if(!hold)
+                               break;
+               }
+       }
 }