@@ -18,7 +18,7 @@ bin_PROGRAMS = pdbg
check_PROGRAMS = $(libpdbg_tests) libpdbg_dtree_test \
libpdbg_p9_fapi_translation_test \
optcmd_test hexdump_test cronus_proxy \
- libpdbg_prop_test
+ libpdbg_prop_test libpdbg_attr_test
PDBG_TESTS = \
tests/test_selection.sh \
@@ -274,6 +274,11 @@ libpdbg_prop_test_CFLAGS = $(libpdbg_test_cflags)
libpdbg_prop_test_LDFLAGS = $(libpdbg_test_ldflags)
libpdbg_prop_test_LDADD = $(libpdbg_test_ldadd)
+libpdbg_attr_test_SOURCES = src/tests/libpdbg_attr_test.c
+libpdbg_attr_test_CFLAGS = $(libpdbg_test_cflags)
+libpdbg_attr_test_LDFLAGS = $(libpdbg_test_ldflags)
+libpdbg_attr_test_LDADD = $(libpdbg_test_ldadd)
+
M4_V = $(M4_V_$(V))
M4_V_ = $(M4_V_$(AM_DEFAULT_VERBOSITY))
M4_V_0 = @echo " M4 " $@;
new file mode 100644
@@ -0,0 +1,322 @@
+/* Copyright 2020 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <endian.h>
+#include <string.h>
+#include <assert.h>
+#include <inttypes.h>
+
+#include <libpdbg.h>
+
+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");
+ exit(1);
+}
+
+static void read_array(struct pdbg_target *target,
+ const char *attr,
+ unsigned int size,
+ unsigned int count)
+{
+ void *buf;
+ unsigned int i;
+
+ buf = malloc(size * count);
+ assert(buf);
+
+ if (!pdbg_target_get_attribute(target, attr, size, count, buf))
+ exit(88);
+
+ if (size == 1) {
+ uint8_t *v = (uint8_t *)buf;
+
+ for (i=0; i<count; i++)
+ printf("0x%02x ", v[i]);
+
+ } else if (size == 2) {
+ uint16_t *v = (uint16_t *)buf;
+
+ for (i=0; i<count; i++)
+ printf("0x%04x ", v[i]);
+
+ } else if (size == 4) {
+ uint32_t *v = (uint32_t *)buf;
+
+ for (i=0; i<count; i++)
+ printf("0x%08x ", v[i]);
+
+ } else if (size == 8) {
+ uint64_t *v = (uint64_t *)buf;
+
+ for (i=0; i<count; i++)
+ printf("0x%016" PRIx64 " ", v[i]);
+
+ }
+ printf("\n");
+
+ free(buf);
+}
+
+static void write_array(struct pdbg_target *target,
+ const char *attr,
+ unsigned int size,
+ unsigned int count,
+ const char **argv)
+{
+ void *buf;
+ unsigned int i;
+
+ buf = malloc(size * count);
+ assert(buf);
+
+ if (size == 1) {
+ uint8_t *v = (uint8_t *)buf;
+
+ for (i=0; i<count; i++)
+ v[i] = strtoul(argv[i], NULL, 0) & 0xff;
+
+ } else if (size == 2) {
+ uint16_t *v = (uint16_t *)buf;
+
+ for (i=0; i<count; i++)
+ v[i] = strtoul(argv[i], NULL, 0) & 0xffff;
+
+ } else if (size == 4) {
+ uint32_t *v = (uint32_t *)buf;
+
+ for (i=0; i<count; i++)
+ v[i] = strtoul(argv[i], NULL, 0);
+
+ } else if (size == 8) {
+ uint64_t *v = (uint64_t *)buf;
+
+ for (i=0; i<count; i++)
+ v[i] = strtoull(argv[i], NULL, 0);
+ }
+
+ if (!pdbg_target_set_attribute(target, attr, size, count, buf))
+ exit(99);
+
+ free(buf);
+}
+
+static size_t spec_size(const char *spec)
+{
+ size_t size = 0, i;
+
+ for (i = 0; i < strlen(spec); i++) {
+ char ch = spec[i];
+
+ if (ch == '1')
+ size += 1;
+ else if (ch == '2')
+ size += 2;
+ else if (ch == '4')
+ size += 4;
+ else if (ch == '8')
+ size += 8;
+ else
+ return -1;
+ }
+
+ return size;
+}
+
+static void read_packed(struct pdbg_target *target,
+ const char *attr,
+ const char *spec)
+{
+ void *buf;
+ size_t size, pos;
+ unsigned int i;
+
+ size = spec_size(spec);
+ assert(size > 0);
+
+ buf = malloc(size);
+ assert(buf);
+
+ if (!pdbg_target_get_attribute_packed(target, attr, spec, buf))
+ exit(88);
+
+ pos = 0;
+ for (i=0; i<strlen(spec); i++) {
+ char ch = spec[i];
+
+ if (ch == '1') {
+ uint8_t u8 = *(uint8_t *)((uint8_t *)buf + pos);
+
+ printf("0x%02x ", u8);
+ pos += 1;
+
+ } else if (ch == '2') {
+ uint16_t u16 = *(uint16_t *)((uint8_t *)buf + pos);
+
+ printf("0x%04x ", u16);
+ pos += 2;
+
+ } else if (ch == '4') {
+ uint32_t u32 = *(uint32_t *)((uint8_t *)buf + pos);
+
+ printf("0x%08x ", u32);
+ pos += 4;
+
+ } else if (ch == '8') {
+ uint64_t u64 = *(uint64_t *)((uint8_t *)buf + pos);
+
+ printf("0x%016" PRIx64 " ", u64);
+ pos += 8;
+ }
+ }
+ printf("\n");
+
+ free(buf);
+}
+
+static void write_packed(struct pdbg_target *target,
+ const char *attr,
+ const char *spec,
+ const char **argv)
+{
+ void *buf;
+ size_t size, pos;
+ unsigned int i;
+
+ size = spec_size(spec);
+ assert(size > 0);
+
+ buf = malloc(size);
+ assert(buf);
+
+ pos = 0;
+ for (i=0; i<strlen(spec); i++) {
+ char ch = spec[i];
+
+ if (ch == '1') {
+ uint8_t *v = (uint8_t *)((uint8_t *)buf + pos);
+
+ *v = strtoul(argv[i], NULL, 0) & 0xff;
+ pos += 1;
+
+ } else if (ch == '2') {
+ uint16_t *v = (uint16_t *)((uint8_t *)buf + pos);
+
+ *v = strtoul(argv[i], NULL, 0) & 0xffffff;
+ pos += 2;
+
+ } else if (ch == '4') {
+ uint32_t *v = (uint32_t *)((uint8_t *)buf + pos);
+
+ *v = strtoul(argv[i], NULL, 0);
+ pos += 4;
+
+ } else if (ch == '8') {
+ uint64_t *v = (uint64_t *)((uint8_t *)buf + pos);
+
+ *v = strtoull(argv[i], NULL, 0);
+ pos += 8;
+ }
+ }
+
+ if (!pdbg_target_set_attribute_packed(target, attr, spec, buf))
+ exit(99);
+
+ free(buf);
+}
+
+int main(int argc, const char **argv)
+{
+ struct pdbg_target *target;
+ const char *path, *attr, *spec = NULL;
+ bool do_read = false, do_write = false;
+ bool is_array = false;
+ int size = 0, count = 0;
+
+ if (argc < 6)
+ usage();
+
+ path = argv[1];
+
+ if (strcmp(argv[2], "read") == 0)
+ do_read = true;
+ else if (strcmp(argv[2], "write") == 0)
+ do_write = true;
+ else
+ usage();
+
+ attr = argv[3];
+
+ if (strcmp(argv[4], "array") == 0)
+ is_array = true;
+ else if (strcmp(argv[4], "packed") == 0)
+ is_array = false;
+ else
+ usage();
+
+ if (is_array) {
+ if (argc < 7)
+ usage();
+
+ size = atoi(argv[5]);
+ if (size != 1 && size != 2 && size != 4 & size != 8)
+ usage();
+
+ count = atoi(argv[6]);
+
+ if (do_read && argc != 7)
+ usage();
+
+ if (do_write && argc != 7 + count)
+ usage();
+ } else {
+ spec = argv[5];
+
+ if (do_read && argc != 6)
+ usage();
+
+ if (do_write && argc != 6 + strlen(spec))
+ usage();
+ }
+
+ pdbg_set_backend(PDBG_BACKEND_FAKE, NULL);
+ assert(pdbg_targets_init(NULL));
+
+ target = pdbg_target_from_path(NULL, path);
+ if (!target)
+ exit(1);
+
+ if (do_read) {
+ if (is_array)
+ read_array(target, attr, size, count);
+ else
+ read_packed(target, attr, spec);
+ }
+
+ if (do_write) {
+ if (is_array)
+ write_array(target, attr, size, count, &argv[7]);
+ else
+ write_packed(target, attr, spec, &argv[6]);
+ }
+
+ return 0;
+}
Signed-off-by: Amitay Isaacs <amitay@ozlabs.org> --- Makefile.am | 7 +- src/tests/libpdbg_attr_test.c | 322 ++++++++++++++++++++++++++++++++++ 2 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 src/tests/libpdbg_attr_test.c