Example #1
0
/* Just before starting the client, we may need to make final
   adjustments to its initial image.  Also we need to set up the VEX
   guest state for thread 1 (the root thread) and copy in essential
   starting values.  This is handed the IIFinaliseImageInfo created by
   VG_(ii_create_image).
*/
void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
{
   UInt   adler32_act;
   SysRes sres;
   /* On AIX we get a block of 37 words telling us the initial state
      for (GPR0 .. GPR31, PC, CR, LR, CTR, XER), and we start with all
      the other registers zeroed. */

   ThreadArchState* arch = &VG_(threads)[1].arch;

#  if defined(VGP_ppc32_aix5)

   vg_assert(0 == sizeof(VexGuestPPC32State) % 8);

   /* Zero out the initial state, and set up the simulated FPU in a
      sane way. */
   LibVEX_GuestPPC32_initialise(&arch->vex);

   /* Zero out the shadow area. */
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC32State));

#  else /* defined(VGP_ppc64_aix5) */

   vg_assert(0 == sizeof(VexGuestPPC64State) % 8);

   /* Zero out the initial state, and set up the simulated FPU in a
      sane way. */
   LibVEX_GuestPPC64_initialise(&arch->vex);

   /* Zero out the shadow area. */
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));

#  endif

   /* iifii.intregs37 contains the integer register state as it needs
      to be at client startup.  These values are supplied by the
      launcher.  The 37 regs are:initial values from launcher for:
      GPR0 .. GPR31, PC, CR, LR, CTR, XER. */

   /* Put essential stuff into the new state. */
   arch->vex.guest_GPR0  =  (UWord)iifii.intregs37[0];
   arch->vex.guest_GPR1  =  (UWord)iifii.intregs37[1];
   arch->vex.guest_GPR2  =  (UWord)iifii.intregs37[2];
   arch->vex.guest_GPR3  =  (UWord)iifii.intregs37[3];
   arch->vex.guest_GPR4  =  (UWord)iifii.intregs37[4];
   arch->vex.guest_GPR5  =  (UWord)iifii.intregs37[5];
   arch->vex.guest_GPR6  =  (UWord)iifii.intregs37[6];
   arch->vex.guest_GPR7  =  (UWord)iifii.intregs37[7];
   arch->vex.guest_GPR8  =  (UWord)iifii.intregs37[8];
   arch->vex.guest_GPR9  =  (UWord)iifii.intregs37[9];
   arch->vex.guest_GPR10 =  (UWord)iifii.intregs37[10];
   arch->vex.guest_GPR11 =  (UWord)iifii.intregs37[11];
   arch->vex.guest_GPR12 =  (UWord)iifii.intregs37[12];
   arch->vex.guest_GPR13 =  (UWord)iifii.intregs37[13];
   arch->vex.guest_GPR14 =  (UWord)iifii.intregs37[14];
   arch->vex.guest_GPR15 =  (UWord)iifii.intregs37[15];
   arch->vex.guest_GPR16 =  (UWord)iifii.intregs37[16];
   arch->vex.guest_GPR17 =  (UWord)iifii.intregs37[17];
   arch->vex.guest_GPR18 =  (UWord)iifii.intregs37[18];
   arch->vex.guest_GPR19 =  (UWord)iifii.intregs37[19];
   arch->vex.guest_GPR20 =  (UWord)iifii.intregs37[20];
   arch->vex.guest_GPR21 =  (UWord)iifii.intregs37[21];
   arch->vex.guest_GPR22 =  (UWord)iifii.intregs37[22];
   arch->vex.guest_GPR23 =  (UWord)iifii.intregs37[23];
   arch->vex.guest_GPR24 =  (UWord)iifii.intregs37[24];
   arch->vex.guest_GPR25 =  (UWord)iifii.intregs37[25];
   arch->vex.guest_GPR26 =  (UWord)iifii.intregs37[26];
   arch->vex.guest_GPR27 =  (UWord)iifii.intregs37[27];
   arch->vex.guest_GPR28 =  (UWord)iifii.intregs37[28];
   arch->vex.guest_GPR29 =  (UWord)iifii.intregs37[29];
   arch->vex.guest_GPR30 =  (UWord)iifii.intregs37[30];
   arch->vex.guest_GPR31 =  (UWord)iifii.intregs37[31];

   arch->vex.guest_CIA      = (UWord)iifii.intregs37[32+0];
   arch->vex.guest_LR       = (UWord)iifii.intregs37[32+2];
   arch->vex.guest_CTR      = (UWord)iifii.intregs37[32+3];

