merge from gcc
[external/binutils.git] / gdb / gdbserver / gdbreplay.c
index c87d1ee..6ce00b3 100644 (file)
@@ -1,13 +1,13 @@
 /* Replay a remote debug session logfile for GDB.
-   Copyright (C) 1996, 1998, 1999, 2000, 2002, 2003, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1998, 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008,
+   2009, 2010 Free Software Foundation, Inc.
    Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include <stdio.h>
+#if HAVE_SYS_FILE_H
 #include <sys/file.h>
+#endif
+#if HAVE_SIGNAL_H
 #include <signal.h>
+#endif
 #include <ctype.h>
+#if HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
+#if HAVE_ERRNO_H
 #include <errno.h>
-
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -49,6 +54,9 @@
 #if HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
 
 #if USE_WIN32API
 #include <winsock.h>
@@ -61,14 +69,69 @@ typedef int socklen_t;
 /* Sort of a hack... */
 #define EOL (EOF - 1)
 
+/* Version information, from version.c.  */
+extern const char version[];
+extern const char host_name[];
+
 static int remote_desc;
 
+#ifdef __MINGW32CE__
+
+#ifndef COUNTOF
+#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0]))
+#endif
+
+#define errno (GetLastError ())
+
+char *
+strerror (DWORD error)
+{
+  static char buf[1024];
+  WCHAR *msgbuf;
+  DWORD lasterr = GetLastError ();
+  DWORD chars = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM
+                               | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                               NULL,
+                               error,
+                               0, /* Default language */
+                               (LPVOID)&msgbuf,
+                               0,
+                               NULL);
+  if (chars != 0)
+    {
+      /* If there is an \r\n appended, zap it.  */
+      if (chars >= 2
+         && msgbuf[chars - 2] == '\r'
+         && msgbuf[chars - 1] == '\n')
+       {
+         chars -= 2;
+         msgbuf[chars] = 0;
+       }
+
+      if (chars > ((COUNTOF (buf)) - 1))
+       {
+         chars = COUNTOF (buf) - 1;
+         msgbuf [chars] = 0;
+       }
+
+      wcstombs (buf, msgbuf, chars + 1);
+      LocalFree (msgbuf);
+    }
+  else
+    sprintf (buf, "unknown win32 error (%ld)", error);
+
+  SetLastError (lasterr);
+  return buf;
+}
+
+#endif /* __MINGW32CE__ */
+
 /* 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.  */
 
 static void
-perror_with_name (char *string)
+perror_with_name (const char *string)
 {
 #ifndef STDC_HEADERS
   extern int errno;
@@ -173,13 +236,11 @@ remote_open (char *name)
       setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
 
       /* Tell TCP not to delay small packets.  This greatly speeds up
-         interactive response. */
+        interactive response. */
       tmp = 1;
       setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
                  (char *) &tmp, sizeof (tmp));
 
-      close (tmp_desc);                /* No longer need this */
-
 #ifndef USE_WIN32API
       close (tmp_desc);                /* No longer need this */
 
@@ -330,16 +391,44 @@ play (FILE *fp)
     }
 }
 
+static void
+gdbreplay_version (void)
+{
+  printf ("GNU gdbreplay %s%s\n"
+         "Copyright (C) 2010 Free Software Foundation, Inc.\n"
+         "gdbreplay is free software, covered by the GNU General Public License.\n"
+         "This gdbreplay was configured as \"%s\"\n",
+         PKGVERSION, version, host_name);
+}
+
+static void
+gdbreplay_usage (FILE *stream)
+{
+  fprintf (stream, "Usage:\tgdbreplay <logfile> <host:port>\n");
+  if (REPORT_BUGS_TO[0] && stream == stdout)
+    fprintf (stream, "Report bugs to \"%s\".\n", REPORT_BUGS_TO);
+}
+
 int
 main (int argc, char *argv[])
 {
   FILE *fp;
   int ch;
 
+  if (argc >= 2 && strcmp (argv[1], "--version") == 0)
+    {
+      gdbreplay_version ();
+      exit (0);
+    }
+  if (argc >= 2 && strcmp (argv[1], "--help") == 0)
+    {
+      gdbreplay_usage (stdout);
+      exit (0);
+    }
+
   if (argc < 3)
     {
-      fprintf (stderr, "Usage: gdbreplay <logfile> <host:port>\n");
-      fflush (stderr);
+      gdbreplay_usage (stderr);
       exit (1);
     }
   fp = fopen (argv[1], "r");