diff mbox series

adu: Fix calculation of bytes read in getmem

Message ID 20180820051256.1285595-1-amitay@ozlabs.org
State Accepted
Headers show
Series adu: Fix calculation of bytes read in getmem | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/build-multiarch success Test build-multiarch on branch master

Commit Message

Amitay Isaacs Aug. 20, 2018, 5:12 a.m. UTC
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>
---
 libpdbg/adu.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)
diff mbox series

Patch

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);