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;
}
Beispiel #4
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
}