server/gdb_server.c: support unavailable registers 76/7876/6
authorEvgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Tue, 22 Aug 2023 13:24:30 +0000 (16:24 +0300)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 17 Sep 2023 12:01:47 +0000 (12:01 +0000)
According to gdb documentation, `g` and `p` packets can report a
register being unavailable by a string of 'x' instead of register's
value.

Change-Id: I8ef279f1357c2e612f5d3290eb0022c1b47d9fa7
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7876
Reviewed-by: Marek Vrbka <marek.vrbka@codasip.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Anatoly Parshintsev <kupokupokupopo@gmail.com>
Tested-by: jenkins
src/server/gdb_server.c

index 4a4ea53dc325162c0de89f48b8a55454f355c18a..497f62c4290dc3663f858041d1ce7dc04973afaf 100644 (file)
@@ -1207,6 +1207,27 @@ static void gdb_target_to_reg(struct target *target,
        }
 }
 
+/* get register value if needed and fill the buffer accordingly */
+static int gdb_get_reg_value_as_str(struct target *target, char *tstr, struct reg *reg)
+{
+       int retval = ERROR_OK;
+
+       if (!reg->valid)
+               retval = reg->type->get(reg);
+
+       const unsigned int len = DIV_ROUND_UP(reg->size, 8) * 2;
+       switch (retval) {
+               case ERROR_OK:
+                       gdb_str_to_target(target, tstr, reg);
+                       return ERROR_OK;
+               case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
+                       memset(tstr, 'x', len);
+                       tstr[len] = '\0';
+                       return ERROR_OK;
+       }
+       return ERROR_FAIL;
+}
+
 static int gdb_get_registers_packet(struct connection *connection,
                char const *packet, int packet_size)
 {
@@ -1248,16 +1269,11 @@ static int gdb_get_registers_packet(struct connection *connection,
        for (i = 0; i < reg_list_size; i++) {
                if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)
                        continue;
-               if (!reg_list[i]->valid) {
-                       retval = reg_list[i]->type->get(reg_list[i]);
-                       if (retval != ERROR_OK && gdb_report_register_access_error) {
-                               LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name);
-                               free(reg_packet);
-                               free(reg_list);
-                               return gdb_error(connection, retval);
-                       }
+               if (gdb_get_reg_value_as_str(target, reg_packet_p, reg_list[i]) != ERROR_OK) {
+                       free(reg_packet);
+                       free(reg_list);
+                       return gdb_error(connection, retval);
                }
-               gdb_str_to_target(target, reg_packet_p, reg_list[i]);
                reg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;
        }
 
@@ -1369,18 +1385,13 @@ static int gdb_get_register_packet(struct connection *connection,
                return ERROR_SERVER_REMOTE_CLOSED;
        }
 
-       if (!reg_list[reg_num]->valid) {
-               retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
-               if (retval != ERROR_OK && gdb_report_register_access_error) {
-                       LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name);
-                       free(reg_list);
-                       return gdb_error(connection, retval);
-               }
-       }
-
        reg_packet = calloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1, 1); /* plus one for string termination null */
 
-       gdb_str_to_target(target, reg_packet, reg_list[reg_num]);
+       if (gdb_get_reg_value_as_str(target, reg_packet, reg_list[reg_num]) != ERROR_OK) {
+               free(reg_packet);
+               free(reg_list);
+               return gdb_error(connection, retval);
+       }
 
        gdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2);
 

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)