server/gdb: fix gdb remote monitor cmd on multi-target
[openocd.git] / src / server / gdb_server.c
index f5736196eddfb4717d389688d631c1e76f31bceb..4efdc1ee7e7b2be361df1f11cf0c12a070a89535 100644 (file)
@@ -371,11 +371,13 @@ static int gdb_write(struct connection *connection, void *data, int len)
        return ERROR_SERVER_REMOTE_CLOSED;
 }
 
-static void gdb_log_incoming_packet(char *packet)
+static void gdb_log_incoming_packet(struct connection *connection, char *packet)
 {
        if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
                return;
 
+       struct target *target = get_target_from_connection(connection);
+
        /* Avoid dumping non-printable characters to the terminal */
        const unsigned packet_len = strlen(packet);
        const char *nonprint = find_nonprint_char(packet, packet_len);
@@ -389,25 +391,31 @@ static void gdb_log_incoming_packet(char *packet)
                if (packet_prefix_printable) {
                        const unsigned int prefix_len = colon - packet + 1;  /* + 1 to include the ':' */
                        const unsigned int payload_len = packet_len - prefix_len;
-                       LOG_DEBUG("received packet: %.*s<binary-data-%u-bytes>", prefix_len, packet, payload_len);
+                       LOG_TARGET_DEBUG(target, "received packet: %.*s<binary-data-%u-bytes>", prefix_len,
+                               packet, payload_len);
                } else {
-                       LOG_DEBUG("received packet: <binary-data-%u-bytes>", packet_len);
+                       LOG_TARGET_DEBUG(target, "received packet: <binary-data-%u-bytes>", packet_len);
                }
        } else {
                /* All chars printable, dump the packet as is */
-               LOG_DEBUG("received packet: %s", packet);
+               LOG_TARGET_DEBUG(target, "received packet: %s", packet);
        }
 }
 
