summaryrefslogtreecommitdiff
path: root/qtest.c
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2015-05-22 14:13:44 -0400
committerJohn Snow <jsnow@redhat.com>2015-05-22 15:58:22 -0400
commit7a6a740d8dcc02f5693315d7935b5de9b963bb96 (patch)
treea2e267889145f6cff4d1af159684568d19bd16a8 /qtest.c
parent332cc7e9b39ddb2feacb4c71dcd18c3e5b0c3147 (diff)
downloadqemu-7a6a740d8dcc02f5693315d7935b5de9b963bb96.tar.gz
qemu-7a6a740d8dcc02f5693315d7935b5de9b963bb96.tar.bz2
qemu-7a6a740d8dcc02f5693315d7935b5de9b963bb96.zip
qtest: Add base64 encoded read/write
For larger pieces of data that won't need to be debugged and viewing the hex nibbles is unlikely to be useful, we can encode data using base64 instead of encoding each byte as %02x, which leads to some space savings and faster reads/writes. For now, the default is left as hex nibbles in memwrite() and memread(). For the purposes of making qtest io easier to read and debug, some callers may want to specify using the old encoding format for small patches of data where the savings from base64 wouldn't be that profound. memwrite/memread use a data encoding that takes 2x the size of the original buffer, but base64 uses "only" (4/3)x, so for larger buffers we can save a decent amount of time and space. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 1430864578-22072-3-git-send-email-jsnow@redhat.com
Diffstat (limited to 'qtest.c')
-rw-r--r--qtest.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/qtest.c b/qtest.c
index 3738eae377..73b7a0f9b8 100644
--- a/qtest.c
+++ b/qtest.c
@@ -119,12 +119,21 @@ static bool qtest_opened;
* > write ADDR SIZE DATA
* < OK
*
+ * > b64read ADDR SIZE
+ * < OK B64_DATA
+ *
+ * > b64write ADDR SIZE B64_DATA
+ * < OK
+ *
* ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
*
* DATA is an arbitrarily long hex number prefixed with '0x'. If it's smaller
* than the expected size, the value will be zero filled at the end of the data
* sequence.
*
+ * B64_DATA is an arbitrarily long base64 encoded string.
+ * If the sizes do not match, the data will be truncated.
+ *
* IRQ management:
*
* > irq_intercept_in QOM-PATH
@@ -182,6 +191,21 @@ static void qtest_send_prefix(CharDriverState *chr)
(long) tv.tv_sec, (long) tv.tv_usec);
}
+static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!qtest_log_fp || !qtest_opened) {
+ return;
+ }
+
+ qtest_send_prefix(NULL);
+
+ va_start(ap, fmt);
+ vfprintf(qtest_log_fp, fmt, ap);
+ va_end(ap);
+}
+
static void do_qtest_send(CharDriverState *chr, const char *str, size_t len)
{
qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
@@ -403,6 +427,23 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
qtest_send(chr, "\n");
g_free(data);
+ } else if (strcmp(words[0], "b64read") == 0) {
+ uint64_t addr, len;
+ uint8_t *data;
+ gchar *b64_data;
+
+ g_assert(words[1] && words[2]);
+ addr = strtoull(words[1], NULL, 0);
+ len = strtoull(words[2], NULL, 0);
+
+ data = g_malloc(len);
+ cpu_physical_memory_read(addr, data, len);
+ b64_data = g_base64_encode(data, len);
+ qtest_send_prefix(chr);
+ qtest_sendf(chr, "OK %s\n", b64_data);
+
+ g_free(data);
+ g_free(b64_data);
} else if (strcmp(words[0], "write") == 0) {
uint64_t addr, len, i;
uint8_t *data;
@@ -432,6 +473,34 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
qtest_send_prefix(chr);
qtest_send(chr, "OK\n");
+ } else if (strcmp(words[0], "b64write") == 0) {
+ uint64_t addr, len;
+ uint8_t *data;
+ size_t data_len;
+ gsize out_len;
+
+ g_assert(words[1] && words[2] && words[3]);
+ addr = strtoull(words[1], NULL, 0);
+ len = strtoull(words[2], NULL, 0);
+
+ data_len = strlen(words[3]);
+ if (data_len < 3) {
+ qtest_send(chr, "ERR invalid argument size\n");
+ return;
+ }
+
+ data = g_base64_decode_inplace(words[3], &out_len);
+ if (out_len != len) {
+ qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
+ "found %zu)\n",
+ len, out_len);
+ out_len = MIN(out_len, len);
+ }
+
+ cpu_physical_memory_write(addr, data, out_len);
+
+ qtest_send_prefix(chr);
+ qtest_send(chr, "OK\n");
} else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
int64_t ns;