GDBserver
|
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 }