~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to coregrind/m_translate.c

  • Committer: Benjamin Kerensa
  • Date: 2012-11-21 23:57:58 UTC
  • mfrom: (1.1.16)
  • Revision ID: bkerensa@ubuntu.com-20121121235758-bd1rv5uc5vzov2p6
Merge from debian unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
   This file is part of Valgrind, a dynamic binary instrumentation
9
9
   framework.
10
10
 
11
 
   Copyright (C) 2000-2011 Julian Seward 
 
11
   Copyright (C) 2000-2012 Julian Seward 
12
12
      jseward@acm.org
13
13
 
14
14
   This program is free software; you can redistribute it and/or
262
262
                          IRType            gWordTy, 
263
263
                          IRType            hWordTy )
264
264
{
265
 
   Int         i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
 
265
   Int         i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
266
266
   Int         first_SP, last_SP, first_Put, last_Put;
267
267
   IRDirty     *dcall, *d;
268
268
   IRStmt*     st;
280
280
   bb->tyenv    = deepCopyIRTypeEnv(sb_in->tyenv);
281
281
   bb->next     = deepCopyIRExpr(sb_in->next);
282
282
   bb->jumpkind = sb_in->jumpkind;
 
283
   bb->offsIP   = sb_in->offsIP;
283
284
 
284
285
   delta = 0;
285
286
 
333
334
         dcall->fxState[0].fx     = Ifx_Read;                           \
334
335
         dcall->fxState[0].offset = layout->offset_SP;                  \
335
336
         dcall->fxState[0].size   = layout->sizeof_SP;                  \
 
337
         dcall->fxState[0].nRepeats  = 0;                               \
 
338
         dcall->fxState[0].repeatLen = 0;                               \
336
339
                                                                        \
337
340
         addStmtToIRSB( bb, IRStmt_Dirty(dcall) );                      \
338
341
                                                                        \
361
364
         dcall->fxState[0].fx     = Ifx_Read;                           \
362
365
         dcall->fxState[0].offset = layout->offset_SP;                  \
363
366
         dcall->fxState[0].size   = layout->sizeof_SP;                  \
 
367
         dcall->fxState[0].nRepeats  = 0;                               \
 
368
         dcall->fxState[0].repeatLen = 0;                               \
364
369
                                                                        \
365
370
         addStmtToIRSB( bb, IRStmt_Dirty(dcall) );                      \
366
371
                                                                        \
585
590
         deal with SP changing in weird ways (well, we can, but not at
586
591
         this time of night).  */
587
592
      if (st->tag == Ist_PutI) {
588
 
         descr = st->Ist.PutI.descr;
 
593
         descr = st->Ist.PutI.details->descr;
589
594
         minoff_ST = descr->base;
590
595
         maxoff_ST = descr->base 
591
596
                     + descr->nElems * sizeofIRType(descr->elemTy) - 1;
596
601
      if (st->tag == Ist_Dirty) {
597
602
         d = st->Ist.Dirty.details;
598
603
         for (j = 0; j < d->nFxState; j++) {
599
 
            minoff_ST = d->fxState[j].offset;
600
 
            maxoff_ST = d->fxState[j].offset + d->fxState[j].size - 1;
601
604
            if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None)
602
605
               continue;
603
 
            if (!(offset_SP > maxoff_ST
604
 
                  || (offset_SP + sizeof_SP - 1) < minoff_ST))
605
 
               goto complain;
 
606
            /* Enumerate the described state segments */
 
607
            for (k = 0; k < 1 + d->fxState[j].nRepeats; k++) {
 
608
               minoff_ST = d->fxState[j].offset + k * d->fxState[j].repeatLen;
 
609
               maxoff_ST = minoff_ST + d->fxState[j].size - 1;
 
610
               if (!(offset_SP > maxoff_ST
 
611
                     || (offset_SP + sizeof_SP - 1) < minoff_ST))
 
612
                  goto complain;
 
613
            }
606
614
         }
607
615
      }
608
616
 
718
726
 
719
727
static Bool translations_allowable_from_seg ( NSegment const* seg )
720
728
{
721
 
#  if defined(VGA_x86) || defined(VGA_s390x)
 
729
#  if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32)
722
730
   Bool allowR = True;
723
731
#  else
724
732
   Bool allowR = False;
905
913
   Int    offB_REDIR_SP    = offsetof(VexGuestPPC64State,guest_REDIR_SP);
906
914
   Int    offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
907
915
   Int    offB_EMWARN      = offsetof(VexGuestPPC64State,guest_EMWARN);
 
916
   Int    offB_CIA         = offsetof(VexGuestPPC64State,guest_CIA);
908
917
   Bool   is64             = True;
909
918
   IRType ty_Word          = Ity_I64;
910
919
   IROp   op_CmpNE         = Iop_CmpNE64;
918
927
   Int    offB_REDIR_SP    = offsetof(VexGuestPPC32State,guest_REDIR_SP);
919
928
   Int    offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
920
929
   Int    offB_EMWARN      = offsetof(VexGuestPPC32State,guest_EMWARN);
 
930
   Int    offB_CIA         = offsetof(VexGuestPPC32State,guest_CIA);
921
931
   Bool   is64             = False;
922
932
   IRType ty_Word          = Ity_I32;
923
933
   IROp   op_CmpNE         = Iop_CmpNE32;
969
979
            mkU(0)
970
980
         ),
971
981
         Ijk_EmFail,
972
 
         is64 ? IRConst_U64(0) : IRConst_U32(0)
 
982
         is64 ? IRConst_U64(0) : IRConst_U32(0),
 
983
         offB_CIA
973
984
      )
