OSDN Git Service

7653bf01d164bb05e7569bc35953fb4f3fa90622
[pf3gnuchains/pf3gnuchains3x.git] / rda / lib / gdbserv-utils.c
1 /* gdbserv-utils.c
2
3    Copyright 1998, 2000, 2001, 2002 Red Hat, Inc.
4
5    This file is part of RDA, the Red Hat Debug Agent (and library).
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 2 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, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21    
22    Alternative licenses for RDA may be arranged by contacting Red Hat,
23    Inc.  */
24
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "gdbserv.h"
32 #include "gdbserv-utils.h"
33
34
35 unsigned char
36 gdbserv_to_hex (int c)
37 {
38   static const unsigned char hexchars[] = "0123456789abcdef";
39   return hexchars[c & 0xf];
40 }
41
42
43 /* Convert ch from a hex digit to an int. */
44
45 int
46 gdbserv_hex_to (unsigned char ch)
47 {
48   switch (ch)
49     {
50     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
51       return ch-'a'+10;
52     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':      
53       return ch-'A'+10;
54     case '0': case '1': case '2': case '3': case '4':
55     case '5': case '6': case '7': case '8': case '9':
56       return ch-'0';
57     default:
58       return -1;
59     }
60 }
61
62 unsigned int
63 gdbserv_ulong_to_hex (char *ptr, unsigned long ulong_value, int num_bits)
64 {
65   int num_chars = 0;
66
67   if (ulong_value == 0)
68     {
69       *(ptr++) = '0';
70       *(ptr++) = '0';
71       return 2;
72     }
73
74   num_bits = (num_bits + 7) / 8;
75   while (num_bits)
76     {
77       int v = (ulong_value >> ((num_bits - 1) * 8));
78       if (v || (num_bits == 1))
79         {
80           v = v & 255;
81           *(ptr++) = gdbserv_to_hex ((v / 16) & 15);
82           *(ptr++) = gdbserv_to_hex (v & 15);
83           num_chars += 2;
84         }
85       num_bits--;
86     }
87
88   return (num_chars);
89 }
90
91 unsigned int
92 gdbserv_raw_to_hex (char **ptr, char *mem, int nr_bytes)
93 {
94   int i;
95   for (i = 0; i < nr_bytes; i++)
96     {
97       *(*ptr)++ = gdbserv_to_hex (*mem >> 4);
98       *(*ptr)++ = gdbserv_to_hex (*mem++);
99     }
100   return i;
101 }
102
103 void
104 gdbserv_reg_to_ulong (struct gdbserv *gdbserv,
105                       const struct gdbserv_reg *reg,
106                       unsigned long *val)
107 {
108   int i;
109   unsigned long l = 0;
110   for (i = 0; i < reg->len; i++)
111     {
112       l <<= 8;
113       l |= (unsigned char) reg->buf[i];
114     }
115   if (reg->negative_p)
116     (*val) = -l;
117   else
118     (*val) = l;
119 }
120
121
122 void
123 gdbserv_reg_to_ulonglong (struct gdbserv *gdbserv,
124                           const struct gdbserv_reg *reg,
125                           unsigned long long *val)
126 {
127   int i;
128   unsigned long long l = 0;
129   for (i = 0; i < reg->len; i++)
130     {
131       l <<= 8;
132       l |= (unsigned char) reg->buf[i];
133     }
134   if (reg->negative_p)
135     (*val) = -l;
136   else
137     (*val) = l;
138 }
139
140 static void
141 unpack_ulongest (struct gdbserv_reg *reg,
142                  unsigned long long val)
143 {
144   int len;
145   int idx;
146   /* unpack */
147   len = 0;
148   do
149     {
150       reg->buf[sizeof (reg->buf) - len - 1] = val & 0xff;
151       val >>= 8;
152       len++;
153     }
154   while (val != 0);
155   /* left shift */
156   for (idx = 0; idx < len; idx++)
157     {
158       reg->buf[idx] = reg->buf[sizeof (reg->buf) - len + idx];
159     }
160   reg->len = len;
161 }
162
163 void
164 gdbserv_ulong_to_reg (struct gdbserv *gdbserv,
165                       unsigned long val,
166                       struct gdbserv_reg *reg)
167 {
168   reg->negative_p = 0;
169   unpack_ulongest (reg, val);
170 }
171
172 void
173 gdbserv_long_to_reg (struct gdbserv *gdbserv,
174                      long val,
175                      struct gdbserv_reg *reg)
176 {
177   if (val < 0)
178     {
179       reg->negative_p = 1;
180       val = -val;
181     }
182   else
183     reg->negative_p = 0;
184   unpack_ulongest (reg, val);
185 }
186
187 void
188 gdbserv_ulonglong_to_reg (struct gdbserv *gdbserv,
189                           unsigned long long val,
190                           struct gdbserv_reg *reg)
191 {
192   reg->negative_p = 0;
193   unpack_ulongest (reg, val);
194 }
195
196 void
197 gdbserv_longlong_to_reg (struct gdbserv *gdbserv,
198                          long long val,
199                          struct gdbserv_reg *reg)
200 {
201   if (val < 0)
202     {
203       reg->negative_p = 1;
204       val = -val;
205     }
206   else
207     reg->negative_p = 0;
208   unpack_ulongest (reg, val);
209 }
210
211 /* Copy bytes from one buffer to another in reverse order.  Used for
212    converting byte order from big endian to little endian or vice versa.  */
213
214 static void
215 reverse_copy_bytes (void *dest, const void *src, int len)
216 {
217   char *d = dest;
218   const char *s = src;
219   int i;
220
221   for (i = 0; i < len; i++)
222     {
223       d[i] = s[len - i - 1];
224     }
225 }
226
227 void
228 gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
229                          const void *buf,
230                          int len,
231                          struct gdbserv_reg *reg)
232 {
233   reg->negative_p = 0;
234   reg->len = len;
235   memcpy (reg->buf, buf, len);
236 }
237
238 void
239 gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
240                            void *buf,
241                            int *lenp,
242                            const struct gdbserv_reg *reg)
243 {
244   *lenp = reg->len;
245   memcpy (buf, reg->buf, reg->len);
246 }
247
248 void
249 gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
250                          const void *buf,
251                          int len,
252                          struct gdbserv_reg *reg)
253 {
254   reg->negative_p = 0;
255   reg->len = len;
256   reverse_copy_bytes (reg->buf, buf, len);
257 }
258
259 void
260 gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
261                            void *buf,
262                            int *lenp,
263                            const struct gdbserv_reg *reg)
264 {
265   *lenp = reg->len;
266   reverse_copy_bytes (buf, reg->buf, reg->len);
267 }
268
269 void
270 gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
271                            const void *buf,
272                            int len,
273                            struct gdbserv_reg *reg)
274 {
275 #ifdef WORDS_BIGENDIAN
276   gdbserv_be_bytes_to_reg (gdbserv, buf, len, reg);
277 #else
278   gdbserv_le_bytes_to_reg (gdbserv, buf, len, reg);
279 #endif
280 }
281
282 void
283 gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
284                              void *buf,
285                              int *lenp,
286                              const struct gdbserv_reg *reg)
287 {
288 #ifdef WORDS_BIGENDIAN
289   gdbserv_be_bytes_from_reg (gdbserv, buf, lenp, reg);
290 #else
291   gdbserv_le_bytes_from_reg (gdbserv, buf, lenp, reg);
292 #endif
293 }