diff options
author | Amitay Isaacs <amitay@ozlabs.org> | 2018-08-20 15:12:56 +1000 |
---|---|---|
committer | Alistair Popple <alistair@popple.id.au> | 2018-09-07 13:42:52 +1000 |
commit | fd0c7c1e3f937e2e8306ae783e47c11926968188 (patch) | |
tree | a0ca571da7853f638b72cfe7ea02584eb22c2b39 /libpdbg | |
parent | ac3d0504402fdadf7e227da851114d10012623c5 (diff) | |
download | pdbg-fd0c7c1e3f937e2e8306ae783e47c11926968188.tar.gz pdbg-fd0c7c1e3f937e2e8306ae783e47c11926968188.zip |
adu: Fix calculation of bytes read in getmem
This avoids the condition addr-start_addr > size.
The number of bytes of memory read must be <= requested size. Since
output variable correctly captures the number of bytes read, use that to
indicate progress tick.
addr0
+-------+-------+-------+-------+
^ ^
| |
start_addr start_addr + size
----|--------|-------|----| output
* * * * progress tick
Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
Diffstat (limited to 'libpdbg')
-rw-r--r-- | libpdbg/adu.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/libpdbg/adu.c b/libpdbg/adu.c index 9f175f8..4f2949f 100644 --- a/libpdbg/adu.c +++ b/libpdbg/adu.c @@ -100,33 +100,45 @@ int __adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *output, uint64_t size, bool ci) { struct adu *adu; + uint8_t *output0; int rc = 0; - uint64_t addr; + uint64_t addr0, addr; assert(!strcmp(adu_target->class, "adu")); adu = target_to_adu(adu_target); + output0 = output; + + /* Align start address to 8-byte boundary */ + addr0 = 8 * (start_addr / 8); + /* We read data in 8-byte aligned chunks */ - for (addr = 8*(start_addr / 8); addr < start_addr + size; addr += 8) { + for (addr = addr0; addr < start_addr + size; addr += 8) { uint64_t data; if (adu->getmem(adu, addr, &data, ci)) return -1; - pdbg_progress_tick(addr - start_addr, size); - /* ADU returns data in big-endian form in the register */ data = __builtin_bswap64(data); if (addr < start_addr) { - memcpy(output, ((uint8_t *) &data) + (start_addr - addr), 8 - (start_addr - addr)); - output += 8 - (start_addr - addr); + size_t offset = start_addr - addr; + size_t n = (size <= 8-offset ? size : 8-offset); + + memcpy(output, ((uint8_t *) &data) + offset, n); + output += n; } else if (addr + 8 > start_addr + size) { - memcpy(output, &data, start_addr + size - addr); + uint64_t offset = start_addr + size - addr; + + memcpy(output, &data, offset); + output += offset; } else { memcpy(output, &data, 8); output += 8; } + + pdbg_progress_tick(output - output0, size); } pdbg_progress_tick(size, size); |