From 6eaaaa9acce0ae811ee5a392b9e4dd0607c0054e Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 25 Oct 2021 10:33:08 -0700 Subject: [PATCH] debug: gdbstub: introduce gdb_bin2hex() Adds a new function gdb_bin2hex() to convert binary into hexadecimal string representation. This is similar to bin2hex() but does not force a null character at the end of the output buffer. This avoids an issue where the last character of the hexadecimal string is replaced with null character before sending to GDB. Signed-off-by: Daniel Leung --- include/debug/gdbstub.h | 16 ++++++++++++++++ subsys/debug/gdbstub.c | 24 +++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/include/debug/gdbstub.h b/include/debug/gdbstub.h index efb14ed4381..eecb43af049 100644 --- a/include/debug/gdbstub.h +++ b/include/debug/gdbstub.h @@ -15,4 +15,20 @@ #define GDB_EXCEPTION_INVALID_MEMORY 11UL #define GDB_EXCEPTION_OVERFLOW 16UL +/** + * @brief Convert a binary array into string representation. + * + * Note that this is similar to bin2hex() but does not force + * a null character at the end of the hexadeciaml output buffer. + * + * @param buf The binary array to convert + * @param buflen The length of the binary array to convert + * @param hex Address of where to store the string representation. + * @param hexlen Size of the storage area for string representation. + * + * @return The length of the converted string, or 0 if an error occurred. + */ +size_t gdb_bin2hex(const uint8_t *buf, size_t buflen, + char *hex, size_t hexlen); + #endif diff --git a/subsys/debug/gdbstub.c b/subsys/debug/gdbstub.c index 308e25b8a76..e3de190220a 100644 --- a/subsys/debug/gdbstub.c +++ b/subsys/debug/gdbstub.c @@ -33,6 +33,24 @@ LOG_MODULE_REGISTER(gdbstub); #define GDB_ERROR_MEMORY "E14" #define GDB_ERROR_OVERFLOW "E22" +size_t gdb_bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen) +{ + if ((hexlen + 1) < buflen * 2) { + return 0; + } + + for (size_t i = 0; i < buflen; i++) { + if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) { + return 0; + } + if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) { + return 0; + } + } + + return 2 * buflen; +} + /** * Add preamble and termination to the given data. * @@ -55,7 +73,7 @@ static int gdb_send_packet(const uint8_t *data, size_t len) /* Send the checksum */ z_gdb_putchar('#'); - if (bin2hex(&checksum, 1, buf, sizeof(buf)) == 0) { + if (gdb_bin2hex(&checksum, 1, buf, sizeof(buf)) == 0) { return -1; } @@ -156,7 +174,7 @@ static int gdb_mem_read(uint8_t *buf, size_t buf_len, /* Read from system memory */ for (pos = 0; pos < len; pos++) { data = *(uint8_t *)(addr + pos); - count += bin2hex(&data, 1, buf + count, buf_len - count); + count += gdb_bin2hex(&data, 1, buf + count, buf_len - count); } return count; @@ -197,7 +215,7 @@ static int gdb_send_exception(uint8_t *buf, size_t len, uint8_t exception) size_t size; *buf = 'T'; - size = bin2hex(&exception, 1, buf + 1, len - 1); + size = gdb_bin2hex(&exception, 1, buf + 1, len - 1); if (size == 0) { return -1; }