static void show_vta(char *msg, VexTranslateArgs *vta) { printf("//// %s translating guest %s(%d) %s %dbits to host %s(%d)" " %s %dbits\n", msg, LibVEX_ppVexArch(vta->arch_guest), vta->arch_guest, LibVEX_ppVexEndness(arch_endness(vta->arch_guest)), mode64(vta->arch_guest) ? 64 : 32, LibVEX_ppVexArch(vta->arch_host), vta->arch_host, LibVEX_ppVexEndness(arch_endness(vta->arch_host)), mode64(vta->arch_host) ? 64 : 32); }
inline bool op64(void) // is current operand size 64-bit? { #ifdef __EA64__ return mode64() && ((cmd.rex & REX_W) != 0 || natop() && insn_default_opsize_64()); // 64-bit segment, rex.w or insns-64 #else return false; #endif }
int main(int argc, char **argv) { const int multiarch = argc > 1 ? atoi(argv[1]) : 0; // 0 means: do not do multiarch // > 0 means: do multiarch // > VexArch_INVALID means: do multiarch, only and specifically // with the host arch equal to multiarch // (ugly interface, but hey, that is for testing only special cases only). const int endness_may_differ = argc > 2 ? atoi(argv[2]) : 0; const int wordsize_may_differ = argc > 3 ? atoi(argv[3]) : 0; // Note: if multiarch > VexArch_INVALID, then endness_may_differ // and wordsize_may_differ are ignored. // So, here are examples of usage: // * run only host == guest: // ./libvexmultiarch_test // ./libvex_test // * run all combinations (this will abort very soon :): // ./libvexmultiarch_test 1 1 1 // * run all combinations that are supposed to work by default : // ./libvexmultiarch_test 1 0 0 // * run a specific host arch (e.g. 1028 i.e. VexArchARM64) // ./libvexmultiarch_test 1028 // * show how a single arch VEX lib reports its failure when host != guest // ./libvex_test 1 0 0 VexArch guest_arch; VexEndness guest_endness; VexControl vcon; VexGuestExtents vge; VexTranslateArgs vta; VexTranslateResult vtr; UChar host_bytes[10000]; Int host_bytes_used; LibVEX_default_VexControl(&vcon); LibVEX_Init (failure_exit, log_bytes, 3, &vcon); get_guest_arch (&guest_arch); guest_endness = arch_endness (guest_arch); LibVEX_default_VexArchInfo(&vta.archinfo_guest); LibVEX_default_VexArchInfo(&vta.archinfo_host); LibVEX_default_VexAbiInfo (&vta.abiinfo_both); // Use some values that makes AMD64 happy. vta.abiinfo_both.guest_stack_redzone_size = 128; // Prepare first for a translation where guest == host // We will translate the get_guest_arch function vta.arch_guest = guest_arch; vta.archinfo_guest.endness = guest_endness; vta.archinfo_guest.hwcaps = arch_hwcaps (vta.arch_guest); vta.arch_host = guest_arch; vta.archinfo_host.endness = guest_endness; vta.archinfo_host.hwcaps = arch_hwcaps (vta.arch_host); vta.callback_opaque = NULL; vta.guest_bytes = (UChar*) get_guest_arch; vta.guest_bytes_addr = (Addr) get_guest_arch; vta.chase_into_ok = return_false; vta.guest_extents = &vge; vta.host_bytes = host_bytes; vta.host_bytes_size = sizeof host_bytes; vta.host_bytes_used = &host_bytes_used; vta.instrument1 = NULL; vta.instrument2 = NULL; vta.finaltidy = NULL; vta.needs_self_check = return_0; vta.preamble_function = NULL; vta.traceflags = 0xFFFFFFFF; vta.sigill_diag = False; vta.addProfInc = False; vta.disp_cp_chain_me_to_slowEP = failure_dispcalled; vta.disp_cp_chain_me_to_fastEP = failure_dispcalled; vta.disp_cp_xindir = failure_dispcalled; vta.disp_cp_xassisted = failure_dispcalled; show_vta("host == guest", &vta); vtr = LibVEX_Translate ( &vta ); if (vtr.status != VexTransOK) return 1; // Now, try various combinations, if told to do so: // host != guest, // endness(host) != endness(guest) (not well supported) // wordsize (host) != wordsize (guest) (not well supported) // The not well supported combinations are not run, unless requested // explicitely via command line arguments. if (multiarch) { VexArch va; for (va = VexArchX86; va <= VexArchTILEGX; va++) { vta.arch_host = va; vta.archinfo_host.endness = arch_endness (vta.arch_host); vta.archinfo_host.hwcaps = arch_hwcaps (vta.arch_host); if (arch_endness(va) != arch_endness(guest_arch) && !endness_may_differ && multiarch != va) { show_vta("skipped (endness differs)", &vta); continue; } if (mode64(va) != mode64(guest_arch) && !wordsize_may_differ && multiarch != va) { show_vta("skipped (word size differs)", &vta); continue; } if (multiarch > VexArch_INVALID && multiarch != va) { show_vta("skipped (!= specific requested arch)", &vta); continue; } show_vta ("doing", &vta); vtr = LibVEX_Translate ( &vta ); if (vtr.status != VexTransOK) return 1; } } printf ("//// libvex testing normal exit\n"); return 0; }
inline bool op64(void) // is current operand size 64-bit? { return mode64() && ((cmd.rex & REX_W) != 0 || natop() && insn_default_opsize_64()); // 64-bit segment, rex.w or insns-64 }