//---------------------------------------------------------------------- // Translate 1 instruction to VEX IR. //---------------------------------------------------------------------- IRSB *translate_insn( VexArch guest, unsigned char *insn_start, unsigned int insn_addr ) { vta.arch_guest = guest; vta.guest_bytes = (UChar *)(insn_start); // Ptr to actual bytes of start of instruction vta.guest_bytes_addr = (Addr64)(insn_addr); irbb_current = NULL; // FIXME: check the result // Do the actual translation vtr = LibVEX_Translate( &vta ); assert(irbb_current); return irbb_current; }
//---------------------------------------------------------------------- // Translate 1 instruction to VEX IR. //---------------------------------------------------------------------- IRSB *vex_inst(VexArch guest, VexEndness endness, unsigned char *insn_start, unsigned long long insn_addr, int max_insns) { vex_prepare_vai(guest, endness, &vai_guest); vex_prepare_vbi(guest, &vbi); debug("Guest arch: %d\n", guest); debug("Guest arch hwcaps: %08x\n", vai_guest.hwcaps); //vta.traceflags = 0xffffffff; vta.archinfo_host = vai_host; #if __amd64__ vta.arch_host = VexArchAMD64; #elif __i386__ vta.arch_host = VexArchX86; #elif __arm__ vta.arch_host = VexArchARM; #elif __aarch64__ vta.arch_host = VexArchARM64; #else #error "Unsupported host arch" #endif vta.archinfo_guest = vai_guest; vta.arch_guest = guest; vta.abiinfo_both = vbi; // Set the vbi value vta.guest_bytes = (UChar *)(insn_start); // Ptr to actual bytes of start of instruction vta.guest_bytes_addr = (Addr64)(insn_addr); debug("Setting VEX max instructions...\n"); debug("... old: %d\n", vex_control.guest_max_insns); vex_control.guest_max_insns = max_insns; // By default, we vex 1 instruction at a time debug("... new: %d\n", vex_control.guest_max_insns); // Do the actual translation vtr = LibVEX_Translate(&vta); debug("Translated!\n"); assert(irbb_current); return irbb_current; }
//---------------------------------------------------------------------- // Translate 1 instruction to VEX IR. //---------------------------------------------------------------------- IRSB *translate_insn( VexArch guest, unsigned char *insn_start, unsigned int insn_addr ) { vta.arch_guest = guest; if (guest == VexArchARM) { /* We must set the ARM version of VEX aborts */ vta.archinfo_guest.hwcaps |= 5 /* ARMv5 */; } vta.guest_bytes = (UChar *)(insn_start); // Ptr to actual bytes of start of instruction vta.guest_bytes_addr = (Addr64)(insn_addr); irbb_current = NULL; // FIXME: check the result // Do the actual translation vtr = LibVEX_Translate( &vta ); assert(irbb_current); return irbb_current; }
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; }
//---------------------------------------------------------------------- // Translate 1 instruction to VEX IR. //---------------------------------------------------------------------- IRSB *translate_insn(VexArch guest, unsigned char *insn_start, unsigned int insn_addr, int *insn_size) { // init global variables vta.arch_guest = guest; vta.archinfo_guest.hwcaps = 0; if (guest == VexArchARM) { // We must set the ARM version of VEX aborts vta.archinfo_guest.hwcaps |= 7 /* ARMv7 */; if (IS_ARM_THUMB(insn_addr)) { // in thumb mode we also need to increment buffer pointer as VEX wants insn_start += 1; } } else if (guest == VexArchX86) { #ifdef USE_SSE // Enable SSE vta.archinfo_guest.hwcaps |= VEX_HWCAPS_X86_SSE1; vta.archinfo_guest.hwcaps |= VEX_HWCAPS_X86_SSE2; vta.archinfo_guest.hwcaps |= VEX_HWCAPS_X86_SSE3; vta.archinfo_guest.hwcaps |= VEX_HWCAPS_X86_LZCNT; #endif // USE_SSE } vta.guest_bytes = insn_start; // Ptr to actual bytes of start of instruction vta.guest_bytes_addr = (Addr64)insn_addr; irbb_current = NULL; size_current = 0; if (!setjmp(vex_error)) { jmp_buf_set = 1; // FIXME: check the result // Do the actual translation vtr = LibVEX_Translate(&vta); assert(irbb_current); if (insn_size) { *insn_size = size_current; } } else { log_write(LOG_ERR, "Critical VEX error, instruction was not translated"); irbb_current = NULL; } return irbb_current; }