974
985
   );
975
986
 
980
991
   /* PutI/GetI have I32-typed indexes regardless of guest word size */
981
992
   addStmtToIRSB(
982
993
      bb, 
983
 
      IRStmt_PutI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e)
984
 
   );
 
994
      IRStmt_PutI(mkIRPutI(descr, 
 
995
                           narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e)));
985
996
}
986
997
 
987
998
 
996
1007
   Int    offB_REDIR_SP    = offsetof(VexGuestPPC64State,guest_REDIR_SP);
997
1008
   Int    offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK);
998
1009
   Int    offB_EMWARN      = offsetof(VexGuestPPC64State,guest_EMWARN);
 
1010
   Int    offB_CIA         = offsetof(VexGuestPPC64State,guest_CIA);
999
1011
   Bool   is64             = True;
1000
1012
   IRType ty_Word          = Ity_I64;
1001
1013
   IROp   op_CmpNE         = Iop_CmpNE64;
1007
1019
   Int    offB_REDIR_SP    = offsetof(VexGuestPPC32State,guest_REDIR_SP);
1008
1020
   Int    offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK);
1009
1021
   Int    offB_EMWARN      = offsetof(VexGuestPPC32State,guest_EMWARN);
 
1022
   Int    offB_CIA         = offsetof(VexGuestPPC32State,guest_CIA);
1010
1023
   Bool   is64             = False;
1011
1024
   IRType ty_Word          = Ity_I32;
1012
1025
   IROp   op_CmpNE         = Iop_CmpNE32;
1048
1061
            mkU(0)
1049
1062
         ),
1050
1063
         Ijk_EmFail,
1051
 
         is64 ? IRConst_U64(0) : IRConst_U32(0)
 
1064
         is64 ? IRConst_U64(0) : IRConst_U32(0),
 
1065
         offB_CIA
1052
1066
      )
1053
1067
   );
1054
1068
 
1099
1113
#  if defined(VGP_ppc64_linux)
1100
1114
   Int    offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2);
1101
1115
   Int    offB_LR   = offsetof(VexGuestPPC64State,guest_LR);
 
1116
   Int    offB_CIA  = offsetof(VexGuestPPC64State,guest_CIA);
1102
1117
   IRTemp old_R2    = newIRTemp( bb->tyenv, Ity_I64 );
