X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Futils.c;h=e50878a9abd94aa7f40bdab2256b71ab9c8b22e7;hb=623b6bdf12dec583722ca6615e5ff26581597d6c;hp=5935380e064dea53d0263df61aea80473f939e6b;hpb=aa5ca48fad05503860c254806750c8a304ec9fc5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c index 5935380e06..e50878a9ab 100644 --- a/gdb/gdbserver/utils.c +++ b/gdb/gdbserver/utils.c @@ -1,6 +1,6 @@ /* General utility routines for the remote server for GDB. - Copyright (C) 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003, - 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1986, 1989, 1993, 1995-1997, 1999-2000, 2002-2003, + 2007-2012 Free Software Foundation, Inc. This file is part of GDB. @@ -24,57 +24,26 @@ #if HAVE_ERRNO_H #include #endif -#if HAVE_MALLOC_H -#include + +#ifdef IN_PROCESS_AGENT +# define PREFIX "ipa: " +# define TOOLNAME "GDBserver in-process agent" +#else +# define PREFIX "gdbserver: " +# define TOOLNAME "GDBserver" #endif /* Generally useful subroutines used throughout the program. */ -static void malloc_failure (size_t size) ATTR_NORETURN; - -static void -malloc_failure (size_t size) +void +malloc_failure (long size) { - fprintf (stderr, "gdbserver: ran out of memory while trying to allocate %lu bytes\n", + fprintf (stderr, + PREFIX "ran out of memory while trying to allocate %lu bytes\n", (unsigned long) size); exit (1); } -/* Allocate memory without fail. - If malloc fails, this will print a message to stderr and exit. */ - -void * -xmalloc (size_t size) -{ - void *newmem; - - if (size == 0) - size = 1; - newmem = malloc (size); - if (!newmem) - malloc_failure (size); - - return newmem; -} - -/* Allocate memory without fail and set it to zero. - If malloc fails, this will print a message to stderr and exit. */ - -void * -xcalloc (size_t nelem, size_t elsize) -{ - void *newmem; - - if (nelem == 0 || elsize == 0) - nelem = elsize = 1; - - newmem = calloc (nelem, elsize); - if (!newmem) - malloc_failure (nelem * elsize); - - return newmem; -} - /* Copy a string into a memory buffer. If malloc fails, this will print a message to stderr and exit. */ @@ -87,6 +56,8 @@ xstrdup (const char *s) return ret; } +#ifndef IN_PROCESS_AGENT + /* Free a standard argv vector. */ void @@ -104,6 +75,8 @@ freeargv (char **vector) } } +#endif + /* Print the system error message for errno, and also mention STRING as the file name for which the error was encountered. Then return to command level. */ @@ -133,13 +106,19 @@ perror_with_name (const char *string) void error (const char *string,...) { +#ifndef IN_PROCESS_AGENT extern jmp_buf toplevel; +#endif va_list args; va_start (args, string); fflush (stdout); vfprintf (stderr, string, args); fprintf (stderr, "\n"); +#ifndef IN_PROCESS_AGENT longjmp (toplevel, 1); +#else + exit (1); +#endif } /* Print an error message and exit reporting failure. @@ -152,7 +131,7 @@ fatal (const char *string,...) { va_list args; va_start (args, string); - fprintf (stderr, "gdbserver: "); + fprintf (stderr, PREFIX); vfprintf (stderr, string, args); fprintf (stderr, "\n"); va_end (args); @@ -165,14 +144,30 @@ warning (const char *string,...) { va_list args; va_start (args, string); - fprintf (stderr, "gdbserver: "); + fprintf (stderr, PREFIX); vfprintf (stderr, string, args); fprintf (stderr, "\n"); va_end (args); } +/* Report a problem internal to GDBserver, and exit. */ + +void +internal_error (const char *file, int line, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + + fprintf (stderr, "\ +%s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line); + vfprintf (stderr, fmt, args); + fprintf (stderr, "\n"); + va_end (args); + exit (1); +} + /* Temporary storage using circular buffer. */ -#define NUMCELLS 4 +#define NUMCELLS 10 #define CELLSIZE 50 /* Return the next entry in the circular buffer. */ @@ -187,20 +182,105 @@ get_cell (void) return buf[cell]; } -/* Stdarg wrapper around vsnprintf. - SIZE is the size of the buffer pointed to by STR. */ +static char * +decimal2str (char *sign, ULONGEST addr) +{ + /* Steal code from valprint.c:print_decimal(). Should this worry + about the real size of addr as the above does? */ + unsigned long temp[3]; + char *str = get_cell (); + int i = 0; + int width = 9; -static int -xsnprintf (char *str, size_t size, const char *format, ...) + do + { + temp[i] = addr % (1000 * 1000 * 1000); + addr /= (1000 * 1000 * 1000); + i++; + } + while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); + + switch (i) + { + case 1: + xsnprintf (str, CELLSIZE, "%s%0*lu", sign, width, temp[0]); + break; + case 2: + xsnprintf (str, CELLSIZE, "%s%0*lu%09lu", sign, width, + temp[1], temp[0]); + break; + case 3: + xsnprintf (str, CELLSIZE, "%s%0*lu%09lu%09lu", sign, width, + temp[2], temp[1], temp[0]); + break; + default: + internal_error (__FILE__, __LINE__, + "failed internal consistency check"); + } + + return str; +} + +/* %u for ULONGEST. The result is stored in a circular static buffer, + NUMCELLS deep. */ + +char * +pulongest (ULONGEST u) { - va_list args; - int ret; + return decimal2str ("", u); +} - va_start (args, format); - ret = vsnprintf (str, size, format, args); - va_end (args); +/* %d for LONGEST. The result is stored in a circular static buffer, + NUMCELLS deep. */ - return ret; +char * +plongest (LONGEST l) +{ + if (l < 0) + return decimal2str ("-", -l); + else + return decimal2str ("", l); +} + +/* Eliminate warning from compiler on 32-bit systems. */ +static int thirty_two = 32; + +/* Convert a ULONGEST into a HEX string, like %lx. The result is + stored in a circular static buffer, NUMCELLS deep. */ + +char * +phex_nz (ULONGEST l, int sizeof_l) +{ + char *str; + + switch (sizeof_l) + { + case 8: + { + unsigned long high = (unsigned long) (l >> thirty_two); + str = get_cell (); + if (high == 0) + xsnprintf (str, CELLSIZE, "%lx", + (unsigned long) (l & 0xffffffff)); + else + xsnprintf (str, CELLSIZE, "%lx%08lx", high, + (unsigned long) (l & 0xffffffff)); + break; + } + case 4: + str = get_cell (); + xsnprintf (str, CELLSIZE, "%lx", (unsigned long) l); + break; + case 2: + str = get_cell (); + xsnprintf (str, CELLSIZE, "%x", (unsigned short) (l & 0xffff)); + break; + default: + str = phex_nz (l, sizeof (l)); + break; + } + + return str; } /* Convert a CORE_ADDR into a HEX string, like %lx. @@ -209,7 +289,17 @@ xsnprintf (char *str, size_t size, const char *format, ...) char * paddress (CORE_ADDR addr) { - char *str = get_cell (); - xsnprintf (str, CELLSIZE, "%lx", (long) addr); - return str; + return phex_nz (addr, sizeof (CORE_ADDR)); +} + +/* Convert a file descriptor into a printable string. */ + +char * +pfildes (gdb_fildes_t fd) +{ +#if USE_WIN32API + return phex_nz (fd, sizeof (gdb_fildes_t)); +#else + return plongest (fd); +#endif }