#  if defined(VGP_ppc32_aix5)

   LibVEX_GuestPPC32_put_CR(  (UWord)iifii.intregs37[32+1], &arch->vex );
   LibVEX_GuestPPC32_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );

   /* Set the cache line size (KLUDGE) */
   VG_(machine_ppc32_set_clszB)( 128 );

#  else /* defined(VGP_ppc64_aix5) */

   LibVEX_GuestPPC64_put_CR(  (UWord)iifii.intregs37[32+1], &arch->vex );
   LibVEX_GuestPPC64_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );

   /* Set the cache line size (KLUDGE) */
   VG_(machine_ppc64_set_clszB)( 128 );

#  endif

   /* Fix up the client's command line.  Its argc/v/envp is in r3/4/5
      (32-bit AIX) or r14/15/16 (64-bit AIX).  but that is for the
      Valgrind invokation as a whole.  Hence we need to decrement argc
      and advance argv to step over the args for Valgrind, and the
      name of the Valgrind tool exe bogusly inserted by the launcher
      (hence the "+1"). */

#  if defined(VGP_ppc32_aix5)

   { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
     vg_assert(arch->vex.guest_GPR3 >= 1 + n_vargs);
     arch->vex.guest_GPR3 -= (1 + n_vargs);
     arch->vex.guest_GPR4 += sizeof(UWord) * (1 + n_vargs);
   }

#  else /* defined(VGP_ppc64_aix5) */

   { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
     vg_assert(arch->vex.guest_GPR14 >= 1 + n_vargs);
     arch->vex.guest_GPR14 -= (1 + n_vargs);
     arch->vex.guest_GPR15 += sizeof(UWord) * (1 + n_vargs);
   }

#  endif

   /* At this point the guest register state is correct for client
      startup.  However, that's not where we want to start; in fact we
      want to start at VG_(ppc{32,64}_aix5_do_preloads_then_start_client),
      passing it iifii.preloadpage in r3.  This will load the core/tool
      preload .so's, then restore r2-r10 from what's stashed in the
      preloadpage, and then start the client really.  Hence: */

   /* Save r2-r10 and the client start point in preloadpage */
   iifii.preloadpage->r2  = (ULong)arch->vex.guest_GPR2;
   iifii.preloadpage->r3  = (ULong)arch->vex.guest_GPR3;
   iifii.preloadpage->r4  = (ULong)arch->vex.guest_GPR4;
   iifii.preloadpage->r5  = (ULong)arch->vex.guest_GPR5;
   iifii.preloadpage->r6  = (ULong)arch->vex.guest_GPR6;
   iifii.preloadpage->r7  = (ULong)arch->vex.guest_GPR7;
   iifii.preloadpage->r8  = (ULong)arch->vex.guest_GPR8;
   iifii.preloadpage->r9  = (ULong)arch->vex.guest_GPR9;
   iifii.preloadpage->r10 = (ULong)arch->vex.guest_GPR10;
   iifii.preloadpage->client_start = (ULong)arch->vex.guest_CIA;


#  if defined(VGP_ppc32_aix5)

   /* Set up to start at VG_(ppc32_aix5_do_preloads_then_start_client) */
   arch->vex.guest_CIA = (UWord)&VG_(ppc32_aix5_do_preloads_then_start_client);

#  else /* defined(VGP_ppc64_aix5) */

   /* Set up to start at VG_(ppc64_aix5_do_preloads_then_start_client) */
   arch->vex.guest_CIA = (UWord)&VG_(ppc64_aix5_do_preloads_then_start_client);

#  endif

   arch->vex.guest_GPR3 = (UWord)iifii.preloadpage;

   /* The rest of the preloadpage fields will already have been filled
      in by VG_(setup_client_initial_image).  So we're done. */

   /* Finally, decompress the page compressed by the launcher.  We
      can't do this any earlier, because the page is (effectively)
      decompressed in place, which trashes iifii.intregs37.  So we have
      to wait till this point, at which we're done with iifii.intregs37
      (to be precise, with what it points at). */
   VG_(debugLog)(1, "initimg", "decompressing page at %p\n", 
                    (void*)iifii.compressed_page);
   vg_assert(VG_IS_PAGE_ALIGNED(iifii.compressed_page));

   Huffman_Uncompress( (void*)iifii.compressed_page, unz_page,
                       VKI_PAGE_SIZE, VKI_PAGE_SIZE );
   adler32_act = compute_adler32(unz_page, VKI_PAGE_SIZE);

   VG_(debugLog)(1, "initimg", 
                    "decompress done, adler32s: act 0x%x, exp 0x%x\n",
                    adler32_act, iifii.adler32_exp );

   VG_(memcpy)((void*)iifii.compressed_page, unz_page, VKI_PAGE_SIZE);

   VG_(debugLog)(1, "initimg", "copy back done\n");

   /* Tell the tool that we just wrote to the registers. */
   VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
             sizeof(VexGuestArchState));

   /* Determine the brk limit. */
   VG_(debugLog)(1, "initimg", "establishing current brk ..\n");
   vg_assert(__NR_AIX5_sbrk != __NR_AIX5_UNKNOWN);
   sres = VG_(do_syscall1)(__NR_AIX5_sbrk, 0);
   vg_assert(sres.err == 0); /* assert no error */
   VG_(brk_base) = VG_(brk_limit) = sres.res;
   VG_(debugLog)(1, "initimg", ".. brk = %p\n", (void*)VG_(brk_base));
}
/* store registers in the guest state (gdbserver_to_valgrind)
   or fetch register from the guest state (valgrind_to_gdbserver). */