1103
1118
   IRTemp old_LR    = newIRTemp( bb->tyenv, Ity_I64 );
1104
1119
   /* Restore R2 */
1112
1127
      blr (hence Ijk_Ret); so we should just mark this jump as Boring,
1113
1128
      else one _Call will have resulted in two _Rets. */
1114
1129
   bb->jumpkind = Ijk_Boring;
1115
 
   bb->next = IRExpr_Binop(Iop_And64, IRExpr_RdTmp(old_LR), mkU64(~(3ULL)));
1116
 
 
 
1130
   bb->next     = IRExpr_Binop(Iop_And64, IRExpr_RdTmp(old_LR), mkU64(~(3ULL)));
 
1131
   bb->offsIP   = offB_CIA;
1117
1132
#  else
1118
1133
#    error Platform is not TOC-afflicted, fortunately
1119
1134
#  endif
1173
1188
         nraddr_szB == 8 ? mkU64(0) : mkU32(0)
1174
1189
      )
1175
1190
   );
 
1191
#  if defined(VGP_mips32_linux)
 
1192
   // t9 needs to be set to point to the start of the redirected function.
 
1193
   VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
 
1194
   Int    offB_GPR25 = offsetof(VexGuestMIPS32State,guest_r25);
 
1195
   addStmtToIRSB( bb, IRStmt_Put( offB_GPR25, mkU32( closure->readdr )) );
 
1196
#  endif
1176
1197
#  if defined(VG_PLAT_USES_PPCTOC)
1177
1198
   { VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
1178
1199
     addStmtToIRSB(
1209
1230
            : IRExpr_Const(IRConst_U32( (UInt)closure->nraddr ))
1210
1231
      )
1211
1232
   );
 
1233
#  if defined(VGP_mips32_linux)
 
1234
   // t9 needs to be set to point to the start of the redirected function.
 
1235
   Int    offB_GPR25 = offsetof(VexGuestMIPS32State,guest_r25);
 
1236
   addStmtToIRSB( bb, IRStmt_Put( offB_GPR25, mkU32( closure->readdr )) );
 
