gdb_server: fix GDB_BUFFER_SIZE usage, fix unaligned access during bulk transfers 09/5109/2
authorBohdan Tymkiv <bhdt@cypress.com>
Tue, 16 Apr 2019 14:28:29 +0000 (17:28 +0300)
committerTomas Vanek <vanekt@fbl.cz>
Tue, 4 Jun 2019 20:37:41 +0000 (21:37 +0100)
Currently size of the GDB buffer is 16384 bytes but it is treated as
nul-terminated string in most of the code, so effective size of the
buffer is actually 16383 bytes. OpenOCD responds with `PacketSize=3fff`
to qSupported request. Result of GDB's `m` command is encoded in hex so
each data byte uses two bytes in the buffer. As a result GDB will split
bulk read requests into chunks 0x1fff bytes each. This causes troubles
on targets (or memory regions) which support only aligned, word-sized
access (such as MMIO buffers).

Steps to reproduce (psoc6 target):
gdb> dump binary memory dump.bin 0x040320000 (0x040320000 + 65536)

OpenOCD:
Error: Failed to read memory at 0x40321ffe
Error: Failed to read memory at 0x40321000
Error: Failed to read memory at 0x40323000
Error: Failed to read memory at 0x40325ffe
Error: Failed to read memory at 0x40329ffa
Error: Failed to read memory at 0x40329ffc
Error: Failed to read memory at 0x4032bffc
Error: Failed to read memory at 0x4032dffa

Consolidate GDB_BUFFER_SIZE usage: ensure size of each buffer is
(GDB_BUFFER_SIZE + 1), add explicit comment that additional byte is used
for nul-termination. Report correct size of the buffer to GDB (0x4000)
as recommended in GDB's docummentation: `if the stub stores packets in a
NUL-terminated format, it should allow an extra byte in its buffer for
the NUL`

Checked with clang-asan, clang-analyzer, valgrind - no new errors.

Change-Id: I909e8a2c6b010c5d4a304641808d4a807a4ec18d
Signed-off-by: Bohdan Tymkiv <bhdt@cypress.com>
Reviewed-on: http://openocd.zylin.com/5109
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
src/rtos/nuttx.c
src/rtos/rtos.c
src/server/gdb_server.c

index 61fd9aa6ca1b366ef0894b8f6f002fad6d4d996c..8c3076e161d9151cd221641f221f2bae2b589714 100644 (file)
@@ -174,7 +174,7 @@ static int rcmd_offset(const char *cmd, const char *name)
 static int nuttx_thread_packet(struct connection *connection,
        char const *packet, int packet_size)
 {
-       char cmd[GDB_BUFFER_SIZE / 2] = "";
+       char cmd[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for nul-termination */
 
        if (!strncmp(packet, "qRcmd", 5)) {
                size_t len = unhexify((uint8_t *)cmd, packet + 6, sizeof(cmd));
index da0a5036295bdbc3f12d9ca2e44d86b225bf64b9..20e875d8b850098a7a64037438532b445a774300 100644 (file)
@@ -223,7 +223,7 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s
        int rtos_detected = 0;
        uint64_t addr = 0;
        size_t reply_len;
-       char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "";
+       char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for nul-termination */
        symbol_table_elem_t *next_sym = NULL;
        struct target *target = get_target_from_connection(connection);
        struct rtos *os = target->rtos;
index c6cf7d350e076d438832d4de9bb038ec2f48218b..60ed4ce0426082753206011ba5c0506cbf7ed865 100644 (file)
@@ -67,7 +67,7 @@ struct target_desc_format {
 
 /* private connection data for GDB */
 struct gdb_connection {
-       char buffer[GDB_BUFFER_SIZE];
+       char buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */
        char *buf_p;
        int buf_cnt;
        int ctrl_c;
@@ -1407,8 +1407,6 @@ static int gdb_error(struct connection *connection, int retval)
 
 /* We don't have to worry about the default 2 second timeout for GDB packets,
  * because GDB breaks up large memory reads into smaller reads.
- *
- * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192?????
  */
 static int gdb_read_memory_packet(struct connection *connection,
                char const *packet, int packet_size)
@@ -2614,7 +2612,7 @@ static int gdb_query_packet(struct connection *connection,
                        &pos,
                        &size,
                        "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+",
-                       (GDB_BUFFER_SIZE - 1),
+                       GDB_BUFFER_SIZE,
                        ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
                        (gdb_target_desc_supported == 1) ? '+' : '-');
 
@@ -3117,7 +3115,7 @@ static void gdb_sig_halted(struct connection *connection)
 static int gdb_input_inner(struct connection *connection)
 {
        /* Do not allocate this on the stack */
-       static char gdb_packet_buffer[GDB_BUFFER_SIZE];
+       static char gdb_packet_buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */
 
        struct target *target;
        char const *packet = gdb_packet_buffer;
@@ -3140,7 +3138,7 @@ static int gdb_input_inner(struct connection *connection)
         * drain the rest of the buffer.
         */
        do {
-               packet_size = GDB_BUFFER_SIZE-1;
+               packet_size = GDB_BUFFER_SIZE;
                retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size);
                if (retval != ERROR_OK)
                        return retval;

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)