diff options
Diffstat (limited to 'thunk.c')
-rw-r--r-- | thunk.c | 154 |
1 files changed, 154 insertions, 0 deletions
@@ -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 |