aboutsummaryrefslogtreecommitdiff
path: root/thunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'thunk.c')
-rw-r--r--thunk.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/thunk.c b/thunk.c
index 7f31cff..c5d9719 100644
--- a/thunk.c
+++ b/thunk.c
@@ -271,6 +271,160 @@ const argtype *thunk_convert(void *dst, const void *src,
return type_ptr;
}
+const argtype *thunk_print(void *arg, const argtype *type_ptr)
+{
+ int type;
+
+ type = *type_ptr++;
+
+ switch (type) {
+ case TYPE_CHAR:
+ qemu_log("%c", *(uint8_t *)arg);
+ break;
+ case TYPE_SHORT:
+ qemu_log("%" PRId16, tswap16(*(uint16_t *)arg));
+ break;
+ case TYPE_INT:
+ qemu_log("%" PRId32, tswap32(*(uint32_t *)arg));
+ break;
+ case TYPE_LONGLONG:
+ qemu_log("%" PRId64, tswap64(*(uint64_t *)arg));
+ break;
+ case TYPE_ULONGLONG:
+ qemu_log("%" PRIu64, tswap64(*(uint64_t *)arg));
+ break;
+#if HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 32
+ case TYPE_PTRVOID:
+ qemu_log("0x%" PRIx32, tswap32(*(uint32_t *)arg));
+ break;
+ case TYPE_LONG:
+ qemu_log("%" PRId32, tswap32(*(uint32_t *)arg));
+ break;
+ case TYPE_ULONG:
+ qemu_log("%" PRIu32, tswap32(*(uint32_t *)arg));
+ break;
+#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
+ case TYPE_PTRVOID:
+ qemu_log("0x%" PRIx32, tswap32(*(uint64_t *)arg & 0xffffffff));
+ break;
+ case TYPE_LONG:
+ qemu_log("%" PRId32, tswap32(*(uint64_t *)arg & 0xffffffff));
+ break;
+ case TYPE_ULONG:
+ qemu_log("%" PRIu32, tswap32(*(uint64_t *)arg & 0xffffffff));
+ break;
+#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
+ case TYPE_PTRVOID:
+ qemu_log("0x%" PRIx64, tswap64(*(uint64_t *)arg));
+ break;
+ case TYPE_LONG:
+ qemu_log("%" PRId64, tswap64(*(uint64_t *)arg));
+ break;
+ case TYPE_ULONG:
+ qemu_log("%" PRIu64, tswap64(*(uint64_t *)arg));
+ break;
+#else
+ case TYPE_PTRVOID:
+ qemu_log("0x%" PRIx64, tswap64(*(uint64_t *)arg));
+ break;
+ case TYPE_LONG:
+ qemu_log("%" PRId64, tswap64(*(uint64_t *)arg));
+ break;
+ case TYPE_ULONG:
+ qemu_log("%" PRIu64, tswap64(*(uint64_t *)arg));
+ break;
+#endif
+ case TYPE_OLDDEVT:
+ {
+ uint64_t val = 0;
+ switch (thunk_type_size(type_ptr - 1, 1)) {
+ case 2:
+ val = *(uint16_t *)arg;
+ break;
+ case 4:
+ val = *(uint32_t *)arg;
+ break;
+ case 8:
+ val = *(uint64_t *)arg;
+ break;
+ }
+ switch (thunk_type_size(type_ptr - 1, 0)) {
+ case 2:
+ qemu_log("%" PRIu16, tswap16(val));
+ break;
+ case 4:
+ qemu_log("%" PRIu32, tswap32(val));
+ break;
+ case 8:
+ qemu_log("%" PRIu64, tswap64(val));
+ break;
+ }
+ }
+ break;
+ case TYPE_ARRAY:
+ {
+ int i, array_length, arg_size;
+ uint8_t *a;
+ int is_string = 0;
+
+ array_length = *type_ptr++;
+ arg_size = thunk_type_size(type_ptr, 0);
+ a = arg;
+
+ if (*type_ptr == TYPE_CHAR) {
+ qemu_log("\"");
+ is_string = 1;
+ } else {
+ qemu_log("[");
+ }
+
+ for (i = 0; i < array_length; i++) {
+ if (i > 0 && !is_string) {
+ qemu_log(",");
+ }
+ thunk_print(a, type_ptr);
+ a += arg_size;
+ }
+
+ if (is_string) {
+ qemu_log("\"");
+ } else {
+ qemu_log("]");
+ }
+
+ type_ptr = thunk_type_next(type_ptr);
+ }
+ break;
+ case TYPE_STRUCT:
+ {
+ int i;
+ const StructEntry *se;
+ uint8_t *a;
+ const argtype *field_types;
+ const int *arg_offsets;
+
+ se = struct_entries + *type_ptr++;
+ a = arg;
+
+ field_types = se->field_types;
+ arg_offsets = se->field_offsets[0];
+
+ qemu_log("{");
+ for (i = 0; i < se->nb_fields; i++) {
+ if (i > 0) {
+ qemu_log(",");
+ }
+ field_types = thunk_print(a + arg_offsets[i], field_types);
+ }
+ qemu_log("}");
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ return type_ptr;
+}
+
/* from em86 */
/* Utility function: Table-driven functions to translate bitmasks