Skip to content

Commit 7dd5b6a

Browse files
mniestrojborneoa
authored andcommitted
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 <[email protected]> Change-Id: I12aa6e202bf12bedcbb888ab595751a2a2518a24 Reviewed-on: https://review.openocd.org/c/openocd/+/7429 Tested-by: jenkins Reviewed-by: Antonio Borneo <[email protected]>
1 parent dfe57ba commit 7dd5b6a

File tree

1 file changed

+14
-20
lines changed

1 file changed

+14
-20
lines changed

src/target/rtt.c

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -241,43 +241,37 @@ int target_rtt_find_control_block(struct target *target,
241241
target_addr_t *address, size_t size, const char *id, bool *found,
242242
void *user_data)
243243
{
244+
target_addr_t address_end = *address + size;
244245
uint8_t buf[1024];
245246

246247
*found = false;
247248

248-
size_t j = 0;
249-
size_t cb_offset = 0;
249+
size_t id_matched_length = 0;
250250
const size_t id_length = strlen(id);
251251

252252
LOG_INFO("rtt: Searching for control block '%s'", id);
253253

254-
for (target_addr_t addr = 0; addr < size; addr = addr + sizeof(buf)) {
254+
for (target_addr_t addr = *address; addr < address_end; addr += sizeof(buf)) {
255255
int ret;
256256

257-
const size_t buf_size = MIN(sizeof(buf), size - addr);
258-
ret = target_read_buffer(target, *address + addr, buf_size, buf);
257+
const size_t buf_size = MIN(sizeof(buf), address_end - addr);
258+
ret = target_read_buffer(target, addr, buf_size, buf);
259259

260260
if (ret != ERROR_OK)
261261
return ret;
262262

263-
size_t start = 0;
264-
size_t i = 0;
265-
266-
while (i < buf_size) {
267-
if (buf[i] != id[j]) {
268-
start++;
269-
cb_offset++;
270-
i = start;
271-
j = 0;
272-
273-
continue;
263+
for (size_t buf_off = 0; buf_off < buf_size; buf_off++) {
264+
if (id_matched_length > 0 &&
265+
buf[buf_off] != id[id_matched_length]) {
266+
/* Start from beginning */
267+
id_matched_length = 0;
274268
}
275269

276-
i++;
277-
j++;
270+
if (buf[buf_off] == id[id_matched_length])
271+
id_matched_length++;
278272

279-
if (j == id_length) {
280-
*address = *address + cb_offset;
273+
if (id_matched_length == id_length) {
274+
*address = addr + buf_off + 1 - id_length;
281275
*found = true;
282276
return ERROR_OK;
283277
}

0 commit comments

Comments
 (0)