Move common-utils.h to common-defs.h
[platform/upstream/binutils.git] / gdb / common / rsp-low.c
1 /* Low-level RSP routines for GDB, the GNU debugger.
2
3    Copyright (C) 1988-2014 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 #ifdef GDBSERVER
21 #include "server.h"
22 #else
23 #include "defs.h"
24 #endif
25
26 #include <string.h>
27
28 #include "rsp-low.h"
29
30 /* See rsp-low.h.  */
31
32 int
33 fromhex (int a)
34 {
35   if (a >= '0' && a <= '9')
36     return a - '0';
37   else if (a >= 'a' && a <= 'f')
38     return a - 'a' + 10;
39   else if (a >= 'A' && a <= 'F')
40     return a - 'A' + 10;
41   else
42     error (_("Reply contains invalid hex digit %d"), a);
43 }
44
45 /* See rsp-low.h.  */
46
47 int
48 tohex (int nib)
49 {
50   if (nib < 10)
51     return '0' + nib;
52   else
53     return 'a' + nib - 10;
54 }
55
56 /* Encode 64 bits in 16 chars of hex.  */
57
58 static const char hexchars[] = "0123456789abcdef";
59
60 static int
61 ishex (int ch, int *val)
62 {
63   if ((ch >= 'a') && (ch <= 'f'))
64     {
65       *val = ch - 'a' + 10;
66       return 1;
67     }
68   if ((ch >= 'A') && (ch <= 'F'))
69     {
70       *val = ch - 'A' + 10;
71       return 1;
72     }
73   if ((ch >= '0') && (ch <= '9'))
74     {
75       *val = ch - '0';
76       return 1;
77     }
78   return 0;
79 }
80
81 /* See rsp-low.h.  */
82
83 char *
84 pack_nibble (char *buf, int nibble)
85 {
86   *buf++ = hexchars[(nibble & 0x0f)];
87   return buf;
88 }
89
90 /* See rsp-low.h.  */
91
92 char *
93 pack_hex_byte (char *pkt, int byte)
94 {
95   *pkt++ = hexchars[(byte >> 4) & 0xf];
96   *pkt++ = hexchars[(byte & 0xf)];
97   return pkt;
98 }
99
100 /* See rsp-low.h.  */
101
102 char *
103 unpack_varlen_hex (char *buff,  /* packet to parse */
104                    ULONGEST *result)
105 {
106   int nibble;
107   ULONGEST retval = 0;
108
109   while (ishex (*buff, &nibble))
110     {
111       buff++;
112       retval = retval << 4;
113       retval |= nibble & 0x0f;
114     }
115   *result = retval;
116   return buff;
117 }
118
119 /* See rsp-low.h.  */
120
121 int
122 hex2bin (const char *hex, gdb_byte *bin, int count)
123 {
124   int i;
125
126   for (i = 0; i < count; i++)
127     {
128       if (hex[0] == 0 || hex[1] == 0)
129         {
130           /* Hex string is short, or of uneven length.
131              Return the count that has been converted so far.  */
132           return i;
133         }
134       *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
135       hex += 2;
136     }
137   return i;
138 }
139
140 /* See rsp-low.h.  */
141
142 int
143 bin2hex (const gdb_byte *bin, char *hex, int count)
144 {
145   int i;
146
147   for (i = 0; i < count; i++)
148     {
149       *hex++ = tohex ((*bin >> 4) & 0xf);
150       *hex++ = tohex (*bin++ & 0xf);
151     }
152   *hex = 0;
153   return i;
154 }
155
156 /* See rsp-low.h.  */
157
158 int
159 remote_escape_output (const gdb_byte *buffer, int len,
160                       gdb_byte *out_buf, int *out_len,
161                       int out_maxlen)
162 {
163   int input_index, output_index;
164
165   output_index = 0;
166   for (input_index = 0; input_index < len; input_index++)
167     {
168       gdb_byte b = buffer[input_index];
169
170       if (b == '$' || b == '#' || b == '}' || b == '*')
171         {
172           /* These must be escaped.  */
173           if (output_index + 2 > out_maxlen)
174             break;
175           out_buf[output_index++] = '}';
176           out_buf[output_index++] = b ^ 0x20;
177         }
178       else
179         {
180           if (output_index + 1 > out_maxlen)
181             break;
182           out_buf[output_index++] = b;
183         }
184     }
185
186   *out_len = input_index;
187   return output_index;
188 }
189
190 /* See rsp-low.h.  */
191
192 int
193 remote_unescape_input (const gdb_byte *buffer, int len,
194                        gdb_byte *out_buf, int out_maxlen)
195 {
196   int input_index, output_index;
197   int escaped;
198
199   output_index = 0;
200   escaped = 0;
201   for (input_index = 0; input_index < len; input_index++)
202     {
203       gdb_byte b = buffer[input_index];
204
205       if (output_index + 1 > out_maxlen)
206         error (_("Received too much data from the target."));
207
208       if (escaped)
209         {
210           out_buf[output_index++] = b ^ 0x20;
211           escaped = 0;
212         }
213       else if (b == '}')
214         escaped = 1;
215       else
216         out_buf[output_index++] = b;
217     }
218
219   if (escaped)
220     error (_("Unmatched escape character in target response."));
221
222   return output_index;
223 }
224