qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Gdbstub user mode -gdb dev option : add unix socket


From: Philippe Waille
Subject: [Qemu-devel] [PATCH] Gdbstub user mode -gdb dev option : add unix sockets
Date: Wed, 15 Apr 2009 11:25:42 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

  This patch removes the -g portnumber option in user mode.
  Adds a -gdb device option as in the system mode.

  -gdb tcp:host:port              or   -gdb tcp::port
  -gdb unix:socketname[,unlink]

  Missing tests :
  + system mode regression test (I don't have a "hello world" example
for system mode)
  + _WIN32 mode


Philippe Waille
-------------------------------------------------------------------------

Index: linux-user/main.c
===================================================================
--- linux-user/main.c   (révision 7105)
+++ linux-user/main.c   (copie de travail)
@@ -2202,40 +2202,37 @@
 
 static void usage(void)
 {
-    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", 
Copyright (c) 2003-2008 Fabrice Bellard\n"
-           "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
-           "Linux CPU emulator (compiled for %s emulation)\n"
-           "\n"
-           "Standard options:\n"
-           "-h                print this help\n"
-           "-g port           wait gdb connection to port\n"
-           "-L path           set the elf interpreter prefix (default=%s)\n"
-           "-s size           set the stack size in bytes (default=%ld)\n"
-           "-cpu model        select CPU (-cpu ? for list)\n"
-           "-drop-ld-preload  drop LD_PRELOAD for target process\n"
-           "-E var=value      sets/modifies targets environment variable(s)\n"
-           "-U var            unsets targets environment variable(s)\n"
-           "\n"
-           "Debug options:\n"
-           "-d options   activate log (logfile=%s)\n"
-           "-p pagesize  set the host page size to 'pagesize'\n"
-           "-singlestep  always run in singlestep mode\n"
-           "-strace      log system calls\n"
-           "\n"
-           "Environment variables:\n"
-           "QEMU_STRACE       Print system calls and arguments similar to 
the\n"
-           "                  'strace' program.  Enable by setting to any 
value.\n"
-           "You can use -E and -U options to set/unset environment variables\n"
-           "for target process.  It is possible to provide several variables\n"
-           "by repeating the option.  For example:\n"
-           "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
-           "Note that if you provide several changes to single variable\n"
-           "last change will stay in effect.\n"
-           ,
-           TARGET_ARCH,
-           interp_prefix,
-           x86_stack_size,
-           DEBUG_LOGFILE);
+    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 
2003-2008 Fabrice Bellard\n");
+    printf("usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n");
+    printf("Linux CPU emulator (compiled for %s emulation)\n",
+           TARGET_ARCH);
+    printf("\n");
+    printf("Standard options:\n");
+    printf("-h                print this help\n");
+    gdbstub_usage();
+    printf("-L path           set the elf interpreter prefix (default=%s)\n",
+           interp_prefix);
+    printf("-s size           set the stack size in bytes (default=%ld)\n",
+           x86_stack_size);
+    printf("-cpu model        select CPU (-cpu ? for list)\n");
+    printf("-drop-ld-preload  drop LD_PRELOAD for target process\n");
+    printf("-E var=value      sets/modifies targets environment 
variable(s)\n");
+    printf("-U var            unsets targets environment variable(s)\n");
+    printf("\n");
+    printf("Debug options:\n");
+    printf("-d options   activate log (logfile=%s)\n", DEBUG_LOGFILE);
+    printf("-p pagesize  set the host page size to 'pagesize'\n");
+    printf("-strace      log system calls\n");
+    printf("\n");
+    printf("Environment variables:\n");
+    printf("QEMU_STRACE       Print system calls and arguments similar to 
the\n");
+    printf("                  'strace' program.  Enable by setting to any 
value.\n");
+    printf("You can use -E and -U options to set/unset environment 
variables\n");
+    printf("for target process.  It is possible to provide several 
variables\n");
+    printf("by repeating the option.  For example:\n");
+    printf("    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n");
+    printf("Note that if you provide several changes to single variable\n");
+    printf("last change will stay in effect.\n");
     exit(1);
 }
 
@@ -2264,7 +2261,6 @@
     CPUState *env;
     int optind;
     const char *r;
-    int gdbstub_port = 0;
     char **target_environ, **wrk;
     envlist_t *envlist = NULL;
 
@@ -2345,10 +2341,15 @@
                 fprintf(stderr, "page size must be a power of two\n");
                 exit(1);
             }
-        } else if (!strcmp(r, "g")) {
-            if (optind >= argc)
+        } else if (!strcmp(r, "gdb")) {
+            if (optind >= argc) {
                 break;
-            gdbstub_port = atoi(argv[optind++]);
+            }
+            if (gdbserver_start(argv[optind++]) < 0) {
+                /* stop command line analysis */
+                optind = argc;
+                break;
+            }
        } else if (!strcmp(r, "r")) {
            qemu_uname_release = argv[optind++];
         } else if (!strcmp(r, "cpu")) {
@@ -2706,8 +2707,10 @@
     ts->heap_limit = 0;
 #endif
 
-    if (gdbstub_port) {
-        gdbserver_start (gdbstub_port);
+    if (gdbstub_accept != NULL) {
+        if ((*gdbstub_accept)() < 0) {
+            return -1;
+        }
         gdb_handlesig(env, 0);
     }
     cpu_loop(env);
Index: gdbstub.c
===================================================================
--- gdbstub.c   (révision 7105)
+++ gdbstub.c   (copie de travail)
@@ -19,23 +19,19 @@
  */
 #include "config.h"
 #include "qemu-common.h"
+
 #ifdef CONFIG_USER_ONLY
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include "qemu.h"
+#include "gdbstub.h"
 
-#include "qemu.h"
-#else
+#else /* CONFIG_USER_ONLY */
 #include "monitor.h"
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "gdbstub.h"
-#endif
+#endif /* CONFIG_USER_ONLY */
 
+
 #define MAX_PACKET_LENGTH 4096
 
 #include "qemu_socket.h"
@@ -215,7 +211,7 @@
     -1
 #endif
 };
-#else
+#else  /* CONFIG_USER_ONLY */
 /* In system mode we only need SIGINT and SIGTRAP; other signals
    are not yet supported.  */
 
@@ -232,7 +228,7 @@
     -1,
     TARGET_SIGTRAP
 };
-#endif
+#endif  /* CONFIG_USER_ONLY */
 
 #ifdef CONFIG_USER_ONLY
 static int target_signal_to_gdb (int sig)
@@ -243,7 +239,7 @@
             return i;
     return GDB_SIGNAL_UNKNOWN;
 }
-#endif
+#endif  /* CONFIG_USER_ONLY */
 
 static int gdb_signal_to_target (int sig)
 {
@@ -307,31 +303,13 @@
 #ifdef CONFIG_USER_ONLY
 /* XXX: This is not thread safe.  Do we care?  */
 static int gdbserver_fd = -1;
+gdbstub_func gdbstub_accept = NULL;
 
-static int get_char(GDBState *s)
-{
-    uint8_t ch;
-    int ret;
+static int gdb_disconnected (GDBState *);
+static int get_char(GDBState *s);
+#endif /* CONFIG_USER_ONLY */
 
-    for(;;) {
-        ret = recv(s->fd, &ch, 1, 0);
-        if (ret < 0) {
-            if (errno == ECONNRESET)
-                s->fd = -1;
-            if (errno != EINTR && errno != EAGAIN)
-                return -1;
-        } else if (ret == 0) {
-            close(s->fd);
-            s->fd = -1;
-            return -1;
-        } else {
-            break;
-        }
-    }
-    return ch;
-}
-#endif
-
+static void put_buffer(GDBState *s, const uint8_t *buf, int len);
 static gdb_syscall_complete_cb gdb_current_syscall_cb;
 
 enum {
@@ -361,26 +339,6 @@
 #endif
 }
 
-static void put_buffer(GDBState *s, const uint8_t *buf, int len)
-{
-#ifdef CONFIG_USER_ONLY
-    int ret;
-
-    while (len > 0) {
-        ret = send(s->fd, buf, len, 0);
-        if (ret < 0) {
-            if (errno != EINTR && errno != EAGAIN)
-                return;
-        } else {
-            buf += ret;
-            len -= ret;
-        }
-    }
-#else
-    qemu_chr_write(s->chr, buf, len);
-#endif
-}
-
 static inline int fromhex(int v)
 {
     if (v >= '0' && v <= '9')
@@ -1280,7 +1238,7 @@
     return 0;
 }
 
-#endif
+#endif /* TARGET */
 
 static int num_g_regs = NUM_CORE_REGS;
 
@@ -2091,8 +2049,7 @@
 }
 
 #ifdef CONFIG_USER_ONLY
-int
-gdb_queuesig (void)
+int gdb_queuesig (void)
 {
     GDBState *s;
 
@@ -2104,16 +2061,41 @@
         return 1;
 }
 
-int
-gdb_handlesig (CPUState *env, int sig)
+/* Tell the remote gdb that the process has exited.  */
+void gdb_exit(CPUState *env, int code)
 {
   GDBState *s;
+  char buf[4];
+
+  s = gdbserver_state;
+  if (gdbserver_fd < 0 || s->fd < 0)
+    return;
+
+  snprintf(buf, sizeof(buf), "W%02x", code);
+  put_packet(s, buf);
+}
+
+void gdb_signalled(CPUState *env, int sig)
+{
+  GDBState *s;
+  char buf[4];
+
+  s = gdbserver_state;
+  if (gdbserver_fd < 0 || s->fd < 0)
+    return;
+
+  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
+  put_packet(s, buf);
+}
+
+int gdb_handlesig (CPUState *env, int sig)
+{
+  GDBState *s;
   char buf[256];
   int n;
 
   s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return sig;
+  if (gdb_disconnected (s)) return sig;
 
   /* disable single step if it was enabled */
   cpu_single_step(env, 0);
@@ -2126,9 +2108,9 @@
     }
   /* put_packet() might have detected that the peer terminated the 
      connection.  */
-  if (s->fd < 0)
-      return sig;
 
+  if (gdb_disconnected (s)) return sig;
+
   sig = 0;
   s->state = RS_IDLE;
   s->running_state = 0;
@@ -2138,10 +2120,11 @@
         {
           int i;
 
-          for (i = 0; i < n; i++)
+          for (i = 0; i < n; i++) {
             gdb_read_byte (s, buf[i]);
+          }
         }
-      else if (n == 0 || errno != EAGAIN)
+      else if (n == 0 || errno != EAGAIN) 
         {
           /* XXX: Connection closed.  Should probably wait for annother
              connection before continuing.  */
@@ -2153,108 +2136,294 @@
   return sig;
 }
 
-/* Tell the remote gdb that the process has exited.  */
-void gdb_exit(CPUState *env, int code)
+static int get_char(GDBState *s)
 {
-  GDBState *s;
-  char buf[4];
+    uint8_t ch;
+    int ret;
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return;
+    for(;;) {
+        ret = recv(s->fd, &ch, 1, 0);
+        if (ret < 0) {
+            if (errno == ECONNRESET)
+                s->fd = -1;
+            if (errno != EINTR && errno != EAGAIN)
+                return -1;
+        } else if (ret == 0) {
+            close(s->fd);
+            s->fd = -1;
+            return -1;
+        } else {
+            break;
+        }
+    }
+    return ch;
+}
 
-  snprintf(buf, sizeof(buf), "W%02x", code);
-  put_packet(s, buf);
+
+static void put_buffer(GDBState *s, const uint8_t *buf, int len)
+{
+    int ret;
+    while (len > 0) {
+        ret = send(s->fd, buf, len, 0);
+        if (ret < 0) {
+            if (errno != EINTR && errno != EAGAIN)
+                return;
+        } else {
+            buf += ret;
+            len -= ret;
+        }
+    }
 }
 
-/* Tell the remote gdb that the process has exited due to SIG.  */
-void gdb_signalled(CPUState *env, int sig)
+static int gdb_disconnected (GDBState *s) 
 {
-  GDBState *s;
-  char buf[4];
+    return  (gdbserver_fd < 0) || (s->fd < 0);
+}
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return;
+static GDBState *gdbserver_create_gdbstate (void)
+{
+    GDBState *s;
 
-  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
-  put_packet(s, buf);
+    s = qemu_mallocz(sizeof(GDBState));
+    s->c_cpu = first_cpu;
+    s->g_cpu = first_cpu;
+    gdb_has_xml = 0;
+    gdbserver_state = s;
+    return s;
 }
 
-static void gdb_accept(void)
+static int gdbserver_tcp_accept (void)
 {
+    int fd,res;
     GDBState *s;
-    struct sockaddr_in sockaddr;
-    socklen_t len;
-    int val, fd;
 
-    for(;;) {
-        len = sizeof(sockaddr);
-        fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
-        if (fd < 0 && errno != EINTR) {
-            perror("accept");
-            return;
-        } else if (fd >= 0) {
-            break;
+    for (;;) {
+        fd = accept (gdbserver_fd, 
+                     (struct sockaddr *) NULL, (socklen_t *) NULL);
+        if (fd < 0) {
+           if (errno != EINTR) {
+              perror("accept");
+              return -1;
+           }
+        } else {
+           break;
         }
     }
-
     /* set short latency */
-    val = 1;
-    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+    res = 1;
+    res = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&res, sizeof (res));
+    if (res < 0) {
+       fprintf (stderr, "gdbserver ERROR : set nodelay\n");
+       return -1;
+    } 
+    res = fcntl(fd, F_SETFL, O_NONBLOCK);
+    if (res < 0) {
+       fprintf (stderr, "gdbserver ERROR : set nonblock\n");
+       return -1;
+    }
+    s = gdbserver_create_gdbstate ();
+    s -> fd = fd;
+    return 0;
+}
 
-    s = qemu_mallocz(sizeof(GDBState));
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
-    s->fd = fd;
-    gdb_has_xml = 0;
 
-    gdbserver_state = s;
+static int gdbserver_tcp_start (const char *host, const char *port,
+                                gdbstub_func faccept)
+{
+    struct addrinfo info_in, *info_out;
+    struct sockaddr_in addrin, *addr;
+    int res;
 
-    fcntl(fd, F_SETFL, O_NONBLOCK);
+    memset (&info_in, 0, sizeof(struct addrinfo));
+    info_in.ai_flags=AI_PASSIVE;  /* force INADDR_ANY if host == NULL */
+    info_in.ai_family= AF_INET;
+    info_in.ai_socktype=SOCK_STREAM;
+    info_in.ai_protocol=IPPROTO_TCP;
+
+    if (getaddrinfo(host, port, &info_in, &info_out) < 0) {
+        perror ("hostname/portname name conversion error");
+        return -1;
+    }
+    addr = (struct sockaddr_in *) info_out -> ai_addr;
+    gdbserver_fd = socket (info_in.ai_family, info_in.ai_socktype,
+                           info_in.ai_protocol);
+    if (info_in.ai_protocol < 0) {
+        perror ("gdb socket");
+        return -1;
+    }
+    /* allow fast reuse */ 
+    res = 1;
+    res = setsockopt(gdbserver_fd, SOL_SOCKET, SO_REUSEADDR,
+                     (char *) &res, sizeof(res));
+    if (res <0) {
+        perror("gdb socket : set  fast reuse\n");
+        return -1;
+    }
+    res = bind (gdbserver_fd, (struct sockaddr *) addr, sizeof (addrin));
+    if (res <0) {
+        perror("gdb socket bind\n");
+        return -1;
+    }
+    res = listen (gdbserver_fd,0);
+    if (res <0) {
+        perror("listen\n");
+        return -1;
+    }
+    gdbstub_accept = faccept;
+    return 0;
+} 
+
+#ifndef     _WIN32
+static int gdbserver_unix_unlink (void)
+{
+    struct sockaddr_un sock;
+    socklen_t len;
+    int res;
+
+    len = sizeof (sock.sun_path);
+    res = getsockname (gdbserver_fd, &sock, &len);
+    if (res < 0 ) {
+       fprintf (stderr,"gdb accept/unlink : cannot get socket name\n");
+       return -1;
+    }
+    res = unlink (sock.sun_path);
+    if (res < 0) {
+       fprintf (stderr,"gdb accept/unlink : cannot unlink %s\n",sock.sun_path);
+       return -1;
+    } 
+    return 0;
 }
 
-static int gdbserver_open(int port)
+static int gdbserver_unix_accept (void)
 {
-    struct sockaddr_in sockaddr;
-    int fd, val, ret;
+    int fd,res;
+    GDBState *s;
+    for (;;) {
+        fd = accept (gdbserver_fd, 
+                     (struct sockaddr *) NULL, ( socklen_t *) NULL);
+        if (fd < 0) {
+           if (errno != EINTR) {
+              perror("accept");
+              return -1;
+           }
+        } else {
+           break;
+        }
+    }
 
-    fd = socket(PF_INET, SOCK_STREAM, 0);
-    if (fd < 0) {
-        perror("socket");
-        return -1;
+    res = fcntl(fd, F_SETFL, O_NONBLOCK);
+    if (res < 0) {
+       fprintf (stderr, "gdbserver ERROR : set nonblock\n");
+       return -1;
     }
+    s = gdbserver_create_gdbstate ();
+    s -> fd = fd;
+    return 0;
+}
 
-    /* allow fast reuse */
-    val = 1;
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+static int gdbserver_unix_accept_unlink (void)
+{
+    return (gdbserver_unix_accept () + gdbserver_unix_unlink ());
+}
 
-    sockaddr.sin_family = AF_INET;
-    sockaddr.sin_port = htons(port);
-    sockaddr.sin_addr.s_addr = 0;
-    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
-    if (ret < 0) {
-        perror("bind");
+static int gdbserver_unix_start (const char *filename, 
+                                 gdbstub_func faccept)
+{
+    struct sockaddr_un addr;
+    int res;
+
+    if (strlen(filename) == 0) {
+       fprintf (stderr, "gdbserver ERROR : missing unix socket name\n");
+       return -1;
+    }
+
+    memset (&addr, 0, sizeof(struct sockaddr_un));
+    addr.sun_family = AF_UNIX;
+    strcpy (addr.sun_path, filename);
+
+    gdbserver_fd = socket (AF_UNIX,SOCK_STREAM,0);
+    if (gdbserver_fd < 0) {
+        perror ("gsbserver socket");
         return -1;
     }
-    ret = listen(fd, 0);
-    if (ret < 0) {
-        perror("listen");
+    res = bind (gdbserver_fd, (struct sockaddr *) &addr, 
+                sizeof(struct sockaddr_un));
+    if (res < 0) {
+        perror ("gdbserver bind\n");
         return -1;
     }
-    return fd;
-}
+    res = listen (gdbserver_fd,0);
+    if (res <0) {
+        perror("listen\n");
+        return -1;
+    }
+    gdbstub_accept = faccept;
+    return 0;
+} 
 
-int gdbserver_start(int port)
+#endif      /* _WIN32 */    
+
+void gdbstub_usage (void) 
 {
-    gdbserver_fd = gdbserver_open(port);
-    if (gdbserver_fd < 0)
-        return -1;
-    /* accept connections */
-    gdb_accept();
+     printf("-gdb device       /* use gdb> target command */\n");
+     printf("     tcp:host:port    target remote host:port  \n");
+#ifndef _WIN32
+     printf("     unix:name        target remote | socat stdio unix:name\n");
+     printf("     unix:name,unlink : unlink remove name from filesystem after 
connection\n");
+#endif /* _WIN32 */
+}     
+
+int gdbserver_start (const char *device)
+{
+    const char *p;
+    char *name, *devicename,*opt;
+
+    name = malloc (strlen(device)+1);
+    /* Light memory leak : will never be freed */
+
+    if (strstart (device, "tcp:",&p)) {
+        if ((p == NULL) || (strlen(p) == 0)) {
+            perror ("tcp socket syntax error");
+            return -1;
+        }
+        strcpy (name,p);
+        devicename = strrchr (name,':');
+        if (devicename == NULL) {
+            return -1;
+        }
+        *devicename++ = 0;
+        if (*devicename == 0) {
+            return -1;
+        }
+        if (*name == 0) {
+            name = NULL;
+        }
+        return gdbserver_tcp_start (name,devicename,
+                                    gdbserver_tcp_accept);
+#ifndef _WIN32
+    } else if (strstart (device, "unix:",&p)) {
+        strcpy (name,p);
+        opt = strrchr(name,',');
+        if (opt == NULL) {
+           return gdbserver_unix_start(name,gdbserver_unix_accept);
+        } else {
+           *opt++ = 0;
+           if (!strcmp(opt,"unlink")) {
+              return gdbserver_unix_start(name,
+                                          gdbserver_unix_accept_unlink);
+           } else {
+              fprintf (stderr,"gdb unix socket : unknown %s option\n",opt);
+              return -1;
+           }
+        } 
+#endif /* _WIN32 */
+    } else {
+       return -1;
+    }
     return 0;
 }
 
+/* Tell the remote gdb that the process has exited due to SIG.  */
 /* Disable gdb stub for child processes.  */
 void gdbserver_fork(CPUState *env)
 {
@@ -2266,7 +2435,14 @@
     cpu_breakpoint_remove_all(env, BP_GDB);
     cpu_watchpoint_remove_all(env, BP_GDB);
 }
-#else
+
+#else /* CONFIG_USER_ONLY */
+
+static void put_buffer(GDBState *s, const uint8_t *buf, int len)
+{
+    qemu_chr_write(s->chr, buf, len);
+}
+
 static int gdb_chr_can_receive(void *opaque)
 {
   /* We can handle an arbitrarily large amount of data.
@@ -2330,7 +2506,7 @@
     if (vm_running)
         vm_stop(EXCP_INTERRUPT);
 }
-#endif
+#endif /* _WIN32 */
 
 int gdbserver_start(const char *device)
 {
@@ -2356,7 +2532,7 @@
             act.sa_handler = gdb_sigterm_handler;
             sigaction(SIGINT, &act, NULL);
         }
-#endif
+#endif /* _WIN32 */
         chr = qemu_chr_open("gdb", device, NULL);
         if (!chr)
             return -1;
@@ -2390,4 +2566,4 @@
 
     return 0;
 }
-#endif
+#endif /* CONFIG_USER_ONLY */
Index: gdbstub.h
===================================================================
--- gdbstub.h   (révision 7105)
+++ gdbstub.h   (copie de travail)
@@ -16,20 +16,25 @@
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 int use_gdb_syscalls(void);
 void gdb_set_stop_cpu(CPUState *env);
+
 #ifdef CONFIG_USER_ONLY
+typedef int (*gdbstub_func) (void);
+extern gdbstub_func gdbstub_accept;
+
 int gdb_queuesig (void);
 int gdb_handlesig (CPUState *, int);
 void gdb_exit(CPUState *, int);
 void gdb_signalled(CPUState *, int);
-int gdbserver_start(int);
 void gdbserver_fork(CPUState *);
-#else
-int gdbserver_start(const char *port);
-#endif
+void gdbstub_usage (void);
+#endif /* CONFIG_USER_ONLY */
+
+int gdbserver_start(const char *device);
+
 /* Get or set a register.  Returns the size of the register.  */
 typedef int (*gdb_reg_cb)(CPUState *env, uint8_t *buf, int reg);
 void gdb_register_coprocessor(CPUState *env,
                               gdb_reg_cb get_reg, gdb_reg_cb set_reg,
                               int num_regs, const char *xml, int g_pos);
 
-#endif
+#endif /* GDBSTUB_H */

Attachment: patch.tar
Description: Unix tar archive


reply via email to

[Prev in Thread] Current Thread [Next in Thread]