diff mbox series

libpdbg: Add count to attribute_(get|set)_packed

Message ID 20200506055125.154002-1-amitay@ozlabs.org
State Accepted
Headers show
Series libpdbg: Add count to attribute_(get|set)_packed | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch fail Failed to apply to any branch
snowpatch_ozlabs/apply_patch warning Failed to apply on branch master (6c10b68bf774a9fe21affd5ef0b40084cd49800d)

Commit Message

Amitay Isaacs May 6, 2020, 5:51 a.m. UTC
Allow arrays of packed integers as attribute values.

Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
---
 libpdbg/device.c              | 114 +++++++++++++++++++---------------
 libpdbg/libpdbg.h             |   6 +-
 src/tests/libpdbg_attr_test.c | 111 ++++++++++++++++++---------------
 tests/test_attr_packed.sh     |  36 ++++++-----
 4 files changed, 148 insertions(+), 119 deletions(-)
diff mbox series

Patch

diff --git a/libpdbg/device.c b/libpdbg/device.c
index 219569e..9459abe 100644
--- a/libpdbg/device.c
+++ b/libpdbg/device.c
@@ -868,58 +868,64 @@  static size_t spec_size(const char *spec)
 	return size;
 }
 
-bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, const void *val)
+bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, uint32_t count, const void *val)
 {
 	void *buf;
-	size_t size, pos, i;
+	size_t size, pos, i, j;
 	bool ok;
 
 	if (!spec || spec[0] == '\0')
 		return false;
 
+	if (count == 0)
+		return false;
+
 	size = spec_size(spec);
 	if (size <= 0)
 		return false;
 
+	size = size * count;
 	buf = malloc(size);
 	if (!buf)
 		return false;
 
 	pos = 0;
-	for (i=0; i<strlen(spec); i++) {
-		char ch = spec[i];
+	for (j=0; j<count; j++) {
+		for (i=0; i<strlen(spec); i++) {
+			char ch = spec[i];
 
-		if (ch == '1') {
-			uint8_t *b = (uint8_t *)buf + pos;
-			uint8_t *v = (uint8_t *)val + pos;
+			if (ch == '1') {
+				uint8_t *b = (uint8_t *)buf + pos;
+				uint8_t *v = (uint8_t *)val + pos;
 
-			*b = *v;
-			pos += 1;
+				*b = *v;
+				pos += 1;
 
-		} else if (ch == '2') {
-			uint16_t *b = (uint16_t *)((uint8_t *)buf + pos);
-			uint16_t *v = (uint16_t *)((uint8_t *)val + pos);
+			} else if (ch == '2') {
+				uint16_t *b = (uint16_t *)((uint8_t *)buf + pos);
+				uint16_t *v = (uint16_t *)((uint8_t *)val + pos);
 
-			*b = htobe16(*v);
-			pos += 2;
+				*b = htobe16(*v);
+				pos += 2;
 
-		} else if (ch == '4') {
-			uint32_t *b = (uint32_t *)((uint8_t *)buf + pos);
-			uint32_t *v = (uint32_t *)((uint8_t *)val + pos);
+			} else if (ch == '4') {
+				uint32_t *b = (uint32_t *)((uint8_t *)buf + pos);
+				uint32_t *v = (uint32_t *)((uint8_t *)val + pos);
 
-			*b = htobe32(*v);
-			pos += 4;
+				*b = htobe32(*v);
+				pos += 4;
 
-		} else if (ch == '8') {
-			uint64_t *b = (uint64_t *)((uint8_t *)buf + pos);
-			uint64_t *v = (uint64_t *)((uint8_t *)val + pos);
+			} else if (ch == '8') {
+				uint64_t *b = (uint64_t *)((uint8_t *)buf + pos);
+				uint64_t *v = (uint64_t *)((uint8_t *)val + pos);
 
-			*b = htobe64(*v);
-			pos += 8;
+				*b = htobe64(*v);
+				pos += 8;
 
-		} else {
-			free(buf);
-			return false;
+			} else {
+				free(buf);
+				return false;
+			}
 		}
 	}
 
@@ -929,54 +935,60 @@  bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *na
 	return ok;
 }
 
-bool pdbg_target_get_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, void *val)
+bool pdbg_target_get_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, uint32_t count, void *val)
 {
 	const void *buf;
-	size_t size, total_size, pos, i;
+	size_t size, total_size, pos, i, j;
 
 	if (!spec || spec[0] == '\0')
 		return false;
 
+	if (count == 0)
+		return false;
+
 	buf = pdbg_target_property(target, name, &total_size);
 	if (!buf)
 		return false;
 
 	size = spec_size(spec);
+	size = size * count;
 	if (total_size != size)
 		return false;
 
 	pos = 0;
-	for (i=0; i<strlen(spec); i++) {
-		char ch = spec[i];
+	for (j=0; j<count; j++) {
+		for (i=0; i<strlen(spec); i++) {
+			char ch = spec[i];
 
-		if (ch == '1') {
-			uint8_t *b = (uint8_t *)buf + pos;
-			uint8_t *v = (uint8_t *)val + pos;
+			if (ch == '1') {
+				uint8_t *b = (uint8_t *)buf + pos;
+				uint8_t *v = (uint8_t *)val + pos;
 
-			*v = *b;
-			pos += 1;
+				*v = *b;
+				pos += 1;
 
-		} else if (ch == '2') {
-			uint16_t *b = (uint16_t *)((uint8_t *)buf + pos);
-			uint16_t *v = (uint16_t *)((uint8_t *)val + pos);
+			} else if (ch == '2') {
+				uint16_t *b = (uint16_t *)((uint8_t *)buf + pos);
+				uint16_t *v = (uint16_t *)((uint8_t *)val + pos);
 
-			*v = be16toh(*b);
-			pos += 2;
+				*v = be16toh(*b);
+				pos += 2;
 
-		} else if (ch == '4') {
-			uint32_t *b = (uint32_t *)((uint8_t *)buf + pos);
-			uint32_t *v = (uint32_t *)((uint8_t *)val + pos);
+			} else if (ch == '4') {
+				uint32_t *b = (uint32_t *)((uint8_t *)buf + pos);
+				uint32_t *v = (uint32_t *)((uint8_t *)val + pos);
 
-			*v = be32toh(*b);
-			pos += 4;
+				*v = be32toh(*b);
+				pos += 4;
 
-		} else if (ch == '8') {
-			uint64_t *b = (uint64_t *)((uint8_t *)buf + pos);
-			uint64_t *v = (uint64_t *)((uint8_t *)val + pos);
+			} else if (ch == '8') {
+				uint64_t *b = (uint64_t *)((uint8_t *)buf + pos);
+				uint64_t *v = (uint64_t *)((uint8_t *)val + pos);
 
-			*v = be64toh(*b);
-			pos += 8;
+				*v = be64toh(*b);
+				pos += 8;
 
+			}
 		}
 	}
 
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 4337025..99e15f2 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -381,12 +381,13 @@  bool pdbg_target_get_attribute(struct pdbg_target *target, const char *name, uin
  * @param[in] target pdbg_target to set the attribute on
  * @param[in] name name of the attribute to set
  * @param[in] spec specification of packed integers
+ * @param[in] count repetition count
  * @param[in] val value of the attribute to set
  * @return true on success, false on failure
  *
  * This function will update the attribute value provided the size matches.
  */
-bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, const void *val);
+bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, uint32_t count, const void *val);
 
 /**
  * @brief Get the value of the given attribute from device tree
@@ -399,13 +400,14 @@  bool pdbg_target_set_attribute_packed(struct pdbg_target *target, const char *na
  * @param[in] target pdbg_target to get the attribute from
  * @param[in] name name of the attribute to get
  * @param[in] spec specification of packed integers
+ * @param[in] count repetition count
  * @param[out] val value of the attribute
  * @return true on success, false on failure
  *
  * This function will copy the attribute value in the given buffer, provided
  * the specification matches.
  */
-bool pdbg_target_get_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, void *val);
+bool pdbg_target_get_attribute_packed(struct pdbg_target *target, const char *name, const char *spec, uint32_t count, void *val);
 
 /**
  * @brief Get the given property value as a uint32_t
diff --git a/src/tests/libpdbg_attr_test.c b/src/tests/libpdbg_attr_test.c
index 759f1fc..b13dba6 100644
--- a/src/tests/libpdbg_attr_test.c
+++ b/src/tests/libpdbg_attr_test.c
@@ -27,8 +27,8 @@  static void usage(void)
 {
 	fprintf(stderr, "Usage: libpdbg_attr_test <path> read <prop> array 1|2|4|8 <count>\n");
 	fprintf(stderr, "       libpdbg_attr_test <path> write <prop> array 1|2|4|8 <count> <value1> [<value2> ...]\n");
-	fprintf(stderr, "       libpdbg_attr_test <path> read <prop> packed <spec>\n");
-	fprintf(stderr, "       libpdbg_attr_test <path> write <prop> packed <spec> <value1> [<value2> ...]\n");
+	fprintf(stderr, "       libpdbg_attr_test <path> read <prop> packed <spec> <count>\n");
+	fprintf(stderr, "       libpdbg_attr_test <path> write <prop> packed <spec> <count> <value1> [<value2> ...]\n");
 	exit(1);
 }
 
@@ -143,48 +143,53 @@  static size_t spec_size(const char *spec)
 
 static void read_packed(struct pdbg_target *target,
 			const char *attr,
-			const char *spec)
+			const char *spec,
+			unsigned int count)
 {
 	void *buf;
 	size_t size, pos;
-	unsigned int i;
+	unsigned int i, j;
 
 	size = spec_size(spec);
 	assert(size > 0);
 
+	size = size * count;
+
 	buf = malloc(size);
 	assert(buf);
 
-	if (!pdbg_target_get_attribute_packed(target, attr, spec, buf))
+	if (!pdbg_target_get_attribute_packed(target, attr, spec, count, buf))
 		exit(88);
 
 	pos = 0;
-	for (i=0; i<strlen(spec); i++) {
-		char ch = spec[i];
+	for (j=0; j<count; j++) {
+		for (i=0; i<strlen(spec); i++) {
+			char ch = spec[i];
 
-		if (ch == '1') {
-			uint8_t u8 = *(uint8_t *)((uint8_t *)buf + pos);
+			if (ch == '1') {
+				uint8_t u8 = *(uint8_t *)((uint8_t *)buf + pos);
 
-			printf("0x%02x ", u8);
-			pos += 1;
+				printf("0x%02x ", u8);
+				pos += 1;
 
-		} else if (ch == '2') {
-			uint16_t u16 = *(uint16_t *)((uint8_t *)buf + pos);
+			} else if (ch == '2') {
+				uint16_t u16 = *(uint16_t *)((uint8_t *)buf + pos);
 
-			printf("0x%04x ", u16);
-			pos += 2;
+				printf("0x%04x ", u16);
+				pos += 2;
 
-		} else if (ch == '4') {
-			uint32_t u32 = *(uint32_t *)((uint8_t *)buf + pos);
+			} else if (ch == '4') {
+				uint32_t u32 = *(uint32_t *)((uint8_t *)buf + pos);
 
-			printf("0x%08x ", u32);
-			pos += 4;
+				printf("0x%08x ", u32);
+				pos += 4;
 
-		} else if (ch == '8') {
-			uint64_t u64 = *(uint64_t *)((uint8_t *)buf + pos);
+			} else if (ch == '8') {
+				uint64_t u64 = *(uint64_t *)((uint8_t *)buf + pos);
 
-			printf("0x%016" PRIx64 " ", u64);
-			pos += 8;
+				printf("0x%016" PRIx64 " ", u64);
+				pos += 8;
+			}
 		}
 	}
 	printf("\n");
@@ -195,49 +200,54 @@  static void read_packed(struct pdbg_target *target,
 static void write_packed(struct pdbg_target *target,
 			 const char *attr,
 			 const char *spec,
+			 unsigned int count,
 			 const char **argv)
 {
 	void *buf;
 	size_t size, pos;
-	unsigned int i;
+	unsigned int i, j;
 
 	size = spec_size(spec);
 	assert(size > 0);
 
+	size = size * count;
 	buf = malloc(size);
 	assert(buf);
 
 	pos = 0;
-	for (i=0; i<strlen(spec); i++) {
-		char ch = spec[i];
+	for (j=0; j<count; j++) {
+		for (i=0; i<strlen(spec); i++) {
+			unsigned index = j * (count-1) + i;
+			char ch = spec[i];
 
-		if (ch == '1') {
-			uint8_t *v = (uint8_t *)((uint8_t *)buf + pos);
+			if (ch == '1') {
+				uint8_t *v = (uint8_t *)((uint8_t *)buf + pos);
 
-			*v = strtoul(argv[i], NULL, 0) & 0xff;
-			pos += 1;
+				*v = strtoul(argv[index], NULL, 0) & 0xff;
+				pos += 1;
 
-		} else if (ch == '2') {
-			uint16_t *v = (uint16_t *)((uint8_t *)buf + pos);
+			} else if (ch == '2') {
+				uint16_t *v = (uint16_t *)((uint8_t *)buf + pos);
 
-			*v = strtoul(argv[i], NULL, 0) & 0xffffff;
-			pos += 2;
+				*v = strtoul(argv[index], NULL, 0) & 0xffffff;
+				pos += 2;
 
-		} else if (ch == '4') {
-			uint32_t *v = (uint32_t *)((uint8_t *)buf + pos);
+			} else if (ch == '4') {
+				uint32_t *v = (uint32_t *)((uint8_t *)buf + pos);
 
-			*v = strtoul(argv[i], NULL, 0);
-			pos += 4;
+				*v = strtoul(argv[index], NULL, 0);
+				pos += 4;
 
-		} else if (ch == '8') {
-			uint64_t *v = (uint64_t *)((uint8_t *)buf + pos);
+			} else if (ch == '8') {
+				uint64_t *v = (uint64_t *)((uint8_t *)buf + pos);
 
-			*v = strtoull(argv[i], NULL, 0);
-			pos += 8;
+				*v = strtoull(argv[index], NULL, 0);
+				pos += 8;
+			}
 		}
 	}
 
-	if (!pdbg_target_set_attribute_packed(target, attr, spec, buf))
+	if (!pdbg_target_set_attribute_packed(target, attr, spec, count, buf))
 		exit(99);
 
 	free(buf);
@@ -249,7 +259,7 @@  int main(int argc, const char **argv)
 	const char *path, *attr, *spec = NULL;
 	bool do_read = false, do_write = false;
 	bool is_array = false;
-	int size = 0, count = 0;
+	unsigned int size = 0, count = 0;
 
 	if (argc < 6)
 		usage();
@@ -276,11 +286,11 @@  int main(int argc, const char **argv)
 		if (argc < 7)
 			usage();
 
-		size = atoi(argv[5]);
+		size = atol(argv[5]);
 		if (size != 1 && size != 2 && size != 4 & size != 8)
 			usage();
 
-		count = atoi(argv[6]);
+		count = atol(argv[6]);
 
 		if (do_read && argc != 7)
 			usage();
@@ -289,11 +299,12 @@  int main(int argc, const char **argv)
 			usage();
 	} else {
 		spec = argv[5];
+		count = atol(argv[6]);
 
-		if (do_read && argc != 6)
+		if (do_read && argc != 7)
 			usage();
 
-		if (do_write && argc != 6 + strlen(spec))
+		if (do_write && argc != 7 + count * strlen(spec))
 			usage();
 	}
 
@@ -308,14 +319,14 @@  int main(int argc, const char **argv)
 		if (is_array)
 			read_array(target, attr, size, count);
 		else
-			read_packed(target, attr, spec);
+			read_packed(target, attr, spec, count);
 	}
 
 	if (do_write) {
 		if (is_array)
 			write_array(target, attr, size, count, &argv[7]);
 		else
-			write_packed(target, attr, spec, &argv[6]);
+			write_packed(target, attr, spec, count, &argv[7]);
 	}
 
 	return 0;
diff --git a/tests/test_attr_packed.sh b/tests/test_attr_packed.sh
index 36606bc..451669b 100755
--- a/tests/test_attr_packed.sh
+++ b/tests/test_attr_packed.sh
@@ -14,69 +14,73 @@  test_group "libpdbg packed attribute tests"
 
 for size in 1 2 4 8 ; do
 	test_result 88 --
-	test_run libpdbg_attr_test / read ATTR16 packed $size
+	test_run libpdbg_attr_test / read ATTR16 packed $size 1
 done
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 4444 0x1111 0x2222 0x3333 0x4444
+test_run libpdbg_attr_test / write ATTR16 packed 4444 1 0x1111 0x2222 0x3333 0x4444
 
 test_result 0 <<EOF
 0x00001111 0x00002222 0x00003333 0x00004444 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 4444
+test_run libpdbg_attr_test / read ATTR16 packed 4444 1
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 88 0x12345678 0x23456789
+test_run libpdbg_attr_test / write ATTR16 packed 8 2 0x12345678 0x23456789
 
 test_result 0 <<EOF
 0x0000000012345678 0x0000000023456789 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 88
+test_run libpdbg_attr_test / read ATTR16 packed 8 2
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 844 0x11111111 0x22222222 0x33333333
+test_run libpdbg_attr_test / write ATTR16 packed 844 1 0x11111111 0x22222222 0x33333333
 
 test_result 0 <<EOF
 0x0000000011111111 0x22222222 0x33333333 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 844
+test_run libpdbg_attr_test / read ATTR16 packed 844 1
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 8422 0x11111111 0x22222222 0x3333 0x4444
+test_run libpdbg_attr_test / write ATTR16 packed 8422 1 0x11111111 0x22222222 0x3333 0x4444
 
 test_result 0 <<EOF
 0x0000000011111111 0x22222222 0x3333 0x4444 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 8422
+test_run libpdbg_attr_test / read ATTR16 packed 8422 1
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 12481 0x11 0x22 0x33 0x44 0x55
+test_run libpdbg_attr_test / write ATTR16 packed 12481 1 0x11 0x22 0x33 0x44 0x55
 
 test_result 0 <<EOF
 0x11 0x0022 0x00000033 0x0000000000000044 0x55 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 12481
+test_run libpdbg_attr_test / read ATTR16 packed 12481 1
 
 test_result 0 --
-test_run libpdbg_attr_test / write ATTR16 packed 88 0x1122334455667788 0x9900aabbccddeeff
+test_run libpdbg_attr_test / write ATTR16 packed 8 2 0x1122334455667788 0x9900aabbccddeeff
 
 test_result 0 <<EOF
 0x1122334455667788 0x9900aabbccddeeff 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 88
+test_run libpdbg_attr_test / read ATTR16 packed 8 2
 
 test_result 0 <<EOF
 0x11223344 0x55667788 0x9900aabb 0xccddeeff 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 4444
+test_run libpdbg_attr_test / read ATTR16 packed 44 2
 
 test_result 0 <<EOF
 0x1122 0x3344 0x5566 0x7788 0x9900 0xaabb 0xccdd 0xeeff 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 22222222
+test_run libpdbg_attr_test / read ATTR16 packed 22 4
 
 test_result 0 <<EOF
 0x1122 0x3344556677889900 0xaabbccdd 0xeeff 
 EOF
-test_run libpdbg_attr_test / read ATTR16 packed 2842
+test_run libpdbg_attr_test / read ATTR16 packed 2842 1
 
+test_result 0 <<EOF
+0x11 0x2233 0x44 0x55 0x6677 0x88 0x99 0x00aa 0xbb 0xcc 0xddee 0xff 
+EOF
+test_run libpdbg_attr_test / read ATTR16 packed 121 4