replace convert_int_to_ascii with bin2hex
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
index 4d286582351023843a4e13364862c3667b77294b..3b3f18333cd637ab9b554628470473c5626e672e 100644 (file)
@@ -1,7 +1,5 @@
 /* Remote utility routines for the remote server for GDB.
-   Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "server.h"
 #include "terminal.h"
 #include "target.h"
+#include "gdbthread.h"
+#include "tdesc.h"
+#include "dll.h"
+#include "rsp-low.h"
+
 #include <stdio.h>
 #include <string.h>
 #if HAVE_SYS_IOCTL_H
@@ -51,9 +54,7 @@
 #include <fcntl.h>
 #endif
 #include <sys/time.h>
-#if HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #if HAVE_ARPA_INET_H
 #include <arpa/inet.h>
 #endif
@@ -107,6 +108,8 @@ struct sym_cache
 int remote_debug = 0;
 struct ui_file *gdb_stdlog;
 
+static int remote_is_stdio = 0;
+
 static gdb_fildes_t remote_desc = INVALID_DESCRIPTOR;
 static gdb_fildes_t listen_desc = INVALID_DESCRIPTOR;
 
@@ -130,6 +133,14 @@ gdb_connected (void)
   return remote_desc != INVALID_DESCRIPTOR;
 }
 
+/* Return true if the remote connection is over stdio.  */
+
+int
+remote_connection_is_stdio (void)
+{
+  return remote_is_stdio;
+}
+
 static void
 enable_async_notification (int fd)
 {
@@ -151,7 +162,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -222,6 +233,17 @@ remote_prepare (char *name)
   socklen_t tmp;
   char *port_end;
 
+  remote_is_stdio = 0;
+  if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+    {
+      /* We need to record fact that we're using stdio sooner than the
+        call to remote_open so start_inferior knows the connection is
+        via stdio.  */
+      remote_is_stdio = 1;
+      transport_is_reliable = 1;
+      return;
+    }
+
   port_str = strchr (name, ':');
   if (port_str == NULL)
     {
@@ -272,11 +294,27 @@ remote_open (char *name)
   char *port_str;
 
   port_str = strchr (name, ':');
+#ifdef USE_WIN32API
   if (port_str == NULL)
+    error ("Only <host>:<port> is supported on this platform.");
+#endif
+
+  if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
+    {
+      fprintf (stderr, "Remote debugging using stdio\n");
+
+      /* Use stdin as the handle of the connection.
+        We only select on reads, for example.  */
+      remote_desc = fileno (stdin);
+
+      enable_async_notification (remote_desc);
+
+      /* Register the event loop handler.  */
+      add_file_handler (remote_desc, handle_serial_event, NULL);
+    }
+#ifndef USE_WIN32API
+  else if (port_str == NULL)
     {
-#ifdef USE_WIN32API
-      error ("Only <host>:<port> is supported on this platform.");
-#else
       struct stat statbuf;
 
       if (stat (name, &statbuf) == 0
@@ -341,8 +379,8 @@ remote_open (char *name)
 
       /* Register the event loop handler.  */
       add_file_handler (remote_desc, handle_serial_event, NULL);
-#endif /* USE_WIN32API */
     }
+#endif /* USE_WIN32API */
   else
     {
       int port;
@@ -372,73 +410,18 @@ remote_close (void)
 #ifdef USE_WIN32API
   closesocket (remote_desc);
 #else
-  close (remote_desc);
+  if (! remote_connection_is_stdio ())
+    close (remote_desc);
 #endif
   remote_desc = INVALID_DESCRIPTOR;
 
   reset_readchar ();
 }
 
-/* Convert hex digit A to a number.  */
-
-static int
-fromhex (int a)
-{
-  if (a >= '0' && a <= '9')
-    return a - '0';
-  else if (a >= 'a' && a <= 'f')
-    return a - 'a' + 10;
-  else
-    error ("Reply contains invalid hex digit");
-  return 0;
-}
-
 #endif
 
-static const char hexchars[] = "0123456789abcdef";
-
-static int
-ishex (int ch, int *val)
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    {
-      *val = ch - 'a' + 10;
-      return 1;
-    }
-  if ((ch >= 'A') && (ch <= 'F'))
-    {
-      *val = ch - 'A' + 10;
-      return 1;
-    }
-  if ((ch >= '0') && (ch <= '9'))
-    {
-      *val = ch - '0';
-      return 1;
-    }
-  return 0;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-int
-unhexify (char *bin, const char *hex, int count)
-{
-  int i;
-
-  for (i = 0; i < count; i++)
-    {
-      if (hex[0] == 0 || hex[1] == 0)
-       {
-         /* Hex string is short, or of uneven length.
-            Return the count that has been converted so far. */
-         return i;
-       }
-      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
-      hex += 2;
-    }
-  return i;
-}
-
 void
 decode_address (CORE_ADDR *addrp, const char *start, int len)
 {
@@ -474,118 +457,8 @@ decode_address_to_semicolon (CORE_ADDR *addrp, const char *start)
 
 #endif
 
-/* Convert number NIB to a hex digit.  */
-
-static int
-tohex (int nib)
-{
-  if (nib < 10)
-    return '0' + nib;
-  else
-    return 'a' + nib - 10;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-int
-hexify (char *hex, const char *bin, int count)
-{
-  int i;
-
-  /* May use a length, or a nul-terminated string as input. */
-  if (count == 0)
-    count = strlen (bin);
-
-  for (i = 0; i < count; i++)
-    {
-      *hex++ = tohex ((*bin >> 4) & 0xf);
-      *hex++ = tohex (*bin++ & 0xf);
-    }
-  *hex = 0;
-  return i;
-}
-
-/* Convert BUFFER, binary data at least LEN bytes long, into escaped
-   binary data in OUT_BUF.  Set *OUT_LEN to the length of the data
-   encoded in OUT_BUF, and return the number of bytes in OUT_BUF
-   (which may be more than *OUT_LEN due to escape characters).  The
-   total number of bytes in the output buffer will be at most
-   OUT_MAXLEN.  */
-
-int
-remote_escape_output (const gdb_byte *buffer, int len,
-                     gdb_byte *out_buf, int *out_len,
-                     int out_maxlen)
-{
-  int input_index, output_index;
-
-  output_index = 0;
-  for (input_index = 0; input_index < len; input_index++)
-    {
-      gdb_byte b = buffer[input_index];
-
-      if (b == '$' || b == '#' || b == '}' || b == '*')
-       {
-         /* These must be escaped.  */
-         if (output_index + 2 > out_maxlen)
-           break;
-         out_buf[output_index++] = '}';
-         out_buf[output_index++] = b ^ 0x20;
-       }
-      else
-       {
-         if (output_index + 1 > out_maxlen)
-           break;
-         out_buf[output_index++] = b;
-       }
-    }
-
-  *out_len = input_index;
-  return output_index;
-}
-
-/* Convert BUFFER, escaped data LEN bytes long, into binary data
-   in OUT_BUF.  Return the number of bytes written to OUT_BUF.
-   Raise an error if the total number of bytes exceeds OUT_MAXLEN.
-
-   This function reverses remote_escape_output.  It allows more
-   escaped characters than that function does, in particular because
-   '*' must be escaped to avoid the run-length encoding processing
-   in reading packets.  */
-
-static int
-remote_unescape_input (const gdb_byte *buffer, int len,
-                      gdb_byte *out_buf, int out_maxlen)
-{
-  int input_index, output_index;
-  int escaped;
-
-  output_index = 0;
-  escaped = 0;
-  for (input_index = 0; input_index < len; input_index++)
-    {
-      gdb_byte b = buffer[input_index];
-
-      if (output_index + 1 > out_maxlen)
-       error ("Received too much data from the target.");
-
-      if (escaped)
-       {
-         out_buf[output_index++] = b ^ 0x20;
-         escaped = 0;
-       }
-      else if (b == '}')
-       escaped = 1;
-      else
-       out_buf[output_index++] = b;
-    }
-
-  if (escaped)
-    error ("Unmatched escape character in target response.");
-
-  return output_index;
-}
-
 /* Look for a sequence of characters which can be run-length encoded.
    If there are any, update *CSUM and *P.  Otherwise, output the
    single character.  Return the number of characters consumed.  */
@@ -632,23 +505,6 @@ try_rle (char *buf, int remaining, unsigned char *csum, char **p)
 
 #endif
 
-char *
-unpack_varlen_hex (char *buff, /* packet to parse */
-                  ULONGEST *result)
-{
-  int nibble;
-  ULONGEST retval = 0;
-
-  while (ishex (*buff, &nibble))
-    {
-      buff++;
-      retval = retval << 4;
-      retval |= nibble & 0x0f;
-    }
-  *result = retval;
-  return buff;
-}
-
 #ifndef IN_PROCESS_AGENT
 
 /* Write a PTID to BUF.  Returns BUF+CHARACTERS_WRITTEN.  */
@@ -724,13 +580,39 @@ read_ptid (char *buf, char **obuf)
 
   /* Since the stub is not sending a process id, then default to
      what's in the current inferior.  */
-  pid = ptid_get_pid (((struct inferior_list_entry *) current_inferior)->id);
+  pid = ptid_get_pid (current_ptid);
 
   if (obuf)
     *obuf = pp;
   return ptid_build (pid, tid, 0);
 }
 
+/* Write COUNT bytes in BUF to the client.
+   The result is the number of bytes written or -1 if error.
+   This may return less than COUNT.  */
+
+static int
+write_prim (const void *buf, int count)
+{
+  if (remote_connection_is_stdio ())
+    return write (fileno (stdout), buf, count);
+  else
+    return write (remote_desc, buf, count);
+}
+
+/* Read COUNT bytes from the client and store in BUF.
+   The result is the number of bytes read or -1 if error.
+   This may return less than COUNT.  */
+
+static int
+read_prim (void *buf, int count)
+{
+  if (remote_connection_is_stdio ())
+    return read (fileno (stdin), buf, count);
+  else
+    return read (remote_desc, buf, count);
+}
+
 /* Send a packet to the remote machine, with error checking.
    The data of the packet is in BUF, and the length of the
    packet is in CNT.  Returns >= 0 on success, -1 otherwise.  */
@@ -768,7 +650,7 @@ putpkt_binary_1 (char *buf, int cnt, int is_notif)
 
   do
     {
-      if (write (remote_desc, buf2, p - buf2) != p - buf2)
+      if (write_prim (buf2, p - buf2) != p - buf2)
        {
          perror ("putpkt(write)");
          free (buf2);
@@ -863,7 +745,7 @@ input_interrupt (int unused)
       int cc;
       char c = 0;
 
-      cc = read (remote_desc, &c, 1);
+      cc = read_prim (&c, 1);
 
       if (cc != 1 || c != '\003' || current_inferior == NULL)
        {
@@ -991,8 +873,7 @@ readchar (void)
 
   if (readchar_bufcnt == 0)
     {
-      readchar_bufcnt = read (remote_desc, readchar_buf,
-                             sizeof (readchar_buf));
+      readchar_bufcnt = read_prim (readchar_buf, sizeof (readchar_buf));
 
       if (readchar_bufcnt <= 0)
        {
@@ -1114,7 +995,7 @@ getpkt (char *buf)
 
       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
               (c1 << 4) + c2, csum, buf);
-      if (write (remote_desc, "-", 1) != 1)
+      if (write_prim ("-", 1) != 1)
        return -1;
     }
 
@@ -1126,7 +1007,7 @@ getpkt (char *buf)
          fflush (stderr);
        }
 
-      if (write (remote_desc, "+", 1) != 1)
+      if (write_prim ("+", 1) != 1)
        return -1;
 
       if (remote_debug)
@@ -1167,36 +1048,8 @@ write_enn (char *buf)
 
 #endif
 
-void
-convert_int_to_ascii (const unsigned char *from, char *to, int n)
-{
-  int nib;
-  int ch;
-  while (n--)
-    {
-      ch = *from++;
-      nib = ((ch & 0xf0) >> 4) & 0x0f;
-      *to++ = tohex (nib);
-      nib = ch & 0x0f;
-      *to++ = tohex (nib);
-    }
-  *to++ = 0;
-}
-
 #ifndef IN_PROCESS_AGENT
 
-void
-convert_ascii_to_int (const char *from, unsigned char *to, int n)
-{
-  int nib1, nib2;
-  while (n--)
-    {
-      nib1 = fromhex (*from++);
-      nib2 = fromhex (*from++);
-      *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
-    }
-}
-
 static char *
 outreg (struct regcache *regcache, int regno, char *buf)
 {
@@ -1208,7 +1061,7 @@ outreg (struct regcache *regcache, int regno, char *buf)
   *buf++ = tohex (regno & 0xf);
   *buf++ = ':';
   collect_register_as_string (regcache, regno, buf);
-  buf += 2 * register_size (regno);
+  buf += 2 * register_size (regcache->tdesc, regno);
   *buf++ = ';';
 
   return buf;
@@ -1252,8 +1105,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
                      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n\n",
-            target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+                 target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
@@ -1266,12 +1119,12 @@ prepare_resume_reply (char *buf, ptid_t ptid,
        sprintf (buf, "T%02x", status->value.sig);
        buf += strlen (buf);
 
-       regp = gdbserver_expedite_regs;
-
        saved_inferior = current_inferior;
 
        current_inferior = find_thread_ptid (ptid);
 
+       regp = current_target_desc ()->expedite_regs;
+
        regcache = get_thread_regcache (current_inferior, 1);
 
        if (the_target->stopped_by_watchpoint != NULL
@@ -1296,7 +1149,7 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 
        while (*regp)
          {
-           buf = outreg (regcache, find_regno (*regp), buf);
+           buf = outreg (regcache, find_regno (regcache->tdesc, *regp), buf);
            regp ++;
          }
        *buf = '\0';
@@ -1329,8 +1182,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
                strcat (buf, ";");
                buf += strlen (buf);
 
-               if (the_target->core_of_thread)
-                 core = (*the_target->core_of_thread) (ptid);
+               core = target_core_of_thread (ptid);
+
                if (core != -1)
                  {
                    sprintf (buf, "core:");
@@ -1546,7 +1399,8 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
 
   /* Send the request.  */
   strcpy (own_buf, "qSymbol:");
-  hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
+  bin2hex ((const gdb_byte *) name, own_buf + strlen ("qSymbol:"),
+         strlen (name));
   if (putpkt (own_buf) < 0)
     return -1;
 
@@ -1569,7 +1423,7 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
       decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
       mem_buf = xmalloc (mem_len);
       if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-       convert_int_to_ascii (mem_buf, own_buf, mem_len);
+       bin2hex (mem_buf, own_buf, mem_len);
       else
        write_enn (own_buf);
       free (mem_buf);
@@ -1653,7 +1507,7 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
          decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
          mem_buf = xmalloc (mem_len);
          if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-           convert_int_to_ascii (mem_buf, own_buf, mem_len);
+           bin2hex (mem_buf, own_buf, mem_len);
          else
            write_enn (own_buf);
        }
@@ -1705,10 +1559,11 @@ relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
 void
 monitor_output (const char *msg)
 {
-  char *buf = xmalloc (strlen (msg) * 2 + 2);
+  int len = strlen (msg);
+  char *buf = xmalloc (len * 2 + 2);
 
   buf[0] = 'O';
-  hexify (buf + 1, msg, 0);
+  bin2hex ((const gdb_byte *) msg, buf + 1, len);
 
   putpkt (buf);
   free (buf);
This page took 0.039993 seconds and 4 git commands to generate.