gdb/common/rsp-low.c - gdb

Global variables defined

Functions defined

Source code

  1. /* Low-level RSP routines for GDB, the GNU debugger.

  2.    Copyright (C) 1988-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "common-defs.h"
  15. #include "rsp-low.h"

  16. /* See rsp-low.h.  */

  17. int
  18. fromhex (int a)
  19. {
  20.   if (a >= '0' && a <= '9')
  21.     return a - '0';
  22.   else if (a >= 'a' && a <= 'f')
  23.     return a - 'a' + 10;
  24.   else if (a >= 'A' && a <= 'F')
  25.     return a - 'A' + 10;
  26.   else
  27.     error (_("Reply contains invalid hex digit %d"), a);
  28. }

  29. /* See rsp-low.h.  */

  30. int
  31. tohex (int nib)
  32. {
  33.   if (nib < 10)
  34.     return '0' + nib;
  35.   else
  36.     return 'a' + nib - 10;
  37. }

  38. /* Encode 64 bits in 16 chars of hex.  */

  39. static const char hexchars[] = "0123456789abcdef";

  40. static int
  41. ishex (int ch, int *val)
  42. {
  43.   if ((ch >= 'a') && (ch <= 'f'))
  44.     {
  45.       *val = ch - 'a' + 10;
  46.       return 1;
  47.     }
  48.   if ((ch >= 'A') && (ch <= 'F'))
  49.     {
  50.       *val = ch - 'A' + 10;
  51.       return 1;
  52.     }
  53.   if ((ch >= '0') && (ch <= '9'))
  54.     {
  55.       *val = ch - '0';
  56.       return 1;
  57.     }
  58.   return 0;
  59. }

  60. /* See rsp-low.h.  */

  61. char *
  62. pack_nibble (char *buf, int nibble)
  63. {
  64.   *buf++ = hexchars[(nibble & 0x0f)];
  65.   return buf;
  66. }

  67. /* See rsp-low.h.  */

  68. char *
  69. pack_hex_byte (char *pkt, int byte)
  70. {
  71.   *pkt++ = hexchars[(byte >> 4) & 0xf];
  72.   *pkt++ = hexchars[(byte & 0xf)];
  73.   return pkt;
  74. }

  75. /* See rsp-low.h.  */

  76. char *
  77. unpack_varlen_hex (char *buff,        /* packet to parse */
  78.                    ULONGEST *result)
  79. {
  80.   int nibble;
  81.   ULONGEST retval = 0;

  82.   while (ishex (*buff, &nibble))
  83.     {
  84.       buff++;
  85.       retval = retval << 4;
  86.       retval |= nibble & 0x0f;
  87.     }
  88.   *result = retval;
  89.   return buff;
  90. }

  91. /* See rsp-low.h.  */

  92. int
  93. hex2bin (const char *hex, gdb_byte *bin, int count)
  94. {
  95.   int i;

  96.   for (i = 0; i < count; i++)
  97.     {
  98.       if (hex[0] == 0 || hex[1] == 0)
  99.         {
  100.           /* Hex string is short, or of uneven length.
  101.              Return the count that has been converted so far.  */
  102.           return i;
  103.         }
  104.       *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
  105.       hex += 2;
  106.     }
  107.   return i;
  108. }

  109. /* See rsp-low.h.  */

  110. int
  111. bin2hex (const gdb_byte *bin, char *hex, int count)
  112. {
  113.   int i;

  114.   for (i = 0; i < count; i++)
  115.     {
  116.       *hex++ = tohex ((*bin >> 4) & 0xf);
  117.       *hex++ = tohex (*bin++ & 0xf);
  118.     }
  119.   *hex = 0;
  120.   return i;
  121. }

  122. /* See rsp-low.h.  */

  123. int
  124. remote_escape_output (const gdb_byte *buffer, int len,
  125.                       gdb_byte *out_buf, int *out_len,
  126.                       int out_maxlen)
  127. {
  128.   int input_index, output_index;

  129.   output_index = 0;
  130.   for (input_index = 0; input_index < len; input_index++)
  131.     {
  132.       gdb_byte b = buffer[input_index];

  133.       if (b == '$' || b == '#' || b == '}' || b == '*')
  134.         {
  135.           /* These must be escaped.  */
  136.           if (output_index + 2 > out_maxlen)
  137.             break;
  138.           out_buf[output_index++] = '}';
  139.           out_buf[output_index++] = b ^ 0x20;
  140.         }
  141.       else
  142.         {
  143.           if (output_index + 1 > out_maxlen)
  144.             break;
  145.           out_buf[output_index++] = b;
  146.         }
  147.     }

  148.   *out_len = input_index;
  149.   return output_index;
  150. }

  151. /* See rsp-low.h.  */

  152. int
  153. remote_unescape_input (const gdb_byte *buffer, int len,
  154.                        gdb_byte *out_buf, int out_maxlen)
  155. {
  156.   int input_index, output_index;
  157.   int escaped;

  158.   output_index = 0;
  159.   escaped = 0;
  160.   for (input_index = 0; input_index < len; input_index++)
  161.     {
  162.       gdb_byte b = buffer[input_index];

  163.       if (output_index + 1 > out_maxlen)
  164.         error (_("Received too much data from the target."));

  165.       if (escaped)
  166.         {
  167.           out_buf[output_index++] = b ^ 0x20;
  168.           escaped = 0;
  169.         }
  170.       else if (b == '}')
  171.         escaped = 1;
  172.       else
  173.         out_buf[output_index++] = b;
  174.     }

  175.   if (escaped)
  176.     error (_("Unmatched escape character in target response."));

  177.   return output_index;
  178. }