-static void gdb_log_outgoing_packet(char *packet_buf, unsigned int packet_len, unsigned char checksum)
+static void gdb_log_outgoing_packet(struct connection *connection, char *packet_buf,
+       unsigned int packet_len, unsigned char checksum)
 {
        if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
                return;
 
+       struct target *target = get_target_from_connection(connection);
+
        if (find_nonprint_char(packet_buf, packet_len))
-               LOG_DEBUG("sending packet: $<binary-data-%u-bytes>#%2.2x", packet_len, checksum);
+               LOG_TARGET_DEBUG(target, "sending packet: $<binary-data-%u-bytes>#%2.2x",
+                       packet_len, checksum);
        else
-               LOG_DEBUG("sending packet: $%.*s#%2.2x'", packet_len, packet_buf, checksum);
+               LOG_TARGET_DEBUG(target, "sending packet: $%.*s#%2.2x", packet_len, packet_buf,
+                       checksum);
 }
 
 static int gdb_put_packet_inner(struct connection *connection,
@@ -450,7 +458,7 @@ static int gdb_put_packet_inner(struct connection *connection,
 #endif
 
        while (1) {
-               gdb_log_outgoing_packet(buffer, len, my_checksum);
+               gdb_log_outgoing_packet(connection, buffer, len, my_checksum);
 
                char local_buffer[1024];
                local_buffer[0] = '$';
@@ -483,22 +491,27 @@ static int gdb_put_packet_inner(struct connection *connection,
                if (retval != ERROR_OK)
                        return retval;
 
-               if (reply == '+')
+               if (reply == '+') {
+                       gdb_log_incoming_packet(connection, "+");
                        break;
-               else if (reply == '-') {
+               else if (reply == '-') {
                        /* Stop sending output packets for now */
                        gdb_con->output_flag = GDB_OUTPUT_NO;
+                       gdb_log_incoming_packet(connection, "-");
                        LOG_WARNING("negative reply, retrying");
                } else if (reply == 0x3) {
                        gdb_con->ctrl_c = true;
+                       gdb_log_incoming_packet(connection, "<Ctrl-C>");
                        retval = gdb_get_char(connection, &reply);
                        if (retval != ERROR_OK)
                                return retval;
-                       if (reply == '+')
+                       if (reply == '+') {
+                               gdb_log_incoming_packet(connection, "+");
                                break;
-                       else if (reply == '-') {
+                       else if (reply == '-') {
                                /* Stop sending output packets for now */
                                gdb_con->output_flag = GDB_OUTPUT_NO;
+                               gdb_log_incoming_packet(connection, "-");
                                LOG_WARNING("negative reply, retrying");
                        } else if (reply == '$') {
                                LOG_ERROR("GDB missing ack(1) - assumed good");
@@ -675,6 +688,7 @@ static int gdb_get_packet_inner(struct connection *connection,
                                case '$':
                                        break;
                                case '+':
+                                       gdb_log_incoming_packet(connection, "+");
                                        /* According to the GDB documentation
                                         * (https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html):
                                         * "gdb sends a final `+` acknowledgment of the stub's `OK`
@@ -692,9 +706,11 @@ static int gdb_get_packet_inner(struct connection *connection,
                                        }
                                        break;
                                case '-':
+                                       gdb_log_incoming_packet(connection, "-");
                                        LOG_WARNING("negative acknowledgment, but no packet pending");
                                        break;
                                case 0x3:
+                                       gdb_log_incoming_packet(connection, "<Ctrl-C>");
                                        gdb_con->ctrl_c = true;
                                        *len = 0;
                                        return ERROR_OK;
@@ -2734,6 +2750,7 @@ static int gdb_query_packet(struct connection *connection,
 
        if (strncmp(packet, "qRcmd,", 6) == 0) {
                if (packet_size > 6) {
+                       Jim_Interp *interp = cmd_ctx->interp;
                        char *cmd;
                        cmd = malloc((packet_size - 6) / 2 + 1);
                        size_t len = unhexify((uint8_t *)cmd, packet + 6, (packet_size - 6) / 2);
@@ -2745,11 +2762,63 @@ static int gdb_query_packet(struct connection *connection,
                        /* some commands need to know the GDB connection, make note of current
                         * GDB connection. */
                        current_gdb_connection = gdb_connection;
-                       command_run_line(cmd_ctx, cmd);
+
+                       struct target *saved_target_override = cmd_ctx->current_target_override;
+                       cmd_ctx->current_target_override = NULL;
+
+                       struct command_context *old_context = Jim_GetAssocData(interp, "context");
+                       Jim_DeleteAssocData(interp, "context");
+                       int retval = Jim_SetAssocData(interp, "context", NULL, cmd_ctx);
+                       if (retval == JIM_OK) {
+                               retval = Jim_EvalObj(interp, Jim_NewStringObj(interp, cmd, -1));
+                               Jim_DeleteAssocData(interp, "context");
+                       }
+                       int inner_retval = Jim_SetAssocData(interp, "context", NULL, old_context);
+                       if (retval == JIM_OK)
+                               retval = inner_retval;
+
+                       cmd_ctx->current_target_override = saved_target_override;
+
                        current_gdb_connection = NULL;
                        target_call_timer_callbacks_now();
                        gdb_connection->output_flag = GDB_OUTPUT_NO;
                        free(cmd);
+                       if (retval == JIM_RETURN)
+                               retval = interp->returnCode;
+                       int lenmsg;
+                       const char *cretmsg = Jim_GetString(Jim_GetResult(interp), &lenmsg);
+                       char *retmsg;
+                       if (lenmsg && cretmsg[lenmsg - 1] != '\n') {
+                               retmsg = alloc_printf("%s\n", cretmsg);
+                               lenmsg++;
+                       } else {
+                               retmsg = strdup(cretmsg);
+                       }
+                       if (!retmsg)
+                               return ERROR_GDB_BUFFER_TOO_SMALL;
+
+                       if (retval == JIM_OK) {
+                               if (lenmsg) {
+                                       char *hex_buffer = malloc(lenmsg * 2 + 1);
+                                       if (!hex_buffer) {
+                                               free(retmsg);
+                                               return ERROR_GDB_BUFFER_TOO_SMALL;
+                                       }
+
+                                       size_t pkt_len = hexify(hex_buffer, (const uint8_t *)retmsg, lenmsg,
+                                                                                       lenmsg * 2 + 1);
+                                       gdb_put_packet(connection, hex_buffer, pkt_len);
+                                       free(hex_buffer);
+                               } else {
+                                       gdb_put_packet(connection, "OK", 2);
+                               }
+                       } else {
+                               if (lenmsg)
+                                       gdb_output_con(connection, retmsg);
+                               gdb_send_error(connection, retval);
+                       }
+                       free(retmsg);
+                       return ERROR_OK;
                }
                gdb_put_packet(connection, "OK", 2);
                return ERROR_OK;
@@ -3452,9 +3521,10 @@ static int gdb_input_inner(struct connection *connection)
                /* terminate with zero */
                gdb_packet_buffer[packet_size] = '\0';
 
-               gdb_log_incoming_packet(gdb_packet_buffer);
-
                if (packet_size > 0) {
+
+                       gdb_log_incoming_packet(connection, gdb_packet_buffer);
+
                        retval = ERROR_OK;
                        switch (packet[0]) {
                                case 'T':       /* Is thread alive? */
@@ -3599,12 +3669,14 @@ static int gdb_input_inner(struct connection *connection)
                                        break;
 
                                case 'j':
+                                       /* DEPRECATED */
                                        /* packet supported only by smp target i.e cortex_a.c*/
                                        /* handle smp packet replying coreid played to gbd */
                                        gdb_read_smp_packet(connection, packet, packet_size);
                                        break;
 
                                case 'J':
+                                       /* DEPRECATED */
                                        /* packet supported only by smp target i.e cortex_a.c */
                                        /* handle smp packet setting coreid to be played at next
                                         * resume to gdb */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)