1237
#  endif
1212
1238
#  if defined(VGP_ppc64_linux)
1213
1239
   addStmtToIRSB( 
1214
1240
      bb,
1318
1344
   if ((kind == T_Redir_Wrap || kind == T_Redir_Replace)
1319
1345
       && (VG_(clo_verbosity) >= 2 || VG_(clo_trace_redir))) {
1320
1346
      Bool ok;
1321
 
      Char name1[64] = "";
1322
 
      Char name2[64] = "";
 
1347
      Char name1[512] = "";
 
1348
      Char name2[512] = "";
1323
1349
      name1[0] = name2[0] = 0;
1324
 
      ok = VG_(get_fnname_w_offset)(nraddr, name1, 64);
 
1350
      ok = VG_(get_fnname_w_offset)(nraddr, name1, 512);
1325
1351
      if (!ok) VG_(strcpy)(name1, "???");
1326
 
      ok = VG_(get_fnname_w_offset)(addr, name2, 64);
 
1352
      ok = VG_(get_fnname_w_offset)(addr, name2, 512);
1327
1353
      if (!ok) VG_(strcpy)(name2, "???");
1328
1354
      VG_(message)(Vg_DebugMsg, 
1329
1355
                   "REDIR: 0x%llx (%s) redirected to 0x%llx (%s)\n",
1337
1363
 
1338
1364
   /* If doing any code printing, print a basic block start marker */
1339
1365
   if (VG_(clo_trace_flags) || debugging_translation) {
1340
 
      Char fnname[64] = "UNKNOWN_FUNCTION";
1341
 
      VG_(get_fnname_w_offset)(addr, fnname, 64);
 
1366
      Char fnname[512] = "UNKNOWN_FUNCTION";
 
1367
      VG_(get_fnname_w_offset)(addr, fnname, 512);
1342
1368
      const UChar* objname = "UNKNOWN_OBJECT";
1343
1369
      OffT         objoff  = 0;
1344
1370
      DebugInfo*   di      = VG_(find_DebugInfo)( addr );
1348
1374
      }
1349
1375
      vg_assert(objname);
1350
1376
      VG_(printf)(
1351
 
         "==== SB %d (exec'd %lld) [tid %d] 0x%llx %s %s+0x%llx\n",
 
1377
         "==== SB %d (evchecks %lld) [tid %d] 0x%llx %s %s+0x%llx\n",
1352
1378
         VG_(get_bbs_translated)(), bbs_done, (Int)tid, addr,
1353
1379
         fnname, objname, (ULong)objoff
1354
1380
      );
1394
1420
   }
1395
1421
   else
1396
1422
   if ( (VG_(clo_trace_flags) > 0
 
1423
        && VG_(get_bbs_translated)() <= VG_(clo_trace_notabove)
1397
1424
        && VG_(get_bbs_translated)() >= VG_(clo_trace_notbelow) )) {
1398
1425
      verbosity = VG_(clo_trace_flags);
1399
1426
   }
1461
1488
   vta.arch_host        = vex_arch;
1462
1489
   vta.archinfo_host    = vex_archinfo;
1463
1490
   vta.abiinfo_both     = vex_abiinfo;
 
1491
   vta.callback_opaque  = (void*)&closure;
1464
1492
   vta.guest_bytes      = (UChar*)ULong_to_Ptr(addr);
1465
1493
   vta.guest_bytes_addr = (Addr64)addr;
1466
 
   vta.callback_opaque  = (void*)&closure;
1467
1494
   vta.chase_into_ok    = chase_into_ok;
1468
 
   vta.preamble_function = preamble_fn;
1469
1495
   vta.guest_extents    = &vge;
1470
1496
   vta.host_bytes       = tmpbuf;
1471
1497
   vta.host_bytes_size  = N_TMPBUF;
1486
1512
               IRSB*,VexGuestLayout*,VexGuestExtents*,
1487
1513
               IRType,IRType)
1488
1514
       = (IRSB*(*)(void*,IRSB*,VexGuestLayout*,VexGuestExtents*,IRType,IRType))f;
1489
 
     vta.instrument1    = g;
 
1515
     vta.instrument1     = g;
1490
1516
   }
1491
1517
   /* No need for type kludgery here. */
1492
 
   vta.instrument2      = need_to_handle_SP_assignment()
1493
 
                             ? vg_SP_update_pass
1494
 
                             : NULL;
1495
 
   vta.finaltidy        = VG_(needs).final_IR_tidy_pass
1496
 
                             ? VG_(tdict).tool_final_IR_tidy_pass
1497
 
                             : NULL;
1498
 
   vta.needs_self_check = needs_self_check;
1499
 
   vta.traceflags       = verbosity;
1500
 
 
1501
 
   /* Set up the dispatch-return info.  For archs without a link
1502
 
      register, vex generates a jump back to the specified dispatch
1503
 
      address.  Else, it just generates a branch-to-LR. */
1504
 
 
1505
 
#  if defined(VGA_x86) || defined(VGA_amd64)
1506
 
   if (!allow_redirection) {
1507
 
      /* It's a no-redir translation.  Will be run with the
1508
 
         nonstandard dispatcher VG_(run_a_noredir_translation) and so
1509
 
         needs a nonstandard return point. */
1510
 
      vta.dispatch_assisted
1511
 
         = (void*) &VG_(run_a_noredir_translation__return_point);
1512
 
      vta.dispatch_unassisted
1513
 
         = vta.dispatch_assisted;
1514
 
   }
1515
 
   else
1516
 
   if (VG_(clo_profile_flags) > 0) {
1517
 
      /* normal translation; although we're profiling. */
1518
 
      vta.dispatch_assisted
1519
 
         = (void*) &VG_(run_innerloop__dispatch_assisted_profiled);
1520
 
      vta.dispatch_unassisted
1521
 
         = (void*) &VG_(run_innerloop__dispatch_unassisted_profiled);
1522
 
   }
