pipes: add documentation for pipes
[fw/openocd] / src / server / gdb_server.c
index e97839d28988aafee59a6f0bc23eab54cd00d4d8..518090265ae9a2449f877835c4e9eff51b35c44c 100644 (file)
@@ -1,4 +1,3 @@
-
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
@@ -81,8 +80,8 @@ static int gdb_breakpoint_override;
 static enum breakpoint_type gdb_breakpoint_override_type;
 
 static int gdb_error(struct connection *connection, int retval);
-static unsigned short gdb_port = 3333;
-static unsigned short gdb_port_next = 0;
+static const char *gdb_port;
+static const char *gdb_port_next;
 static const char DIGITS[16] = "0123456789abcdef";
 
 static void gdb_log_callback(void *priv, const char *file, unsigned line,
@@ -177,7 +176,7 @@ static int gdb_get_char_inner(struct connection *connection, int* next_char)
 #endif
        for (;;)
        {
-               if (connection->service->type == CONNECTION_PIPE)
+               if (connection->service->type != CONNECTION_TCP)
                {
                        gdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);
                }
@@ -329,20 +328,9 @@ static int gdb_write(struct connection *connection, void *data, int len)
        if (gdb_con->closed)
                return ERROR_SERVER_REMOTE_CLOSED;
 
-       if (connection->service->type == CONNECTION_PIPE)
-       {
-               /* write to stdout */
-               if (write(STDOUT_FILENO, data, len) == len)
-               {
-                       return ERROR_OK;
-               }
-       }
-       else
+       if (connection_write(connection, data, len) == len)
        {
-               if (write_socket(connection->fd, data, len) == len)
-               {
-                       return ERROR_OK;
-               }
+               return ERROR_OK;
        }
        gdb_con->closed = 1;
        return ERROR_SERVER_REMOTE_CLOSED;
@@ -1682,6 +1670,7 @@ static int gdb_memory_map(struct connection *connection,
        char *separator;
        uint32_t ram_start = 0;
        int i;
+       int target_flash_banks = 0;
 
        /* skip command character */
        packet += 23;
@@ -1708,10 +1697,11 @@ static int gdb_memory_map(struct connection *connection,
                        gdb_error(connection, retval);
                        return retval;
                }
-               banks[i] = p;
+               if(p->target == target)
+                       banks[target_flash_banks++] = p;
        }
 
-       qsort(banks, flash_get_bank_count(), sizeof(struct flash_bank *),
+       qsort(banks, target_flash_banks, sizeof(struct flash_bank *),
                        compare_bank);
 
        for (i = 0; i < flash_get_bank_count(); i++) {
@@ -2397,55 +2387,40 @@ static int gdb_input(struct connection *connection)
        return ERROR_OK;
 }
 
-static int gdb_target_start(struct target *target, uint16_t port)
+static int gdb_target_start(struct target *target, const char *port)
 {
-       bool use_pipes = 0 == port;
        struct gdb_service *gdb_service = malloc(sizeof(struct gdb_service));
        if (NULL == gdb_service)
                return -ENOMEM;
 
        gdb_service->target = target;
 
-       add_service("gdb", use_pipes ? CONNECTION_PIPE : CONNECTION_TCP,
+       return add_service("gdb",
                        port, 1, &gdb_new_connection, &gdb_input,
                        &gdb_connection_closed, gdb_service);
-
-       const char *name = target_name(target);
-       if (use_pipes)
-               LOG_DEBUG("gdb service for target '%s' using pipes", name);
-       else
-               LOG_DEBUG("gdb service for target '%s' on TCP port %u", name, port);
-       return ERROR_OK;
 }
 
 static int gdb_target_add_one(struct target *target)
 {
-       if (gdb_port == 0 && server_use_pipes == 0)
-       {
-               LOG_INFO("gdb port disabled");
-               return ERROR_OK;
-       }
-       if (0 == gdb_port_next)
-               gdb_port_next = gdb_port;
-
-       bool use_pipes = server_use_pipes;
-       static bool server_started_with_pipes = false;
-       if (server_started_with_pipes)
-       {
-               LOG_WARNING("gdb service permits one target when using pipes");
-               if (0 == gdb_port)
-                       return ERROR_OK;
-
-               use_pipes = false;
-       }
-
-       int e = gdb_target_start(target, use_pipes ? 0 : gdb_port_next);
-       if (ERROR_OK == e)
+       int retval = gdb_target_start(target, gdb_port_next);
+       if (retval == ERROR_OK)
        {
-               server_started_with_pipes |= use_pipes;
-               gdb_port_next++;
+               long portnumber;
+               /* If we can parse the port number
+                * then we increment the port number for the next target.
+                */
+               char *end;
+               strtol(gdb_port_next, &end, 0);
+               if (!*end)
+               {
+                       if (parse_long(gdb_port_next, &portnumber) == ERROR_OK)
+                       {
+                               free((void *)gdb_port_next);
+                               gdb_port_next = alloc_printf("%d", portnumber+1);
+                       }
+               }
        }
-       return e;
+       return retval;
 }
 
 int gdb_target_add_all(struct target *target)
@@ -2490,9 +2465,9 @@ COMMAND_HANDLER(handle_gdb_sync_command)
 /* daemon configuration command gdb_port */
 COMMAND_HANDLER(handle_gdb_port_command)
 {
-       int retval = CALL_COMMAND_HANDLER(server_port_command, &gdb_port);
+       int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);
        if (ERROR_OK == retval)
-               gdb_port_next = gdb_port;
+               gdb_port_next = strdup(gdb_port);
        return retval;
 }
 
@@ -2570,9 +2545,13 @@ static const struct command_registration gdb_command_handlers[] = {
                .name = "gdb_port",
                .handler = handle_gdb_port_command,
                .mode = COMMAND_ANY,
-               .help = "Display or specify base port on which to listen "
-                       "for incoming GDB connections.  "
-                       "No arguments reports GDB port; zero disables.",
+               .help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB "
+                               "server listens for the next port number after the "
+                               "base port number specified. "
+                               "No arguments reports GDB port. \"pipe\" means listen to stdin "
+                               "output to stdout, an integer is base port number, \"disable\" disables "
+                               "port. Any other string is are interpreted as named pipe to listen to. "
+                               "Output pipe is the same name as input pipe, but with 'o' appended.",
                .usage = "[port_num]",
        },
        {
@@ -2609,5 +2588,7 @@ static const struct command_registration gdb_command_handlers[] = {
 
 int gdb_register_commands(struct command_context *cmd_ctx)
 {
+       gdb_port = strdup("3333");
+       gdb_port_next = strdup("3333");
        return register_commands(cmd_ctx, NULL, gdb_command_handlers);
 }