diff options
author | Marcin Niestroj <m.niestroj@emb.dev> | 2023-01-02 08:04:06 +0100 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2023-01-11 17:02:25 +0000 |
commit | 7dd5b6a4645cf0ce9c635a7fc8b140575385c827 (patch) | |
tree | bf37d3b832ffb25273026b89367ea6b38647644c /src/target/rtt.c | |
parent | dfe57baa16cdbc0dc2ae7182b5b3831028637223 (diff) | |
download | riscv-openocd-7dd5b6a4645cf0ce9c635a7fc8b140575385c827.zip riscv-openocd-7dd5b6a4645cf0ce9c635a7fc8b140575385c827.tar.gz riscv-openocd-7dd5b6a4645cf0ce9c635a7fc8b140575385c827.tar.bz2 |
rtt: fix corner-cases of finding control block
This patch fixes two corner-cases of finding RTT control block.
The first one is when there was a partial match (even single byte) at
the end of loaded buffer (uint8_t buf[1024]), but this was not part of
full match. In that case `cb_offset` was not updated correctly and the
returned `*address` was lower by the legth of the partial match. In case
of searched 'SEGGER RTT' (the default control block ID) string, it was
enough to match `buf[1023] == 'S'`, which is quite likely to happen, and
the `*address` was offset by 1 (e.g. it was 0x20000fff instead of
0x20010000).
Updating (or even maintaining) `cb_offset` is not needed, as start
address of control block can be calculated based on memory address that
was loaded into `uint8_t buf[1024]`, the offset within this buffer and
the length of expected string.
The second issue is when control block is prepended with a byte that
matches first ID character, e.g. there is `SEGGER RTT` control block ID
is prepended by another `S`, making memory contents be `SSEGGER RTT`. In
that case there was no match found.
Fix that issue by making sure that tested byte is always compared with
first byte of expected control block ID.
While at it, change names of local variables to better describe their
meaning.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
Change-Id: I12aa6e202bf12bedcbb888ab595751a2a2518a24
Reviewed-on: https://review.openocd.org/c/openocd/+/7429
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Diffstat (limited to 'src/target/rtt.c')
-rw-r--r-- | src/target/rtt.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/src/target/rtt.c b/src/target/rtt.c index ef2c45d..b14c42f 100644 --- a/src/target/rtt.c +++ b/src/target/rtt.c @@ -241,43 +241,37 @@ int target_rtt_find_control_block(struct target *target, target_addr_t *address, size_t size, const char *id, bool *found, void *user_data) { + target_addr_t address_end = *address + size; uint8_t buf[1024]; *found = false; - size_t j = 0; - size_t cb_offset = 0; + size_t id_matched_length = 0; const size_t id_length = strlen(id); LOG_INFO("rtt: Searching for control block '%s'", id); - for (target_addr_t addr = 0; addr < size; addr = addr + sizeof(buf)) { + for (target_addr_t addr = *address; addr < address_end; addr += sizeof(buf)) { int ret; - const size_t buf_size = MIN(sizeof(buf), size - addr); - ret = target_read_buffer(target, *address + addr, buf_size, buf); + const size_t buf_size = MIN(sizeof(buf), address_end - addr); + ret = target_read_buffer(target, addr, buf_size, buf); if (ret != ERROR_OK) return ret; - size_t start = 0; - size_t i = 0; - - while (i < buf_size) { - if (buf[i] != id[j]) { - start++; - cb_offset++; - i = start; - j = 0; - - continue; + for (size_t buf_off = 0; buf_off < buf_size; buf_off++) { + if (id_matched_length > 0 && + buf[buf_off] != id[id_matched_length]) { + /* Start from beginning */ + id_matched_length = 0; } - i++; - j++; + if (buf[buf_off] == id[id_matched_length]) + id_matched_length++; - if (j == id_length) { - *address = *address + cb_offset; + if (id_matched_length == id_length) { + *address = addr + buf_off + 1 - id_length; *found = true; return ERROR_OK; } |