1523
 
   else {
1524
 
      /* normal translation and we're not profiling (the normal case) */
1525
 
      vta.dispatch_assisted
1526
 
         = (void*) &VG_(run_innerloop__dispatch_assisted_unprofiled);
1527
 
      vta.dispatch_unassisted
1528
 
         = (void*) &VG_(run_innerloop__dispatch_unassisted_unprofiled);
1529
 
   }
1530
 
 
1531
 
#  elif defined(VGA_ppc32) || defined(VGA_ppc64) \
1532
 
        || defined(VGA_arm) || defined(VGA_s390x)
1533
 
   /* See comment in libvex.h.  This target uses a
1534
 
      return-to-link-register scheme to get back to the dispatcher, so
1535
 
      both fields are NULL. */
1536
 
   vta.dispatch_assisted   = NULL;
1537
 
   vta.dispatch_unassisted = NULL;
1538
 
 
1539
 
#  else
1540
 
#    error "Unknown arch"
1541
 
#  endif
 
1518
   vta.instrument2       = need_to_handle_SP_assignment()
 
1519
                              ? vg_SP_update_pass
 
1520
                              : NULL;
 
1521
   vta.finaltidy         = VG_(needs).final_IR_tidy_pass
 
1522
                              ? VG_(tdict).tool_final_IR_tidy_pass
 
1523
                              : NULL;
 
1524
   vta.needs_self_check  = needs_self_check;
 
1525
   vta.preamble_function = preamble_fn;
 
1526
   vta.traceflags        = verbosity;
 
1527
   vta.addProfInc        = VG_(clo_profile_flags) > 0
 
1528
                           && kind != T_NoRedir;
 
1529
 
 
1530
   /* Set up the dispatch continuation-point info.  If this is a
 
1531
      no-redir translation then it cannot be chained, and the chain-me
 
1532
      points are set to NULL to indicate that.  The indir point must
 
1533
      also be NULL, since we can't allow this translation to do an
 
1534
      indir transfer -- that would take it back into the main
 
1535
      translation cache too.
 
1536
 
 
1537
      All this is because no-redir translations live outside the main
 
1538
      translation cache (in a secondary one) and chaining them would
 
1539
      involve more adminstrative complexity that isn't worth the
 
1540
      hassle, because we don't expect them to get used often.  So
 
1541
      don't bother. */
 
1542
   if (allow_redirection) {
 
1543
      vta.disp_cp_chain_me_to_slowEP
 
1544
         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_slowEP) );
 
1545
      vta.disp_cp_chain_me_to_fastEP
 
1546
         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_fastEP) );
 
1547
      vta.disp_cp_xindir
 
1548
         = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xindir) );
 
1549
   } else {
 
1550
      vta.disp_cp_chain_me_to_slowEP = NULL;
 
1551
      vta.disp_cp_chain_me_to_fastEP = NULL;
 
1552
      vta.disp_cp_xindir             = NULL;
 
1553
   }
 
1554
   /* This doesn't involve chaining and so is always allowable. */
 
1555
   vta.disp_cp_xassisted
 
1556
      = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xassisted) );
1542
1557
 
1543
1558
   /* Sheesh.  Finally, actually _do_ the translation! */
1544
1559
   tres = LibVEX_Translate ( &vta );
1581
1596
                                nraddr,
1582
1597
                                (Addr)(&tmpbuf[0]), 
1583
1598
                                tmpbuf_used,
1584
 
                                tres.n_sc_extents > 0 );
 
1599
                                tres.n_sc_extents > 0,
 
1600
                                tres.offs_profInc,
 
1601
                                tres.n_guest_instrs,
 
1602
                                vex_arch );
1585
1603
      } else {
 
1604
          vg_assert(tres.offs_profInc == -1); /* -1 == unset */
1586
1605
          VG_(add_to_unredir_transtab)( &vge,
1587
1606
                                        nraddr,
1588
1607
                                        (Addr)(&tmpbuf[0]),