2011-02-26 Michael Snyder <msnyder@vmware.com>
[external/binutils.git] / gdb / gdbserver / utils.c
1 /* General utility routines for the remote server for GDB.
2    Copyright (C) 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
3    2007, 2008, 2009, 2010, 2011 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 "server.h"
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #if HAVE_ERRNO_H
25 #include <errno.h>
26 #endif
27
28 #ifdef IN_PROCESS_AGENT
29 #  define PREFIX "ipa: "
30 #  define TOOLNAME "GDBserver in-process agent"
31 #else
32 #  define PREFIX "gdbserver: "
33 #  define TOOLNAME "GDBserver"
34 #endif
35
36 /* Generally useful subroutines used throughout the program.  */
37
38 static void malloc_failure (size_t size) ATTR_NORETURN;
39
40 static void
41 malloc_failure (size_t size)
42 {
43   fprintf (stderr,
44            PREFIX "ran out of memory while trying to allocate %lu bytes\n",
45            (unsigned long) size);
46   exit (1);
47 }
48
49 /* Allocate memory without fail.
50    If malloc fails, this will print a message to stderr and exit.  */
51
52 void *
53 xmalloc (size_t size)
54 {
55   void *newmem;
56
57   if (size == 0)
58     size = 1;
59   newmem = malloc (size);
60   if (!newmem)
61     malloc_failure (size);
62
63   return newmem;
64 }
65
66 /* Reallocate memory without fail.  This works like xmalloc. */
67
68 void *
69 xrealloc (void *ptr, size_t size)
70 {
71   void *val;
72
73   if (size == 0)
74     size = 1;
75
76   if (ptr != NULL)
77     val = realloc (ptr, size);  /* OK: realloc */
78   else
79     val = malloc (size);        /* OK: malloc */
80   if (val == NULL)
81     malloc_failure (size);
82
83   return val;
84 }
85
86 /* Allocate memory without fail and set it to zero.
87    If malloc fails, this will print a message to stderr and exit.  */
88
89 void *
90 xcalloc (size_t nelem, size_t elsize)
91 {
92   void *newmem;
93
94   if (nelem == 0 || elsize == 0)
95     nelem = elsize = 1;
96
97   newmem = calloc (nelem, elsize);
98   if (!newmem)
99     malloc_failure (nelem * elsize);
100
101   return newmem;
102 }
103
104 /* Copy a string into a memory buffer.
105    If malloc fails, this will print a message to stderr and exit.  */
106
107 char *
108 xstrdup (const char *s)
109 {
110   char *ret = strdup (s);
111   if (ret == NULL)
112     malloc_failure (strlen (s) + 1);
113   return ret;
114 }
115
116 #ifndef IN_PROCESS_AGENT
117
118 /* Free a standard argv vector.  */
119
120 void
121 freeargv (char **vector)
122 {
123   char **scan;
124
125   if (vector != NULL)
126     {
127       for (scan = vector; *scan != NULL; scan++)
128         {
129           free (*scan);
130         }
131       free (vector);
132     }
133 }
134
135 #endif
136
137 /* Print the system error message for errno, and also mention STRING
138    as the file name for which the error was encountered.
139    Then return to command level.  */
140
141 void
142 perror_with_name (const char *string)
143 {
144   const char *err;
145   char *combined;
146
147   err = strerror (errno);
148   if (err == NULL)
149     err = "unknown error";
150
151   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
152   strcpy (combined, string);
153   strcat (combined, ": ");
154   strcat (combined, err);
155
156   error ("%s.", combined);
157 }
158
159 /* Print an error message and return to command level.
160    STRING is the error message, used as a fprintf string,
161    and ARG is passed as an argument to it.  */
162
163 void
164 error (const char *string,...)
165 {
166 #ifndef IN_PROCESS_AGENT
167   extern jmp_buf toplevel;
168 #endif
169   va_list args;
170   va_start (args, string);
171   fflush (stdout);
172   vfprintf (stderr, string, args);
173   fprintf (stderr, "\n");
174 #ifndef IN_PROCESS_AGENT
175   longjmp (toplevel, 1);
176 #else
177   exit (1);
178 #endif
179 }
180
181 /* Print an error message and exit reporting failure.
182    This is for a error that we cannot continue from.
183    STRING and ARG are passed to fprintf.  */
184
185 /* VARARGS */
186 void
187 fatal (const char *string,...)
188 {
189   va_list args;
190   va_start (args, string);
191   fprintf (stderr, PREFIX);
192   vfprintf (stderr, string, args);
193   fprintf (stderr, "\n");
194   va_end (args);
195   exit (1);
196 }
197
198 /* VARARGS */
199 void
200 warning (const char *string,...)
201 {
202   va_list args;
203   va_start (args, string);
204   fprintf (stderr, PREFIX);
205   vfprintf (stderr, string, args);
206   fprintf (stderr, "\n");
207   va_end (args);
208 }
209
210 /* Report a problem internal to GDBserver, and exit.  */
211
212 void
213 internal_error (const char *file, int line, const char *fmt, ...)
214 {
215   va_list args;
216   va_start (args, fmt);
217
218   fprintf (stderr,  "\
219 %s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line);
220   vfprintf (stderr, fmt, args);
221   fprintf (stderr, "\n");
222   va_end (args);
223   exit (1);
224 }
225
226 /* Temporary storage using circular buffer.  */
227 #define NUMCELLS 10
228 #define CELLSIZE 50
229
230 /* Return the next entry in the circular buffer.  */
231
232 static char *
233 get_cell (void)
234 {
235   static char buf[NUMCELLS][CELLSIZE];
236   static int cell = 0;
237   if (++cell >= NUMCELLS)
238     cell = 0;
239   return buf[cell];
240 }
241
242 /* Stdarg wrapper around vsnprintf.
243    SIZE is the size of the buffer pointed to by STR.  */
244
245 int
246 xsnprintf (char *str, size_t size, const char *format, ...)
247 {
248   va_list args;
249   int ret;
250
251   va_start (args, format);
252   ret = vsnprintf (str, size, format, args);
253   va_end (args);
254
255   return ret;
256 }
257
258 static char *
259 decimal2str (char *sign, ULONGEST addr)
260 {
261   /* Steal code from valprint.c:print_decimal().  Should this worry
262      about the real size of addr as the above does? */
263   unsigned long temp[3];
264   char *str = get_cell ();
265   int i = 0;
266   int width;
267
268   do
269     {
270       temp[i] = addr % (1000 * 1000 * 1000);
271       addr /= (1000 * 1000 * 1000);
272       i++;
273       width -= 9;
274     }
275   while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
276
277   width = 9;
278
279   switch (i)
280     {
281     case 1:
282       xsnprintf (str, CELLSIZE, "%s%0*lu", sign, width, temp[0]);
283       break;
284     case 2:
285       xsnprintf (str, CELLSIZE, "%s%0*lu%09lu", sign, width,
286                  temp[1], temp[0]);
287       break;
288     case 3:
289       xsnprintf (str, CELLSIZE, "%s%0*lu%09lu%09lu", sign, width,
290                  temp[2], temp[1], temp[0]);
291       break;
292     default:
293       internal_error (__FILE__, __LINE__,
294                       "failed internal consistency check");
295     }
296
297   return str;
298 }
299
300 /* %u for ULONGEST.  The result is stored in a circular static buffer,
301    NUMCELLS deep.  */
302
303 char *
304 pulongest (ULONGEST u)
305 {
306   return decimal2str ("", u);
307 }
308
309 /* %d for LONGEST.  The result is stored in a circular static buffer,
310    NUMCELLS deep.  */
311
312 char *
313 plongest (LONGEST l)
314 {
315   if (l < 0)
316     return decimal2str ("-", -l);
317   else
318     return decimal2str ("", l);
319 }
320
321 /* Eliminate warning from compiler on 32-bit systems.  */
322 static int thirty_two = 32;
323
324 /* Convert a ULONGEST into a HEX string, like %lx.  The result is
325    stored in a circular static buffer, NUMCELLS deep.  */
326
327 char *
328 phex_nz (ULONGEST l, int sizeof_l)
329 {
330   char *str;
331
332   switch (sizeof_l)
333     {
334     case 8:
335       {
336         unsigned long high = (unsigned long) (l >> thirty_two);
337         str = get_cell ();
338         if (high == 0)
339           xsnprintf (str, CELLSIZE, "%lx",
340                      (unsigned long) (l & 0xffffffff));
341         else
342           xsnprintf (str, CELLSIZE, "%lx%08lx", high,
343                      (unsigned long) (l & 0xffffffff));
344         break;
345       }
346     case 4:
347       str = get_cell ();
348       xsnprintf (str, CELLSIZE, "%lx", (unsigned long) l);
349       break;
350     case 2:
351       str = get_cell ();
352       xsnprintf (str, CELLSIZE, "%x", (unsigned short) (l & 0xffff));
353       break;
354     default:
355       str = phex_nz (l, sizeof (l));
356       break;
357     }
358
359   return str;
360 }
361
362 /* Convert a CORE_ADDR into a HEX string, like %lx.
363    The result is stored in a circular static buffer, NUMCELLS deep.  */
364
365 char *
366 paddress (CORE_ADDR addr)
367 {
368   return phex_nz (addr, sizeof (CORE_ADDR));
369 }
370
371 /* Convert a file descriptor into a printable string.  */
372
373 char *
374 pfildes (gdb_fildes_t fd)
375 {
376 #if USE_WIN32API
377   return phex_nz (fd, sizeof (gdb_fildes_t));
378 #else
379   return plongest (fd);
380 #endif
381 }