1 /* Low-level RSP routines for GDB, the GNU debugger.
2 
3    Copyright (C) 1988-2021 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "common-defs.h"
21 #include "rsp-low.h"
22 
23 /* See rsp-low.h.  */
24 
25 int
tohex(int nib)26 tohex (int nib)
27 {
28   if (nib < 10)
29     return '0' + nib;
30   else
31     return 'a' + nib - 10;
32 }
33 
34 /* Encode 64 bits in 16 chars of hex.  */
35 
36 static const char hexchars[] = "0123456789abcdef";
37 
38 static int
ishex(int ch,int * val)39 ishex (int ch, int *val)
40 {
41   if ((ch >= 'a') && (ch <= 'f'))
42     {
43       *val = ch - 'a' + 10;
44       return 1;
45     }
46   if ((ch >= 'A') && (ch <= 'F'))
47     {
48       *val = ch - 'A' + 10;
49       return 1;
50     }
51   if ((ch >= '0') && (ch <= '9'))
52     {
53       *val = ch - '0';
54       return 1;
55     }
56   return 0;
57 }
58 
59 /* See rsp-low.h.  */
60 
61 char *
pack_nibble(char * buf,int nibble)62 pack_nibble (char *buf, int nibble)
63 {
64   *buf++ = hexchars[(nibble & 0x0f)];
65   return buf;
66 }
67 
68 /* See rsp-low.h.  */
69 
70 char *
pack_hex_byte(char * pkt,int byte)71 pack_hex_byte (char *pkt, int byte)
72 {
73   *pkt++ = hexchars[(byte >> 4) & 0xf];
74   *pkt++ = hexchars[(byte & 0xf)];
75   return pkt;
76 }
77 
78 /* See rsp-low.h.  */
79 
80 const char *
unpack_varlen_hex(const char * buff,ULONGEST * result)81 unpack_varlen_hex (const char *buff,	/* packet to parse */
82 		   ULONGEST *result)
83 {
84   int nibble;
85   ULONGEST retval = 0;
86 
87   while (ishex (*buff, &nibble))
88     {
89       buff++;
90       retval = retval << 4;
91       retval |= nibble & 0x0f;
92     }
93   *result = retval;
94   return buff;
95 }
96 
97 /* See rsp-low.h.  */
98 
99 std::string
hex2str(const char * hex)100 hex2str (const char *hex)
101 {
102   return hex2str (hex, strlen (hex));
103 }
104 
105 /* See rsp-low.h.  */
106 
107 std::string
hex2str(const char * hex,int count)108 hex2str (const char *hex, int count)
109 {
110   std::string ret;
111 
112   ret.reserve (count);
113   for (size_t i = 0; i < count; ++i)
114     {
115       if (hex[0] == '\0' || hex[1] == '\0')
116 	{
117 	  /* Hex string is short, or of uneven length.  Return what we
118 	     have so far.  */
119 	  return ret;
120 	}
121       ret += fromhex (hex[0]) * 16 + fromhex (hex[1]);
122       hex += 2;
123     }
124 
125   return ret;
126 }
127 
128 /* See rsp-low.h.  */
129 
130 int
bin2hex(const gdb_byte * bin,char * hex,int count)131 bin2hex (const gdb_byte *bin, char *hex, int count)
132 {
133   int i;
134 
135   for (i = 0; i < count; i++)
136     {
137       *hex++ = tohex ((*bin >> 4) & 0xf);
138       *hex++ = tohex (*bin++ & 0xf);
139     }
140   *hex = 0;
141   return i;
142 }
143 
144 /* See rsp-low.h.  */
145 
146 std::string
bin2hex(const gdb_byte * bin,int count)147 bin2hex (const gdb_byte *bin, int count)
148 {
149   std::string ret;
150 
151   ret.reserve (count * 2);
152   for (int i = 0; i < count; ++i)
153     {
154       ret += tohex ((*bin >> 4) & 0xf);
155       ret += tohex (*bin++ & 0xf);
156     }
157 
158   return ret;
159 }
160 
161 /* Return whether byte B needs escaping when sent as part of binary data.  */
162 
163 static int
needs_escaping(gdb_byte b)164 needs_escaping (gdb_byte b)
165 {
166   return b == '$' || b == '#' || b == '}' || b == '*';
167 }
168 
169 /* See rsp-low.h.  */
170 
171 int
remote_escape_output(const gdb_byte * buffer,int len_units,int unit_size,gdb_byte * out_buf,int * out_len_units,int out_maxlen_bytes)172 remote_escape_output (const gdb_byte *buffer, int len_units, int unit_size,
173 		      gdb_byte *out_buf, int *out_len_units,
174 		      int out_maxlen_bytes)
175 {
176   int input_unit_index, output_byte_index = 0, byte_index_in_unit;
177   int number_escape_bytes_needed;
178 
179   /* Try to copy integral addressable memory units until
180      (1) we run out of space or
181      (2) we copied all of them.  */
182   for (input_unit_index = 0;
183        input_unit_index < len_units;
184        input_unit_index++)
185     {
186       /* Find out how many escape bytes we need for this unit.  */
187       number_escape_bytes_needed = 0;
188       for (byte_index_in_unit = 0;
189 	   byte_index_in_unit < unit_size;
190 	   byte_index_in_unit++)
191 	{
192 	  int idx = input_unit_index * unit_size + byte_index_in_unit;
193 	  gdb_byte b = buffer[idx];
194 	  if (needs_escaping (b))
195 	    number_escape_bytes_needed++;
196 	}
197 
198       /* Check if we have room to fit this escaped unit.  */
199       if (output_byte_index + unit_size + number_escape_bytes_needed >
200 	    out_maxlen_bytes)
201 	  break;
202 
203       /* Copy the unit byte per byte, adding escapes.  */
204       for (byte_index_in_unit = 0;
205 	   byte_index_in_unit < unit_size;
206 	   byte_index_in_unit++)
207 	{
208 	  int idx = input_unit_index * unit_size + byte_index_in_unit;
209 	  gdb_byte b = buffer[idx];
210 	  if (needs_escaping (b))
211 	    {
212 	      out_buf[output_byte_index++] = '}';
213 	      out_buf[output_byte_index++] = b ^ 0x20;
214 	    }
215 	  else
216 	    out_buf[output_byte_index++] = b;
217 	}
218     }
219 
220   *out_len_units = input_unit_index;
221   return output_byte_index;
222 }
223 
224 /* See rsp-low.h.  */
225 
226 int
remote_unescape_input(const gdb_byte * buffer,int len,gdb_byte * out_buf,int out_maxlen)227 remote_unescape_input (const gdb_byte *buffer, int len,
228 		       gdb_byte *out_buf, int out_maxlen)
229 {
230   int input_index, output_index;
231   int escaped;
232 
233   output_index = 0;
234   escaped = 0;
235   for (input_index = 0; input_index < len; input_index++)
236     {
237       gdb_byte b = buffer[input_index];
238 
239       if (output_index + 1 > out_maxlen)
240 	error (_("Received too much data from the target."));
241 
242       if (escaped)
243 	{
244 	  out_buf[output_index++] = b ^ 0x20;
245 	  escaped = 0;
246 	}
247       else if (b == '}')
248 	escaped = 1;
249       else
250 	out_buf[output_index++] = b;
251     }
252 
253   if (escaped)
254     error (_("Unmatched escape character in target response."));
255 
256   return output_index;
257 }
258 
259