static
void transfer_register (ThreadId tid, int abs_regno, void * buf,
                        transfer_direction dir, int size, Bool *mod)
{
   ThreadState* tst = VG_(get_ThreadState)(tid);
   int set = abs_regno / num_regs;
   int regno = abs_regno % num_regs;
   *mod = False;

   VexGuestPPC32State* ppc32 = (VexGuestPPC32State*) get_arch (set, tst);

   switch (regno) { 
   // numbers here have to match the order of regs above
   // Attention: gdb order does not match valgrind order.
   case 0:  VG_(transfer) (&ppc32->guest_GPR0,  buf, dir, size, mod); break;
   case 1:  VG_(transfer) (&ppc32->guest_GPR1,  buf, dir, size, mod); break;
   case 2:  VG_(transfer) (&ppc32->guest_GPR2,  buf, dir, size, mod); break;
   case 3:  VG_(transfer) (&ppc32->guest_GPR3,  buf, dir, size, mod); break;
   case 4:  VG_(transfer) (&ppc32->guest_GPR4,  buf, dir, size, mod); break;
   case 5:  VG_(transfer) (&ppc32->guest_GPR5,  buf, dir, size, mod); break;
   case 6:  VG_(transfer) (&ppc32->guest_GPR6,  buf, dir, size, mod); break;
   case 7:  VG_(transfer) (&ppc32->guest_GPR7,  buf, dir, size, mod); break;
   case 8:  VG_(transfer) (&ppc32->guest_GPR8,  buf, dir, size, mod); break;
   case 9:  VG_(transfer) (&ppc32->guest_GPR9,  buf, dir, size, mod); break;
   case 10: VG_(transfer) (&ppc32->guest_GPR10, buf, dir, size, mod); break;
   case 11: VG_(transfer) (&ppc32->guest_GPR11, buf, dir, size, mod); break;
   case 12: VG_(transfer) (&ppc32->guest_GPR12, buf, dir, size, mod); break;
   case 13: VG_(transfer) (&ppc32->guest_GPR13, buf, dir, size, mod); break;
   case 14: VG_(transfer) (&ppc32->guest_GPR14, buf, dir, size, mod); break;
   case 15: VG_(transfer) (&ppc32->guest_GPR15, buf, dir, size, mod); break;
   case 16: VG_(transfer) (&ppc32->guest_GPR16, buf, dir, size, mod); break;
   case 17: VG_(transfer) (&ppc32->guest_GPR17, buf, dir, size, mod); break;
   case 18: VG_(transfer) (&ppc32->guest_GPR18, buf, dir, size, mod); break;
   case 19: VG_(transfer) (&ppc32->guest_GPR19, buf, dir, size, mod); break;
   case 20: VG_(transfer) (&ppc32->guest_GPR20, buf, dir, size, mod); break;
   case 21: VG_(transfer) (&ppc32->guest_GPR21, buf, dir, size, mod); break;
   case 22: VG_(transfer) (&ppc32->guest_GPR22, buf, dir, size, mod); break;
   case 23: VG_(transfer) (&ppc32->guest_GPR23, buf, dir, size, mod); break;
   case 24: VG_(transfer) (&ppc32->guest_GPR24, buf, dir, size, mod); break;
   case 25: VG_(transfer) (&ppc32->guest_GPR25, buf, dir, size, mod); break;
   case 26: VG_(transfer) (&ppc32->guest_GPR26, buf, dir, size, mod); break;
   case 27: VG_(transfer) (&ppc32->guest_GPR27, buf, dir, size, mod); break;
   case 28: VG_(transfer) (&ppc32->guest_GPR28, buf, dir, size, mod); break;
   case 29: VG_(transfer) (&ppc32->guest_GPR29, buf, dir, size, mod); break;
   case 30: VG_(transfer) (&ppc32->guest_GPR30, buf, dir, size, mod); break;
   case 31: VG_(transfer) (&ppc32->guest_GPR31, buf, dir, size, mod); break;
   case 32: VG_(transfer) (&ppc32->guest_VSR0,  buf, dir, size, mod); break;
   case 33: VG_(transfer) (&ppc32->guest_VSR1,  buf, dir, size, mod); break;
   case 34: VG_(transfer) (&ppc32->guest_VSR2,  buf, dir, size, mod); break;
   case 35: VG_(transfer) (&ppc32->guest_VSR3,  buf, dir, size, mod); break;
   case 36: VG_(transfer) (&ppc32->guest_VSR4,  buf, dir, size, mod); break;
   case 37: VG_(transfer) (&ppc32->guest_VSR5,  buf, dir, size, mod); break;
   case 38: VG_(transfer) (&ppc32->guest_VSR6,  buf, dir, size, mod); break;
   case 39: VG_(transfer) (&ppc32->guest_VSR7,  buf, dir, size, mod); break;
   case 40: VG_(transfer) (&ppc32->guest_VSR8,  buf, dir, size, mod); break;
   case 41: VG_(transfer) (&ppc32->guest_VSR9,  buf, dir, size, mod); break;
   case 42: VG_(transfer) (&ppc32->guest_VSR10, buf, dir, size, mod); break;
   case 43: VG_(transfer) (&ppc32->guest_VSR11, buf, dir, size, mod); break;
   case 44: VG_(transfer) (&ppc32->guest_VSR12, buf, dir, size, mod); break;
   case 45: VG_(transfer) (&ppc32->guest_VSR13, buf, dir, size, mod); break;
   case 46: VG_(transfer) (&ppc32->guest_VSR14, buf, dir, size, mod); break;
   case 47: VG_(transfer) (&ppc32->guest_VSR15, buf, dir, size, mod); break;
   case 48: VG_(transfer) (&ppc32->guest_VSR16, buf, dir, size, mod); break;
   case 49: VG_(transfer) (&ppc32->guest_VSR17, buf, dir, size, mod); break;
   case 50: VG_(transfer) (&ppc32->guest_VSR18, buf, dir, size, mod); break;
   case 51: VG_(transfer) (&ppc32->guest_VSR19, buf, dir, size, mod); break;
   case 52: VG_(transfer) (&ppc32->guest_VSR20, buf, dir, size, mod); break;
   case 53: VG_(transfer) (&ppc32->guest_VSR21, buf, dir, size, mod); break;
   case 54: VG_(transfer) (&ppc32->guest_VSR22, buf, dir, size, mod); break;
   case 55: VG_(transfer) (&ppc32->guest_VSR23, buf, dir, size, mod); break;
   case 56: VG_(transfer) (&ppc32->guest_VSR24, buf, dir, size, mod); break;
   case 57: VG_(transfer) (&ppc32->guest_VSR25, buf, dir, size, mod); break;
   case 58: VG_(transfer) (&ppc32->guest_VSR26, buf, dir, size, mod); break;
   case 59: VG_(transfer) (&ppc32->guest_VSR27, buf, dir, size, mod); break;
   case 60: VG_(transfer) (&ppc32->guest_VSR28, buf, dir, size, mod); break;
   case 61: VG_(transfer) (&ppc32->guest_VSR29, buf, dir, size, mod); break;
   case 62: VG_(transfer) (&ppc32->guest_VSR30, buf, dir, size, mod); break;
   case 63: VG_(transfer) (&ppc32->guest_VSR31, buf, dir, size, mod); break;
   case 64: VG_(transfer) (&ppc32->guest_CIA,   buf, dir, size, mod); break;
   case 65: *mod = False; break; // VEX does not model Machine State Register
   case 66: {
      UInt cr = LibVEX_GuestPPC32_get_CR (ppc32);
      if (dir == valgrind_to_gdbserver) {
         VG_(transfer) (&cr, buf, dir, size, mod); 
      } else {
         UInt newcr;
         VG_(transfer) (&newcr, buf, dir, size, mod);
         *mod = newcr != cr;
         LibVEX_GuestPPC32_put_CR (newcr, ppc32);
      }
      break;
   }
   case 67: VG_(transfer) (&ppc32->guest_LR,    buf, dir, size, mod); break;
   case 68: VG_(transfer) (&ppc32->guest_CTR,   buf, dir, size, mod); break;
   case 69: {
      UInt xer = LibVEX_GuestPPC32_get_XER (ppc32);
      if (dir == valgrind_to_gdbserver) {
         VG_(transfer) (&xer, buf, dir, size, mod); 
      } else {
         UInt newxer;
         VG_(transfer) (&newxer, buf, dir, size, mod);
         *mod = newxer != xer;
         LibVEX_GuestPPC32_put_XER (newxer, ppc32);
      }
      break;
   }
   case 70:  VG_(transfer) (&ppc32->guest_FPROUND, buf, dir, size, mod); break;
   case 71:  *mod = False; break; // GDBTD???? VEX { "orig_r3", 3296, 32 },
   case 72:  *mod = False; break; // GDBTD???? VEX { "trap", 3328, 32 },
   case 73:  VG_(transfer) (&ppc32->guest_VSR32, buf, dir, size, mod); break;
   case 74:  VG_(transfer) (&ppc32->guest_VSR33, buf, dir, size, mod); break;
   case 75:  VG_(transfer) (&ppc32->guest_VSR34, buf, dir, size, mod); break;
   case 76:  VG_(transfer) (&ppc32->guest_VSR35, buf, dir, size, mod); break;
   case 77:  VG_(transfer) (&ppc32->guest_VSR36, buf, dir, size, mod); break;
   case 78:  VG_(transfer) (&ppc32->guest_VSR37, buf, dir, size, mod); break;
   case 79:  VG_(transfer) (&ppc32->guest_VSR38, buf, dir, size, mod); break;
   case 80:  VG_(transfer) (&ppc32->guest_VSR39, buf, dir, size, mod); break;
   case 81:  VG_(transfer) (&ppc32->guest_VSR40, buf, dir, size, mod); break;
   case 82:  VG_(transfer) (&ppc32->guest_VSR41, buf, dir, size, mod); break;
   case 83:  VG_(transfer) (&ppc32->guest_VSR42, buf, dir, size, mod); break;
   case 84:  VG_(transfer) (&ppc32->guest_VSR43, buf, dir, size, mod); break;
   case 85:  VG_(transfer) (&ppc32->guest_VSR44, buf, dir, size, mod); break;
   case 86:  VG_(transfer) (&ppc32->guest_VSR45, buf, dir, size, mod); break;
   case 87:  VG_(transfer) (&ppc32->guest_VSR46, buf, dir, size, mod); break;
   case 88:  VG_(transfer) (&ppc32->guest_VSR47, buf, dir, size, mod); break;
   case 89:  VG_(transfer) (&ppc32->guest_VSR48, buf, dir, size, mod); break;
   case 90:  VG_(transfer) (&ppc32->guest_VSR49, buf, dir, size, mod); break;
   case 91:  VG_(transfer) (&ppc32->guest_VSR50, buf, dir, size, mod); break;
   case 92:  VG_(transfer) (&ppc32->guest_VSR51, buf, dir, size, mod); break;
   case 93:  VG_(transfer) (&ppc32->guest_VSR52, buf, dir, size, mod); break;
   case 94:  VG_(transfer) (&ppc32->guest_VSR53, buf, dir, size, mod); break;
   case 95:  VG_(transfer) (&ppc32->guest_VSR54, buf, dir, size, mod); break;
   case 96:  VG_(transfer) (&ppc32->guest_VSR55, buf, dir, size, mod); break;
   case 97:  VG_(transfer) (&ppc32->guest_VSR56, buf, dir, size, mod); break;
   case 98:  VG_(transfer) (&ppc32->guest_VSR57, buf, dir, size, mod); break;
   case 99:  VG_(transfer) (&ppc32->guest_VSR58, buf, dir, size, mod); break;
   case 100: VG_(transfer) (&ppc32->guest_VSR59, buf, dir, size, mod); break;
   case 101: VG_(transfer) (&ppc32->guest_VSR60, buf, dir, size, mod); break;
   case 102: VG_(transfer) (&ppc32->guest_VSR61, buf, dir, size, mod); break;
   case 103: VG_(transfer) (&ppc32->guest_VSR62, buf, dir, size, mod); break;
   case 104: VG_(transfer) (&ppc32->guest_VSR63, buf, dir, size, mod); break;
   case 105: VG_(transfer) (&ppc32->guest_VSCR,  buf, dir, size, mod); break;
   case 106: VG_(transfer) (&ppc32->guest_VRSAVE, buf, dir, size, mod); break;
   default: vg_assert(0);
   }
}