GDBserver
/home/stan/gdb/src/gdb/gdbserver/utils.c
Go to the documentation of this file.
00001 /* General utility routines for the remote server for GDB.
00002    Copyright (C) 1986-2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 #include "server.h"
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #if HAVE_ERRNO_H
00024 #include <errno.h>
00025 #endif
00026 
00027 #ifdef IN_PROCESS_AGENT
00028 #  define PREFIX "ipa: "
00029 #  define TOOLNAME "GDBserver in-process agent"
00030 #else
00031 #  define PREFIX "gdbserver: "
00032 #  define TOOLNAME "GDBserver"
00033 #endif
00034 
00035 /* Generally useful subroutines used throughout the program.  */
00036 
00037 void
00038 malloc_failure (long size)
00039 {
00040   fprintf (stderr,
00041            PREFIX "ran out of memory while trying to allocate %lu bytes\n",
00042            (unsigned long) size);
00043   exit (1);
00044 }
00045 
00046 /* Copy a string into a memory buffer.
00047    If malloc fails, this will print a message to stderr and exit.  */
00048 
00049 char *
00050 xstrdup (const char *s)
00051 {
00052   char *ret = strdup (s);
00053   if (ret == NULL)
00054     malloc_failure (strlen (s) + 1);
00055   return ret;
00056 }
00057 
00058 #ifndef IN_PROCESS_AGENT
00059 
00060 /* Free a standard argv vector.  */
00061 
00062 void
00063 freeargv (char **vector)
00064 {
00065   char **scan;
00066 
00067   if (vector != NULL)
00068     {
00069       for (scan = vector; *scan != NULL; scan++)
00070         {
00071           free (*scan);
00072         }
00073       free (vector);
00074     }
00075 }
00076 
00077 #endif
00078 
00079 /* Print the system error message for errno, and also mention STRING
00080    as the file name for which the error was encountered.
00081    Then return to command level.  */
00082 
00083 void
00084 perror_with_name (const char *string)
00085 {
00086   const char *err;
00087   char *combined;
00088 
00089   err = strerror (errno);
00090   if (err == NULL)
00091     err = "unknown error";
00092 
00093   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
00094   strcpy (combined, string);
00095   strcat (combined, ": ");
00096   strcat (combined, err);
00097 
00098   error ("%s.", combined);
00099 }
00100 
00101 /* Print an error message and return to command level.
00102    STRING is the error message, used as a fprintf string,
00103    and ARG is passed as an argument to it.  */
00104 
00105 void
00106 error (const char *string,...)
00107 {
00108 #ifndef IN_PROCESS_AGENT
00109   extern jmp_buf toplevel;
00110 #endif
00111   va_list args;
00112   va_start (args, string);
00113   fflush (stdout);
00114   vfprintf (stderr, string, args);
00115   fprintf (stderr, "\n");
00116 #ifndef IN_PROCESS_AGENT
00117   longjmp (toplevel, 1);
00118 #else
00119   exit (1);
00120 #endif
00121 }
00122 
00123 /* Print an error message and exit reporting failure.
00124    This is for a error that we cannot continue from.
00125    STRING and ARG are passed to fprintf.  */
00126 
00127 /* VARARGS */
00128 void
00129 fatal (const char *string,...)
00130 {
00131   va_list args;
00132   va_start (args, string);
00133   fprintf (stderr, PREFIX);
00134   vfprintf (stderr, string, args);
00135   fprintf (stderr, "\n");
00136   va_end (args);
00137   exit (1);
00138 }
00139 
00140 /* VARARGS */
00141 void
00142 warning (const char *string,...)
00143 {
00144   va_list args;
00145   va_start (args, string);
00146   fprintf (stderr, PREFIX);
00147   vfprintf (stderr, string, args);
00148   fprintf (stderr, "\n");
00149   va_end (args);
00150 }
00151 
00152 /* Report a problem internal to GDBserver, and exit.  */
00153 
00154 void
00155 internal_error (const char *file, int line, const char *fmt, ...)
00156 {
00157   va_list args;
00158   va_start (args, fmt);
00159 
00160   fprintf (stderr,  "\
00161 %s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line);
00162   vfprintf (stderr, fmt, args);
00163   fprintf (stderr, "\n");
00164   va_end (args);
00165   exit (1);
00166 }
00167 
00168 /* Temporary storage using circular buffer.  */
00169 #define NUMCELLS 10
00170 #define CELLSIZE 50
00171 
00172 /* Return the next entry in the circular buffer.  */
00173 
00174 static char *
00175 get_cell (void)
00176 {
00177   static char buf[NUMCELLS][CELLSIZE];
00178   static int cell = 0;
00179   if (++cell >= NUMCELLS)
00180     cell = 0;
00181   return buf[cell];
00182 }
00183 
00184 static char *
00185 decimal2str (char *sign, ULONGEST addr)
00186 {
00187   /* Steal code from valprint.c:print_decimal().  Should this worry
00188      about the real size of addr as the above does? */
00189   unsigned long temp[3];
00190   char *str = get_cell ();
00191   int i = 0;
00192   int width = 9;
00193 
00194   do
00195     {
00196       temp[i] = addr % (1000 * 1000 * 1000);
00197       addr /= (1000 * 1000 * 1000);
00198       i++;
00199     }
00200   while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
00201 
00202   switch (i)
00203     {
00204     case 1:
00205       xsnprintf (str, CELLSIZE, "%s%0*lu", sign, width, temp[0]);
00206       break;
00207     case 2:
00208       xsnprintf (str, CELLSIZE, "%s%0*lu%09lu", sign, width,
00209                  temp[1], temp[0]);
00210       break;
00211     case 3:
00212       xsnprintf (str, CELLSIZE, "%s%0*lu%09lu%09lu", sign, width,
00213                  temp[2], temp[1], temp[0]);
00214       break;
00215     default:
00216       internal_error (__FILE__, __LINE__,
00217                       "failed internal consistency check");
00218     }
00219 
00220   return str;
00221 }
00222 
00223 /* %u for ULONGEST.  The result is stored in a circular static buffer,
00224    NUMCELLS deep.  */
00225 
00226 char *
00227 pulongest (ULONGEST u)
00228 {
00229   return decimal2str ("", u);
00230 }
00231 
00232 /* %d for LONGEST.  The result is stored in a circular static buffer,
00233    NUMCELLS deep.  */
00234 
00235 char *
00236 plongest (LONGEST l)
00237 {
00238   if (l < 0)
00239     return decimal2str ("-", -l);
00240   else
00241     return decimal2str ("", l);
00242 }
00243 
00244 /* Eliminate warning from compiler on 32-bit systems.  */
00245 static int thirty_two = 32;
00246 
00247 /* Convert a ULONGEST into a HEX string, like %lx.  The result is
00248    stored in a circular static buffer, NUMCELLS deep.  */
00249 
00250 char *
00251 phex_nz (ULONGEST l, int sizeof_l)
00252 {
00253   char *str;
00254 
00255   switch (sizeof_l)
00256     {
00257     case 8:
00258       {
00259         unsigned long high = (unsigned long) (l >> thirty_two);
00260         str = get_cell ();
00261         if (high == 0)
00262           xsnprintf (str, CELLSIZE, "%lx",
00263                      (unsigned long) (l & 0xffffffff));
00264         else
00265           xsnprintf (str, CELLSIZE, "%lx%08lx", high,
00266                      (unsigned long) (l & 0xffffffff));
00267         break;
00268       }
00269     case 4:
00270       str = get_cell ();
00271       xsnprintf (str, CELLSIZE, "%lx", (unsigned long) l);
00272       break;
00273     case 2:
00274       str = get_cell ();
00275       xsnprintf (str, CELLSIZE, "%x", (unsigned short) (l & 0xffff));
00276       break;
00277     default:
00278       str = phex_nz (l, sizeof (l));
00279       break;
00280     }
00281 
00282   return str;
00283 }
00284 
00285 /* Convert a CORE_ADDR into a HEX string, like %lx.
00286    The result is stored in a circular static buffer, NUMCELLS deep.  */
00287 
00288 char *
00289 paddress (CORE_ADDR addr)
00290 {
00291   return phex_nz (addr, sizeof (CORE_ADDR));
00292 }
00293 
00294 /* Convert a file descriptor into a printable string.  */
00295 
00296 char *
00297 pfildes (gdb_fildes_t fd)
00298 {
00299 #if USE_WIN32API
00300   return phex_nz (fd, sizeof (gdb_fildes_t));
00301 #else
00302   return plongest (fd);
00303 #endif
00304 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines