This is an automated email from Gerrit.

Tim Newsome (t...@sifive.com) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/4452

-- gerrit

commit 6c21b53b48aa9e3f9747e0682feeaf7cb3b014a8
Author: Tim Newsome <t...@sifive.com>
Date:   Tue Mar 6 14:10:04 2018 -0800

    Let gdb know when accessing a register fails.
    
    We can't just enable this for all targets, because at least if you do
    that for ARM then gdb will disconnect very briefly after connecting and
    failing to read a register. The idea is that targets that know they have
    good behavior can set target->propagate_register_errors.
    
    We have this set for RISC-V, but there's still some cleanup that needs
    to be done before that can be upstreamed.
    
    Signed-off-by: Tim Newsome <t...@sifive.com>
    Change-Id: I7e56109ea52d18b780c14a07fb35f9e6e8979da4

diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index a15c5bb..e1c3ff7 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1185,8 +1185,15 @@ static int gdb_get_registers_packet(struct connection 
*connection,
        reg_packet_p = reg_packet;
 
        for (i = 0; i < reg_list_size; i++) {
-               if (!reg_list[i]->valid)
-                       reg_list[i]->type->get(reg_list[i]);
+               if (!reg_list[i]->valid) {
+                       retval = reg_list[i]->type->get(reg_list[i]);
+                       if (retval != ERROR_OK && 
target->propagate_register_errors) {
+                               LOG_DEBUG("Couldn't get register %s.", 
reg_list[i]->name);
+                               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;
        }
@@ -1247,7 +1254,13 @@ static int gdb_set_registers_packet(struct connection 
*connection,
                bin_buf = malloc(DIV_ROUND_UP(reg_list[i]->size, 8));
                gdb_target_to_reg(target, packet_p, chars, bin_buf);
 
-               reg_list[i]->type->set(reg_list[i], bin_buf);
+               retval = reg_list[i]->type->set(reg_list[i], bin_buf);
+               if (retval != ERROR_OK && target->propagate_register_errors) {
+                       LOG_DEBUG("Couldn't set register %s.", 
reg_list[i]->name);
+                       free(reg_list);
+                       free(bin_buf);
+                       return gdb_error(connection, retval);
+               }
 
                /* advance packet pointer */
                packet_p += chars;
@@ -1287,8 +1300,14 @@ static int gdb_get_register_packet(struct connection 
*connection,
                return ERROR_SERVER_REMOTE_CLOSED;
        }
 
-       if (!reg_list[reg_num]->valid)
-               reg_list[reg_num]->type->get(reg_list[reg_num]);
+       if (!reg_list[reg_num]->valid) {
+               retval = reg_list[reg_num]->type->get(reg_list[reg_num]);
+               if (retval != ERROR_OK && target->propagate_register_errors) {
+                       LOG_DEBUG("Couldn't get register %s.", 
reg_list[reg_num]->name);
+                       free(reg_list);
+                       return gdb_error(connection, retval);
+               }
+       }
 
        reg_packet = malloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1); 
/* plus one for string termination null */
 
@@ -1342,7 +1361,13 @@ static int gdb_set_register_packet(struct connection 
*connection,
 
        gdb_target_to_reg(target, separator + 1, chars, bin_buf);
 
-       reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);
+       retval = reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);
+       if (retval != ERROR_OK && target->propagate_register_errors) {
+               LOG_DEBUG("Couldn't set register %s.", reg_list[reg_num]->name);
+               free(bin_buf);
+               free(reg_list);
+               return gdb_error(connection, retval);
+       }
 
        gdb_put_packet(connection, "OK", 2);
 
diff --git a/src/target/target.h b/src/target/target.h
index 6020400..a9a9ba8 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -204,6 +204,14 @@ struct target {
 
        /* file-I/O information for host to do syscall */
        struct gdb_fileio_info *fileio_info;
+
+       /**
+        * When true, send gdb an error result when reading/writing a register
+        * fails. This must be false for some ARM targets (Cortex-M3), where a 
'g'
+        * packet results in an attempt to read 'r0', which fails, which causes 
gdb
+        * to close the connection.
+        */
+       bool propagate_register_errors;
 };
 
 struct target_list {

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to