Add support for PIC executables (e.g. firefox on Ubuntu 11) by adding
the "auxv" protocol packet to gdbsrv.  (Philippe Waroquiers,
philippe.waroquiers@skynet.be).  Bug 214909 comment 108.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11836 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_gdbserver/server.c b/coregrind/m_gdbserver/server.c
index 546fe3b..db4d1f7 100644
--- a/coregrind/m_gdbserver/server.c
+++ b/coregrind/m_gdbserver/server.c
@@ -26,6 +26,7 @@
 #include "pub_core_options.h"
 #include "pub_core_translate.h"
 #include "pub_core_mallocfree.h"
+#include "pub_core_initimg.h"
 
 unsigned long cont_thread;
 unsigned long general_thread;
@@ -580,6 +581,59 @@
       }
    }
 
+   if (strncmp ("qXfer:auxv:read:", arg_own_buf, 16) == 0) {
+      unsigned char *data;
+      int n;
+      CORE_ADDR ofs;
+      unsigned int len;
+      char *annex;
+
+      /* Reject any annex; grab the offset and length.  */
+      if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
+          || annex[0] != '\0') {
+         strcpy (arg_own_buf, "E00");
+         return;
+      }
+
+      if (len > PBUFSIZ - 2)
+         len = PBUFSIZ - 2;
+      data = malloc (len);
+
+      {
+         UWord *client_auxv = VG_(client_auxv);
+         unsigned int client_auxv_len = 0;
+         while (*client_auxv != 0) {
+            dlog(4, "auxv %lld %llx\n",
+                 (ULong)*client_auxv,
+                 (ULong)*(client_auxv+1));
+            client_auxv++;
+            client_auxv++;
+            client_auxv_len += 2 * sizeof(UWord);
+         }
+         client_auxv_len += 2 * sizeof(UWord);
+         dlog(4, "auxv len %d\n", client_auxv_len);
+
+         if (ofs >= client_auxv_len)
+            n = -1;
+         else {
+            n = client_auxv_len - ofs;
+            VG_(memcpy) (data, (unsigned char *) VG_(client_auxv), n);
+         }
+      }
+
+      if (n < 0)
+         write_enn (arg_own_buf);
+      else if (n > len)
+         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1);
+      else
+         *new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0);
+      
+      free (data);
+      
+      return;
+   }
+
+
    /* Protocol features query.  */
    if (strncmp ("qSupported", arg_own_buf, 10) == 0
        && (arg_own_buf[10] == ':' || arg_own_buf[10] == '\0')) {
@@ -589,6 +643,8 @@
       
       strcat (arg_own_buf, ";QStartNoAckMode+");
       strcat (arg_own_buf, ";QPassSignals+");
+      if (VG_(client_auxv))
+         strcat (arg_own_buf, ";qXfer:auxv:read+");
 
       if ((*the_target->target_xml)() != NULL
           || (*the_target->shadow_target_xml)() != NULL) {