diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index 26aa8cced..76f657f8d 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -45,6 +45,11 @@ static const unsigned char bit_reverse_table256[] = { 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; +static const char hex_digits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' +}; + void *buf_cpy(const void *from, void *_to, unsigned size) { if (NULL == from || NULL == _to) @@ -407,18 +412,34 @@ size_t unhexify(uint8_t *bin, const char *hex, size_t count) return i / 2; } -int hexify(char *hex, const char *bin, int count, int out_maxlen) +/** + * Convert binary data into a string of hexadecimal pairs. + * + * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size + * must be at least @p length. + * @param[in] bin Buffer with binary data to convert into hexadecimal pairs. + * @param[in] count Number of bytes to convert. + * @param[in] length Maximum number of characters, including null-terminator, + * to store into @p hex. + * + * @returns The length of the converted string excluding null-terminator. + */ +size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length) { - int i, cmd_len = 0; + size_t i; + uint8_t tmp; - /* May use a length, or a null-terminated string as input. */ - if (count == 0) - count = strlen(bin); + if (!length) + return 0; - for (i = 0; i < count; i++) - cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff); + for (i = 0; i < length - 1 && i < 2 * count; i++) { + tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f; + hex[i] = hex_digits[tmp]; + } - return cmd_len; + hex[i] = 0; + + return i; } void buffer_shr(void *_buf, unsigned buf_len, unsigned count) diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h index b035779af..f1da8c4aa 100644 --- a/src/helper/binarybuffer.h +++ b/src/helper/binarybuffer.h @@ -235,7 +235,7 @@ void bit_copy_discard(struct bit_copy_queue *q); /* functions to convert to/from hex encoded buffer * used in ti-icdi driver and gdb server */ size_t unhexify(uint8_t *bin, const char *hex, size_t count); -int hexify(char *hex, const char *bin, int count, int out_maxlen); +size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t out_maxlen); void buffer_shr(void *_buf, unsigned buf_len, unsigned count); #endif /* OPENOCD_HELPER_BINARYBUFFER_H */ diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index 7a6272fdb..171ac66c4 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -242,7 +242,8 @@ static int icdi_send_remote_cmd(void *handle, const char *data) struct icdi_usb_handle_s *h = handle; size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,"); - cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len); + cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data, + strlen(data), h->max_packet - cmd_len); return icdi_send_packet(handle, cmd_len); } @@ -512,7 +513,7 @@ static int icdi_usb_write_reg(void *handle, int num, uint32_t val) h_u32_to_le(buf, val); int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num); - hexify(cmd + cmd_len, (const char *)buf, 4, sizeof(cmd)); + hexify(cmd + cmd_len, buf, 4, sizeof(cmd)); result = icdi_send_cmd(handle, cmd); if (result != ERROR_OK) diff --git a/src/rtos/linux.c b/src/rtos/linux.c index 31d661844..e5a4efcde 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -1229,7 +1229,8 @@ int linux_thread_extra_info(struct target *target, sprintf(tmp_str_ptr, "%s", name); sprintf(tmp_str_ptr, "%s", temp->name); char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1); - int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1); + size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str, + strlen(tmp_str), strlen(tmp_str) * 2 + 1); gdb_put_packet(connection, hex_str, pkt_len); free(hex_str); free(tmp_str); diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 6938336f4..84ee498be 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -266,7 +266,9 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s } reply_len = snprintf(reply, sizeof(reply), "qSymbol:"); - reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len); + reply_len += hexify(reply + reply_len, + (const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name), + sizeof(reply) - reply_len); done: gdb_put_packet(connection, reply, reply_len); @@ -321,7 +323,8 @@ int rtos_thread_packet(struct connection *connection, char const *packet, int pa (size_t) (tmp_str_ptr - tmp_str)); char *hex_str = malloc(strlen(tmp_str) * 2 + 1); - int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1); + size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str, + strlen(tmp_str), strlen(tmp_str) * 2 + 1); gdb_put_packet(connection, hex_str, pkt_len); free(hex_str); diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 6f111e14a..fe0074441 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -697,7 +697,8 @@ static int gdb_output_con(struct connection *connection, const char *line) return ERROR_GDB_BUFFER_TOO_SMALL; hex_buffer[0] = 'O'; - int pkt_len = hexify(hex_buffer + 1, line, bin_size, bin_size * 2 + 1); + size_t pkt_len = hexify(hex_buffer + 1, (const uint8_t *)line, bin_size, + bin_size * 2 + 1); int retval = gdb_put_packet(connection, hex_buffer, pkt_len + 1); free(hex_buffer); @@ -1407,7 +1408,7 @@ static int gdb_read_memory_packet(struct connection *connection, if (retval == ERROR_OK) { hex_buffer = malloc(len * 2 + 1); - int pkt_len = hexify(hex_buffer, (char *)buffer, len, len * 2 + 1); + size_t pkt_len = hexify(hex_buffer, buffer, len, len * 2 + 1); gdb_put_packet(connection, hex_buffer, pkt_len); diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c index 15a8736fe..0077339f2 100644 --- a/src/server/tcl_server.c +++ b/src/server/tcl_server.c @@ -105,7 +105,7 @@ static int tcl_target_callback_trace_handler(struct target *target, if (tclc->tc_trace) { hex = malloc(hex_len); buf = malloc(max_len); - hexify(hex, (const char *)data, len, hex_len); + hexify(hex, data, len, hex_len); snprintf(buf, max_len, "%s%s%s", header, hex, trailer); tcl_output(connection, buf, strlen(buf)); free(hex); diff --git a/src/target/smp.c b/src/target/smp.c index 3dc6f6d5b..bdf81a0ee 100644 --- a/src/target/smp.c +++ b/src/target/smp.c @@ -64,7 +64,8 @@ int gdb_read_smp_packet(struct connection *connection, char hex_buffer[len * 2 + 1]; uint8_t buffer[len]; buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]); - int pkt_len = hexify(hex_buffer, (char *)buffer, sizeof(buffer), sizeof(hex_buffer)); + size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer), + sizeof(hex_buffer)); retval = gdb_put_packet(connection, hex_buffer, pkt_len); }