You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(3) |
2
(2) |
3
|
4
(1) |
|
5
|
6
(2) |
7
|
8
(1) |
9
|
10
(2) |
11
(8) |
|
12
(2) |
13
(9) |
14
(2) |
15
(6) |
16
(5) |
17
(3) |
18
|
|
19
|
20
(1) |
21
(1) |
22
(6) |
23
(8) |
24
(2) |
25
(1) |
|
26
|
27
(3) |
28
(8) |
29
(17) |
30
(6) |
31
(3) |
|
Author: petarj
Date: Mon Mar 13 17:50:25 2017
New Revision: 3316
Log:
mips: emulate LL/SC w/ guest_LLaddr and guest_LLdata
Improve LL/SC emulation with introduction of LLaddr and LLdata in the
guest state. LLaddr gets invalidated when the threads switch.
More info at KDE #344524. This patch should fix the issue.
Currently, this is effective for Cavium boards only.
Patch by Maran Pakkirisamy.
Modified:
trunk/priv/guest_mips_defs.h
trunk/priv/guest_mips_helpers.c
trunk/priv/guest_mips_toIR.c
trunk/pub/libvex_guest_mips32.h
trunk/pub/libvex_guest_mips64.h
Modified: trunk/priv/guest_mips_defs.h
==============================================================================
--- trunk/priv/guest_mips_defs.h (original)
+++ trunk/priv/guest_mips_defs.h Mon Mar 13 17:50:25 2017
@@ -94,6 +94,12 @@
SUBS, SUBD, DIVS
} flt_op;
+#if defined (_MIPSEL)
+ #define MIPS_IEND Iend_LE
+#else
+ #define MIPS_IEND Iend_BE
+#endif
+
#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
extern UInt mips32_dirtyhelper_rdhwr ( UInt rt, UInt rd );
extern ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd );
Modified: trunk/priv/guest_mips_helpers.c
==============================================================================
--- trunk/priv/guest_mips_helpers.c (original)
+++ trunk/priv/guest_mips_helpers.c Mon Mar 13 17:50:25 2017
@@ -167,6 +167,9 @@
vex_state->guest_CP0_status = 0;
+ vex_state->guest_LLaddr = 0xFFFFFFFF;
+ vex_state->guest_LLdata = 0;
+
/* MIPS32 DSP ASE(r2) specific registers */
vex_state->guest_DSPControl = 0; /* DSPControl register */
vex_state->guest_ac0 = 0; /* Accumulator 0 */
@@ -276,6 +279,9 @@
vex_state->guest_COND = 0;
vex_state->guest_CP0_status = MIPS_CP0_STATUS_FR;
+
+ vex_state->guest_LLaddr = 0xFFFFFFFFFFFFFFFFULL;
+ vex_state->guest_LLdata = 0;
}
/*-----------------------------------------------------------*/
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Mon Mar 13 17:50:25 2017
@@ -549,6 +549,9 @@
dres.jk_StopHere = Ijk_SigILL; \
dres.whatNext = Dis_StopHere;
+#define LLADDR_INVALID \
+ (mode64 ? mkU64(0xFFFFFFFFFFFFFFFFULL) : mkU32(0xFFFFFFFF))
+
/*------------------------------------------------------------*/
/*--- Field helpers ---*/
/*------------------------------------------------------------*/
@@ -1087,6 +1090,22 @@
return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
}
+static IRExpr *getLLaddr(void)
+{
+ if (mode64)
+ return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLaddr), Ity_I64);
+ else
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLaddr), Ity_I32);
+}
+
+static IRExpr *getLLdata(void)
+{
+ if (mode64)
+ return IRExpr_Get(offsetof(VexGuestMIPS64State, guest_LLdata), Ity_I64);
+ else
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata), Ity_I32);
+}
+
/* Get byte from register reg, byte pos from 0 to 3 (or 7 for MIPS64) . */
static IRExpr *getByteFromReg(UInt reg, UInt byte_pos)
{
@@ -1109,6 +1128,22 @@
stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
}
+static void putLLaddr(IRExpr * e)
+{
+ if (mode64)
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLaddr), e));
+ else
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLaddr), e));
+}
+
+static void putLLdata(IRExpr * e)
+{
+ if (mode64)
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LLdata), e));
+ else
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata), e));
+}
+
/* fs - fpu source register number.
inst - fpu instruction that needs to be executed.
sz32 - size of source register.
@@ -1339,6 +1374,16 @@
return src;
}
+/* Convenience function to move to next instruction on condition. */
+static void mips_next_insn_if(IRExpr *condition) {
+ vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
+
+ stmt(IRStmt_Exit(condition, Ijk_Boring,
+ mode64 ? IRConst_U64(guest_PC_curr_instr + 4) :
+ IRConst_U32(guest_PC_curr_instr + 4),
+ OFFB_PC));
+}
+
static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
{
ULong branch_offset;
@@ -16935,64 +16980,106 @@
putIReg(rt, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), False));
break;
- case 0x30: /* LL / LWC0 */
+ case 0x30: /* LL */
DIP("ll r%u, %u(r%u)", rt, imm, rs);
LOAD_STORE_PATTERN;
-
- t2 = newTemp(Ity_I32);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#endif
- if (mode64)
- putIReg(rt, unop(Iop_32Sto64, mkexpr(t2)));
- else
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t2 = newTemp(ty);
+ assign(t2, mkWidenFrom32(ty, load(Ity_I32, mkexpr(t1)), True));
+ putLLaddr(mkexpr(t1));
+ putLLdata(mkexpr(t2));
putIReg(rt, mkexpr(t2));
+ } else {
+ t2 = newTemp(Ity_I32);
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
+ putIReg(rt, mkWidenFrom32(ty, mkexpr(t2), True));
+ }
break;
case 0x34: /* Load Linked Doubleword - LLD; MIPS64 */
DIP("lld r%u, %u(r%u)", rt, imm, rs);
- LOAD_STORE_PATTERN;
-
- t2 = newTemp(Ity_I64);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC
- (Iend_LE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC
- (Iend_BE, t2, mkexpr(t1), NULL /* this is a load */ ));
-#endif
-
- putIReg(rt, mkexpr(t2));
+ if (mode64) {
+ LOAD_STORE_PATTERN;
+ t2 = newTemp(Ity_I64);
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ assign(t2, load(Ity_I64, mkexpr(t1)));
+ putLLaddr(mkexpr(t1));
+ putLLdata(mkexpr(t2));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), NULL));
+ }
+ putIReg(rt, mkexpr(t2));
+ } else {
+ ILLEGAL_INSTRUCTON;
+ }
break;
- case 0x38: /* SC / SWC0 */
+ case 0x38: /* SC */
DIP("sc r%u, %u(r%u)", rt, imm, rs);
+ t2 = newTemp(Ity_I1);
LOAD_STORE_PATTERN;
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t3 = newTemp(Ity_I32);
+ assign(t2, binop(mode64 ? Iop_CmpNE64 : Iop_CmpNE32,
+ mkexpr(t1), getLLaddr()));
+ assign(t3, mkNarrowTo32(ty, getIReg(rt)));
+ putLLaddr(LLADDR_INVALID);
+ putIReg(rt, getIReg(0));
- t2 = newTemp(Ity_I1);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), mkNarrowTo32(ty, getIReg(rt))));
-#endif
+ mips_next_insn_if(mkexpr(t2));
+
+ t4 = newTemp(Ity_I32);
+ t5 = newTemp(Ity_I32);
+
+ assign(t5, mkNarrowTo32(ty, getLLdata()));
+
+ stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
+ MIPS_IEND, mkexpr(t1), /* addr */
+ NULL, mkexpr(t5), /* expected value */
+ NULL, mkexpr(t3) /* new value */)));
- putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
+ putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32,
+ binop(Iop_CmpEQ32, mkexpr(t4), mkexpr(t5))));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1),
+ mkNarrowTo32(ty, getIReg(rt))));
+ putIReg(rt, unop(mode64 ? Iop_1Uto64 : Iop_1Uto32, mkexpr(t2)));
+ }
break;
case 0x3C: /* Store Conditional Doubleword - SCD; MIPS64 */
- DIP("sdc r%u, %u(r%u)", rt, imm, rs);
- LOAD_STORE_PATTERN;
+ DIP("scd r%u, %u(r%u)", rt, imm, rs);
+ if (mode64) {
+ t2 = newTemp(Ity_I1);
+ LOAD_STORE_PATTERN;
+ if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+ t3 = newTemp(Ity_I64);
+ assign(t2, binop(Iop_CmpNE64, mkexpr(t1), getLLaddr()));
+ assign(t3, getIReg(rt));
+ putLLaddr(LLADDR_INVALID);
+ putIReg(rt, getIReg(0));
- t2 = newTemp(Ity_I1);
-#if defined (_MIPSEL)
- stmt(IRStmt_LLSC(Iend_LE, t2, mkexpr(t1), getIReg(rt)));
-#elif defined (_MIPSEB)
- stmt(IRStmt_LLSC(Iend_BE, t2, mkexpr(t1), getIReg(rt)));
-#endif
+ mips_next_insn_if(mkexpr(t2));
- putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
+ t4 = newTemp(Ity_I64);
+ t5 = newTemp(Ity_I64);
+
+ assign(t5, getLLdata());
+
+ stmt(IRStmt_CAS(mkIRCAS(IRTemp_INVALID, t4, /* old_mem */
+ MIPS_IEND, mkexpr(t1), /* addr */
+ NULL, mkexpr(t5), /* expected value */
+ NULL, mkexpr(t3) /* new value */)));
+
+ putIReg(rt, unop(Iop_1Uto64,
+ binop(Iop_CmpEQ64, mkexpr(t4), mkexpr(t5))));
+ } else {
+ stmt(IRStmt_LLSC(MIPS_IEND, t2, mkexpr(t1), getIReg(rt)));
+ putIReg(rt, unop(Iop_1Uto64, mkexpr(t2)));
+ }
+ } else {
+ ILLEGAL_INSTRUCTON;
+ }
break;
case 0x37: /* Load Doubleword - LD; MIPS64 */
Modified: trunk/pub/libvex_guest_mips32.h
==============================================================================
--- trunk/pub/libvex_guest_mips32.h (original)
+++ trunk/pub/libvex_guest_mips32.h Mon Mar 13 17:50:25 2017
@@ -151,7 +151,10 @@
/* 488 */ UInt guest_CP0_status;
- /* 492 */ UInt _padding2;
+ /* 492 */ UInt guest_LLaddr;
+ /* 496 */ UInt guest_LLdata;
+
+ /* 500 */ UInt _padding2[3];
} VexGuestMIPS32State;
/*---------------------------------------------------------------*/
/*--- Utility functions for MIPS32 guest stuff. ---*/
Modified: trunk/pub/libvex_guest_mips64.h
==============================================================================
--- trunk/pub/libvex_guest_mips64.h (original)
+++ trunk/pub/libvex_guest_mips64.h Mon Mar 13 17:50:25 2017
@@ -148,7 +148,10 @@
/* 608 */ ULong guest_NRADDR;
- /* 616 */ ULong _padding2;
+ /* 616 */ ULong guest_LLaddr;
+ /* 624 */ ULong guest_LLdata;
+
+ /* 632 */ ULong _padding2;
} VexGuestMIPS64State;
/*---------------------------------------------------------------*/
|
|
From: <sv...@va...> - 2017-03-13 13:08:25
|
Author: iraisr
Date: Mon Mar 13 13:08:13 2017
New Revision: 3315
Log:
Fix IRSB traversal problem in sanityCheckIRSB()
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Mon Mar 13 13:08:13 2017
@@ -4006,6 +4006,11 @@
return True;
}
+Bool isFlatIRSB(const IRSB* irsb)
+{
+ return isFlatIRStmtVec(irsb->stmts);
+}
+
/*---------------------------------------------------------------*/
/*--- Sanity checking ---*/
/*---------------------------------------------------------------*/
@@ -4137,7 +4142,7 @@
def_counts[tmp.id][tmp.index]++;
if (def_counts[tmp.id][tmp.index] > 1) {
- sanityCheckFail(bb,stmt,err_msg_assigned_more_than_once);
+ sanityCheckFail(bb, stmt, err_msg_assigned_more_than_once);
}
}
@@ -4236,9 +4241,6 @@
}
}
-static void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[]);
-
static
void useBeforeDef_Stmt(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, UInt* def_counts[])
@@ -4322,8 +4324,7 @@
case Ist_IfThenElse:
useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond,
def_counts);
- useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
- useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
if (stmt->Ist.IfThenElse.phi_nodes != NULL) {
useBeforeDef_PhiNodes(bb, stmts, stmt,
stmt->Ist.IfThenElse.phi_nodes, def_counts);
@@ -4335,18 +4336,6 @@
}
static
-void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[])
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- useBeforeDef_Stmt(bb, stmts, stmts->stmts[i], def_counts);
- }
-}
-
-static void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[]);
-
-static
void assignedOnce_Stmt(const IRSB* bb, const IRStmtVec* stmts,
const IRStmt* stmt, UInt* def_counts[])
{
@@ -4396,8 +4385,7 @@
"IRStmt.LLSC: destination tmp is assigned more than once");
break;
case Ist_IfThenElse: {
- assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
- assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
if (phi_nodes != NULL) {
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
@@ -4420,15 +4408,6 @@
}
static
-void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
- UInt* def_counts[])
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- assignedOnce_Stmt(bb, stmts, stmts->stmts[i], def_counts);
- }
-}
-
-static
void tcExpr(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
const IRExpr* expr, IRType gWordTy)
{
@@ -4652,9 +4631,6 @@
}
}
-static void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
- IRType gWordTy);
-
static
void tcStmt(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
Bool require_flat, IRType gWordTy)
@@ -4940,8 +4916,7 @@
tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
- tcStmts(bb, stmt->Ist.IfThenElse.then_leg, require_flat, gWordTy);
- tcStmts(bb, stmt->Ist.IfThenElse.else_leg, require_flat, gWordTy);
+ /* Traversing into legs driven from sanityCheckIRStmtVec(). */
const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
if (phi_nodes != NULL) {
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
@@ -4955,18 +4930,10 @@
}
static
-void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
- IRType gWordTy)
-{
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- tcStmt(bb, stmts, stmts->stmts[i], require_flat, gWordTy);
- }
-}
-
-static
void sanityCheckIRStmtVec(const IRSB* bb, const IRStmtVec* stmts,
Bool require_flat, UInt* def_counts[],
- UInt n_stmt_vecs, UInt id_counts[])
+ UInt n_stmt_vecs, UInt id_counts[],
+ IRType gWordTy)
{
const IRTypeEnv* tyenv = stmts->tyenv;
IRTyEnvID id = tyenv->id;
@@ -5009,21 +4976,30 @@
}
}
- /* Check for flatness, if required. */
- if (require_flat) {
- for (UInt i = 0; i < stmts->stmts_used; i++) {
- const IRStmt *stmt = stmts->stmts[i];
- if (stmt == NULL)
- sanityCheckFail(bb,stmt,"IRStmt: is NULL");
- if (!isFlatIRStmt(stmt))
- sanityCheckFail(bb,stmt,"IRStmt: is not flat");
- if (stmt->tag == Ist_IfThenElse) {
- sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.then_leg,
- require_flat, def_counts, n_stmt_vecs, id_counts);
- sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.else_leg,
- require_flat, def_counts, n_stmt_vecs, id_counts);
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ const IRStmt *stmt = stmts->stmts[i];
+ if (stmt == NULL)
+ sanityCheckFail(bb, stmt, "IRStmt: is NULL");
+
+ /* Check for flatness, if required. */
+ if (require_flat) {
+ if (!isFlatIRStmt(stmt)) {
+ sanityCheckFail(bb, stmt, "IRStmt: is not flat");
}
}
+
+ /* Count the defs of each temp. Only one def is allowed.
+ Also, check that each used temp has already been defd. */
+ useBeforeDef_Stmt(bb, stmts, stmt, def_counts);
+ assignedOnce_Stmt(bb, stmts, stmt, def_counts);
+ tcStmt(bb, stmts, stmt, require_flat, gWordTy);
+
+ if (stmt->tag == Ist_IfThenElse) {
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.then_leg, require_flat,
+ def_counts, n_stmt_vecs, id_counts, gWordTy);
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.else_leg, require_flat,
+ def_counts, n_stmt_vecs, id_counts, gWordTy);
+ }
}
}
@@ -5047,13 +5023,7 @@
vassert(gWordTy == Ity_I32 || gWordTy == Ity_I64);
sanityCheckIRStmtVec(bb, bb->stmts, require_flat, def_counts, n_stmt_vecs,
- id_counts);
-
- /* Count the defs of each temp. Only one def is allowed.
- Also, check that each used temp has already been defd. */
- useBeforeDef_Stmts(bb, bb->stmts, def_counts);
- assignedOnce_Stmts(bb, bb->stmts, def_counts);
- tcStmts(bb, bb->stmts, require_flat, gWordTy);
+ id_counts, gWordTy);
if (require_flat) {
if (!isIRAtom(bb->next)) {
|
|
From: <sv...@va...> - 2017-03-13 10:31:12
|
Author: iraisr
Date: Mon Mar 13 10:31:02 2017
New Revision: 16268
Log:
Progress further with IfThenElse in memcheck/mc_translate.c
Modified:
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c Mon Mar 13 10:31:02 2017
@@ -174,30 +174,10 @@
TempMapEnt;
-/* Carries around state during memcheck instrumentation. */
typedef
- struct _MCEnv {
- /* MODIFIED: the superblock being constructed. IRStmts are
- added. */
- IRSB* sb;
+ struct _MCEnvSettings {
Bool trace;
- /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
- current kind and possibly shadow temps for each temp in the
- IRSB being constructed. Note that it does not contain the
- type of each tmp. If you want to know the type, look at the
- relevant entry in sb->tyenv. It follows that at all times
- during the instrumentation process, the valid indices for
- tmpMap and sb->tyenv are identical, being 0 .. N-1 where N is
- total number of Orig, V- and B- temps allocated so far.
-
- The reason for this strange split (types in one place, all
- other info in another) is that we need the types to be
- attached to sb so as to make it possible to do
- "typeOfIRExpr(mce->bb->tyenv, ...)" at various places in the
- instrumentation process. */
- XArray* /* of TempMapEnt */ tmpMap;
-
/* MODIFIED: indicates whether "bogus" literals have so far been
found. Starts off False, and may change to True. */
Bool bogusLiterals;
@@ -217,6 +197,37 @@
Ity_I32 or Ity_I64 only. */
IRType hWordTy;
}
+ MCEnvSettings;
+
+/* Carries around state corresponding to one IRStmtVec during Memcheck
+ instrumentation. */
+typedef
+ struct _MCEnv {
+ /* MODIFIED: the stmts being constructed. IRStmts are added. */
+ IRStmtVec* stmts;
+ IRTypeEnv* tyenv;
+ IRTyEnvID id;
+
+ /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the
+ current kind and possibly shadow temps for each temp in the
+ IRStmtVec being constructed. Note that it does not contain the
+ type of each tmp. If you want to know the type, look at the
+ relevant entry in tyenv. It follows that at all times
+ during the instrumentation process, the valid indices for
+ tmpMap and tyenv are identical, being 0 .. N-1 where N is
+ total number of Orig, V- and B- temps allocated so far.
+
+ The reason for this strange split (types in one place, all
+ other info in another) is that we need the types to be
+ attached to sb so as to make it possible to do
+ "typeOfIRExpr(mce->tyenv, ...)" at various places in the
+ instrumentation process. */
+ XArray* /* of TempMapEnt */ tmpMap;
+
+ struct _MCEnv* parent;
+
+ MCEnvSettings* settings;
+ }
MCEnv;
/* SHADOW TMP MANAGEMENT. Shadow tmps are allocated lazily (on
@@ -251,12 +262,12 @@
{
Word newIx;
TempMapEnt ent;
- IRTemp tmp = newIRTemp(mce->sb->tyenv, ty);
+ IRTemp tmp = newIRTemp(mce->tyenv, ty);
ent.kind = kind;
- ent.shadowV = IRTemp_INVALID;
- ent.shadowB = IRTemp_INVALID;
+ ent.shadowV = IRTemp_INVALID();
+ ent.shadowB = IRTemp_INVALID();
newIx = VG_(addToXA)( mce->tmpMap, &ent );
- tl_assert(newIx == (Word)tmp);
+ tl_assert(newIx == tmp.index);
return tmp;
}
@@ -265,22 +276,24 @@
so far exists, allocate one. */
static IRTemp findShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
- /* VG_(indexXA) range-checks 'orig', hence no need to check
- here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
- tl_assert(ent->kind == Orig);
- if (ent->shadowV == IRTemp_INVALID) {
- IRTemp tmpV
- = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh );
- /* newTemp may cause mce->tmpMap to resize, hence previous results
- from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ if (mce->id == orig.id) {
+ /* VG_(indexXA) range-checks 'orig', hence no need to check here. */
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
- tl_assert(ent->shadowV == IRTemp_INVALID);
- ent->shadowV = tmpV;
+ if (isIRTempInvalid(ent->shadowV)) {
+ IRTemp tmpV = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]),
+ VSh);
+ /* newTemp may cause mce->tmpMap to resize, hence previous results
+ from VG_(indexXA) are invalid. */
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ tl_assert(ent->kind == Orig);
+ tl_assert(isIRTempInvalid(ent->shadowV));
+ ent->shadowV = tmpV;
+ }
+ return ent->shadowV;
+ } else {
+ return findShadowTmpV(mce->parent, orig);
}
- return ent->shadowV;
}
/* Allocate a new shadow for the given original tmp. This means any
@@ -295,22 +308,59 @@
regardless. */
static void newShadowTmpV ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
+ tl_assert(mce->id == orig.id);
+
/* VG_(indexXA) range-checks 'orig', hence no need to check
here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
if (1) {
IRTemp tmpV
- = newTemp( mce, shadowTypeV(mce->sb->tyenv->types[orig]), VSh );
+ = newTemp(mce, shadowTypeV(mce->tyenv->types[orig.index]), VSh);
/* newTemp may cause mce->tmpMap to resize, hence previous results
from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
ent->shadowV = tmpV;
}
}
+/* Set up the running environment. Both .stmts and .tmpMap are modified as we go
+ along. Note that tmps are added to both .tyenv and .tmpMap together, so the
+ valid index-set for those two arrays should always be identical. */
+static void initMCEnv(IRStmtVec* stmts_in, MCEnv* mce, MCEnv* parent_mce)
+{
+ IRStmtVec* stmts_out = emptyIRStmtVec();
+ stmts_out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
+ stmts_out->parent = parent_mce->stmts;
+
+ mce->stmts = stmts_out;
+ mce->tyenv = stmts_out->tyenv;
+ mce->id = mce->tyenv->id;
+ mce->parent = parent_mce;
+ mce->settings = (parent_mce != NULL) ? parent_mce->settings : NULL;
+
+ mce->tmpMap = VG_(newXA)(VG_(malloc), "mc.createMCEnv.1", VG_(free),
+ sizeof(TempMapEnt));
+ VG_(hintSizeXA)(mce->tmpMap, mce->tyenv->types_used);
+ for (UInt i = 0; i < mce->tyenv->types_used; i++) {
+ TempMapEnt ent;
+ ent.kind = Orig;
+ ent.shadowV = IRTemp_INVALID();
+ ent.shadowB = IRTemp_INVALID();
+ VG_(addToXA)(mce->tmpMap, &ent);
+ }
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == stmts_in->tyenv->types_used);
+}
+
+static void deinitMCEnv(MCEnv* mce)
+{
+ /* If this fails, there's been some serious snafu with tmp management,
+ that should be investigated. */
+ tl_assert(VG_(sizeXA)(mce->tmpMap) == mce->tyenv->types_used);
+ VG_(deleteXA)(mce->tmpMap);
+}
+
/*------------------------------------------------------------*/
/*--- IRAtoms -- a subset of IRExprs ---*/
@@ -332,8 +382,12 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp );
- return ent->kind == Orig;
+ if (mce->id == a1->Iex.RdTmp.tmp.id) {
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ return ent->kind == Orig;
+ } else {
+ return isOriginalAtom(mce->parent, a1);
+ }
}
return False;
}
@@ -345,8 +399,12 @@
if (a1->tag == Iex_Const)
return True;
if (a1->tag == Iex_RdTmp) {
- TempMapEnt* ent = VG_(indexXA)( mce->tmpMap, a1->Iex.RdTmp.tmp );
- return ent->kind == VSh || ent->kind == BSh;
+ if (mce->id == a1->Iex.RdTmp.tmp.id) {
+ TempMapEnt* ent = VG_(indexXA)(mce->tmpMap, a1->Iex.RdTmp.tmp.index);
+ return ent->kind == VSh || ent->kind == BSh;
+ } else {
+ return isShadowAtom(mce->parent, a1);
+ }
}
return False;
}
@@ -418,12 +476,12 @@
/* add stmt to a bb */
static inline void stmt ( HChar cat, MCEnv* mce, IRStmt* st ) {
- if (mce->trace) {
+ if (mce->settings->trace) {
VG_(printf)(" %c: ", cat);
ppIRStmt(st);
VG_(printf)("\n");
}
- addStmtToIRSB(mce->sb, st);
+ addStmtToIRStmtVec(mce->stmts, st);
}
/* assign value to tmp */
@@ -432,6 +490,16 @@
stmt(cat, mce, IRStmt_WrTmp(tmp,expr));
}
+static void phi(HChar cat, MCEnv* mce, IRPhiVec* phi_nodes, IRPhi *phi)
+{
+ if (mce->settings->trace) {
+ VG_(printf)(" %c: ", cat);
+ ppIRPhi(phi);
+ VG_(printf)("\n");
+ }
+ addIRPhiToIRPhiVec(phi_nodes, phi);
+}
+
/* build various kinds of expressions */
#define triop(_op, _arg1, _arg2, _arg3) \
IRExpr_Triop((_op),(_arg1),(_arg2),(_arg3))
@@ -457,7 +525,7 @@
{
TempKind k;
IRTemp t;
- IRType tyE = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType tyE = typeOfIRExpr(mce->tyenv, e);
tl_assert(tyE == ty); /* so 'ty' is redundant (!) */
switch (cat) {
@@ -761,7 +829,7 @@
/* Note, dst_ty is a shadow type, not an original type. */
tl_assert(isShadowAtom(mce,vbits));
- src_ty = typeOfIRExpr(mce->sb->tyenv, vbits);
+ src_ty = typeOfIRExpr(mce->tyenv, vbits);
/* Fast-track some common cases */
if (src_ty == Ity_I32 && dst_ty == Ity_I32)
@@ -1185,16 +1253,19 @@
behaviour of all 'emit-a-complaint' style functions we might
call. */
-static void setHelperAnns ( MCEnv* mce, IRDirty* di ) {
+static void setHelperAnns ( MCEnv* mce, IRDirty* di )
+{
+ const VexGuestLayout* layout = mce->settings->layout;
+
di->nFxState = 2;
di->fxState[0].fx = Ifx_Read;
- di->fxState[0].offset = mce->layout->offset_SP;
- di->fxState[0].size = mce->layout->sizeof_SP;
+ di->fxState[0].offset = layout->offset_SP;
+ di->fxState[0].size = layout->sizeof_SP;
di->fxState[0].nRepeats = 0;
di->fxState[0].repeatLen = 0;
di->fxState[1].fx = Ifx_Read;
- di->fxState[1].offset = mce->layout->offset_IP;
- di->fxState[1].size = mce->layout->sizeof_IP;
+ di->fxState[1].offset = layout->offset_IP;
+ di->fxState[1].size = layout->sizeof_IP;
di->fxState[1].nRepeats = 0;
di->fxState[1].repeatLen = 0;
}
@@ -1248,7 +1319,7 @@
tl_assert(isShadowAtom(mce, vatom));
tl_assert(sameKindedAtoms(atom, vatom));
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
/* sz is only used for constructing the error message */
sz = ty==Ity_I1 ? 0 : sizeofIRType(ty);
@@ -1261,7 +1332,7 @@
zero origin. */
if (MC_(clo_mc_level) == 3) {
origin = schemeE( mce, atom );
- if (mce->hWordTy == Ity_I64) {
+ if (mce->settings->hWordTy == Ity_I64) {
origin = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, origin) );
}
} else {
@@ -1408,15 +1479,16 @@
*/
static Bool isAlwaysDefd ( MCEnv* mce, Int offset, Int size )
{
+ const VexGuestLayout* layout = mce->settings->layout;
Int minoffD, maxoffD, i;
Int minoff = offset;
Int maxoff = minoff + size - 1;
tl_assert((minoff & ~0xFFFF) == 0);
tl_assert((maxoff & ~0xFFFF) == 0);
- for (i = 0; i < mce->layout->n_alwaysDefd; i++) {
- minoffD = mce->layout->alwaysDefd[i].offset;
- maxoffD = minoffD + mce->layout->alwaysDefd[i].size - 1;
+ for (i = 0; i < layout->n_alwaysDefd; i++) {
+ minoffD = layout->alwaysDefd[i].offset;
+ maxoffD = minoffD + layout->alwaysDefd[i].size - 1;
tl_assert((minoffD & ~0xFFFF) == 0);
tl_assert((maxoffD & ~0xFFFF) == 0);
@@ -1442,6 +1514,7 @@
void do_shadow_PUT ( MCEnv* mce, Int offset,
IRAtom* atom, IRAtom* vatom, IRExpr *guard )
{
+ const VexGuestLayout* layout = mce->settings->layout;
IRType ty;
// Don't do shadow PUTs if we're not doing undefined value checking.
@@ -1459,7 +1532,7 @@
tl_assert(isShadowAtom(mce, vatom));
}
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
+ ty = typeOfIRExpr(mce->tyenv, vatom);
tl_assert(ty != Ity_I1);
if (isAlwaysDefd(mce, offset, sizeofIRType(ty))) {
/* later: no ... */
@@ -1474,10 +1547,10 @@
cond = assignNew('V', mce, Ity_I1, guard);
iffalse = assignNew('V', mce, ty,
- IRExpr_Get(offset + mce->layout->total_sizeB, ty));
+ IRExpr_Get(offset + layout->total_sizeB, ty));
vatom = assignNew('V', mce, ty, IRExpr_ITE(cond, vatom, iffalse));
}
- stmt( 'V', mce, IRStmt_Put( offset + mce->layout->total_sizeB, vatom ));
+ stmt( 'V', mce, IRStmt_Put( offset + layout->total_sizeB, vatom ));
}
}
@@ -1519,7 +1592,7 @@
/* Do a cloned version of the Put that refers to the shadow
area. */
IRRegArray* new_descr
- = mkIRRegArray( descr->base + mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + mce->settings->layout->total_sizeB,
tyS, descr->nElems);
stmt( 'V', mce, IRStmt_PutI( mkIRPutI(new_descr, ix, bias, vatom) ));
}
@@ -1542,7 +1615,7 @@
/* return a cloned version of the Get that refers to the shadow
area. */
/* FIXME: this isn't an atom! */
- return IRExpr_Get( offset + mce->layout->total_sizeB, tyS );
+ return IRExpr_Get( offset + mce->settings->layout->total_sizeB, tyS );
}
}
@@ -1567,7 +1640,7 @@
/* return a cloned version of the Get that refers to the shadow
area. */
IRRegArray* new_descr
- = mkIRRegArray( descr->base + mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + mce->settings->layout->total_sizeB,
tyS, descr->nElems);
return IRExpr_GetI( new_descr, ix, bias );
}
@@ -1586,8 +1659,8 @@
IRAtom* mkLazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
@@ -1643,9 +1716,9 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
+ IRType t3 = typeOfIRExpr(mce->tyenv, va3);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1777,10 +1850,10 @@
IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 )
{
IRAtom* at;
- IRType t1 = typeOfIRExpr(mce->sb->tyenv, va1);
- IRType t2 = typeOfIRExpr(mce->sb->tyenv, va2);
- IRType t3 = typeOfIRExpr(mce->sb->tyenv, va3);
- IRType t4 = typeOfIRExpr(mce->sb->tyenv, va4);
+ IRType t1 = typeOfIRExpr(mce->tyenv, va1);
+ IRType t2 = typeOfIRExpr(mce->tyenv, va2);
+ IRType t3 = typeOfIRExpr(mce->tyenv, va3);
+ IRType t4 = typeOfIRExpr(mce->tyenv, va4);
tl_assert(isShadowAtom(mce,va1));
tl_assert(isShadowAtom(mce,va2));
tl_assert(isShadowAtom(mce,va3));
@@ -1879,7 +1952,7 @@
tl_assert(isOriginalAtom(mce, exprvec[i]));
if (cee->mcx_mask & (1<<i))
continue;
- if (typeOfIRExpr(mce->sb->tyenv, exprvec[i]) != Ity_I64)
+ if (typeOfIRExpr(mce->tyenv, exprvec[i]) != Ity_I64)
mergeTy64 = False;
}
@@ -2971,6 +3044,7 @@
IROp op,
IRAtom* atom1, IRAtom* atom2 )
{
+ const MCEnvSettings* settings = mce->settings;
IRType and_or_ty;
IRAtom* (*uifu) (MCEnv*, IRAtom*, IRAtom*);
IRAtom* (*difd) (MCEnv*, IRAtom*, IRAtom*);
@@ -4025,13 +4099,13 @@
return mkLazy2(mce, Ity_I64, vatom1, vatom2);
case Iop_Add32:
- if (mce->bogusLiterals || mce->useLLVMworkarounds)
+ if (settings->bogusLiterals || settings->useLLVMworkarounds)
return expensiveAddSub(mce,True,Ity_I32,
vatom1,vatom2, atom1,atom2);
else
goto cheap_AddSub32;
case Iop_Sub32:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
return expensiveAddSub(mce,False,Ity_I32,
vatom1,vatom2, atom1,atom2);
else
@@ -4048,13 +4122,13 @@
return doCmpORD(mce, op, vatom1,vatom2, atom1,atom2);
case Iop_Add64:
- if (mce->bogusLiterals || mce->useLLVMworkarounds)
+ if (settings->bogusLiterals || settings->useLLVMworkarounds)
return expensiveAddSub(mce,True,Ity_I64,
vatom1,vatom2, atom1,atom2);
else
goto cheap_AddSub64;
case Iop_Sub64:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
return expensiveAddSub(mce,False,Ity_I64,
vatom1,vatom2, atom1,atom2);
else
@@ -4076,7 +4150,7 @@
case Iop_CmpEQ64:
case Iop_CmpNE64:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
goto expensive_cmp64;
else
goto cheap_cmp64;
@@ -4092,7 +4166,7 @@
case Iop_CmpEQ32:
case Iop_CmpNE32:
- if (mce->bogusLiterals)
+ if (settings->bogusLiterals)
goto expensive_cmp32;
else
goto cheap_cmp32;
@@ -4781,7 +4855,7 @@
} else {
IROp mkAdd;
IRAtom* eBias;
- IRType tyAddr = mce->hWordTy;
+ IRType tyAddr = mce->settings->hWordTy;
tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
eBias = tyAddr==Ity_I32 ? mkU32(bias) : mkU64(bias);
@@ -4954,7 +5028,7 @@
vbitsC = expr2vbits(mce, cond);
vbits1 = expr2vbits(mce, iftrue);
vbits0 = expr2vbits(mce, iffalse);
- ty = typeOfIRExpr(mce->sb->tyenv, vbits0);
+ ty = typeOfIRExpr(mce->tyenv, vbits0);
return
mkUifU(mce, ty, assignNew('V', mce, ty,
@@ -4980,7 +5054,7 @@
return IRExpr_RdTmp( findShadowTmpV(mce, e->Iex.RdTmp.tmp) );
case Iex_Const:
- return definedOfType(shadowTypeV(typeOfIRExpr(mce->sb->tyenv, e)));
+ return definedOfType(shadowTypeV(typeOfIRExpr(mce->tyenv, e)));
case Iex_Qop:
return expr2vbits_Qop(
@@ -5045,8 +5119,8 @@
/* vatom is vbits-value and as such can only have a shadow type. */
tl_assert(isShadowAtom(mce,vatom));
- ty = typeOfIRExpr(mce->sb->tyenv, vatom);
- tyH = mce->hWordTy;
+ ty = typeOfIRExpr(mce->tyenv, vatom);
+ tyH = mce->settings->hWordTy;
if (tyH == Ity_I32) {
switch (ty) {
@@ -5106,7 +5180,7 @@
const HChar* hname = NULL;
IRConst* c;
- tyAddr = mce->hWordTy;
+ tyAddr = mce->settings->hWordTy;
mkAdd = tyAddr==Ity_I32 ? Iop_Add32 : Iop_Add64;
tl_assert( tyAddr == Ity_I32 || tyAddr == Ity_I64 );
tl_assert( end == Iend_LE || end == Iend_BE );
@@ -5125,10 +5199,10 @@
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
- ty = typeOfIRExpr(mce->sb->tyenv, vdata);
+ ty = typeOfIRExpr(mce->tyenv, vdata);
// If we're not doing undefined value checking, pretend that this value
// is "all valid". That lets Vex's optimiser remove some of the V bit
@@ -5456,9 +5530,9 @@
tl_assert(d->mAddr);
complainIfUndefined(mce, d->mAddr, d->guard);
- tyAddr = typeOfIRExpr(mce->sb->tyenv, d->mAddr);
+ tyAddr = typeOfIRExpr(mce->tyenv, d->mAddr);
tl_assert(tyAddr == Ity_I32 || tyAddr == Ity_I64);
- tl_assert(tyAddr == mce->hWordTy); /* not really right */
+ tl_assert(tyAddr == mce->settings->hWordTy); /* not really right */
}
/* Deal with memory inputs (reads or modifies) */
@@ -5505,9 +5579,9 @@
results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmpV(mce, d->tmp);
- tyDst = typeOfIRTemp(mce->sb->tyenv, d->tmp);
+ tyDst = typeOfIRTemp(mce->tyenv, d->tmp);
assign( 'V', mce, dst, mkPCastTo( mce, tyDst, curr) );
}
@@ -5815,7 +5889,7 @@
definedness test for "expected == old" was removed at r10432 of
this file.
*/
- if (cas->oldHi == IRTemp_INVALID) {
+ if (isIRTempInvalid(cas->oldHi)) {
do_shadow_CAS_single( mce, cas );
} else {
do_shadow_CAS_double( mce, cas );
@@ -5835,11 +5909,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* single CAS */
- tl_assert(cas->oldHi == IRTemp_INVALID);
+ tl_assert(isIRTempInvalid(cas->oldHi));
tl_assert(cas->expdHi == NULL);
tl_assert(cas->dataHi == NULL);
- elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
switch (elemTy) {
case Ity_I8: elemSzB = 1; opCasCmpEQ = Iop_CasCmpEQ8; break;
case Ity_I16: elemSzB = 2; opCasCmpEQ = Iop_CasCmpEQ16; break;
@@ -5929,11 +6003,11 @@
Bool otrak = MC_(clo_mc_level) >= 3; /* a shorthand */
/* double CAS */
- tl_assert(cas->oldHi != IRTemp_INVALID);
+ tl_assert(!isIRTempInvalid(cas->oldHi));
tl_assert(cas->expdHi != NULL);
tl_assert(cas->dataHi != NULL);
- elemTy = typeOfIRExpr(mce->sb->tyenv, cas->expdLo);
+ elemTy = typeOfIRExpr(mce->tyenv, cas->expdLo);
switch (elemTy) {
case Ity_I8:
opCasCmpEQ = Iop_CasCmpEQ8; opOr = Iop_Or8; opXor = Iop_Xor8;
@@ -6087,7 +6161,7 @@
assignment of the loaded (shadow) data to the result temporary.
Treat a store-conditional like a normal store, and mark the
result temporary as defined. */
- IRType resTy = typeOfIRTemp(mce->sb->tyenv, stResult);
+ IRType resTy = typeOfIRTemp(mce->tyenv, stResult);
IRTemp resTmp = findShadowTmpV(mce, stResult);
tl_assert(isIRAtom(stAddr));
@@ -6108,7 +6182,7 @@
} else {
/* Store Conditional */
/* Stay sane */
- IRType dataTy = typeOfIRExpr(mce->sb->tyenv,
+ IRType dataTy = typeOfIRExpr(mce->tyenv,
stStoredata);
tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32
|| dataTy == Ity_I16 || dataTy == Ity_I8);
@@ -6193,6 +6267,51 @@
}
+static void instrument_IRStmtVec(IRStmtVec* stmts_in, UInt stmts_in_first,
+ MCEnv* mce);
+
+static void do_shadow_IfThenElse(MCEnv* mce, IRExpr* cond, IRStmtVec* then_leg,
+ IRStmtVec* else_leg, IRPhiVec* phi_nodes_in)
+{
+ IRTemp (*findShadowTmp)(MCEnv* mce, IRTemp orig);
+ HChar category;
+ if (MC_(clo_mc_level) == 3) {
+ findShadowTmp = findShadowTmpB;
+ category = 'B';
+ } else {
+ findShadowTmp = findShadowTmpV;
+ category = 'V';
+ }
+
+ complainIfUndefined(mce, cond, NULL);
+
+ MCEnv then_mce;
+ initMCEnv(then_leg, &then_mce, mce);
+ instrument_IRStmtVec(then_leg, 0, &then_mce);
+
+ MCEnv else_mce;
+ initMCEnv(else_leg, &else_mce, mce);
+ instrument_IRStmtVec(else_leg, 0, &else_mce);
+
+ IRPhiVec* phi_nodes_out = NULL;
+ if (phi_nodes_in != NULL) {
+ phi_nodes_out = emptyIRPhiVec();
+ for (UInt i = 0; i < phi_nodes_in->phis_used; i++) {
+ IRPhi* phi_in = phi_nodes_in->phis[i];
+ IRPhi* phi_shadow = mkIRPhi(findShadowTmp(mce, phi_in->dst),
+ findShadowTmp(&then_mce, phi_in->srcThen),
+ findShadowTmp(&else_mce, phi_in->srcElse));
+ phi(category, mce, phi_nodes_out, phi_shadow);
+ phi('C', mce, phi_nodes_out, phi_in);
+ }
+ }
+
+ stmt(category, mce, IRStmt_IfThenElse(cond, then_mce.stmts, else_mce.stmts,
+ phi_nodes_out));
+ deinitMCEnv(&then_mce);
+ deinitMCEnv(&else_mce);
+}
+
/*------------------------------------------------------------*/
/*--- Memcheck main ---*/
/*------------------------------------------------------------*/
@@ -6236,7 +6355,9 @@
);
}
-static Bool checkForBogusLiterals ( /*FLAT*/ IRStmt* st )
+static Bool isBogusIRStmtVec(/*FLAT*/ IRStmtVec* stmts);
+
+static Bool isBogusIRStmt(/*FLAT*/ IRStmt* st)
{
Int i;
IRExpr* e;
@@ -6335,14 +6456,169 @@
|| (st->Ist.LLSC.storedata
? isBogusAtom(st->Ist.LLSC.storedata)
: False);
+ case Ist_IfThenElse:
+ return isBogusAtom(st->Ist.IfThenElse.cond)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.then_leg)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.else_leg);
default:
unhandled:
ppIRStmt(st);
- VG_(tool_panic)("hasBogusLiterals");
+ VG_(tool_panic)("isBogusIRStmt");
+ }
+}
+
+static Bool isBogusIRStmtVec(/*FLAT*/ IRStmtVec* stmts)
+{
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ IRStmt* st = stmts->stmts[i];
+
+ Bool bogus = isBogusIRStmt(st);
+ if (0 && bogus) {
+ VG_(printf)("bogus: ");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+ if (bogus) {
+ return True;
+ }
}
+
+ return False;
}
+/* Is to be called with already created and setup MCEnv as per initMCEnv(). */
+static void instrument_IRStmtVec(IRStmtVec* stmts_in, UInt stmts_in_first,
+ MCEnv* mce)
+{
+ for (UInt i = stmts_in_first; i < stmts_in->stmts_used; i++) {
+ IRStmt* st = stmts_in->stmts[i];
+ UInt first_stmt = mce->stmts->stmts_used;
+
+ if (mce->settings->trace) {
+ VG_(printf)("\n");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+
+ if (MC_(clo_mc_level) == 3) {
+ /* See comments on case Ist_CAS and Ist_IfThenElse below. */
+ if (st->tag != Ist_CAS && st->tag != Ist_IfThenElse)
+ schemeS(mce, st);
+ }
+
+ /* Generate instrumentation code for each stmt ... */
+
+ switch (st->tag) {
+
+ case Ist_WrTmp:
+ assign('V', mce, findShadowTmpV(mce, st->Ist.WrTmp.tmp),
+ expr2vbits(mce, st->Ist.WrTmp.data));
+ break;
+
+ case Ist_Put:
+ do_shadow_PUT( mce,
+ st->Ist.Put.offset,
+ st->Ist.Put.data,
+ NULL /* shadow atom */, NULL /* guard */ );
+ break;
+
+ case Ist_PutI:
+ do_shadow_PUTI(mce, st->Ist.PutI.details);
+ break;
+
+ case Ist_Store:
+ do_shadow_Store(mce, st->Ist.Store.end,
+ st->Ist.Store.addr, 0/* addr bias */,
+ st->Ist.Store.data,
+ NULL /* shadow data */,
+ NULL/*guard*/);
+ break;
+
+ case Ist_StoreG:
+ do_shadow_StoreG(mce, st->Ist.StoreG.details);
+ break;
+
+ case Ist_LoadG:
+ do_shadow_LoadG(mce, st->Ist.LoadG.details);
+ break;
+
+ case Ist_Exit:
+ complainIfUndefined(mce, st->Ist.Exit.guard, NULL);
+ break;
+
+ case Ist_IMark:
+ break;
+
+ case Ist_NoOp:
+ case Ist_MBE:
+ break;
+
+ case Ist_Dirty:
+ do_shadow_Dirty(mce, st->Ist.Dirty.details);
+ break;
+
+ case Ist_AbiHint:
+ do_AbiHint(mce, st->Ist.AbiHint.base,
+ st->Ist.AbiHint.len,
+ st->Ist.AbiHint.nia);
+ break;
+
+ case Ist_CAS:
+ do_shadow_CAS(mce, st->Ist.CAS.details);
+ /* Note, do_shadow_CAS copies the CAS itself to the output
+ stmts, because it needs to add instrumentation both
+ before and after it. Hence skip the copy below. Also
+ skip the origin-tracking stuff (call to schemeS) above,
+ since that's all tangled up with it too; do_shadow_CAS
+ does it all. */
+ break;
+
+ case Ist_LLSC:
+ do_shadow_LLSC( mce,
+ st->Ist.LLSC.end,
+ st->Ist.LLSC.result,
+ st->Ist.LLSC.addr,
+ st->Ist.LLSC.storedata );
+ break;
+
+ case Ist_IfThenElse:
+ do_shadow_IfThenElse(mce, st->Ist.IfThenElse.cond,
+ st->Ist.IfThenElse.then_leg,
+ st->Ist.IfThenElse.else_leg,
+ st->Ist.IfThenElse.phi_nodes);
+ /* Note, do_shadow_IfThenElse copies the IfThenElse itself to the
+ output stmts, because it needs to add instrumentation to the legs
+ and to phi nodes. Hence skip the copy below. Also skip the
+ origin-tracking stuff (call to schemeS) above, since that's all
+ tangled up with it too; do_shadow_IfThenElse does it all. */
+ break;
+
+ default:
+ VG_(printf)("\n");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ VG_(tool_panic)("memcheck: unhandled IRStmt");
+
+ } /* switch (st->tag) */
+
+ if (0 && mce->settings->trace) {
+ for (UInt j = first_stmt; j < mce->stmts->stmts_used; j++) {
+ VG_(printf)(" ");
+ ppIRStmt(mce->stmts->stmts[j]);
+ VG_(printf)("\n");
+ }
+ VG_(printf)("\n");
+ }
+
+ /* ... and finally copy the stmt itself to the output. Except,
+ skip the copy of IRCASs and IfThenElse; see comments on cases Ist_CAS
+ and Ist_IfThenElse above. */
+ if (st->tag != Ist_CAS && st->tag != Ist_IfThenElse)
+ stmt('C', mce, st);
+ }
+}
+
IRSB* MC_(instrument) ( VgCallbackClosure* closure,
IRSB* sb_in,
const VexGuestLayout* layout,
@@ -6350,11 +6626,7 @@
const VexArchInfo* archinfo_host,
IRType gWordTy, IRType hWordTy )
{
- Bool verboze = 0||False;
- Int i, j, first_stmt;
- IRStmt* st;
- MCEnv mce;
- IRSB* sb_out;
+ Bool verboze = 0 || False;
if (gWordTy != hWordTy) {
/* We don't currently support this case. */
@@ -6372,19 +6644,14 @@
tl_assert(MC_(clo_mc_level) >= 1 && MC_(clo_mc_level) <= 3);
- /* Set up SB */
- sb_out = deepCopyIRSBExceptStmts(sb_in);
+ /* Set up SB, MCEnv and MCEnvSettings. */
+ IRSB* sb_out = deepCopyIRSBExceptStmts(sb_in);
- /* Set up the running environment. Both .sb and .tmpMap are
- modified as we go along. Note that tmps are added to both
- .sb->tyenv and .tmpMap together, so the valid index-set for
- those two arrays should always be identical. */
- VG_(memset)(&mce, 0, sizeof(mce));
- mce.sb = sb_out;
- mce.trace = verboze;
- mce.layout = layout;
- mce.hWordTy = hWordTy;
- mce.bogusLiterals = False;
+ MCEnvSettings settings;
+ settings.trace = verboze;
+ settings.layout = layout;
+ settings.hWordTy = hWordTy;
+ settings.bogusLiterals = False;
/* Do expensive interpretation for Iop_Add32 and Iop_Add64 on
Darwin. 10.7 is mostly built with LLVM, which uses these for
@@ -6395,66 +6662,40 @@
interpretation, but that would require some way to tag them in
the _toIR.c front ends, which is a lot of faffing around. So
for now just use the slow and blunt-instrument solution. */
- mce.useLLVMworkarounds = False;
+ settings.useLLVMworkarounds = False;
# if defined(VGO_darwin)
- mce.useLLVMworkarounds = True;
+ settings.useLLVMworkarounds = True;
# endif
- mce.tmpMap = VG_(newXA)( VG_(malloc), "mc.MC_(instrument).1", VG_(free),
- sizeof(TempMapEnt));
- VG_(hintSizeXA) (mce.tmpMap, sb_in->tyenv->types_used);
- for (i = 0; i < sb_in->tyenv->types_used; i++) {
- TempMapEnt ent;
- ent.kind = Orig;
- ent.shadowV = IRTemp_INVALID;
- ent.shadowB = IRTemp_INVALID;
- VG_(addToXA)( mce.tmpMap, &ent );
- }
- tl_assert( VG_(sizeXA)( mce.tmpMap ) == sb_in->tyenv->types_used );
+ MCEnv mce;
+ initMCEnv(sb_in->stmts, &mce, NULL);
+ mce.settings = &settings;
+
+ tl_assert(isFlatIRSB(sb_in));
if (MC_(clo_expensive_definedness_checks)) {
- /* For expensive definedness checking skip looking for bogus
- literals. */
- mce.bogusLiterals = True;
+ /* For expensive definedness checking skip looking for bogus literals. */
+ settings.bogusLiterals = True;
} else {
/* Make a preliminary inspection of the statements, to see if there
are any dodgy-looking literals. If there are, we generate
- extra-detailed (hence extra-expensive) instrumentation in
- places. Scan the whole bb even if dodgyness is found earlier,
- so that the flatness assertion is applied to all stmts. */
- Bool bogus = False;
-
- for (i = 0; i < sb_in->stmts_used; i++) {
- st = sb_in->stmts[i];
- tl_assert(st);
- tl_assert(isFlatIRStmt(st));
-
- if (!bogus) {
- bogus = checkForBogusLiterals(st);
- if (0 && bogus) {
- VG_(printf)("bogus: ");
- ppIRStmt(st);
- VG_(printf)("\n");
- }
- if (bogus) break;
- }
- }
- mce.bogusLiterals = bogus;
+ extra-detailed (hence extra-expensive) instrumentation in places. */
+ settings.bogusLiterals = isBogusIRStmtVec(sb_in->stmts);
}
/* Copy verbatim any IR preamble preceding the first IMark */
- tl_assert(mce.sb == sb_out);
- tl_assert(mce.sb != sb_in);
+ tl_assert(mce.stmts == sb_out->stmts);
+ tl_assert(mce.stmts != sb_in->stmts);
- i = 0;
- while (i < sb_in->stmts_used && sb_in->stmts[i]->tag != Ist_IMark) {
+ UInt i = 0;
+ while (i < sb_in->stmts->stmts_used
+ && sb_in->stmts->stmts[i]->tag != Ist_IMark) {
- st = sb_in->stmts[i];
- tl_assert(st);
- tl_assert(isFlatIRStmt(st));
+ IRStmt* st = sb_in->stmts->stmts[i];
+ tl_assert(st != NULL);
- stmt( 'C', &mce, sb_in->stmts[i] );
+ stmt('C', &mce, sb_in->stmts->stmts[i]);
i++;
}
@@ -6480,18 +6721,18 @@
assignment for the corresponding origin (B) shadow, claiming
no-origin, as appropriate for a defined value.
*/
- for (j = 0; j < i; j++) {
- if (sb_in->stmts[j]->tag == Ist_WrTmp) {
+ for (UInt j = 0; j < i; j++) {
+ if (sb_in->stmts->stmts[j]->tag == Ist_WrTmp) {
/* findShadowTmpV checks its arg is an original tmp;
no need to assert that here. */
- IRTemp tmp_o = sb_in->stmts[j]->Ist.WrTmp.tmp;
+ IRTemp tmp_o = sb_in->stmts->stmts[j]->Ist.WrTmp.tmp;
IRTemp tmp_v = findShadowTmpV(&mce, tmp_o);
- IRType ty_v = typeOfIRTemp(sb_out->tyenv, tmp_v);
- assign( 'V', &mce, tmp_v, definedOfType( ty_v ) );
+ IRType ty_v = typeOfIRTemp(mce.tyenv, tmp_v);
+ assign('V', &mce, tmp_v, definedOfType(ty_v));
if (MC_(clo_mc_level) == 3) {
IRTemp tmp_b = findShadowTmpB(&mce, tmp_o);
- tl_assert(typeOfIRTemp(sb_out->tyenv, tmp_b) == Ity_I32);
- assign( 'B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
+ tl_assert(typeOfIRTemp(mce.tyenv, tmp_b) == Ity_I32);
+ assign('B', &mce, tmp_b, mkU32(0)/* UNKNOWN ORIGIN */);
}
if (0) {
VG_(printf)("create shadow tmp(s) for preamble tmp [%d] ty ", j);
@@ -6503,129 +6744,13 @@
/* Iterate over the remaining stmts to generate instrumentation. */
- tl_assert(sb_in->stmts_used > 0);
- tl_assert(i >= 0);
- tl_assert(i < sb_in->stmts_used);
- tl_assert(sb_in->stmts[i]->tag == Ist_IMark);
-
- for (/* use current i*/; i < sb_in->stmts_used; i++) {
-
- st = sb_in->stmts[i];
- first_stmt = sb_out->stmts_used;
-
- if (verboze) {
- VG_(printf)("\n");
- ppIRStmt(st);
- VG_(printf)("\n");
- }
-
- if (MC_(clo_mc_level) == 3) {
- /* See comments on case Ist_CAS below. */
- if (st->tag != Ist_CAS)
- schemeS( &mce, st );
- }
-
- /* Generate instrumentation code for each stmt ... */
-
- switch (st->tag) {
-
- case Ist_WrTmp:
- assign( 'V', &mce, findShadowTmpV(&mce, st->Ist.WrTmp.tmp),
- expr2vbits( &mce, st->Ist.WrTmp.data) );
- break;
-
- case Ist_Put:
- do_shadow_PUT( &mce,
- st->Ist.Put.offset,
- st->Ist.Put.data,
- NULL /* shadow atom */, NULL /* guard */ );
- break;
-
- case Ist_PutI:
- do_shadow_PUTI( &mce, st->Ist.PutI.details);
- break;
-
- case Ist_Store:
- do_shadow_Store( &mce, st->Ist.Store.end,
- st->Ist.Store.addr, 0/* addr bias */,
- st->Ist.Store.data,
- NULL /* shadow data */,
- NULL/*guard*/ );
- break;
-
- case Ist_StoreG:
- do_shadow_StoreG( &mce, st->Ist.StoreG.details );
- break;
-
- case Ist_LoadG:
- do_shadow_LoadG( &mce, st->Ist.LoadG.details );
- break;
-
- case Ist_Exit:
- complainIfUndefined( &mce, st->Ist.Exit.guard, NULL );
- break;
-
- case Ist_IMark:
- break;
-
- case Ist_NoOp:
- case Ist_MBE:
- break;
-
- case Ist_Dirty:
- do_shadow_Dirty( &mce, st->Ist.Dirty.details );
- break;
-
- case Ist_AbiHint:
- do_AbiHint( &mce, st->Ist.AbiHint.base,
- st->Ist.AbiHint.len,
- st->Ist.AbiHint.nia );
- break;
-
- case Ist_CAS:
- do_shadow_CAS( &mce, st->Ist.CAS.details );
- /* Note, do_shadow_CAS copies the CAS itself to the output
- block, because it needs to add instrumentation both
- before and after it. Hence skip the copy below. Also
- skip the origin-tracking stuff (call to schemeS) above,
- since that's all tangled up with it too; do_shadow_CAS
- does it all. */
- break;
-
- case Ist_LLSC:
- do_shadow_LLSC( &mce,
- st->Ist.LLSC.end,
- st->Ist.LLSC.result,
- st->Ist.LLSC.addr,
- st->Ist.LLSC.storedata );
- break;
-
- default:
- VG_(printf)("\n");
- ppIRStmt(st);
- VG_(printf)("\n");
- VG_(tool_panic)("memcheck: unhandled IRStmt");
-
- } /* switch (st->tag) */
-
- if (0 && verboze) {
- for (j = first_stmt; j < sb_out->stmts_used; j++) {
- VG_(printf)(" ");
- ppIRStmt(sb_out->stmts[j]);
- VG_(printf)("\n");
- }
- VG_(printf)("\n");
- }
-
- /* ... and finally copy the stmt itself to the output. Except,
- skip the copy of IRCASs; see comments on case Ist_CAS
- above. */
- if (st->tag != Ist_CAS)
- stmt('C', &mce, st);
- }
+ tl_assert(sb_in->stmts->stmts_used > 0);
+ tl_assert(i < sb_in->stmts->stmts_used);
+ tl_assert(sb_in->stmts->stmts[i]->tag == Ist_IMark);
+ instrument_IRStmtVec(sb_in->stmts, i, &mce);
/* Now we need to complain if the jump target is undefined. */
- first_stmt = sb_out->stmts_used;
+ UInt first_stmt = sb_out->stmts->stmts_used;
if (verboze) {
VG_(printf)("sb_in->next = ");
@@ -6633,23 +6758,20 @@
VG_(printf)("\n\n");
}
- complainIfUndefined( &mce, sb_in->next, NULL );
+ complainIfUndefined(&mce, sb_in->next, NULL);
if (0 && verboze) {
- for (j = first_stmt; j < sb_out->stmts_used; j++) {
+ for (UInt j = first_stmt; j < sb_out->stmts->stmts_used; j++) {
VG_(printf)(" ");
- ppIRStmt(sb_out->stmts[j]);
+ ppIRStmt(sb_out->stmts->stmts[j]);
VG_(printf)("\n");
}
VG_(printf)("\n");
}
- /* If this fails, there's been some serious snafu with tmp management,
- that should be investigated. */
- tl_assert( VG_(sizeXA)( mce.tmpMap ) == mce.sb->tyenv->types_used );
- VG_(deleteXA)( mce.tmpMap );
+ tl_assert(mce.stmts == sb_out->stmts);
+ deinitMCEnv(&mce);
- tl_assert(mce.sb == sb_out);
return sb_out;
}
@@ -6751,7 +6873,7 @@
return e1->Iex.Unop.op == e2->Iex.Unop.op
&& sameIRValue(e1->Iex.Unop.arg, e2->Iex.Unop.arg);
case Iex_RdTmp:
- return e1->Iex.RdTmp.tmp == e2->Iex.RdTmp.tmp;
+ return eqIRTemp(e1->Iex.RdTmp.tmp, e2->Iex.RdTmp.tmp);
case Iex_ITE:
return sameIRValue( e1->Iex.ITE.cond, e2->Iex.ITE.cond )
&& sameIRValue( e1->Iex.ITE.iftrue, e2->Iex.ITE.iftrue )
@@ -6860,16 +6982,9 @@
|| 0==VG_(strcmp)(name, "1_fail_w_o)");
}
-IRSB* MC_(final_tidy) ( IRSB* sb_in )
+static IRStmtVec* final_tidy_IRStmtVec(IRStmtVec* stmts)
{
- Int i;
- IRStmt* st;
- IRDirty* di;
- IRExpr* guard;
- IRCallee* cee;
- Bool alreadyPresent;
- Pairs pairs;
-
+ Pairs pairs;
pairs.pairsUsed = 0;
pairs.pairs[N_TIDYING_PAIRS].entry = (void*)0x123;
@@ -6879,25 +6994,33 @@
of the relevant helpers is seen, check if we have made a
previous call to the same helper using the same guard
expression, and if so, delete the call. */
- for (i = 0; i < sb_in->stmts_used; i++) {
- st = sb_in->stmts[i];
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ IRStmt* st = stmts->stmts[i];
tl_assert(st);
+
+ if (st->tag == Ist_IfThenElse) {
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.then_leg);
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ }
+
if (st->tag != Ist_Dirty)
continue;
- di = st->Ist.Dirty.details;
- guard = di->guard;
+
+ IRDirty* di = st->Ist.Dirty.details;
+ IRExpr* guard = di->guard;
tl_assert(guard);
if (0) { ppIRExpr(guard); VG_(printf)("\n"); }
- cee = di->cee;
+ IRCallee* cee = di->cee;
if (!is_helperc_value_checkN_fail( cee->name ))
continue;
+
/* Ok, we have a call to helperc_value_check0/1/4/8_fail with
guard 'guard'. Check if we have already seen a call to this
function with the same guard. If so, delete it. If not,
add it to the set of calls we do know about. */
- alreadyPresent = check_or_add( &pairs, guard, cee->addr );
+ Bool alreadyPresent = check_or_add( &pairs, guard, cee->addr );
if (alreadyPresent) {
- sb_in->stmts[i] = IRStmt_NoOp();
+ stmts->stmts[i] = IRStmt_NoOp();
if (0) VG_(printf)("XX\n");
}
}
@@ -6905,6 +7028,12 @@
tl_assert(pairs.pairs[N_TIDYING_PAIRS].entry == (void*)0x123);
tl_assert(pairs.pairs[N_TIDYING_PAIRS].guard == (IRExpr*)0x456);
+ return stmts;
+}
+
+IRSB* MC_(final_tidy) ( IRSB* sb_in )
+{
+ final_tidy_IRStmtVec(sb_in->stmts);
return sb_in;
}
@@ -6918,22 +7047,23 @@
/* Almost identical to findShadowTmpV. */
static IRTemp findShadowTmpB ( MCEnv* mce, IRTemp orig )
{
- TempMapEnt* ent;
- /* VG_(indexXA) range-checks 'orig', hence no need to check
- here. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
- tl_assert(ent->kind == Orig);
- if (ent->shadowB == IRTemp_INVALID) {
- IRTemp tmpB
- = newTemp( mce, Ity_I32, BSh );
- /* newTemp may cause mce->tmpMap to resize, hence previous results
- from VG_(indexXA) are invalid. */
- ent = (TempMapEnt*)VG_(indexXA)( mce->tmpMap, (Word)orig );
+ if (mce->id == orig.id) {
+ /* VG_(indexXA) range-checks 'orig', hence no need to check here. */
+ TempMapEnt* ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
tl_assert(ent->kind == Orig);
- tl_assert(ent->shadowB == IRTemp_INVALID);
- ent->shadowB = tmpB;
+ if (isIRTempInvalid(ent->shadowB)) {
+ IRTemp tmpB = newTemp( mce, Ity_I32, BSh );
+ /* newTemp may cause mce->tmpMap to resize, hence previous results
+ from VG_(indexXA) are invalid. */
+ ent = (TempMapEnt*) VG_(indexXA)(mce->tmpMap, orig.index);
+ tl_assert(ent->kind == Orig);
+ tl_assert(isIRTempInvalid(ent->shadowB));
+ ent->shadowB = tmpB;
+ }
+ return ent->shadowB;
+ } else {
+ return findShadowTmpB(mce->parent, orig);
}
- return ent->shadowB;
}
static IRAtom* gen_maxU32 ( MCEnv* mce, IRAtom* b1, IRAtom* b2 )
@@ -6958,7 +7088,7 @@
const HChar* hName;
IRTemp bTmp;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (offset != 0) {
@@ -6966,7 +7096,7 @@
: mkU64( (Long)(Int)offset );
ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
}
- bTmp = newTemp(mce, mce->hWordTy, BSh);
+ bTmp = newTemp(mce, mce->settings->hWordTy, BSh);
switch (szB) {
case 1: hFun = (void*)&MC_(helperc_b_load1);
@@ -7007,7 +7137,7 @@
/* no need to mess with any annotations. This call accesses
neither guest state nor guest memory. */
stmt( 'B', mce, IRStmt_Dirty(di) );
- if (mce->hWordTy == Ity_I64) {
+ if (mce->settings->hWordTy == Ity_I64) {
/* 64-bit host */
IRTemp bTmp32 = newTemp(mce, Ity_I32, BSh);
assign( 'B', mce, bTmp32, unop(Iop_64to32, mkexpr(bTmp)) );
@@ -7073,19 +7203,19 @@
void* hFun;
const HChar* hName;
IRDirty* di;
- IRType aTy = typeOfIRExpr( mce->sb->tyenv, baseaddr );
+ IRType aTy = typeOfIRExpr( mce->tyenv, baseaddr );
IROp opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;
IRAtom* ea = baseaddr;
if (guard) {
tl_assert(isOriginalAtom(mce, guard));
- tl_assert(typeOfIRExpr(mce->sb->tyenv, guard) == Ity_I1);
+ tl_assert(typeOfIRExpr(mce->tyenv, guard) == Ity_I1);
}
if (offset != 0) {
IRAtom* off = aTy == Ity_I32 ? mkU32( offset )
: mkU64( (Long)(Int)offset );
ea = assignNew( 'B', mce, aTy, binop(opAdd, ea, off));
}
- if (mce->hWordTy == Ity_I64)
+ if (mce->settings->hWordTy == Ity_I64)
dataB = assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, dataB));
switch (szB) {
@@ -7121,7 +7251,7 @@
}
static IRAtom* narrowTo32 ( MCEnv* mce, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->tyenv, e);
if (eTy == Ity_I64)
return assignNew( 'B', mce, Ity_I32, unop(Iop_64to32, e) );
if (eTy == Ity_I32)
@@ -7130,7 +7260,7 @@
}
static IRAtom* zWidenFrom32 ( MCEnv* mce, IRType dstTy, IRAtom* e ) {
- IRType eTy = typeOfIRExpr(mce->sb->tyenv, e);
+ IRType eTy = typeOfIRExpr(mce->tyenv, e);
tl_assert(eTy == Ity_I32);
if (dstTy == Ity_I64)
return assignNew( 'B', mce, Ity_I64, unop(Iop_32Uto64, e) );
@@ -7142,6 +7272,8 @@
{
tl_assert(MC_(clo_mc_level) == 3);
+ const VexGuestLayout* layout = mce->settings->layout;
+
switch (e->tag) {
case Iex_GetI: {
@@ -7156,8 +7288,8 @@
return mkU32(0);
tl_assert(sizeofIRType(equivIntTy) >= 4);
tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy));
- descr_b = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB,
- equivIntTy, descr->nElems );
+ descr_b = mkIRRegArray(descr->base + 2 * layout->total_sizeB,
+ equivIntTy, descr->nElems);
/* Do a shadow indexed get of the same size, giving t1. Take
the bottom 32 bits of it, giving t2. Compute into t3 the
origin for the index (almost certainly zero, but there's
@@ -7202,7 +7334,8 @@
/* assert that the B value for the address is already
available (somewhere) */
tl_assert(isIRAtom(e->Iex.Load.addr));
- tl_assert(mce->hWordTy == Ity_I32 || mce->hWordTy == Ity_I64);
+ tl_assert(mce->settings->hWordTy == Ity_I32
+ || mce->settings->hWordTy == Ity_I64);
return gen_load_b( mce, dszB, e->Iex.Load.addr, 0 );
}
case Iex_ITE: {
@@ -7257,12 +7390,10 @@
e->Iex.Get.offset,
sizeofIRType(e->Iex.Get.ty)
);
- tl_assert(b_offset >= -1
- && b_offset <= mce->layout->total_sizeB -4);
+ tl_assert(b_offset >= -1 && b_offset <= layout->total_sizeB -4);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
- return IRExpr_Get( b_offset + 2*mce->layout->total_sizeB,
- Ity_I32 );
+ return IRExpr_Get(b_offset + 2 * layout->total_sizeB, Ity_I32);
}
return mkU32(0);
}
@@ -7276,6 +7407,8 @@
static void do_origins_Dirty ( MCEnv* mce, IRDirty* d )
{
+ const VexGuestLayout* layout = mce->settings->layout;
+
// This is a hacked version of do_shadow_Dirty
Int i, k, n, toDo, gSz, gOff;
IRAtom *here, *curr;
@@ -7338,7 +7471,7 @@
iffalse = mkU32(0);
iftrue = assignNew( 'B', mce, Ity_I32,
IRExpr_Get(b_offset
- + 2*mce->layout->total_sizeB,
+ + 2 * layout->total_sizeB,
Ity_I32));
here = assignNew( 'B', mce, Ity_I32,
IRExpr_ITE(cond, iftrue, iffalse));
@@ -7397,7 +7530,7 @@
Now we need to re-distribute the results to all destinations. */
/* Outputs: the destination temporary, if there is one. */
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
dst = findShadowTmpB(mce, d->tmp);
assign( 'V', mce, dst, curr );
}
@@ -7437,13 +7570,13 @@
d->guard);
iffalse = assignNew('B', mce, Ity_I32,
IRExpr_Get(b_offset +
- 2*mce->layout->total_sizeB,
+ 2 * layout->total_sizeB,
Ity_I32));
curr = assignNew('V', mce, Ity_I32,
IRExpr_ITE(cond, curr, iffalse));
stmt( 'B', mce, IRStmt_Put(b_offset
- + 2*mce->layout->total_sizeB,
+ + 2 * layout->total_sizeB,
curr ));
}
gSz -= n;
@@ -7493,7 +7626,7 @@
XXXX how does this actually ensure that?? */
tl_assert(isIRAtom(stAddr));
tl_assert(isIRAtom(stData));
- dszB = sizeofIRType( typeOfIRExpr(mce->sb->tyenv, stData ) );
+ dszB = sizeofIRType( typeOfIRExpr(mce->tyenv, stData ) );
dataB = schemeE( mce, stData );
gen_store_b( mce, dszB, stAddr, 0/*offset*/, dataB, guard );
}
@@ -7546,6 +7679,8 @@
{
tl_assert(MC_(clo_mc_level) == 3);
+ const VexGuestLayout* layout = mce->settings->layout;
+
switch (st->tag) {
case Ist_AbiHint:
@@ -7570,7 +7705,7 @@
tl_assert(sizeofIRType(equivIntTy) >= 4);
tl_assert(sizeofIRType(equivIntTy) == sizeofIRType(descr->elemTy));
descr_b
- = mkIRRegArray( descr->base + 2*mce->layout->total_sizeB,
+ = mkIRRegArray( descr->base + 2 * layout->total_sizeB,
equivIntTy, descr->nElems );
/* Compute a value to Put - the conjoinment of the origin for
the data to be Put-ted (obviously) and of the index value
@@ -7610,7 +7745,7 @@
if (st->Ist.LLSC.storedata == NULL) {
/* Load Linked */
IRType resTy
- = typeOfIRTemp(mce->sb->tyenv, st->Ist.LLSC.result);
+ = typeOfIRTemp(mce->tyenv, st->Ist.LLSC.result);
IRExpr* vanillaLoad
= IRExpr_Load(st->Ist.LLSC.end, resTy, st->Ist.LLSC.addr);
tl_assert(resTy == Ity_I64 || resTy == Ity_I32
@@ -7636,11 +7771,11 @@
Int b_offset
= MC_(get_otrack_shadow_offset)(
st->Ist.Put.offset,
- sizeofIRType(typeOfIRExpr(mce->sb->tyenv, st->Ist.Put.data))
+ sizeofIRType(typeOfIRExpr(mce->tyenv, st->Ist.Put.data))
);
if (b_offset >= 0) {
/* FIXME: this isn't an atom! */
- stmt( 'B', mce, IRStmt_Put(b_offset + 2*mce->layout->total_sizeB,
+ stmt( 'B', mce, IRStmt_Put(b_offset + 2 * layout->total_sizeB,
schemeE( mce, st->Ist.Put.data )) );
}
break;
|
|
From: <sv...@va...> - 2017-03-13 10:30:40
|
Author: iraisr
Date: Mon Mar 13 10:30:32 2017
New Revision: 3314
Log:
Small refinement in VEX IR interface
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Mon Mar 13 10:30:32 2017
@@ -3675,16 +3675,8 @@
/*--- Helper functions for the IR -- IR Phi Nodes ---*/
/*---------------------------------------------------------------*/
-void addIRPhi(IRStmt* st, IRPhi* phi)
+void addIRPhiToIRPhiVec(IRPhiVec* phi_nodes, IRPhi* phi)
{
- vassert(st->tag == Ist_IfThenElse);
-
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- if (phi_nodes == NULL) {
- phi_nodes = emptyIRPhiVec();
- st->Ist.IfThenElse.phi_nodes = phi_nodes;
- }
-
if (phi_nodes->phis_used == phi_nodes->phis_size) {
IRPhi** phis2 = LibVEX_Alloc_inline(2 * phi_nodes->phis_size * sizeof(IRPhi*));
for (UInt i = 0; i < phi_nodes->phis_size; i++)
Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Mon Mar 13 10:30:32 2017
@@ -2760,12 +2760,14 @@
IRPhiVec;
extern void ppIRPhi(const IRPhi*);
-extern IRPhi* mkIRPhi(IRTemp, IRTemp, IRTemp);
+extern IRPhi* mkIRPhi(IRTemp dst, IRTemp srcThen, IRTemp srcElse);
extern IRPhi* deepCopyIRPhi(const IRPhi*);
extern void ppIRPhiVec(const IRPhiVec*);
extern IRPhiVec* emptyIRPhiVec(void);
extern IRPhiVec* deepCopyIRPhiVec(const IRPhiVec*);
+extern void addIRPhiToIRPhiVec(IRPhiVec* , IRPhi*);
+
/* ------------------ Type Environments ------------------ */
@@ -3151,9 +3153,6 @@
/* Pretty-print an IRStmt. */
extern void ppIRStmt ( const IRStmt* );
-/* Adds a phi node to IfThenElse statement. */
-extern void addIRPhi(IRStmt* , IRPhi*);
-
/* ------------------ Basic Blocks ------------------ */
/* Code blocks, which in proper compiler terminology are superblocks
|
|
From: <sv...@va...> - 2017-03-12 08:02:55
|
Author: iraisr
Date: Sun Mar 12 08:02:47 2017
New Revision: 16267
Log:
Progress further with m_gdbserver.c and m_translate.c
Modified:
branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c Sun Mar 12 08:02:47 2017
@@ -1144,11 +1144,10 @@
}
static void VG_(add_stmt_call_invalidate_if_not_gdbserved)
- ( IRSB* sb_in,
- const VexGuestLayout* layout,
- const VexGuestExtents* vge,
- IRTemp jmp,
- IRSB* irsb)
+ (const VexGuestLayout* layout,
+ const VexGuestExtents* vge,
+ IRTemp jmp,
+ IRSB* irsb)
{
void* fn;
@@ -1167,7 +1166,7 @@
di->nFxState = 0;
- addStmtToIRSB(irsb, IRStmt_Dirty(di));
+ addStmtToIRStmtVec(irsb->stmts, IRStmt_Dirty(di));
}
/* software_breakpoint support --------------------------------------*/
@@ -1182,13 +1181,12 @@
of other breaks in the same sb_in while the process is stopped), a
debugger statement will be inserted for all instructions of a block. */
static void VG_(add_stmt_call_gdbserver)
- (IRSB* sb_in, /* block being translated */
- const VexGuestLayout* layout,
+ (const VexGuestLayout* layout,
const VexGuestExtents* vge,
IRType gWordTy, IRType hWordTy,
- Addr iaddr, /* Addr of instruction being instrumented */
- UChar delta, /* delta to add to iaddr to obtain IP */
- IRSB* irsb) /* irsb block to which call is added */
+ Addr iaddr, /* Addr of instruction being instrumented */
+ UChar delta, /* delta to add to iaddr to obtain IP */
+ IRStmtVec* stmts) /* list of statements to which call is added */
{
void* fn;
const HChar* nm;
@@ -1213,8 +1211,8 @@
IP when executing thumb code. gdb uses this thumb bit a.o.
to properly guess the next IP for the 'step' and 'stepi' commands. */
vg_assert(delta <= 1);
- addStmtToIRSB(irsb, IRStmt_Put(layout->offset_IP ,
- mkIRExpr_HWord(iaddr + (Addr)delta)));
+ addStmtToIRStmtVec(stmts, IRStmt_Put(layout->offset_IP ,
+ mkIRExpr_HWord(iaddr + (Addr)delta)));
fn = &VG_(helperc_CallDebugger);
nm = "VG_(helperc_CallDebugger)";
@@ -1245,8 +1243,7 @@
di->fxState[1].nRepeats = 0;
di->fxState[1].repeatLen = 0;
- addStmtToIRSB(irsb, IRStmt_Dirty(di));
-
+ addStmtToIRStmtVec(stmts, IRStmt_Dirty(di));
}
@@ -1269,31 +1266,25 @@
: sb_in->next->Iex.Const.con->Ico.U32);
} else if (sb_in->next->tag == Iex_RdTmp) {
VG_(add_stmt_call_invalidate_if_not_gdbserved)
- (sb_in, layout, vge, sb_in->next->Iex.RdTmp.tmp, irsb);
+ (layout, vge, sb_in->next->Iex.RdTmp.tmp, irsb);
} else {
vg_assert (0); /* unexpected expression tag in exit. */
}
}
-IRSB* VG_(instrument_for_gdbserver_if_needed)
- (IRSB* sb_in,
- const VexGuestLayout* layout,
- const VexGuestExtents* vge,
- IRType gWordTy, IRType hWordTy)
+static IRStmtVec* instrument_for_gdbserver_IRStmtVec
+ (IRStmtVec* stmts_in,
+ IRStmtVec* parent,
+ const VgVgdb instr_needed,
+ const VexGuestLayout* layout,
+ const VexGuestExtents* vge,
+ IRType gWordTy, IRType hWordTy)
{
- IRSB* sb_out;
- Int i;
- const VgVgdb instr_needed = VG_(gdbserver_instrumentation_needed) (vge);
+ IRStmtVec* stmts_out = emptyIRStmtVec();
+ stmts_out->parent = parent;
- if (instr_needed == Vg_VgdbNo)
- return sb_in;
-
-
- /* here, we need to instrument for gdbserver */
- sb_out = deepCopyIRSBExceptStmts(sb_in);
-
- for (i = 0; i < sb_in->stmts_used; i++) {
- IRStmt* st = sb_in->stmts[i];
+ for (UInt i = 0; i < stmts_in->stmts_used; i++) {
+ IRStmt* st = stmts_in->stmts[i];
if (!st || st->tag == Ist_NoOp) continue;
@@ -1303,18 +1294,27 @@
st->Ist.Exit.dst->Ico.U64 :
st->Ist.Exit.dst->Ico.U32);
}
- addStmtToIRSB( sb_out, st );
+
+ if (st->tag == Ist_IfThenElse) {
+ st = IRStmt_IfThenElse(
+ st->Ist.IfThenElse.cond,
+ instrument_for_gdbserver_IRStmtVec(st->Ist.IfThenElse.then_leg,
+ stmts_out, instr_needed, layout, vge, gWordTy, hWordTy),
+ instrument_for_gdbserver_IRStmtVec(st->Ist.IfThenElse.else_leg,
+ stmts_out, instr_needed, layout, vge, gWordTy, hWordTy),
+ st->Ist.IfThenElse.phi_nodes);
+ }
+ addStmtToIRStmtVec(stmts_out, st);
+
if (st->tag == Ist_IMark) {
/* For an Ist_Mark, add a call to debugger. */
switch (instr_needed) {
case Vg_VgdbNo: vg_assert (0);
case Vg_VgdbYes:
case Vg_VgdbFull:
- VG_(add_stmt_call_gdbserver) ( sb_in, layout, vge,
- gWordTy, hWordTy,
- st->Ist.IMark.addr,
- st->Ist.IMark.delta,
- sb_out);
+ VG_(add_stmt_call_gdbserver)(layout, vge, gWordTy, hWordTy,
+ st->Ist.IMark.addr, st->Ist.IMark.delta,
+ stmts_out);
/* There is an optimisation possible here for Vg_VgdbFull:
Put a guard ensuring we only call gdbserver if 'FullCallNeeded'.
FullCallNeeded would be set to 1 we have just switched on
@@ -1329,11 +1329,28 @@
}
}
+ return stmts_out;
+}
+
+IRSB* VG_(instrument_for_gdbserver_if_needed)
+ (IRSB* sb_in,
+ const VexGuestLayout* layout,
+ const VexGuestExtents* vge,
+ IRType gWordTy, IRType hWordTy)
+{
+ const VgVgdb instr_needed = VG_(gdbserver_instrumentation_needed) (vge);
+
+ if (instr_needed == Vg_VgdbNo)
+ return sb_in;
+
+ /* here, we need to instrument for gdbserver */
+ IRSB* sb_out = deepCopyIRSBExceptStmts(sb_in);
+ sb_out->stmts = instrument_for_gdbserver_IRStmtVec(sb_in->stmts, NULL,
+ instr_needed, layout, vge, gWordTy, hWordTy);
+
if (instr_needed == Vg_VgdbYes) {
- VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved) (sb_in,
- layout, vge,
- gWordTy,
- sb_out);
+ VG_(add_stmt_call_invalidate_exit_target_if_not_gdbserved)(sb_in, layout,
+ vge, gWordTy, sb_out);
}
return sb_out;
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c Sun Mar 12 08:02:47 2017
@@ -159,7 +159,7 @@
{
Int i;
for (i = 0; i < N_ALIASES; i++) {
- SP_aliases[i].temp = IRTemp_INVALID;
+ SP_aliases[i].temp = IRTemp_INVALID();
SP_aliases[i].delta = 0;
}
next_SP_alias_slot = 0;
@@ -167,7 +167,7 @@
static void add_SP_alias(IRTemp temp, Long delta)
{
- vg_assert(temp != IRTemp_INVALID);
+ vg_assert(!isIRTempInvalid(temp));
SP_aliases[ next_SP_alias_slot ].temp = temp;
SP_aliases[ next_SP_alias_slot ].delta = delta;
next_SP_alias_slot++;
@@ -177,17 +177,17 @@
static Bool get_SP_delta(IRTemp temp, Long* delta)
{
Int i; // i must be signed!
- vg_assert(IRTemp_INVALID != temp);
+ vg_assert(!isIRTempInvalid(temp));
// Search backwards between current buffer position and the start.
for (i = next_SP_alias_slot-1; i >= 0; i--) {
- if (temp == SP_aliases[i].temp) {
+ if (eqIRTemp(temp, SP_aliases[i].temp)) {
*delta = SP_aliases[i].delta;
return True;
}
}
// Search backwards between the end and the current buffer position.
for (i = N_ALIASES-1; i >= next_SP_alias_slot; i--) {
- if (temp == SP_aliases[i].temp) {
+ if (eqIRTemp(temp, SP_aliases[i].temp)) {
*delta = SP_aliases[i].delta;
return True;
}
@@ -199,7 +199,7 @@
{
Int i;
for (i = 0; i < N_ALIASES; i++) {
- if (SP_aliases[i].temp == IRTemp_INVALID) {
+ if (isIRTempInvalid(SP_aliases[i].temp)) {
return;
}
SP_aliases[i].delta += delta;
@@ -268,39 +268,36 @@
only parts of SP. Bizarre, but it has been known to happen.
*/
static
-IRSB* vg_SP_update_pass ( void* closureV,
- IRSB* sb_in,
- const VexGuestLayout* layout,
- const VexGuestExtents* vge,
- const VexArchInfo* vai,
- IRType gWordTy,
- IRType hWordTy )
+IRStmtVec* vg_SP_update_IRStmtVec(void* closureV,
+ IRStmtVec* stmts_in,
+ IRStmtVec* parent,
+ const VexGuestLayout* layout,
+ const VexGuestExtents* vge,
+ const VexArchInfo* vai,
+ IRType gWordTy,
+ IRType hWordTy)
{
- Int i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP;
+ Int j, k, minoff_ST, maxoff_ST;
Int first_SP, last_SP, first_Put, last_Put;
IRDirty *dcall, *d;
- IRStmt* st;
IRExpr* e;
IRRegArray* descr;
- IRType typeof_SP;
Long delta, con;
/* Set up stuff for tracking the guest IP */
Bool curr_IP_known = False;
Addr curr_IP = 0;
- /* Set up BB */
- IRSB* bb = emptyIRSB();
- bb->tyenv = deepCopyIRTypeEnv(sb_in->tyenv);
- bb->next = deepCopyIRExpr(sb_in->next);
- bb->jumpkind = sb_in->jumpkind;
- bb->offsIP = sb_in->offsIP;
+ /* Set up new IRStmtVec */
+ IRStmtVec* out = emptyIRStmtVec();
+ out->tyenv = deepCopyIRTypeEnv(stmts_in->tyenv);
+ out->parent = parent;
delta = 0;
- sizeof_SP = layout->sizeof_SP;
- offset_SP = layout->offset_SP;
- typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64;
+ UInt sizeof_SP = layout->sizeof_SP;
+ UInt offset_SP = layout->offset_SP;
+ IRType typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64;
vg_assert(sizeof_SP == 4 || sizeof_SP == 8);
/* --- Start of #defines --- */
@@ -351,7 +348,7 @@
dcall->fxState[0].nRepeats = 0; \
dcall->fxState[0].repeatLen = 0; \
\
- addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
+ addStmtToIRStmtVec(out, IRStmt_Dirty(dcall)); \
\
vg_assert(syze > 0); \
update_SP_aliases(syze); \
@@ -381,7 +378,7 @@
dcall->fxState[0].nRepeats = 0; \
dcall->fxState[0].repeatLen = 0; \
\
- addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \
+ addStmtToIRStmtVec(out, IRStmt_Dirty(dcall) ); \
\
vg_assert(syze > 0); \
update_SP_aliases(-(syze)); \
@@ -392,11 +389,11 @@
/* --- End of #defines --- */
+ // TODO-JIT: can we move this to vg_SP_update_pass?
clear_SP_aliases();
- for (i = 0; i < sb_in->stmts_used; i++) {
-
- st = sb_in->stmts[i];
+ for (UInt i = 0; i < stmts_in->stmts_used; i++) {
+ IRStmt* st = stmts_in->stmts[i];
if (st->tag == Ist_IMark) {
curr_IP_known = True;
@@ -409,9 +406,9 @@
if (e->tag != Iex_Get) goto case2;
if (e->Iex.Get.offset != offset_SP) goto case2;
if (e->Iex.Get.ty != typeof_SP) goto case2;
- vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, 0);
- addStmtToIRSB( bb, st );
+ addStmtToIRStmtVec(out, st);
continue;
case2:
@@ -424,13 +421,13 @@
if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3;
if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3;
con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con);
- vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
if (IS_ADD(e->Iex.Binop.op)) {
add_SP_alias(st->Ist.WrTmp.tmp, delta + con);
} else {
add_SP_alias(st->Ist.WrTmp.tmp, delta - con);
}
- addStmtToIRSB( bb, st );
+ addStmtToIRStmtVec(out, st);
continue;
case3:
@@ -439,9 +436,9 @@
e = st->Ist.WrTmp.data;
if (e->tag != Iex_RdTmp) goto case4;
if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4;
- vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out->tyenv, st->Ist.WrTmp.tmp) == typeof_SP );
add_SP_alias(st->Ist.WrTmp.tmp, delta);
- addStmtToIRSB( bb, st );
+ addStmtToIRStmtVec(out, st);
continue;
case4:
@@ -454,7 +451,7 @@
last_SP = first_SP + sizeof_SP - 1;
first_Put = st->Ist.Put.offset;
last_Put = first_Put
- + sizeofIRType( typeOfIRExpr( bb->tyenv, st->Ist.Put.data ))
+ + sizeofIRType(typeOfIRExpr(out->tyenv, st->Ist.Put.data))
- 1;
vg_assert(first_SP <= last_SP);
vg_assert(first_Put <= last_Put);
@@ -472,31 +469,31 @@
put_SP_alias is immediately preceded by an assertion that
we are putting in a binding for a correctly-typed
temporary. */
- vg_assert( typeOfIRTemp(bb->tyenv, tttmp) == typeof_SP );
+ vg_assert( typeOfIRTemp(out->tyenv, tttmp) == typeof_SP );
/* From the same type-and-offset-correctness argument, if
we found a useable alias, it must for an "exact" write of SP. */
vg_assert(first_SP == first_Put);
vg_assert(last_SP == last_Put);
switch (delta) {
- case 0: addStmtToIRSB(bb,st); continue;
- case 4: DO_DIE( 4, tttmp); addStmtToIRSB(bb,st); continue;
- case -4: DO_NEW( 4, tttmp); addStmtToIRSB(bb,st); continue;
- case 8: DO_DIE( 8, tttmp); addStmtToIRSB(bb,st); continue;
- case -8: DO_NEW( 8, tttmp); addStmtToIRSB(bb,st); continue;
- case 12: DO_DIE( 12, tttmp); addStmtToIRSB(bb,st); continue;
- case -12: DO_NEW( 12, tttmp); addStmtToIRSB(bb,st); continue;
- case 16: DO_DIE( 16, tttmp); addStmtToIRSB(bb,st); continue;
- case -16: DO_NEW( 16, tttmp); addStmtToIRSB(bb,st); continue;
- case 32: DO_DIE( 32, tttmp); addStmtToIRSB(bb,st); continue;
- case -32: DO_NEW( 32, tttmp); addStmtToIRSB(bb,st); continue;
- case 112: DO_DIE( 112, tttmp); addStmtToIRSB(bb,st); continue;
- case -112: DO_NEW( 112, tttmp); addStmtToIRSB(bb,st); continue;
- case 128: DO_DIE( 128, tttmp); addStmtToIRSB(bb,st); continue;
- case -128: DO_NEW( 128, tttmp); addStmtToIRSB(bb,st); continue;
- case 144: DO_DIE( 144, tttmp); addStmtToIRSB(bb,st); continue;
- case -144: DO_NEW( 144, tttmp); addStmtToIRSB(bb,st); continue;
- case 160: DO_DIE( 160, tttmp); addStmtToIRSB(bb,st); continue;
- case -160: DO_NEW( 160, tttmp); addStmtToIRSB(bb,st); continue;
+ case 0: addStmtToIRStmtVec(out,st); continue;
+ case 4: DO_DIE( 4, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -4: DO_NEW( 4, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 8: DO_DIE( 8, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -8: DO_NEW( 8, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 12: DO_DIE( 12, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -12: DO_NEW( 12, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 16: DO_DIE( 16, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -16: DO_NEW( 16, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 32: DO_DIE( 32, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -32: DO_NEW( 32, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 112: DO_DIE(112, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -112: DO_NEW(112, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 128: DO_DIE(128, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -128: DO_NEW(128, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 144: DO_DIE(144, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -144: DO_NEW(144, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case 160: DO_DIE(160, tttmp); addStmtToIRStmtVec(out,st); continue;
+ case -160: DO_NEW(160, tttmp); addStmtToIRStmtVec(out,st); continue;
default:
/* common values for ppc64: 144 128 160 112 176 */
n_SP_updates_generic_known++;
@@ -524,9 +521,9 @@
generic:
/* Pass both the old and new SP values to this helper. Also,
pass an origin tag, even if it isn't needed. */
- old_SP = newIRTemp(bb->tyenv, typeof_SP);
- addStmtToIRSB(
- bb,
+ old_SP = newIRTemp(out->tyenv, typeof_SP);
+ addStmtToIRStmtVec(
+ out,
IRStmt_WrTmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) )
);
@@ -552,9 +549,9 @@
mkIRExprVec_2( IRExpr_RdTmp(old_SP), st->Ist.Put.data )
);
- addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
+ addStmtToIRStmtVec(out, IRStmt_Dirty(dcall));
/* don't forget the original assignment */
- addStmtToIRSB( bb, st );
+ addStmtToIRStmtVec(out, st);
} else {
/* We have a partial update to SP. We need to know what
the new SP will be, and hand that to the helper call,
@@ -569,15 +566,16 @@
*/
IRTemp new_SP;
/* 1 */
- addStmtToIRSB( bb, st );
+ addStmtToIRStmtVec(out, st);
/* 2 */
- new_SP = newIRTemp(bb->tyenv, typeof_SP);
- addStmtToIRSB(
- bb,
+ new_SP = newIRTemp(out->tyenv, typeof_SP);
+ addStmtToIRStmtVec(
+ out,
IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) )
);
/* 3 */
- addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) ));
+ addStmtToIRStmtVec(out,
+ IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP)));
/* 4 */
vg_assert(curr_IP_known);
if (NULL != VG_(tdict).track_new_mem_stack_w_ECU)
@@ -597,9 +595,10 @@
mkIRExprVec_2( IRExpr_RdTmp(old_SP),
IRExpr_RdTmp(new_SP) )
);
- addStmtToIRSB( bb, IRStmt_Dirty(dcall) );
+ addStmtToIRStmtVec(out, IRStmt_Dirty(dcall));
/* 5 */
- addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) ));
+ addStmtToIRStmtVec(out,
+ IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP)));
}
/* Forget what we already know. */
@@ -610,7 +609,7 @@
if (first_Put == first_SP && last_Put == last_SP
&& st->Ist.Put.data->tag == Iex_RdTmp) {
- vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
+ vg_assert( typeOfIRTemp(out->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp)
== typeof_SP );
add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0);
}
@@ -646,15 +645,24 @@
}
}
- /* well, not interesting. Just copy and keep going. */
- addStmtToIRSB( bb, st );
+ if (st->tag == Ist_IfThenElse) {
+ st = IRStmt_IfThenElse(
+ st->Ist.IfThenElse.cond,
+ vg_SP_update_IRStmtVec(closureV, st->Ist.IfThenElse.then_leg,
+ out, layout, vge, vai, gWordTy, hWordTy),
+ vg_SP_update_IRStmtVec(closureV, st->Ist.IfThenElse.else_leg,
+ out, layout, vge, vai, gWordTy, hWordTy),
+ st->Ist.IfThenElse.phi_nodes);
+ }
- } /* for (i = 0; i < sb_in->stmts_used; i++) */
+ /* well, not interesting. Just copy and keep going. */
+ addStmtToIRStmtVec(out, st);
+ } /* for (UInt i = 0; i < stmts_in->stmts_used; i++) */
- return bb;
+ return out;
complain:
- VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP");
+ VG_(core_panic)("vg_SP_update_IRStmtVec: PutI or Dirty which overlaps SP");
#undef IS_ADD
#undef IS_SUB
@@ -664,6 +672,28 @@
#undef DO_DIE
}
+/* See vg_SP_update_IRStmtVec() for detailed explanation. */
+static
+IRSB* vg_SP_update_pass ( void* closureV,
+ IRSB* sb_in,
+ const VexGuestLayout* layout,
+ const VexGuestExtents* vge,
+ const VexArchInfo* vai,
+ IRType gWordTy,
+ IRType hWordTy )
+{
+ /* Set up BB */
+ IRSB* bb = emptyIRSB();
+ bb->id_seq = sb_in->id_seq;
+ bb->next = deepCopyIRExpr(sb_in->next);
+ bb->jumpkind = sb_in->jumpkind;
+ bb->offsIP = sb_in->offsIP;
+
+ bb->stmts = vg_SP_update_IRStmtVec(closureV, sb_in->stmts, NULL, layout,
+ vge, vai, gWordTy, hWordTy);
+ return bb;
+}
+
/*------------------------------------------------------------*/
/*--- Main entry point for the JITter. ---*/
/*------------------------------------------------------------*/
@@ -1325,8 +1355,8 @@
= sizeof(((VexGuestArchState*)0)->guest_NRADDR);
vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
vg_assert(nraddr_szB == VG_WORDSIZE);
- addStmtToIRSB(
- bb,
+ addStmtToIRStmtVec(
+ bb->stmts,
IRStmt_Put(
offsetof(VexGuestArchState,guest_NRADDR),
nraddr_szB == 8 ? mkU64(0) : mkU32(0)
@@ -1383,8 +1413,8 @@
= sizeof(((VexGuestArchState*)0)->guest_NRADDR);
vg_assert(nraddr_szB == 4 || nraddr_szB == 8);
vg_assert(nraddr_szB == VG_WORDSIZE);
- addStmtToIRSB(
- bb,
+ addStmtToIRStmtVec(
+ bb->stmts,
IRStmt_Put(
offsetof(VexGuestArchState,guest_NRADDR),
nraddr_szB == 8
|
|
From: <sv...@va...> - 2017-03-12 07:59:32
|
Author: iraisr
Date: Sun Mar 12 07:59:25 2017
New Revision: 3313
Log:
Forgotten id_seq in flatten_BB
Modified:
branches/VEX_JIT_HACKS/priv/ir_opt.c
Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Sun Mar 12 07:59:25 2017
@@ -538,6 +538,7 @@
static IRSB* flatten_BB ( IRSB* in )
{
IRSB* out = emptyIRSB();
+ out->id_seq = in->id_seq;
out->stmts = flatten_IRStmtVec(in->stmts, NULL);
out->next = flatten_Expr(out->stmts, in->next);
out->jumpkind = in->jumpkind;
|
|
From: <sv...@va...> - 2017-03-11 21:07:29
|
Author: philippe
Date: Sat Mar 11 21:07:21 2017
New Revision: 16266
Log:
Add missing break for the DRM ioctl operations that do not have any args
Due to this missing break, the code was falling through to
the case VKI_SNDRV_CTL_IOCTL_PVERSION:
and was then setting some bytes as defined at (whatever address is in) ARG3.
Patch and analysis by Daniel Glöckner
Modified:
trunk/coregrind/m_syswrap/syswrap-linux.c
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Sat Mar 11 21:07:21 2017
@@ -9520,6 +9520,8 @@
case VKI_SNDRV_TIMER_IOCTL_STOP:
case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
case VKI_SNDRV_TIMER_IOCTL_PAUSE:
+ break;
+
case VKI_SNDRV_CTL_IOCTL_PVERSION: {
POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
break;
|
|
From: <sv...@va...> - 2017-03-11 14:48:42
|
Author: iraisr
Date: Sat Mar 11 14:48:35 2017
New Revision: 3312
Log:
Make compilable x86 VEX isel backend.
Modified:
branches/VEX_JIT_HACKS/priv/host_x86_isel.c
Modified: branches/VEX_JIT_HACKS/priv/host_x86_isel.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_x86_isel.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_x86_isel.c Sat Mar 11 14:48:35 2017
@@ -192,18 +192,20 @@
static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
{
- vassert(tmp >= 0);
- vassert(tmp < env->n_vregmap);
- return env->vregmap[tmp];
+ vassert(tmp.id == 0); // TODO-JIT: assume now only IRTypeEnv ID #0
+ vassert(tmp.index >= 0);
+ vassert(tmp.index < env->n_vregmap);
+ return env->vregmap[tmp.index];
}
static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
{
- vassert(tmp >= 0);
- vassert(tmp < env->n_vregmap);
- vassert(! hregIsInvalid(env->vregmapHI[tmp]));
- *vrLO = env->vregmap[tmp];
- *vrHI = env->vregmapHI[tmp];
+ vassert(tmp.id == 0); // TODO-JIT: assume now only IRTypeEnv ID #0
+ vassert(tmp.index >= 0);
+ vassert(tmp.index < env->n_vregmap);
+ vassert(! hregIsInvalid(env->vregmapHI[tmp.index]));
+ *vrLO = env->vregmap[tmp.index];
+ *vrHI = env->vregmapHI[tmp.index];
}
static void addInstr ( ISelEnv* env, X86Instr* instr )
@@ -4089,7 +4091,7 @@
/* Figure out the return type, if any. */
IRType retty = Ity_INVALID;
- if (d->tmp != IRTemp_INVALID)
+ if (!isIRTempInvalid(d->tmp))
retty = typeOfIRTemp(env->type_env, d->tmp);
Bool retty_ok = False;
@@ -4116,7 +4118,7 @@
switch (retty) {
case Ity_INVALID: {
/* No return value. Nothing to do. */
- vassert(d->tmp == IRTemp_INVALID);
+ vassert(isIRTempInvalid(d->tmp));
vassert(rloc.pri == RLPri_None);
vassert(addToSp == 0);
return;
@@ -4174,7 +4176,7 @@
/* --------- ACAS --------- */
case Ist_CAS:
- if (stmt->Ist.CAS.details->oldHi == IRTemp_INVALID) {
+ if (isIRTempInvalid(stmt->Ist.CAS.details->oldHi)) {
/* "normal" singleton CAS */
UChar sz;
IRCAS* cas = stmt->Ist.CAS.details;
@@ -4455,11 +4457,13 @@
env->code = newHInstrArray();
/* Copy BB's type env. */
- env->type_env = bb->tyenv;
+ /* TODO-JIT: Works only with IRTypeEnv ID #0. */
+ vassert(bb->stmts->tyenv->id == 0);
+ env->type_env = bb->stmts->tyenv;
/* Make up an IRTemp -> virtual HReg mapping. This doesn't
change as we go along. */
- env->n_vregmap = bb->tyenv->types_used;
+ env->n_vregmap = bb->stmts->tyenv->types_used;
env->vregmap = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
env->vregmapHI = LibVEX_Alloc_inline(env->n_vregmap * sizeof(HReg));
@@ -4473,7 +4477,7 @@
j = 0;
for (i = 0; i < env->n_vregmap; i++) {
hregHI = hreg = INVALID_HREG;
- switch (bb->tyenv->types[i]) {
+ switch (bb->stmts->tyenv->types[i]) {
case Ity_I1:
case Ity_I8:
case Ity_I16:
@@ -4483,7 +4487,7 @@
case Ity_F32:
case Ity_F64: hreg = mkHReg(True, HRcFlt64, 0, j++); break;
case Ity_V128: hreg = mkHReg(True, HRcVec128, 0, j++); break;
- default: ppIRType(bb->tyenv->types[i]);
+ default: ppIRType(bb->stmts->tyenv->types[i]);
vpanic("iselBB: IRTemp type");
}
env->vregmap[i] = hreg;
@@ -4505,8 +4509,8 @@
}
/* Ok, finally we can iterate over the statements. */
- for (i = 0; i < bb->stmts_used; i++)
- iselStmt(env, bb->stmts[i]);
+ for (i = 0; i < bb->stmts->stmts_used; i++)
+ iselStmt(env, bb->stmts->stmts[i]);
iselNext(env, bb->next, bb->jumpkind, bb->offsIP);
|
|
From: <sv...@va...> - 2017-03-11 14:43:18
|
Author: iraisr
Date: Sat Mar 11 14:43:10 2017
New Revision: 3311
Log:
Progress further with compilation of x86 VEX frontend.
Modified:
branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c
branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
Modified: branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c (original)
+++ branches/VEX_JIT_HACKS/priv/guest_generic_bb_to_IR.c Sat Mar 11 14:43:10 2017
@@ -264,9 +264,9 @@
each). We won't know until later the extents and checksums of
the areas, if any, that need to be checked. */
nop = IRStmt_NoOp();
- selfcheck_idx = irsb->stmts_used;
+ selfcheck_idx = irsb->stmts->stmts_used;
for (i = 0; i < 3 * 5; i++)
- addStmtToIRSB( irsb, nop );
+ addStmtToIRStmtVec(irsb->stmts, nop);
/* If the caller supplied a function to add its own preamble, use
it now. */
@@ -315,7 +315,7 @@
/* This is the irsb statement array index of the first stmt in
this insn. That will always be the instruction-mark
descriptor. */
- first_stmt_idx = irsb->stmts_used;
+ first_stmt_idx = irsb->stmts->stmts_used;
/* Add an instruction-mark statement. We won't know until after
disassembling the instruction how long it instruction is, so
@@ -334,19 +334,19 @@
libvex_guest_arm.h. */
if (arch_guest == VexArchARM && (guest_IP_curr_instr & 1)) {
/* Thumb insn => mask out the T bit, but put it in delta */
- addStmtToIRSB( irsb,
- IRStmt_IMark(guest_IP_curr_instr & ~(Addr)1,
- 0, /* len */
- 1 /* delta */
- )
+ addStmtToIRStmtVec(irsb->stmts,
+ IRStmt_IMark(guest_IP_curr_instr & ~(Addr)1,
+ 0, /* len */
+ 1 /* delta */
+ )
);
} else {
/* All other targets: store IP as-is, and set delta to zero. */
- addStmtToIRSB( irsb,
- IRStmt_IMark(guest_IP_curr_instr,
- 0, /* len */
- 0 /* delta */
- )
+ addStmtToIRStmtVec(irsb->stmts,
+ IRStmt_IMark(guest_IP_curr_instr,
+ 0, /* len */
+ 0 /* delta */
+ )
);
}
@@ -384,8 +384,8 @@
vassert(dres.whatNext != Dis_ResteerC);
/* Fill in the insn-mark length field. */
- vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
- imark = irsb->stmts[first_stmt_idx];
+ vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts->stmts_used);
+ imark = irsb->stmts->stmts[first_stmt_idx];
vassert(imark);
vassert(imark->tag == Ist_IMark);
vassert(imark->Ist.IMark.len == 0);
@@ -393,9 +393,9 @@
/* Print the resulting IR, if needed. */
if (vex_traceflags & VEX_TRACE_FE) {
- for (i = first_stmt_idx; i < irsb->stmts_used; i++) {
+ for (i = first_stmt_idx; i < irsb->stmts->stmts_used; i++) {
vex_printf(" ");
- ppIRStmt(irsb->stmts[i]);
+ ppIRStmt(irsb->stmts->stmts[i]);
vex_printf("\n");
}
}
@@ -408,9 +408,9 @@
/* Individual insn disassembly must finish the IR for each
instruction with an assignment to the guest PC. */
- vassert(first_stmt_idx < irsb->stmts_used);
+ vassert(first_stmt_idx < irsb->stmts->stmts_used);
/* it follows that irsb->stmts_used must be > 0 */
- { IRStmt* st = irsb->stmts[irsb->stmts_used-1];
+ { IRStmt* st = irsb->stmts->stmts[irsb->stmts->stmts_used-1];
vassert(st);
vassert(st->tag == Ist_Put);
vassert(st->Ist.Put.offset == offB_GUEST_IP);
@@ -669,8 +669,8 @@
the area of guest code to invalidate should we exit with a
self-check failure. */
- tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
- tilen_tmp = newIRTemp(irsb->tyenv, guest_word_type);
+ tistart_tmp = newIRTemp(irsb->stmts->tyenv, guest_word_type);
+ tilen_tmp = newIRTemp(irsb->stmts->tyenv, guest_word_type);
IRConst* base2check_IRConst
= guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
@@ -679,16 +679,16 @@
= guest_word_type==Ity_I32 ? IRConst_U32(len2check)
: IRConst_U64(len2check);
- irsb->stmts[selfcheck_idx + i * 5 + 0]
+ irsb->stmts->stmts[selfcheck_idx + i * 5 + 0]
= IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
- irsb->stmts[selfcheck_idx + i * 5 + 1]
+ irsb->stmts->stmts[selfcheck_idx + i * 5 + 1]
= IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
- irsb->stmts[selfcheck_idx + i * 5 + 2]
+ irsb->stmts->stmts[selfcheck_idx + i * 5 + 2]
= IRStmt_Put( offB_GUEST_CMSTART, IRExpr_RdTmp(tistart_tmp) );
- irsb->stmts[selfcheck_idx + i * 5 + 3]
+ irsb->stmts->stmts[selfcheck_idx + i * 5 + 3]
= IRStmt_Put( offB_GUEST_CMLEN, IRExpr_RdTmp(tilen_tmp) );
/* Generate the entry point descriptors */
@@ -730,7 +730,7 @@
);
}
- irsb->stmts[selfcheck_idx + i * 5 + 4]
+ irsb->stmts->stmts[selfcheck_idx + i * 5 + 4]
= IRStmt_Exit(
IRExpr_Binop(
host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
Modified: branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c (original)
+++ branches/VEX_JIT_HACKS/priv/guest_x86_toIR.c Sat Mar 11 14:43:10 2017
@@ -208,7 +208,8 @@
translated. */
static Addr32 guest_EIP_curr_instr;
-/* The IRSB* into which we're generating code. */
+/* The IRSB* into which we're generating code. All functions below work
+ implicitly with the main statement vector held by irsb->stmts. */
static IRSB* irsb;
@@ -309,17 +310,17 @@
#define R_GS 5
-/* Add a statement to the list held by "irbb". */
+/* Add a statement to the main statement vector held by "irbb->stmts". */
static void stmt ( IRStmt* st )
{
- addStmtToIRSB( irsb, st );
+ addStmtToIRStmtVec(irsb->stmts, st);
}
/* Generate a new temporary of the given type. */
static IRTemp newTemp ( IRType ty )
{
vassert(isPlausibleIRType(ty));
- return newIRTemp( irsb->tyenv, ty );
+ return newIRTemp(irsb->stmts->tyenv, ty);
}
/* Various simple conversions */
@@ -547,7 +548,7 @@
/* Ditto, but write to a reg instead. */
static void putIReg ( Int sz, UInt archreg, IRExpr* e )
{
- IRType ty = typeOfIRExpr(irsb->tyenv, e);
+ IRType ty = typeOfIRExpr(irsb->stmts->tyenv, e);
switch (sz) {
case 1: vassert(ty == Ity_I8); break;
case 2: vassert(ty == Ity_I16); break;
@@ -565,7 +566,7 @@
static void putSReg ( UInt sreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I16);
stmt( IRStmt_Put( segmentGuestRegOffset(sreg), e ) );
}
@@ -596,37 +597,37 @@
static void putXMMReg ( UInt xmmreg, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_V128);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_V128);
stmt( IRStmt_Put( xmmGuestRegOffset(xmmreg), e ) );
}
static void putXMMRegLane64 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane64F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_F64);
stmt( IRStmt_Put( xmmGuestRegLane64offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane32F ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_F32);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_F32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
}
static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I16);
stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );
}
@@ -734,8 +735,8 @@
static IRExpr* mkAnd1 ( IRExpr* x, IRExpr* y )
{
- vassert(typeOfIRExpr(irsb->tyenv,x) == Ity_I1);
- vassert(typeOfIRExpr(irsb->tyenv,y) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, x) == Ity_I1);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, y) == Ity_I1);
return unop(Iop_32to1,
binop(Iop_And32,
unop(Iop_1Uto32,x),
@@ -752,15 +753,15 @@
Addr32 restart_point )
{
IRCAS* cas;
- IRType tyE = typeOfIRExpr(irsb->tyenv, expVal);
- IRType tyN = typeOfIRExpr(irsb->tyenv, newVal);
+ IRType tyE = typeOfIRExpr(irsb->stmts->tyenv, expVal);
+ IRType tyN = typeOfIRExpr(irsb->stmts->tyenv, newVal);
IRTemp oldTmp = newTemp(tyE);
IRTemp expTmp = newTemp(tyE);
vassert(tyE == tyN);
vassert(tyE == Ity_I32 || tyE == Ity_I16 || tyE == Ity_I8);
assign(expTmp, expVal);
- cas = mkIRCAS( IRTemp_INVALID, oldTmp, Iend_LE, addr,
- NULL, mkexpr(expTmp), NULL, newVal );
+ cas = mkIRCAS(IRTemp_INVALID(), oldTmp, Iend_LE, addr,
+ NULL, mkexpr(expTmp), NULL, newVal);
stmt( IRStmt_CAS(cas) );
stmt( IRStmt_Exit(
binop( mkSizedOp(tyE,Iop_CasCmpNE8),
@@ -867,7 +868,7 @@
/* U-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenUto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->tyenv,e)) {
+ switch (typeOfIRExpr(irsb->stmts->tyenv, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Uto32,e);
case Ity_I8: return unop(Iop_8Uto32,e);
@@ -878,7 +879,7 @@
/* S-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenSto32 ( IRExpr* e )
{
- switch (typeOfIRExpr(irsb->tyenv,e)) {
+ switch (typeOfIRExpr(irsb->stmts->tyenv, e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Sto32,e);
case Ity_I8: return unop(Iop_8Sto32,e);
@@ -890,7 +891,7 @@
of these combinations make sense. */
static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
{
- IRType src_ty = typeOfIRExpr(irsb->tyenv,e);
+ IRType src_ty = typeOfIRExpr(irsb->stmts->tyenv, e);
if (src_ty == dst_ty)
return e;
if (src_ty == Ity_I32 && dst_ty == Ity_I16)
@@ -970,7 +971,7 @@
Int ccOp = ty==Ity_I8 ? 2 : (ty==Ity_I16 ? 1 : 0);
vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
- vassert(guard);
+ vassert(!isIRTempInvalid(guard));
/* Both kinds of right shifts are handled by the same thunk
operation. */
@@ -1132,7 +1133,7 @@
IROp plus = mkSizedOp(ty, Iop_Add8);
IROp xor = mkSizedOp(ty, Iop_Xor8);
- vassert(typeOfIRTemp(irsb->tyenv, tres) == ty);
+ vassert(typeOfIRTemp(irsb->stmts->tyenv, tres) == ty);
vassert(sz == 1 || sz == 2 || sz == 4);
thunkOp = sz==4 ? X86G_CC_OP_ADCL
: (sz==2 ? X86G_CC_OP_ADCW : X86G_CC_OP_ADCB);
@@ -1150,12 +1151,12 @@
/* Possibly generate a store of 'tres' to 'taddr'. See comment at
start of this function. */
- if (taddr != IRTemp_INVALID) {
- if (texpVal == IRTemp_INVALID) {
+ if (!isIRTempInvalid(taddr)) {
+ if (isIRTempInvalid(texpVal)) {
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->tyenv, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->stmts->tyenv, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -1186,7 +1187,7 @@
IROp minus = mkSizedOp(ty, Iop_Sub8);
IROp xor = mkSizedOp(ty, Iop_Xor8);
- vassert(typeOfIRTemp(irsb->tyenv, tres) == ty);
+ vassert(typeOfIRTemp(irsb->stmts->tyenv, tres) == ty);
vassert(sz == 1 || sz == 2 || sz == 4);
thunkOp = sz==4 ? X86G_CC_OP_SBBL
: (sz==2 ? X86G_CC_OP_SBBW : X86G_CC_OP_SBBB);
@@ -1204,12 +1205,12 @@
/* Possibly generate a store of 'tres' to 'taddr'. See comment at
start of this function. */
- if (taddr != IRTemp_INVALID) {
- if (texpVal == IRTemp_INVALID) {
+ if (!isIRTempInvalid(taddr)) {
+ if (isIRTempInvalid(texpVal)) {
vassert(restart_point == 0);
storeLE( mkexpr(taddr), mkexpr(tres) );
} else {
- vassert(typeOfIRTemp(irsb->tyenv, texpVal) == ty);
+ vassert(typeOfIRTemp(irsb->stmts->tyenv, texpVal) == ty);
/* .. and hence 'texpVal' has the same type as 'tres'. */
casLE( mkexpr(taddr),
mkexpr(texpVal), mkexpr(tres), restart_point );
@@ -1728,7 +1729,6 @@
default:
vpanic("disAMode(x86)");
- return 0; /*notreached*/
}
}
@@ -1838,7 +1838,7 @@
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
UChar rm = getUChar(delta0);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
/* addSubCarry == True indicates the intended operation is
add-with-carry or subtract-with-borrow. */
@@ -1861,12 +1861,12 @@
if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else {
assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
@@ -1890,12 +1890,12 @@
if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, gregOfRM(rm), mkexpr(dst1));
} else {
assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
@@ -1951,7 +1951,7 @@
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
UChar rm = getIByte(delta0);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
/* addSubCarry == True indicates the intended operation is
add-with-carry or subtract-with-borrow. */
@@ -1974,12 +1974,12 @@
if (addSubCarry && op8 == Iop_Add8) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, eregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
putIReg(size, eregOfRM(rm), mkexpr(dst1));
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2011,7 +2011,7 @@
} else {
/* normal store */
helper_ADC( size, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID, 0 );
+ /*store*/addr, IRTemp_INVALID(), 0 );
}
} else
if (addSubCarry && op8 == Iop_Sub8) {
@@ -2022,7 +2022,7 @@
} else {
/* normal store */
helper_SBB( size, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID, 0 );
+ /*store*/addr, IRTemp_INVALID(), 0 );
}
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2168,12 +2168,12 @@
else
if (op8 == Iop_Add8 && carrying) {
helper_ADC( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
}
else
if (op8 == Iop_Sub8 && carrying) {
helper_SBB( size, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
}
else
vpanic("dis_op_imm_A(x86,guest)");
@@ -2291,7 +2291,7 @@
IRTemp dst1 = newTemp(ty);
IRTemp src = newTemp(ty);
IRTemp dst0 = newTemp(ty);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
IROp op8 = Iop_INVALID;
UInt mask = sz==1 ? 0xFF : (sz==2 ? 0xFFFF : 0xFFFFFFFF);
@@ -2313,11 +2313,11 @@
if (gregOfRM(modrm) == 2 /* ADC */) {
helper_ADC( sz, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
} else
if (gregOfRM(modrm) == 3 /* SBB */) {
helper_SBB( sz, dst1, dst0, src,
- /*no store*/IRTemp_INVALID, IRTemp_INVALID, 0 );
+ /*no store*/IRTemp_INVALID(), IRTemp_INVALID(), 0 );
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
if (isAddSub(op8))
@@ -2346,7 +2346,7 @@
} else {
/* normal store */
helper_ADC( sz, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID, 0 );
+ /*store*/addr, IRTemp_INVALID(), 0 );
}
} else
if (gregOfRM(modrm) == 3 /* SBB */) {
@@ -2357,7 +2357,7 @@
} else {
/* normal store */
helper_SBB( sz, dst1, dst0, src,
- /*store*/addr, IRTemp_INVALID, 0 );
+ /*store*/addr, IRTemp_INVALID(), 0 );
}
} else {
assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
@@ -2400,7 +2400,7 @@
IRType ty = szToITy(sz);
IRTemp dst0 = newTemp(ty);
IRTemp dst1 = newTemp(ty);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
*decode_OK = True;
@@ -2638,7 +2638,7 @@
IRType ty = szToITy(sz);
IRTemp t2 = newTemp(Ity_I32);
IRTemp t2m = newTemp(Ity_I32);
- IRTemp t_addr = IRTemp_INVALID;
+ IRTemp t_addr = IRTemp_INVALID();
HChar dis_buf[50];
UInt mask;
@@ -3043,10 +3043,10 @@
Int len;
UChar modrm;
HChar dis_buf[50];
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
IRType ty = szToITy(sz);
IRTemp t1 = newTemp(ty);
- IRTemp t2 = IRTemp_INVALID;
+ IRTemp t2 = IRTemp_INVALID();
*decode_OK = True;
@@ -3172,14 +3172,14 @@
/* Code shared by all the string ops */
static
-void dis_string_op_increment(Int sz, Int t_inc)
+void dis_string_op_increment(Int sz, IRTemp t_inc)
{
if (sz == 4 || sz == 2) {
- assign( t_inc,
+ assign( t_inc,
binop(Iop_Shl32, IRExpr_Get( OFFB_DFLAG, Ity_I32 ),
mkU8(sz/2) ) );
} else {
- assign( t_inc,
+ assign( t_inc,
IRExpr_Get( OFFB_DFLAG, Ity_I32 ) );
}
}
@@ -3451,7 +3451,7 @@
static void put_emwarn ( IRExpr* e /* :: Ity_I32 */ )
{
- vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( OFFB_EMNOTE, e ) );
}
@@ -3475,7 +3475,7 @@
static void put_ftop ( IRExpr* e )
{
- vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I32);
stmt( IRStmt_Put( OFFB_FTOP, e ) );
}
@@ -3527,7 +3527,7 @@
static void put_ST_TAG ( Int i, IRExpr* value )
{
IRRegArray* descr;
- vassert(typeOfIRExpr(irsb->tyenv, value) == Ity_I8);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, value) == Ity_I8);
descr = mkIRRegArray( OFFB_FPTAGS, Ity_I8, 8 );
stmt( IRStmt_PutI( mkIRPutI(descr, get_ftop(), i, value) ) );
}
@@ -3551,7 +3551,7 @@
static void put_ST_UNCHECKED ( Int i, IRExpr* value )
{
IRRegArray* descr;
- vassert(typeOfIRExpr(irsb->tyenv, value) == Ity_F64);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, value) == Ity_F64);
descr = mkIRRegArray( OFFB_FPREGS, Ity_F64, 8 );
stmt( IRStmt_PutI( mkIRPutI(descr, get_ftop(), i, value) ) );
/* Mark the register as in-use. */
@@ -5141,7 +5141,7 @@
case 7: { /* FNSTSW m16 */
IRExpr* sw = get_FPU_sw();
- vassert(typeOfIRExpr(irsb->tyenv, sw) == Ity_I16);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, sw) == Ity_I16);
storeLE( mkexpr(addr), sw );
DIP("fnstsw %s\n", dis_buf);
break;
@@ -5543,7 +5543,7 @@
static void putMMXReg ( UInt archreg, IRExpr* e )
{
vassert(archreg < 8);
- vassert(typeOfIRExpr(irsb->tyenv,e) == Ity_I64);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, e) == Ity_I64);
stmt( IRStmt_Put( OFFB_FPREGS + 8 * archreg, e ) );
}
@@ -6193,11 +6193,11 @@
IRType ty = szToITy(sz);
IRTemp gsrc = newTemp(ty);
IRTemp esrc = newTemp(ty);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
IRTemp tmpSH = newTemp(Ity_I8);
- IRTemp tmpL = IRTemp_INVALID;
- IRTemp tmpRes = IRTemp_INVALID;
- IRTemp tmpSubSh = IRTemp_INVALID;
+ IRTemp tmpL = IRTemp_INVALID();
+ IRTemp tmpRes = IRTemp_INVALID();
+ IRTemp tmpSubSh = IRTemp_INVALID();
IROp mkpair;
IROp getres;
IROp shift;
@@ -6325,7 +6325,7 @@
t_fetched = t_bitno0 = t_bitno1 = t_bitno2
= t_addr0 = t_addr1 = t_esp
- = t_mask = t_new = IRTemp_INVALID;
+ = t_mask = t_new = IRTemp_INVALID();
t_fetched = newTemp(Ity_I8);
t_new = newTemp(Ity_I8);
@@ -6652,7 +6652,7 @@
IRTemp dest2 = newTemp(ty);
IRTemp acc2 = newTemp(ty);
IRTemp cond = newTemp(Ity_I1);
- IRTemp addr = IRTemp_INVALID;
+ IRTemp addr = IRTemp_INVALID();
UChar rm = getUChar(delta0);
/* There are 3 cases to consider:
@@ -6708,7 +6708,7 @@
assign( src, getIReg(size, gregOfRM(rm)) );
assign( acc, getIReg(size, R_EAX) );
stmt( IRStmt_CAS(
- mkIRCAS( IRTemp_INVALID, dest, Iend_LE, mkexpr(addr),
+ mkIRCAS( IRTemp_INVALID(), dest, Iend_LE, mkexpr(addr),
NULL, mkexpr(acc), NULL, mkexpr(src) )
));
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
@@ -7542,7 +7542,7 @@
static void put_sse_roundingmode ( IRExpr* sseround )
{
- vassert(typeOfIRExpr(irsb->tyenv, sseround) == Ity_I32);
+ vassert(typeOfIRExpr(irsb->stmts->tyenv, sseround) == Ity_I32);
stmt( IRStmt_Put( OFFB_SSEROUND, sseround ) );
}
@@ -7558,10 +7558,10 @@
assign( hi64, unop(Iop_V128HIto64, mkexpr(t128)) );
assign( lo64, unop(Iop_V128to64, mkexpr(t128)) );
- vassert(t0 && *t0 == IRTemp_INVALID);
- vassert(t1 && *t1 == IRTemp_INVALID);
- vassert(t2 && *t2 == IRTemp_INVALID);
- vassert(t3 && *t3 == IRTemp_INVALID);
+ vassert(t0 && isIRTempInvalid(*t0));
+ vassert(t1 && isIRTempInvalid(*t1));
+ vassert(t2 && isIRTempInvalid(*t2));
+ vassert(t3 && isIRTempInvalid(*t3));
*t0 = newTemp(Ity_I32);
*t1 = newTemp(Ity_I32);
@@ -7597,10 +7597,10 @@
assign( hi32, unop(Iop_64HIto32, mkexpr(t64)) );
assign( lo32, unop(Iop_64to32, mkexpr(t64)) );
- vassert(t0 && *t0 == IRTemp_INVALID);
- vassert(t1 && *t1 == IRTemp_INVALID);
- vassert(t2 && *t2 == IRTemp_INVALID);
- vassert(t3 && *t3 == IRTemp_INVALID);
+ vassert(t0 && isIRTempInvalid(*t0));
+ vassert(t1 && isIRTempInvalid(*t1));
+ vassert(t2 && isIRTempInvalid(*t2));
+ vassert(t3 && isIRTempInvalid(*t3));
*t0 = newTemp(Ity_I16);
*t1 = newTemp(Ity_I16);
@@ -7642,7 +7642,7 @@
Bool emit_AC_emwarn,
Addr32 next_insn_EIP )
{
- vassert(typeOfIRTemp(irsb->tyenv,t1) == Ity_I32);
+ vassert(typeOfIRTemp(irsb->stmts->tyenv,t1) == Ity_I32);
/* t1 is the flag word. Mask out everything except OSZACP and set
the flags thunk to X86G_CC_OP_COPY. */
@@ -8050,8 +8050,6 @@
return t2;
}
vassert(0);
- /*NOTREACHED*/
- return IRTemp_INVALID;
}
/*------------------------------------------------------------*/
@@ -8118,7 +8116,7 @@
*expect_CAS = False;
- addr = t0 = t1 = t2 = t3 = t4 = t5 = t6 = IRTemp_INVALID;
+ addr = t0 = t1 = t2 = t3 = t4 = t5 = t6 = IRTemp_INVALID();
vassert(guest_EIP_bbstart + delta == guest_EIP_curr_instr);
DIP("\t0x%x: ", guest_EIP_bbstart+delta);
@@ -9046,7 +9044,7 @@
if (sz == 4 && insn[0] == 0x0F && insn[1] == 0x70) {
Int order;
IRTemp sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = IRTemp_INVALID();
sV = newTemp(Ity_I64);
dV = newTemp(Ity_I64);
do_MMX_preamble();
@@ -9397,7 +9395,7 @@
IRTemp s3, s2, s1, s0, d3, d2, d1, d0;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
modrm = insn[2];
assign( dV, getXMMReg(gregOfRM(modrm)) );
@@ -9498,7 +9496,7 @@
Bool hi = toBool(insn[1] == 0x15);
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
modrm = insn[2];
assign( dV, getXMMReg(gregOfRM(modrm)) );
@@ -11157,7 +11155,7 @@
IRTemp s3, s2, s1, s0, d3, d2, d1, d0;
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
- s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = d3 = d2 = d1 = d0 = IRTemp_INVALID();
t1 = newTemp(Ity_I64);
t0 = newTemp(Ity_I64);
modrm = insn[2];
@@ -11243,7 +11241,7 @@
if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x70) {
Int order;
IRTemp sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = IRTemp_INVALID();
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
modrm = insn[2];
@@ -11281,7 +11279,7 @@
if (insn[0] == 0xF3 && insn[1] == 0x0F && insn[2] == 0x70) {
Int order;
IRTemp sVhi, dVhi, sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = IRTemp_INVALID();
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
sVhi = newTemp(Ity_I64);
@@ -11325,7 +11323,7 @@
if (insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x70) {
Int order;
IRTemp sVlo, dVlo, sV, dV, s3, s2, s1, s0;
- s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = IRTemp_INVALID();
sV = newTemp(Ity_V128);
dV = newTemp(Ity_V128);
sVlo = newTemp(Ity_I64);
@@ -11802,7 +11800,7 @@
IRTemp s3, s2, s1, s0;
IRTemp sV = newTemp(Ity_V128);
Bool isH = insn[2] == 0x16;
- s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ s3 = s2 = s1 = s0 = IRTemp_INVALID();
modrm = insn[3];
if (epartIsReg(modrm)) {
@@ -11861,7 +11859,7 @@
IRTemp addV = newTemp(Ity_V128);
IRTemp subV = newTemp(Ity_V128);
IRTemp rm = newTemp(Ity_I32);
- a3 = a2 = a1 = a0 = s3 = s2 = s1 = s0 = IRTemp_INVALID;
+ a3 = a2 = a1 = a0 = s3 = s2 = s1 = s0 = IRTemp_INVALID();
modrm = insn[3];
if (epartIsReg(modrm)) {
@@ -11940,7 +11938,7 @@
IRTemp rm = newTemp(Ity_I32);
Bool isAdd = insn[2] == 0x7C;
const HChar* str = isAdd ? "add" : "sub";
- e3 = e2 = e1 = e0 = g3 = g2 = g1 = g0 = IRTemp_INVALID;
+ e3 = e2 = e1 = e0 = g3 = g2 = g1 = g0 = IRTemp_INVALID();
modrm = insn[3];
if (epartIsReg(modrm)) {
@@ -15450,13 +15448,13 @@
guest_EIP_curr_instr = (Addr32)guest_IP;
guest_EIP_bbstart = (Addr32)toUInt(guest_IP - delta);
- x1 = irsb_IN->stmts_used;
+ x1 = irsb_IN->stmts->stmts_used;
expect_CAS = False;
dres = disInstr_X86_WRK ( &expect_CAS, resteerOkFn,
resteerCisOk,
callback_opaque,
delta, archinfo, abiinfo, sigill_diag_IN );
- x2 = irsb_IN->stmts_used;
+ x2 = irsb_IN->stmts->stmts_used;
vassert(x2 >= x1);
/* See comment at the top of disInstr_X86_WRK for meaning of
@@ -15464,7 +15462,7 @@
IRCAS as directed by the returned expect_CAS value. */
has_CAS = False;
for (i = x1; i < x2; i++) {
- if (irsb_IN->stmts[i]->tag == Ist_CAS)
+ if (irsb_IN->stmts->stmts[i]->tag == Ist_CAS)
has_CAS = True;
}
@@ -15478,7 +15476,7 @@
delta, archinfo, abiinfo, sigill_diag_IN );
for (i = x1; i < x2; i++) {
vex_printf("\t\t");
- ppIRStmt(irsb_IN->stmts[i]);
+ ppIRStmt(irsb_IN->stmts->stmts[i]);
vex_printf("\n");
}
/* Failure of this assertion is serious and denotes a bug in
Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Sat Mar 11 14:43:10 2017
@@ -1693,7 +1693,7 @@
for (UInt i = 0; i < env->types_used; i++) {
if (i % 8 == 0)
vex_printf( " ");
- IRTemp temp = {env->id, i};
+ IRTemp temp = mkIRTemp(env->id, i);
ppIRTemp(temp);
vex_printf("=");
ppIRType(env->types[i]);
@@ -3739,8 +3739,7 @@
if (env->types_used < env->types_size) {
env->types[env->types_used] = ty;
- IRTemp tmp = {env->id, env->types_used++};
- return tmp;
+ return mkIRTemp(env->id, env->types_used++);
} else {
Int i;
Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
@@ -5008,7 +5007,7 @@
/* Ensure each temp has a plausible type. */
for (UInt i = 0; i < n_temps; i++) {
- IRTemp temp = {id, i};
+ IRTemp temp = mkIRTemp(id, i);
IRType ty = typeOfIRTemp(tyenv, temp);
if (!isPlausibleIRType(ty)) {
vex_printf("Temp ");
Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Sat Mar 11 14:43:10 2017
@@ -3790,8 +3790,7 @@
HWord res;
/* env :: IRTemp -> IRTemp */
if (lookupHHW(env, &res, (HWord)tmp.index)) {
- IRTemp ret = {tmp.id, res};
- return ret;
+ return mkIRTemp(tmp.id, res);
} else {
return tmp;
}
Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Sat Mar 11 14:43:10 2017
@@ -413,7 +413,16 @@
}
IRTemp;
-#define IRTemp_INVALID {IRTyEnvID_INVALID, IRTyEnvIndex_INVALID}
+static inline IRTemp mkIRTemp(IRTyEnvID id, IRTyEnvIndex index)
+{
+ IRTemp tmp = {id, index};
+ return tmp;
+}
+
+static inline IRTemp IRTemp_INVALID(void)
+{
+ return mkIRTemp(IRTyEnvID_INVALID, IRTyEnvIndex_INVALID);
+}
/* Pretty-print an IRTemp. */
extern void ppIRTemp ( IRTemp );
|
Author: iraisr
Date: Sat Mar 11 14:07:07 2017
New Revision: 3310
Log:
First cut at introducing "if-then-else" control flow
into Valgrind's intermediate representation (IR).
Major rework done so far in modules: ir_defs.c and ir_opt.c.
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_inject.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/priv/main_main.c
branches/VEX_JIT_HACKS/priv/main_util.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
branches/VEX_JIT_HACKS/useful/test_main.c
Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Sat Mar 11 14:07:07 2017
@@ -33,6 +33,8 @@
without prior written permission.
*/
+/* Copyright (C) 2017-2017 Ivo Raisr <iv...@iv...> */
+
#include "libvex_basictypes.h"
#include "libvex_ir.h"
#include "libvex.h"
@@ -111,10 +113,10 @@
void ppIRTemp ( IRTemp tmp )
{
- if (tmp == IRTemp_INVALID)
+ if (isIRTempInvalid(tmp))
vex_printf("IRTemp_INVALID");
else
- vex_printf( "t%u", tmp);
+ vex_printf("t%u:%u", tmp.id, tmp.index);
}
void ppIROp ( IROp op )
@@ -1409,7 +1411,7 @@
void ppIRDirty ( const IRDirty* d )
{
Int i;
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
ppIRTemp(d->tmp);
vex_printf(" = ");
}
@@ -1451,7 +1453,7 @@
{
/* Print even structurally invalid constructions, as an aid to
debugging. */
- if (cas->oldHi != IRTemp_INVALID) {
+ if (!isIRTempInvalid(cas->oldHi)) {
ppIRTemp(cas->oldHi);
vex_printf(",");
}
@@ -1567,6 +1569,25 @@
}
}
+void ppIRPhi(const IRPhi* phi)
+{
+ ppIRTemp(phi->dst);
+ vex_printf(" = phi(");
+ ppIRTemp(phi->srcThen);
+ vex_printf(",");
+ ppIRTemp(phi->srcElse);
+ vex_printf(")");
+}
+
+void ppIRPhiVec(const IRPhiVec* phis)
+{
+ for (UInt i = 0; i < phis->phis_used; i++) {
+ vex_printf(" ");
+ ppIRPhi(phis->phis[i]);
+ vex_printf("\n");
+ }
+}
+
void ppIRStmt ( const IRStmt* s )
{
if (!s) {
@@ -1649,19 +1670,32 @@
ppIRJumpKind(s->Ist.Exit.jk);
vex_printf(" } ");
break;
- default:
+ case Ist_IfThenElse:
+ vex_printf("if (");
+ ppIRExpr(s->Ist.IfThenElse.cond);
+ vex_printf(") then {\n");
+ ppIRStmtVec(s->Ist.IfThenElse.then_leg); // TODO-JIT: indent properly
+ vex_printf("} else {\n");
+ ppIRStmtVec(s->Ist.IfThenElse.else_leg); // TODO-JIT: indent properly
+ vex_printf("}\n");
+ IRPhiVec* phi_nodes = s->Ist.IfThenElse.phi_nodes;
+ if (phi_nodes != NULL) {
+ ppIRPhiVec(phi_nodes);
+ }
+ break;
+ default:
vpanic("ppIRStmt");
}
}
void ppIRTypeEnv ( const IRTypeEnv* env )
{
- UInt i;
- for (i = 0; i < env->types_used; i++) {
+ for (UInt i = 0; i < env->types_used; i++) {
if (i % 8 == 0)
vex_printf( " ");
- ppIRTemp(i);
- vex_printf( ":");
+ IRTemp temp = {env->id, i};
+ ppIRTemp(temp);
+ vex_printf("=");
ppIRType(env->types[i]);
if (i % 8 == 7)
vex_printf( "\n");
@@ -1672,17 +1706,22 @@
vex_printf( "\n");
}
-void ppIRSB ( const IRSB* bb )
+/* TODO-JIT: account for indentation */
+void ppIRStmtVec(const IRStmtVec* stmts)
{
- Int i;
- vex_printf("IRSB {\n");
- ppIRTypeEnv(bb->tyenv);
+ ppIRTypeEnv(stmts->tyenv);
vex_printf("\n");
- for (i = 0; i < bb->stmts_used; i++) {
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
vex_printf( " ");
- ppIRStmt(bb->stmts[i]);
- vex_printf( "\n");
+ ppIRStmt(stmts->stmts[i]);
+ vex_printf("\n");
}
+}
+
+void ppIRSB ( const IRSB* bb )
+{
+ vex_printf("IRSB {\n");
+ ppIRStmtVec(bb->stmts);
vex_printf( " PUT(%d) = ", bb->offsIP );
ppIRExpr( bb->next );
vex_printf( "; exit-");
@@ -2056,15 +2095,16 @@
/* Constructors -- IRDirty */
IRDirty* emptyIRDirty ( void ) {
- IRDirty* d = LibVEX_Alloc_inline(sizeof(IRDirty));
- d->cee = NULL;
- d->guard = NULL;
- d->args = NULL;
- d->tmp = IRTemp_INVALID;
- d->mFx = Ifx_None;
- d->mAddr = NULL;
- d->mSize = 0;
- d->nFxState = 0;
+ IRDirty* d = LibVEX_Alloc_inline(sizeof(IRDirty));
+ d->cee = NULL;
+ d->guard = NULL;
+ d->args = NULL;
+ d->tmp.id = IRTyEnvID_INVALID;
+ d->tmp.index = IRTyEnvIndex_INVALID;
+ d->mFx = Ifx_None;
+ d->mAddr = NULL;
+ d->mSize = 0;
+ d->nFxState = 0;
return d;
}
@@ -2131,6 +2171,24 @@
/* Constructors -- IRStmt */
+IRPhi* mkIRPhi(IRTemp dst, IRTemp srcThen, IRTemp srcElse)
+{
+ IRPhi* phi = LibVEX_Alloc_inline(sizeof(IRPhi));
+ phi->dst = dst;
+ phi->srcThen = srcThen;
+ phi->srcElse = srcElse;
+ return phi;
+}
+
+IRPhiVec* emptyIRPhiVec(void)
+{
+ IRPhiVec* vec = LibVEX_Alloc_inline(sizeof(IRPhiVec));
+ vec->phis_used = 0;
+ vec->phis_size = 8;
+ vec->phis = LibVEX_Alloc_inline(vec->phis_size * sizeof(IRPhi*));
+ return vec;
+}
+
IRStmt* IRStmt_NoOp ( void )
{
/* Just use a single static closure. */
@@ -2239,6 +2297,18 @@
return s;
}
+IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRStmtVec* then_leg,
+ IRStmtVec* else_leg, IRPhiVec* phi_nodes)
+{
+ IRStmt* s = LibVEX_Alloc_inline(sizeof(IRStmt));
+ s->tag = Ist_IfThenElse;
+ s->Ist.IfThenElse.cond = cond;
+ s->Ist.IfThenElse.then_leg = then_leg;
+ s->Ist.IfThenElse.else_leg = else_leg;
+ s->Ist.IfThenElse.phi_nodes = phi_nodes;
+ return s;
+}
+
/* Constructors -- IRTypeEnv */
@@ -2248,31 +2318,54 @@
env->types = LibVEX_Alloc_inline(8 * sizeof(IRType));
env->types_size = 8;
env->types_used = 0;
+ env->id = IRTyEnvID_INVALID;
return env;
}
+/* Constructors -- IRStmtVec */
+
+IRStmtVec* emptyIRStmtVec(void)
+{
+ IRStmtVec* stmts = LibVEX_Alloc_inline(sizeof(IRStmtVec));
+ stmts->tyenv = emptyIRTypeEnv();
+ stmts->stmts_used = 0;
+ stmts->stmts_size = 8;
+ stmts->stmts = LibVEX_Alloc_inline(stmts->stmts_size * sizeof(IRStmt*));
+ stmts->parent = NULL;
+ return stmts;
+}
+
+
/* Constructors -- IRSB */
IRSB* emptyIRSB ( void )
{
- IRSB* bb = LibVEX_Alloc_inline(sizeof(IRSB));
- bb->tyenv = emptyIRTypeEnv();
- bb->stmts_used = 0;
- bb->stmts_size = 8;
- bb->stmts = LibVEX_Alloc_inline(bb->stmts_size * sizeof(IRStmt*));
- bb->next = NULL;
- bb->jumpkind = Ijk_Boring;
- bb->offsIP = 0;
+ IRSB* bb = LibVEX_Alloc_inline(sizeof(IRSB));
+ bb->stmts = emptyIRStmtVec();
+ bb->id_seq = 0;
+ bb->next = NULL;
+ bb->jumpkind = Ijk_Boring;
+ bb->offsIP = 0;
+
+ bb->stmts->tyenv->id = nextIRTyEnvID(bb);
return bb;
}
+IRTyEnvID nextIRTyEnvID(IRSB* irsb)
+{
+ IRTyEnvID next = irsb->id_seq;
+ irsb->id_seq += 1;
+ vassert(irsb->id_seq < IRTyEnvID_INVALID);
+ return next;
+}
-/*---------------------------------------------------------------*/
-/*--- (Deep) copy constructors. These make complete copies ---*/
-/*--- the original, which can be modified without affecting ---*/
-/*--- the original. ---*/
-/*---------------------------------------------------------------*/
+
+/*----------------------------------------------------------------*/
+/*--- (Deep) copy constructors. These make complete copies ---*/
+/*--- of the original, which can be modified without affecting ---*/
+/*--- the original. ---*/
+/*----------------------------------------------------------------*/
/* Copying IR Expr vectors (for call args). */
@@ -2437,7 +2530,27 @@
deepCopyIRExpr(puti->data));
}
-IRStmt* deepCopyIRStmt ( const IRStmt* s )
+IRPhi* deepCopyIRPhi(const IRPhi* phi)
+{
+ return mkIRPhi(phi->dst, phi->srcThen, phi->srcElse);
+}
+
+IRPhiVec* deepCopyIRPhiVec(const IRPhiVec* vec)
+{
+ if (vec == NULL) {
+ return NULL;
+ }
+
+ IRPhiVec* vec2 = LibVEX_Alloc_inline(sizeof(IRPhiVec));
+ vec2->phis_used = vec2->phis_size = vec->phis_used;
+ IRPhi **phis2 = LibVEX_Alloc_inline(vec2->phis_used * sizeof(IRPhi*));
+ for (UInt i = 0; i < vec2->phis_used; i++)
+ phis2[i] = deepCopyIRPhi(vec->phis[i]);
+ vec2->phis = phis2;
+ return vec2;
+}
+
+IRStmt* deepCopyIRStmt(const IRStmt* s, IRStmtVec* parent)
{
switch (s->tag) {
case Ist_NoOp:
@@ -2494,43 +2607,59 @@
s->Ist.Exit.jk,
deepCopyIRConst(s->Ist.Exit.dst),
s->Ist.Exit.offsIP);
+ case Ist_IfThenElse:
+ return IRStmt_IfThenElse(deepCopyIRExpr(s->Ist.IfThenElse.cond),
+ deepCopyIRStmtVec(s->Ist.IfThenElse.then_leg, parent),
+ deepCopyIRStmtVec(s->Ist.IfThenElse.else_leg, parent),
+ deepCopyIRPhiVec(s->Ist.IfThenElse.phi_nodes));
default:
vpanic("deepCopyIRStmt");
}
}
-IRTypeEnv* deepCopyIRTypeEnv ( const IRTypeEnv* src )
+IRStmtVec* deepCopyIRStmtVec(const IRStmtVec* src, IRStmtVec* parent)
{
- Int i;
- IRTypeEnv* dst = LibVEX_Alloc_inline(sizeof(IRTypeEnv));
+ IRStmtVec* vec2 = LibVEX_Alloc_inline(sizeof(IRStmtVec));
+ vec2->tyenv = deepCopyIRTypeEnv(src->tyenv);
+ vec2->parent = parent;
+ vec2->stmts_used = vec2->stmts_size = src->stmts_used;
+ IRStmt **stmts2 = LibVEX_Alloc_inline(vec2->stmts_used * sizeof(IRStmt*));
+ for (UInt i = 0; i < vec2->stmts_used; i++) {
+ stmts2[i] = deepCopyIRStmt(src->stmts[i], vec2);
+ }
+ vec2->stmts = stmts2;
+ return vec2;
+}
+
+IRTypeEnv* deepCopyIRTypeEnv(const IRTypeEnv* src)
+{
+ IRTypeEnv* dst = LibVEX_Alloc_inline(sizeof(IRTypeEnv));
dst->types_size = src->types_size;
dst->types_used = src->types_used;
- dst->types = LibVEX_Alloc_inline(dst->types_size * sizeof(IRType));
- for (i = 0; i < src->types_used; i++)
+ dst->types = LibVEX_Alloc_inline(dst->types_size * sizeof(IRType));
+ for (UInt i = 0; i < src->types_used; i++)
dst->types[i] = src->types[i];
+ dst->id = src->id;
return dst;
}
IRSB* deepCopyIRSB ( const IRSB* bb )
{
- Int i;
- IRStmt** sts2;
IRSB* bb2 = deepCopyIRSBExceptStmts(bb);
- bb2->stmts_used = bb2->stmts_size = bb->stmts_used;
- sts2 = LibVEX_Alloc_inline(bb2->stmts_used * sizeof(IRStmt*));
- for (i = 0; i < bb2->stmts_used; i++)
- sts2[i] = deepCopyIRStmt(bb->stmts[i]);
- bb2->stmts = sts2;
+ // TODO-JIT: does a deep copy of bb->stmts->tyenv once more
+ bb2->stmts = deepCopyIRStmtVec(bb->stmts, NULL);
return bb2;
}
IRSB* deepCopyIRSBExceptStmts ( const IRSB* bb )
{
- IRSB* bb2 = emptyIRSB();
- bb2->tyenv = deepCopyIRTypeEnv(bb->tyenv);
- bb2->next = deepCopyIRExpr(bb->next);
- bb2->jumpkind = bb->jumpkind;
- bb2->offsIP = bb->offsIP;
+ IRSB* bb2 = emptyIRSB();
+ bb2->stmts = emptyIRStmtVec();
+ bb2->stmts->tyenv = deepCopyIRTypeEnv(bb->stmts->tyenv);
+ bb2->id_seq = bb->id_seq;
+ bb2->next = deepCopyIRExpr(bb->next);
+ bb2->jumpkind = bb->jumpkind;
+ bb2->offsIP = bb->offsIP;
return bb2;
}
@@ -3543,22 +3672,54 @@
/*---------------------------------------------------------------*/
+/*--- Helper functions for the IR -- IR Phi Nodes ---*/
+/*---------------------------------------------------------------*/
+
+void addIRPhi(IRStmt* st, IRPhi* phi)
+{
+ vassert(st->tag == Ist_IfThenElse);
+
+ IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
+ if (phi_nodes == NULL) {
+ phi_nodes = emptyIRPhiVec();
+ st->Ist.IfThenElse.phi_nodes = phi_nodes;
+ }
+
+ if (phi_nodes->phis_used == phi_nodes->phis_size) {
+ IRPhi** phis2 = LibVEX_Alloc_inline(2 * phi_nodes->phis_size * sizeof(IRPhi*));
+ for (UInt i = 0; i < phi_nodes->phis_size; i++)
+ phis2[i] = phi_nodes->phis[i];
+ phi_nodes->phis = phis2;
+ phi_nodes->phis_size *= 2;
+ }
+
+ vassert(phi_nodes->phis_used < phi_nodes->phis_size);
+ phi_nodes->phis[phi_nodes->phis_used] = phi;
+ phi_nodes->phis_used += 1;
+}
+
+
+/*---------------------------------------------------------------*/
/*--- Helper functions for the IR -- IR Basic Blocks ---*/
/*---------------------------------------------------------------*/
+void addStmtToIRStmtVec(IRStmtVec* stmts, IRStmt* st)
+{
+ if (stmts->stmts_used == stmts->stmts_size) {
+ IRStmt** stmts2 = LibVEX_Alloc_inline(2 * stmts->stmts_size * sizeof(IRStmt*));
+ for (UInt i = 0; i < stmts->stmts_size; i++)
+ stmts2[i] = stmts->stmts[i];
+ stmts->stmts = stmts2;
+ stmts->stmts_size *= 2;
+ }
+ vassert(stmts->stmts_used < stmts->stmts_size);
+ stmts->stmts[stmts->stmts_used] = st;
+ stmts->stmts_used++;
+}
+
void addStmtToIRSB ( IRSB* bb, IRStmt* st )
{
- Int i;
- if (bb->stmts_used == bb->stmts_size) {
- IRStmt** stmts2 = LibVEX_Alloc_inline(2 * bb->stmts_size * sizeof(IRStmt*));
- for (i = 0; i < bb->stmts_size; i++)
- stmts2[i] = bb->stmts[i];
- bb->stmts = stmts2;
- bb->stmts_size *= 2;
- }
- vassert(bb->stmts_used < bb->stmts_size);
- bb->stmts[bb->stmts_used] = st;
- bb->stmts_used++;
+ addStmtToIRStmtVec(bb->stmts, st);
}
@@ -3574,9 +3735,12 @@
vassert(env->types_used >= 0);
vassert(env->types_size >= 0);
vassert(env->types_used <= env->types_size);
+ vassert(env->id != IRTyEnvID_INVALID);
+
if (env->types_used < env->types_size) {
env->types[env->types_used] = ty;
- return env->types_used++;
+ IRTemp tmp = {env->id, env->types_used++};
+ return tmp;
} else {
Int i;
Int new_size = env->types_size==0 ? 8 : 2*env->types_size;
@@ -3598,9 +3762,9 @@
inline
IRType typeOfIRTemp ( const IRTypeEnv* env, IRTemp tmp )
{
- vassert(tmp >= 0);
- vassert(tmp < env->types_used);
- return env->types[tmp];
+ vassert(tmp.index >= 0);
+ vassert(tmp.index < env->types_used);
+ return env->types[tmp.index];
}
IRType typeOfIRConst ( const IRConst* con )
@@ -3729,6 +3893,9 @@
return UNLIKELY(is_IRExpr_VECRET_or_GSPTR(e));
}
+static Bool isFlatIRStmtVec(const IRStmtVec* stmts);
+
+static
Bool isFlatIRStmt ( const IRStmt* st )
{
Int i;
@@ -3828,11 +3995,25 @@
return True;
case Ist_Exit:
return isIRAtom(st->Ist.Exit.guard);
+ case Ist_IfThenElse:
+ return isIRAtom(st->Ist.IfThenElse.cond)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.then_leg)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.else_leg);
default:
vpanic("isFlatIRStmt(st)");
}
}
+static
+Bool isFlatIRStmtVec(const IRStmtVec* stmts)
+{
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ if (!isFlatIRStmt(stmts->stmts[i]))
+ return False;
+ }
+
+ return True;
+}
/*---------------------------------------------------------------*/
/*--- Sanity checking ---*/
@@ -3845,6 +4026,10 @@
bit expression, depending on the guest's word size.
Each temp is assigned only once, before its uses.
+ Each temp is referenced from the right scope.
+
+ Phi functions refer to existing, already assigned temporaries from
+ [parent, then leg, else leg] type environments.
*/
static inline Int countArgs ( IRExpr** args )
@@ -3903,74 +4088,107 @@
}
}
-/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of
- range ones. Report any which are read and for which the current
- def_count is zero. */
+/* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of range or out
+ of scope ones. Report any which are read and for which the current
+ def_count is zero. Report any which are assigned more than once or assigned
+ after being used. */
+
+static Bool inRangeIRTemp(const IRStmtVec* stmts, IRTemp tmp)
+{
+ vassert(tmp.id != IRTyEnvID_INVALID);
+
+ if (tmp.index >= 0 || tmp.index < stmts->tyenv->types_used) {
+ return True;
+ }
+ return False;
+}
+
+static Bool inScopeIRTemp(const IRStmtVec* stmts, IRTemp tmp)
+{
+ vassert(tmp.id != IRTyEnvID_INVALID);
+
+ if (stmts->tyenv->id == tmp.id) {
+ return True;
+ }
+ if (stmts->parent != NULL) {
+ return inScopeIRTemp(stmts->parent, tmp);
+ }
+ return False;
+}
static
-void useBeforeDef_Temp ( const IRSB* bb, const IRStmt* stmt, IRTemp tmp,
- Int* def_counts )
+void useBeforeDef_Temp(const IRSB* bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, IRTemp tmp, UInt* def_counts[])
{
- if (tmp < 0 || tmp >= bb->tyenv->types_used)
- sanityCheckFail(bb,stmt, "out of range Temp in IRExpr");
- if (def_counts[tmp] < 1)
- sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr");
+ vassert(tmp.id != IRTyEnvID_INVALID);
+
+ if (!inRangeIRTemp(stmts, tmp))
+ sanityCheckFail(bb, stmt, "out of range Temp in IRExpr");
+ if (!inScopeIRTemp(stmts, tmp))
+ sanityCheckFail(bb, stmt, "out of scope Temp in IRExpr");
+ if (def_counts[tmp.id][tmp.index] < 1)
+ sanityCheckFail(bb, stmt, "IRTemp use before def in IRExpr");
}
static
-void assignedOnce_Temp(const IRSB *bb, const IRStmt *stmt, IRTemp tmp,
- Int *def_counts, UInt n_def_counts,
- const HChar *err_msg_out_of_range,
- const HChar *err_msg_assigned_more_than_once)
+void assignedOnce_Temp(const IRSB* bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, IRTemp tmp, UInt* def_counts[],
+ const HChar* err_msg_out_of_range,
+ const HChar* err_msg_out_of_scope,
+ const HChar* err_msg_assigned_more_than_once)
{
- if (tmp < 0 || tmp >= n_def_counts) {
+ vassert(tmp.id != IRTyEnvID_INVALID);
+
+ if (!inRangeIRTemp(stmts, tmp))
sanityCheckFail(bb, stmt, err_msg_out_of_range);
- }
+ if (!inScopeIRTemp(stmts, tmp))
+ sanityCheckFail(bb, stmt, err_msg_out_of_scope);
- def_counts[tmp]++;
- if (def_counts[tmp] > 1) {
- sanityCheckFail(bb, stmt, err_msg_assigned_more_than_once);
+ def_counts[tmp.id][tmp.index]++;
+ if (def_counts[tmp.id][tmp.index] > 1) {
+ sanityCheckFail(bb,stmt,err_msg_assigned_more_than_once);
}
}
static
-void useBeforeDef_Expr ( const IRSB* bb, const IRStmt* stmt,
- const IRExpr* expr, Int* def_counts )
+void useBeforeDef_Expr(const IRSB *bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, const IRExpr* expr,
+ UInt* def_counts[])
{
Int i;
switch (expr->tag) {
case Iex_Get:
break;
case Iex_GetI:
- useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.GetI.ix, def_counts);
break;
case Iex_RdTmp:
- useBeforeDef_Temp(bb,stmt,expr->Iex.RdTmp.tmp,def_counts);
+ useBeforeDef_Temp(bb, stmts, stmt, expr->Iex.RdTmp.tmp, def_counts);
break;
case Iex_Qop: {
const IRQop* qop = expr->Iex.Qop.details;
- useBeforeDef_Expr(bb,stmt,qop->arg1,def_counts);
- useBeforeDef_Expr(bb,stmt,qop->arg2,def_counts);
- useBeforeDef_Expr(bb,stmt,qop->arg3,def_counts);
- useBeforeDef_Expr(bb,stmt,qop->arg4,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, qop->arg1, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, qop->arg2, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, qop->arg3, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, qop->arg4, def_counts);
break;
}
case Iex_Triop: {
const IRTriop* triop = expr->Iex.Triop.details;
- useBeforeDef_Expr(bb,stmt,triop->arg1,def_counts);
- useBeforeDef_Expr(bb,stmt,triop->arg2,def_counts);
- useBeforeDef_Expr(bb,stmt,triop->arg3,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, triop->arg1, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, triop->arg2, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, triop->arg3, def_counts);
break;
}
case Iex_Binop:
- useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.Binop.arg1, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.Binop.arg2, def_counts);
break;
case Iex_Unop:
- useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.Unop.arg, def_counts);
break;
case Iex_Load:
- useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.Load.addr, def_counts);
break;
case Iex_Const:
break;
@@ -3981,16 +4199,17 @@
/* These aren't allowed in CCall lists. Let's detect
and throw them out here, though, rather than
segfaulting a bit later on. */
- sanityCheckFail(bb,stmt, "IRExprP__* value in CCall arg list");
+ sanityCheckFail(bb,stmt,
+ "IRExprP__* value in CCall arg list");
} else {
- useBeforeDef_Expr(bb,stmt,arg,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, arg, def_counts);
}
}
break;
case Iex_ITE:
- useBeforeDef_Expr(bb,stmt,expr->Iex.ITE.cond,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.ITE.iftrue,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.ITE.iffalse,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.ITE.cond, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.ITE.iftrue, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, expr->Iex.ITE.iffalse, def_counts);
break;
default:
vpanic("useBeforeDef_Expr");
@@ -3998,7 +4217,40 @@
}
static
-void useBeforeDef_Stmt ( const IRSB* bb, const IRStmt* stmt, Int* def_counts )
+void useBeforeDef_PhiNodes(const IRSB* bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, const IRPhiVec* phi_nodes,
+ UInt* def_counts[])
+{
+ vassert(stmt->tag == Ist_IfThenElse);
+
+ for (UInt i = 0; i < phi_nodes->phis_used; i++) {
+ const IRPhi* phi = phi_nodes->phis[i];
+ useBeforeDef_Temp(bb, stmts, stmt, phi->srcThen, def_counts);
+ useBeforeDef_Temp(bb, stmts, stmt, phi->srcElse, def_counts);
+
+ /* Check also that referenced IRStmtVec's actually exist and belong to
+ "parent", "then", and "else", respectively. */
+ if (phi->dst.id != stmts->tyenv->id) {
+ sanityCheckFail(bb,stmt,"Istmt.IfThenElse.Phi.dst does not "
+ "reference parent IRStmtVec");
+ }
+ if (phi->srcThen.id != stmt->Ist.IfThenElse.then_leg->tyenv->id) {
+ sanityCheckFail(bb,stmt,"Istmt.IfThenElse.Phi.srcThen does not "
+ "reference \"then\" IRStmtVec leg");
+ }
+ if (phi->srcElse.id != stmt->Ist.IfThenElse.else_leg->tyenv->id) {
+ sanityCheckFail(bb,stmt,"Istmt.IfThenElse.Phi.srcElse does not "
+ "reference \"else\" IRStmtVec leg");
+ }
+ }
+}
+
+static void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
+ UInt* def_counts[]);
+
+static
+void useBeforeDef_Stmt(const IRSB* bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, UInt* def_counts[])
{
Int i;
const IRDirty* d;
@@ -4010,50 +4262,51 @@
case Ist_IMark:
break;
case Ist_AbiHint:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
- useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.nia,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.AbiHint.base, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.AbiHint.nia, def_counts);
break;
case Ist_Put:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Put.data, def_counts);
break;
case Ist_PutI:
puti = stmt->Ist.PutI.details;
- useBeforeDef_Expr(bb,stmt,puti->ix,def_counts);
- useBeforeDef_Expr(bb,stmt,puti->data,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, puti->ix, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, puti->data, def_counts);
break;
case Ist_WrTmp:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.WrTmp.data,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.WrTmp.data, def_counts);
break;
case Ist_Store:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts);
- useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Store.addr, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Store.data, def_counts);
break;
case Ist_StoreG:
sg = stmt->Ist.StoreG.details;
- useBeforeDef_Expr(bb,stmt,sg->addr,def_counts);
- useBeforeDef_Expr(bb,stmt,sg->data,def_counts);
- useBeforeDef_Expr(bb,stmt,sg->guard,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, sg->addr, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, sg->data, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, sg->guard, def_counts);
break;
case Ist_LoadG:
lg = stmt->Ist.LoadG.details;
- useBeforeDef_Expr(bb,stmt,lg->addr,def_counts);
- useBeforeDef_Expr(bb,stmt,lg->alt,def_counts);
- useBeforeDef_Expr(bb,stmt,lg->guard,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, lg->addr, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, lg->alt, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, lg->guard, def_counts);
break;
case Ist_CAS:
cas = stmt->Ist.CAS.details;
- useBeforeDef_Expr(bb,stmt,cas->addr,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, cas->addr, def_counts);
if (cas->expdHi)
- useBeforeDef_Expr(bb,stmt,cas->expdHi,def_counts);
- useBeforeDef_Expr(bb,stmt,cas->expdLo,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, cas->expdHi, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, cas->expdLo, def_counts);
if (cas->dataHi)
- useBeforeDef_Expr(bb,stmt,cas->dataHi,def_counts);
- useBeforeDef_Expr(bb,stmt,cas->dataLo,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, cas->dataHi, def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, cas->dataLo, def_counts);
break;
case Ist_LLSC:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.addr,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.LLSC.addr, def_counts);
if (stmt->Ist.LLSC.storedata != NULL)
- useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.storedata,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.LLSC.storedata,
+ def_counts);
break;
case Ist_Dirty:
d = stmt->Ist.Dirty.details;
@@ -4063,17 +4316,27 @@
/* This is ensured by isFlatIRStmt */
;
} else {
- useBeforeDef_Expr(bb,stmt,arg,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, arg, def_counts);
}
}
if (d->mFx != Ifx_None)
- useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, d->mAddr, def_counts);
break;
case Ist_NoOp:
case Ist_MBE:
break;
case Ist_Exit:
- useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts);
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Exit.guard, def_counts);
+ break;
+ case Ist_IfThenElse:
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond,
+ def_counts);
+ useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
+ useBeforeDef_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ if (stmt->Ist.IfThenElse.phi_nodes != NULL) {
+ useBeforeDef_PhiNodes(bb, stmts, stmt,
+ stmt->Ist.IfThenElse.phi_nodes, def_counts);
+ }
break;
default:
vpanic("useBeforeDef_Stmt");
@@ -4081,48 +4344,81 @@
}
static
-void assignedOnce_Stmt(const IRSB *bb, const IRStmt *stmt,
- Int *def_counts, UInt n_def_counts)
+void useBeforeDef_Stmts(const IRSB* bb, const IRStmtVec* stmts,
+ UInt* def_counts[])
+{
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ useBeforeDef_Stmt(bb, stmts, stmts->stmts[i], def_counts);
+ }
+}
+
+static void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
+ UInt* def_counts[]);
+
+static
+void assignedOnce_Stmt(const IRSB* bb, const IRStmtVec* stmts,
+ const IRStmt* stmt, UInt* def_counts[])
{
switch (stmt->tag) {
case Ist_WrTmp:
assignedOnce_Temp(
- bb, stmt, stmt->Ist.WrTmp.tmp, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.WrTmp.tmp, def_counts,
"IRStmt.Tmp: destination tmp is out of range",
+ "IRStmt.Tmp: destination tmp is out of scope",
"IRStmt.Tmp: destination tmp is assigned more than once");
break;
case Ist_LoadG:
assignedOnce_Temp(
- bb, stmt, stmt->Ist.LoadG.details->dst, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.LoadG.details->dst, def_counts,
"IRStmt.LoadG: destination tmp is out of range",
+ "IRStmt.LoadG: destination tmp is out of scope",
"IRStmt.LoadG: destination tmp is assigned more than once");
break;
case Ist_Dirty:
- if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(stmt->Ist.Dirty.details->tmp)) {
assignedOnce_Temp(
- bb, stmt, stmt->Ist.Dirty.details->tmp, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.Dirty.details->tmp, def_counts,
"IRStmt.Dirty: destination tmp is out of range",
+ "IRStmt.Dirty: destination tmp is out of scope",
"IRStmt.Dirty: destination tmp is assigned more than once");
}
break;
case Ist_CAS:
- if (stmt->Ist.CAS.details->oldHi != IRTemp_INVALID) {
+ if (!isIRTempInvalid(stmt->Ist.CAS.details->oldHi)) {
assignedOnce_Temp(
- bb, stmt, stmt->Ist.CAS.details->oldHi, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.CAS.details->oldHi, def_counts,
"IRStmt.CAS: destination tmpHi is out of range",
+ "IRStmt.CAS: destination tmpHi is out of scope",
"IRStmt.CAS: destination tmpHi is assigned more than once");
}
assignedOnce_Temp(
- bb, stmt, stmt->Ist.CAS.details->oldLo, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.CAS.details->oldLo, def_counts,
"IRStmt.CAS: destination tmpLo is out of range",
+ "IRStmt.CAS: destination tmpLo is out of scope",
"IRStmt.CAS: destination tmpLo is assigned more than once");
break;
case Ist_LLSC:
assignedOnce_Temp(
- bb, stmt, stmt->Ist.LLSC.result, def_counts, n_def_counts,
+ bb, stmts, stmt, stmt->Ist.LLSC.result, def_counts,
"IRStmt.LLSC: destination tmp is out of range",
+ "IRStmt.LLSC: destination tmp is out of scope",
"IRStmt.LLSC: destination tmp is assigned more than once");
break;
+ case Ist_IfThenElse: {
+ assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.then_leg, def_counts);
+ assignedOnce_Stmts(bb, stmt->Ist.IfThenElse.else_leg, def_counts);
+ const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
+ if (phi_nodes != NULL) {
+ for (UInt i = 0; i < phi_nodes->phis_used; i++) {
+ assignedOnce_Temp(
+ bb, stmts, stmt, phi_nodes->phis[i]->dst, def_counts,
+ "IRStmt.IfThenElse.Phi: destination tmp is out of range",
+ "IRStmt.IfThenElse.Phi: destination tmp is out of scope",
+ "IRStmt.IfThenElse: destination tmp is assigned more than once");
+ }
+ }
+ break;
+ }
// Ignore all other cases
case Ist_NoOp: case Ist_IMark: case Ist_AbiHint: case Ist_Put: case Ist_PutI:
case Ist_Store: case Ist_StoreG: case Ist_MBE: case Ist_Exit:
@@ -4133,18 +4429,27 @@
}
static
-void tcExpr ( const IRSB* bb, const IRStmt* stmt, const IRExpr* expr,
- IRType gWordTy )
+void assignedOnce_Stmts(const IRSB* bb, const IRStmtVec* stmts,
+ UInt* def_counts[])
+{
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ assignedOnce_Stmt(bb, stmts, stmts->stmts[i], def_counts);
+ }
+}
+
+static
+void tcExpr(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
+ const IRExpr* expr, IRType gWordTy)
{
Int i;
IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4;
- const IRTypeEnv* tyenv = bb->tyenv;
+ const IRTypeEnv* tyenv = stmts->tyenv;
switch (expr->tag) {
case Iex_Get:
case Iex_RdTmp:
break;
case Iex_GetI:
- tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy );
+ tcExpr(bb, stmts, stmt, expr->Iex.GetI.ix, gWordTy);
if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32");
if (!saneIRRegArray(expr->Iex.GetI.descr))
@@ -4153,10 +4458,10 @@
case Iex_Qop: {
IRType ttarg1, ttarg2, ttarg3, ttarg4;
const IRQop* qop = expr->Iex.Qop.details;
- tcExpr(bb,stmt, qop->arg1, gWordTy );
- tcExpr(bb,stmt, qop->arg2, gWordTy );
- tcExpr(bb,stmt, qop->arg3, gWordTy );
- tcExpr(bb,stmt, qop->arg4, gWordTy );
+ tcExpr(bb, stmts, stmt, qop->arg1, gWordTy);
+ tcExpr(bb, stmts, stmt, qop->arg2, gWordTy);
+ tcExpr(bb, stmts, stmt, qop->arg3, gWordTy);
+ tcExpr(bb, stmts, stmt, qop->arg4, gWordTy);
typeOfPrimop(qop->op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
@@ -4205,9 +4510,9 @@
case Iex_Triop: {
IRType ttarg1, ttarg2, ttarg3;
const IRTriop *triop = expr->Iex.Triop.details;
- tcExpr(bb,stmt, triop->arg1, gWordTy );
- tcExpr(bb,stmt, triop->arg2, gWordTy );
- tcExpr(bb,stmt, triop->arg3, gWordTy );
+ tcExpr(bb, stmts, stmt, triop->arg1, gWordTy);
+ tcExpr(bb, stmts, stmt, triop->arg2, gWordTy);
+ tcExpr(bb, stmts, stmt, triop->arg3, gWordTy);
typeOfPrimop(triop->op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
@@ -4249,8 +4554,8 @@
}
case Iex_Binop: {
IRType ttarg1, ttarg2;
- tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
- tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
+ tcExpr(bb, stmts, stmt, expr->Iex.Binop.arg1, gWordTy);
+ tcExpr(bb, stmts, stmt, expr->Iex.Binop.arg2, gWordTy);
typeOfPrimop(expr->Iex.Binop.op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
@@ -4286,7 +4591,7 @@
break;
}
case Iex_Unop:
- tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
+ tcExpr(bb, stmts, stmt, expr->Iex.Unop.arg, gWordTy);
typeOfPrimop(expr->Iex.Unop.op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID
@@ -4296,7 +4601,7 @@
sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty");
break;
case Iex_Load:
- tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy);
+ tcExpr(bb, stmts, stmt, expr->Iex.Load.addr, gWordTy);
if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy)
sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type");
if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE)
@@ -4313,10 +4618,11 @@
IRExpr* arg = expr->Iex.CCall.args[i];
if (UNLIKELY(is_IRExpr_VECRET_or_GSPTR(arg)))
sanityCheckFail(bb,stmt,"Iex.CCall.args: is VECRET/GSPTR");
- tcExpr(bb,stmt, arg, gWordTy);
+ tcExpr(bb, stmts, stmt, arg, gWordTy);
}
if (expr->Iex.CCall.retty == Ity_I1)
- sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1");
+ sanityCheckFail(bb,stmt,
+ "Iex.CCall.retty: cannot return :: Ity_I1");
for (i = 0; expr->Iex.CCall.args[i]; i++)
if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1)
sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1");
@@ -4326,9 +4632,9 @@
sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const");
break;
case Iex_ITE:
- tcExpr(bb,stmt, expr->Iex.ITE.cond, gWordTy);
- tcExpr(bb,stmt, expr->Iex.ITE.iftrue, gWordTy);
- tcExpr(bb,stmt, expr->Iex.ITE.iffalse, gWordTy);
+ tcExpr(bb, stmts, stmt, expr->Iex.ITE.cond, gWordTy);
+ tcExpr(bb, stmts, stmt, expr->Iex.ITE.iftrue, gWordTy);
+ tcExpr(bb, stmts, stmt, expr->Iex.ITE.iffalse, gWordTy);
if (typeOfIRExpr(tyenv, expr->Iex.ITE.cond) != Ity_I1)
sanityCheckFail(bb,stmt,"Iex.ITE.cond: cond :: Ity_I1");
if (typeOfIRExpr(tyenv, expr->Iex.ITE.iftrue)
@@ -4340,13 +4646,30 @@
}
}
+static
+void tcPhi(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
+ const IRPhi* phi)
+{
+ const IRTypeEnv* tyenv = stmts->tyenv;
+ if (typeOfIRTemp(tyenv, phi->srcThen) != typeOfIRTemp(tyenv, phi->srcElse)) {
+ sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'then' and 'else' "
+ "tmp do not match");
+ }
+ if (typeOfIRTemp(tyenv, phi->dst) != typeOfIRTemp(tyenv, phi->srcThen)) {
+ sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.Phi: 'dst' and 'then' "
+ "tmp do not match");
+ }
+}
+
+static void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
+ IRType gWordTy);
static
-void tcStmt ( const IRSB* bb, const IRStmt* stmt, IRType gWordTy )
+void tcStmt(const IRSB* bb, const IRStmtVec* stmts, const IRStmt* stmt,
+ Bool require_flat, IRType gWordTy)
{
- Int i;
IRType tyExpd, tyData;
- const IRTypeEnv* tyenv = bb->tyenv;
+ const IRTypeEnv* tyenv = stmts->tyenv;
switch (stmt->tag) {
case Ist_IMark:
/* Somewhat heuristic, but rule out totally implausible
@@ -4365,18 +4688,18 @@
"not :: guest word type");
break;
case Ist_Put:
- tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
+ tcExpr(bb, stmts, stmt, stmt->Ist.Put.data, gWordTy);
if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1");
break;
case Ist_PutI:{
const IRPutI* puti = stmt->Ist.PutI.details;
- tcExpr( bb, stmt, puti->data, gWordTy );
- tcExpr( bb, stmt, puti->ix, gWordTy );
+ tcExpr(bb, stmts, stmt, puti->data, gWordTy);
+ tcExpr(bb, stmts, stmt, puti->ix, gWordTy);
if (typeOfIRExpr(tyenv,puti->data) == Ity_I1)
- sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1");
- if (typeOfIRExpr(tyenv,puti->data)
- != puti->descr->elemTy)
+ sanityCheckFail(bb,stmt,
+ "IRStmt.PutI.data: cannot PutI :: Ity_I1");
+ if (typeOfIRExpr(tyenv,puti->data) != puti->descr->elemTy)
sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty");
if (typeOfIRExpr(tyenv,puti->ix) != Ity_I32)
sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32");
@@ -4385,15 +4708,15 @@
break;
}
case Ist_WrTmp:
- tcExpr( bb, stmt, stmt->Ist.WrTmp.data, gWordTy );
+ tcExpr(bb, stmts, stmt, stmt->Ist.WrTmp.data, gWordTy);
if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp)
!= typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data))
sanityCheckFail(bb,stmt,
"IRStmt.Put.Tmp: tmp and expr do not match");
break;
case Ist_Store:
- tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy );
- tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy );
+ tcExpr(bb, stmts, stmt, stmt->Ist.Store.addr, gWordTy);
+ tcExpr(bb, stmts, stmt, stmt->Ist.Store.data, gWordTy);
if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy)
sanityCheckFail(bb,stmt,
"IRStmt.Store.addr: not :: guest word type");
@@ -4405,9 +4728,9 @@
break;
case Ist_StoreG: {
const IRStoreG* sg = stmt->Ist.StoreG.details;
- tcExpr( bb, stmt, sg->addr, gWordTy );
- tcExpr( bb, stmt, sg->data, gWordTy );
- tcExpr( bb, stmt, sg->guard, gWordTy );
+ tcExpr(bb, stmts, stmt, sg->addr, gWordTy);
+ tcExpr(bb, stmts, stmt, sg->data, gWordTy);
+ tcExpr(bb, stmts, stmt, sg->guard, gWordTy);
if (typeOfIRExpr(tyenv, sg->addr) != gWordTy)
sanityCheckFail(bb,stmt,"IRStmtG...addr: not :: guest word type");
if (typeOfIRExpr(tyenv, sg->data) == Ity_I1)
@@ -4420,9 +4743,9 @@
}
case Ist_LoadG: {
const IRLoadG* lg = stmt->Ist.LoadG.details;
- tcExpr( bb, stmt, lg->addr, gWordTy );
- tcExpr( bb, stmt, lg->alt, gWordTy );
- tcExpr( bb, stmt, lg->guard, gWordTy );
+ tcExpr(bb, stmts, stmt, lg->addr, gWordTy);
+ tcExpr(bb, stmts, stmt, lg->alt, gWordTy);
+ tcExpr(bb, stmts, stmt, lg->guard, gWordTy);
if (typeOfIRExpr(tyenv, lg->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.LoadG.guard: not :: Ity_I1");
if (typeOfIRExpr(tyenv, lg->addr) != gWordTy)
@@ -4439,12 +4762,12 @@
case Ist_CAS: {
const IRCAS* cas = stmt->Ist.CAS.details;
/* make sure it's definitely either a CAS or a DCAS */
- if (cas->oldHi == IRTemp_INVALID
+ if (isIRTempInvalid(cas->oldHi)
&& cas->expdHi == NULL && cas->dataHi == NULL) {
/* fine; it's a single cas */
}
else
- if (cas->oldHi != IRTemp_INVALID
+ if (!isIRTempInvalid(cas->oldHi)
&& cas->expdHi != NULL && cas->dataHi != NULL) {
/* fine; it's a double cas */
}
@@ -4453,7 +4776,7 @@
goto bad_cas;
}
/* check the address type */
- tcExpr( bb, stmt, cas->addr, gWordTy );
+ tcExpr(bb, stmts, stmt, cas->addr, gWordTy);
if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas;
/* check types on the {old,expd,data}Lo components agree */
tyExpd = typeOfIRExpr(tyenv, cas->expdLo);
@@ -4470,7 +4793,7 @@
}
/* If it's a DCAS, check types on the {old,expd,data}Hi
components too */
- if (cas->oldHi != IRTemp_INVALID) {
+ if (!isIRTempInvalid(cas->oldHi)) {
tyExpd = typeOfIRExpr(tyenv, cas->expdHi);
tyData = typeOfIRExpr(tyenv, cas->dataHi);
if (tyExpd != tyData) goto bad_cas;
@@ -4526,7 +4849,7 @@
}
if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE)
goto bad_dirty;
- for (i = 0; i < d->nFxState; i++) {
+ for (UInt i = 0; i < d->nFxState; i++) {
if (d->fxState[i].fx == Ifx_None) goto bad_dirty;
if (d->fxState[i].size <= 0) goto bad_dirty;
if (d->fxState[i].nRepeats == 0) {
@@ -4541,18 +4864,18 @@
}
/* check guard */
if (d->guard == NULL) goto bad_dirty;
- tcExpr( bb, stmt, d->guard, gWordTy );
+ tcExpr(bb, stmts, stmt, d->guard, gWordTy);
if (typeOfIRExpr(tyenv, d->guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1");
/* check types, minimally */
IRType retTy = Ity_INVALID;
- if (d->tmp != IRTemp_INVALID) {
+ if (!isIRTempInvalid(d->tmp)) {
retTy = typeOfIRTemp(tyenv, d->tmp);
if (retTy == Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1");
}
UInt nVECRETs = 0, nGSPTRs = 0;
- for (i = 0; d->args[i] != NULL; i++) {
+ for (UInt i = 0; d->args[i] != NULL; i++) {
if (i >= 32)
sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args");
const IRExpr* arg = d->args[i];
@@ -4611,7 +4934,7 @@
}
break;
case Ist_Exit:
- tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy );
+ tcExpr(bb, stmts, stmt, stmt->Ist.Exit.guard, gWordTy);
if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1");
if (!saneIRConst(stmt->Ist.Exit.dst))
@@ -4622,77 +4945,139 @@
if (stmt->Ist.Exit.offsIP < 16)
sanityCheckFail(bb,stmt,"IRStmt.Exit.offsIP: too low");
break;
+ case Ist_IfThenElse:
+ tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
+ if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
+ sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
+ tcStmts(bb, stmt->Ist.IfThenElse.then_leg, require_flat, gWordTy);
+ tcStmts(bb, stmt->Ist.IfThenElse.else_leg, require_flat, gWordTy);
+ const IRPhiVec* phi_nodes = stmt->Ist.IfThenElse.phi_nodes;
+ if (phi_nodes != NULL) {
+ for (UInt i = 0; i < phi_nodes->phis_used; i++) {
+ tcPhi(bb, stmts, stmt, phi_nodes->phis[i]);
+ }
+ }
+ break;
default:
vpanic("tcStmt");
}
}
-void sanityCheckIRSB ( const IRSB* bb, const HChar* caller,
- Bool require_flat, IRType guest_word_size )
+static
+void tcStmts(const IRSB* bb, const IRStmtVec* stmts, Bool require_flat,
+ IRType gWordTy)
{
- Int i;
- Int n_temps = bb->tyenv->types_used;
- Int* def_counts = LibVEX_Alloc_inline(n_temps * sizeof(Int));
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ tcStmt(bb, stmts, stmts->stmts[i], require_flat, gWordTy);
+ }
+}
- if (0)
- vex_printf("sanityCheck: %s\n", caller);
+static
+void sanityCheckIRStmtVec(const IRSB* bb, const IRStmtVec* stmts,
+ Bool require_flat, UInt* def_counts[],
+ UInt n_stmt_vecs, UInt id_counts[])
+{
+ const IRTypeEnv* tyenv = stmts->tyenv;
+ IRTyEnvID id = tyenv->id;
+ if (id == IRTyEnvID_INVALID) {
+ vpanic("sanityCheckIRStmtVec: invalid IRTypeEnv ID");
+ }
+
+ if (id >= n_stmt_vecs) {
+ vex_printf("IRTypeEnv's ID (%u) is larger than number of IRStmtVec's "
+ "(%u)\n", id, n_stmt_vecs);
+ sanityCheckFail(bb, NULL, "IRTypeEnv's ID larger than number of "
+ "IRStmtVec's");
+ }
- vassert(guest_word_size == Ity_I32
- || guest_word_size == Ity_I64);
+ id_counts[id] += 1;
+ if (id_counts[id] > 1) {
+ sanityCheckFail(bb, NULL, "the same IRTyEnv ID used more than once");
+ }
+
+ UInt n_temps = tyenv->types_used;
+ def_counts[id] = LibVEX_Alloc_inline(n_temps * sizeof(UInt));
+ for (UInt i = 0; i < n_temps; i++)
+ def_counts[id][i] = 0;
- if (bb->stmts_used < 0 || bb->stmts_size < 8
- || bb->stmts_used > bb->stmts_size)
- /* this BB is so strange we can't even print it */
- vpanic("sanityCheckIRSB: stmts array limits wierd");
+ if (stmts->stmts_used < 0 || stmts->stmts_size < 8
+ || stmts->stmts_used > stmts->stmts_size) {
+ /* this IRStmtVec is so strange we can't even print it */
+ vpanic("sanityCheckIRStmtVec: stmts array limits wierd");
+ }
/* Ensure each temp has a plausible type. */
- for (i = 0; i < n_temps; i++) {
- IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i);
+ for (UInt i = 0; i < n_temps; i++) {
+ IRTemp temp = {id, i};
+ IRType ty = typeOfIRTemp(tyenv, temp);
if (!isPlausibleIRType(ty)) {
- vex_printf("Temp t%d declared with implausible type 0x%x\n",
- i, (UInt)ty);
- sanityCheckFail(bb,NULL,"Temp declared with implausible type");
+ vex_printf("Temp ");
+ ppIRTemp(temp);
+ vex_printf(" declared with implausible type 0x%x\n", (UInt) ty);
+ sanityCheckFail(bb, NULL, "Temp declared with implausible type");
}
}
- const IRStmt* stmt;
-
/* Check for flatness, if required. */
if (require_flat) {
- for (i = 0; i < bb->stmts_used; i++) {
- stmt = bb->stmts[i];
- if (!stmt)
- sanityCheckFail(bb, stmt, "IRStmt: is NULL");
+ for (UInt i = 0; i < stmts->stmts_used; i++) {
+ const IRStmt *stmt = stmts->stmts[i];
+ if (stmt == NULL)
+ sanityCheckFail(bb,stmt,"IRStmt: is NULL");
if (!isFlatIRStmt(stmt))
- sanityCheckFail(bb, stmt, "IRStmt: is not flat");
+ sanityCheckFail(bb,stmt,"IRStmt: is not flat");
+ if (stmt->tag == Ist_IfThenElse) {
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.then_leg,
+ require_flat, def_counts, n_stmt_vecs, id_counts);
+ sanityCheckIRStmtVec(bb, stmt->Ist.IfThenElse.else_leg,
+ require_flat, def_counts, n_stmt_vecs, id_counts);
+ }
}
- if (!isIRAtom(bb->next))
- sanityCheckFail(bb, NULL, "bb->next is not an atom");
}
+}
+
+
+/* Sanity checks basic block of IR.
+ Also checks for IRTyEnvID uniqueness. */
+void sanityCheckIRSB(const IRSB* bb, const HChar* caller, Bool require_flat,
+ IRType gWordTy)
+{
+ UInt n_stmt_vecs = bb->id_seq;
+ UInt **def_counts = LibVEX_Alloc_inline(n_stmt_vecs * sizeof(UInt *));
+ UInt *id_counts = LibVEX_Alloc_inline(n_stmt_vecs * sizeof(UInt));
+ for (UInt i = 0; i < n_stmt_vecs; i++) {
+ def_counts[i] = NULL;
+ id_counts[i] = 0;
+ }
+
+ if (0)
+ vex_printf("sanityCheck: %s\n", caller);
+
+ vassert(gWordTy == Ity_I32 || gWordTy == Ity_I64);
+
+ sanityCheckIRStmtVec(bb, bb->stmts, require_flat, def_counts, n_stmt_vecs,
+ id_counts);
/* Count the defs of each temp. Only one def is allowed.
Also, check that each used temp has already been defd. */
+ useBeforeDef_Stmts(bb, bb->stmts, def_counts);
+ assignedOnce_Stmts(bb, bb->stmts, def_counts);
+ tcStmts(bb, bb->stmts, require_flat, gWordTy);
- for (i = 0; i < n_temps; i++)
- def_counts[i] = 0;
+ if (require_flat) {
+ if (!isIRAtom(bb->next)) {
+ sanityCheckFail(bb, NULL, "bb->next is not an atom");
+ }
+ }
- for (i = 0; i < bb->stmts_used; i++) {
- stmt = bb->stmts[i];
- /* Check any temps used by this statement. */
- useBeforeDef_Stmt(bb,stmt,def_counts);
-
- /* Now make note of any temps defd by this statement. */
- assignedOnce_Stmt(bb, stmt, def_counts, n_temps);
- }
-
- /* Typecheck everything. */
- for (i = 0; i < bb->stmts_used; i++)
- tcStmt(bb, bb->stmts[i], guest_word_size);
- if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
+ /* Typecheck also next destination. */
+ if (typeOfIRExpr(bb->stmts->tyenv, bb->next) != gWordTy) {
sanityCheckFail(bb, NULL, "bb->next field has wrong type");
+ }
/* because it would intersect with host_EvC_* */
- if (bb->offsIP < 16)
+ if (bb->offsIP < 16) {
sanityCheckFail(bb, NULL, "bb->offsIP: too low");
+ }
}
/*---------------------------------------------------------------*/
@@ -4805,7 +5190,7 @@
vassert(isIRAtom(a1));
vassert(isIRAtom(a2));
if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp)
- return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp);
+ return eqIRTemp(a1->Iex.RdTmp.tmp, a2->Iex.RdTmp.tmp);
if (a1->tag == Iex_Const && a2->tag == Iex_Const)
return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con);
return False;
Modified: branches/VEX_JIT_HACKS/priv/ir_inject.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_inject.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_inject.c Sat Mar 11 14:07:07 2017
@@ -43,7 +43,7 @@
#define binop(kind, a1, a2) IRExpr_Binop(kind, a1, a2)
#define triop(kind, a1, a2, a3) IRExpr_Triop(kind, a1, a2, a3)
#define qop(kind, a1, a2, a3, a4) IRExpr_Qop(kind, a1, a2, a3, a4)
-#define stmt(irsb, st) addStmtToIRSB(irsb, st)
+#define stmt(irsb, st) addStmtToIRStmtVec(irsb->stmts, st)
/* The IR Injection Control Block. vex_inject_ir will query its contents
@@ -125,13 +125,13 @@
static void
store_aux(IRSB *irsb, IREndness endian, IRExpr *addr, IRExpr *data)
{
- if (typeOfIRExpr(irsb->tyenv, data) == Ity_D64) {
+ if (typeOfIRExpr(irsb->stmts->tyenv, data) == Ity_D64) {
/* The insn selectors do not support writing a DFP value to memory.
So we need to fix it here by reinterpreting the DFP value as an
integer and storing that. */
data = unop(Iop_ReinterpD64asI64, data);
}
- if (typeOfIRExpr(irsb->tyenv, data) == Ity_I1) {
+ if (typeOfIRExpr(irsb->stmts->tyenv, data) == Ity_I1) {
/* We cannot store a single bit. So we store it in a 32-bit container.
See also load_aux. */
data = unop(Iop_1Uto32, data);
@@ -158,7 +158,7 @@
vpanic("invalid #bytes for address");
}
- IRType type = typeOfIRExpr(irsb->tyenv, data);
+ IRType type = typeOfIRExpr(irsb->stmts->tyenv, data);
vassert(type == Ity_I1 || sizeofIRType(type) <= 16);
@@ -188,7 +188,7 @@
/* Inject IR stmts depending on the data provided in the control
- block iricb. */
+ block iricb. IR statements are injected into main IRStmtVec with ID #0. */
void
vex_inject_ir(IRSB *irsb, IREndness endian)
{
@@ -310,11 +310,11 @@
if (0) {
vex_printf("BEGIN inject\n");
if (iricb.t_result == Ity_I1 || sizeofIRType(iricb.t_result) <= 8) {
- ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
+ ppIRStmt(irsb->stmts->stmts[irsb->stmts->stmts_used - 1]);
} else if (sizeofIRType(iricb.t_result) == 16) {
- ppIRStmt(irsb->stmts[irsb->stmts_used - 2]);
+ ppIRStmt(irsb->stmts->stmts[irsb->stmts->stmts_used - 2]);
vex_printf("\n");
- ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
+ ppIRStmt(irsb->stmts->stmts[irsb->stmts->stmts_used - 1]);
}
vex_printf("\nEND inject\n");
}
Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Sat Mar 11 14:07:07 2017
@@ -266,7 +266,7 @@
/* Non-critical helper, heuristic for reducing the number of tmp-tmp
copies made by flattening. If in doubt return False. */
-static Bool isFlat ( IRExpr* e )
+static Bool isFlat(const IRExpr* e)
{
if (e->tag == Iex_Get)
return True;
@@ -280,102 +280,102 @@
/* Flatten out 'ex' so it is atomic, returning a new expression with
the same value, after having appended extra IRTemp assignments to
- the end of 'bb'. */
+ the end of 'stmts'. */
-static IRExpr* flatten_Expr ( IRSB* bb, IRExpr* ex )
+static IRExpr* flatten_Expr(IRStmtVec* stmts, IRExpr* ex)
{
Int i;
IRExpr** newargs;
- IRType ty = typeOfIRExpr(bb->tyenv, ex);
+ IRTypeEnv* tyenv = stmts->tyenv;
+ IRType ty = typeOfIRExpr(tyenv, ex);
IRTemp t1;
switch (ex->tag) {
case Iex_GetI:
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_GetI(ex->Iex.GetI.descr,
- flatten_Expr(bb, ex->Iex.GetI.ix),
+ flatten_Expr(stmts, ex->Iex.GetI.ix),
ex->Iex.GetI.bias)));
return IRExpr_RdTmp(t1);
case Iex_Get:
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb,
- IRStmt_WrTmp(t1, ex));
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1, ex));
return IRExpr_RdTmp(t1);
case Iex_Qop: {
IRQop* qop = ex->Iex.Qop.details;
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Qop(qop->op,
- flatten_Expr(bb, qop->arg1),
- flatten_Expr(bb, qop->arg2),
- flatten_Expr(bb, qop->arg3),
- flatten_Expr(bb, qop->arg4))));
+ flatten_Expr(stmts, qop->arg1),
+ flatten_Expr(stmts, qop->arg2),
+ flatten_Expr(stmts, qop->arg3),
+ flatten_Expr(stmts, qop->arg4))));
return IRExpr_RdTmp(t1);
}
case Iex_Triop: {
IRTriop* triop = ex->Iex.Triop.details;
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Triop(triop->op,
- flatten_Expr(bb, triop->arg1),
- flatten_Expr(bb, triop->arg2),
- flatten_Expr(bb, triop->arg3))));
+ flatten_Expr(stmts, triop->arg1),
+ flatten_Expr(stmts, triop->arg2),
+ flatten_Expr(stmts, triop->arg3))));
return IRExpr_RdTmp(t1);
}
case Iex_Binop:
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Binop(ex->Iex.Binop.op,
- flatten_Expr(bb, ex->Iex.Binop.arg1),
- flatten_Expr(bb, ex->Iex.Binop.arg2))));
+ flatten_Expr(stmts, ex->Iex.Binop.arg1),
+ flatten_Expr(stmts, ex->Iex.Binop.arg2))));
return IRExpr_RdTmp(t1);
case Iex_Unop:
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Unop(ex->Iex.Unop.op,
- flatten_Expr(bb, ex->Iex.Unop.arg))));
+ flatten_Expr(stmts, ex->Iex.Unop.arg))));
return IRExpr_RdTmp(t1);
case Iex_Load:
- t1 = newIRTemp(bb->tyenv, ty);
- addStmtToIRSB(bb, IRStmt_WrTmp(t1,
+ t1 = newIRTemp(tyenv, ty);
+ addStmtToIRStmtVec(stmts, IRStmt_WrTmp(t1,
IRExpr_Load(ex->Iex.Load.end,
ex->Iex.Load.ty,
- flatten_Expr(bb, ex->Iex.Load.addr))));
+ flatten_Expr(stmts, ex->Iex.Load.addr))));
return IRExpr_RdTmp(t1);
case Iex_CCall:
newargs ...
[truncated message content] |
|
From: <sv...@va...> - 2017-03-11 13:59:35
|
Author: iraisr
Date: Sat Mar 11 13:59:28 2017
New Revision: 16265
Log:
Focus on x86 frontend and backend first
Modified:
branches/VALGRIND_JIT_HACKS/Makefile.vex.am
Modified: branches/VALGRIND_JIT_HACKS/Makefile.vex.am
==============================================================================
--- branches/VALGRIND_JIT_HACKS/Makefile.vex.am (original)
+++ branches/VALGRIND_JIT_HACKS/Makefile.vex.am Sat Mar 11 13:59:28 2017
@@ -130,20 +130,6 @@
priv/guest_generic_x87.c \
priv/guest_x86_helpers.c \
priv/guest_x86_toIR.c \
- priv/guest_amd64_helpers.c \
- priv/guest_amd64_toIR.c \
- priv/guest_ppc_helpers.c \
- priv/guest_ppc_toIR.c \
- priv/guest_arm_helpers.c \
- priv/guest_arm_toIR.c \
- priv/guest_arm64_helpers.c \
- priv/guest_arm64_toIR.c \
- priv/guest_s390_helpers.c \
- priv/guest_s390_toIR.c \
- priv/guest_mips_helpers.c \
- priv/guest_mips_toIR.c \
- priv/guest_tilegx_helpers.c \
- priv/guest_tilegx_toIR.c \
priv/host_generic_regs.c \
priv/host_generic_simd64.c \
priv/host_generic_simd128.c \
@@ -151,23 +137,7 @@
priv/host_generic_maddf.c \
priv/host_generic_reg_alloc2.c \
priv/host_x86_defs.c \
- priv/host_x86_isel.c \
- priv/host_amd64_defs.c \
- priv/host_amd64_isel.c \
- priv/host_ppc_defs.c \
- priv/host_ppc_isel.c \
- priv/host_arm_defs.c \
- priv/host_arm_isel.c \
- priv/host_arm64_defs.c \
- priv/host_arm64_isel.c \
- priv/host_s390_defs.c \
- priv/host_s390_isel.c \
- priv/s390_disasm.c \
- priv/host_mips_defs.c \
- priv/host_mips_isel.c \
- priv/host_tilegx_defs.c \
- priv/host_tilegx_isel.c \
- priv/tilegx_disasm.c
+ priv/host_x86_isel.c
LIBVEXMULTIARCH_SOURCES = priv/multiarch_main_main.c
|
|
From: <sv...@va...> - 2017-03-11 13:52:36
|
Author: iraisr
Date: Sat Mar 11 13:52:29 2017
New Revision: 16264
Log:
Swizzle VEX external to branches/VEX_JIT_HACKS
Modified:
branches/VALGRIND_JIT_HACKS/ (props changed)
|
|
From: <sv...@va...> - 2017-03-11 07:39:42
|
Author: iraisr
Date: Sat Mar 11 07:39:35 2017
New Revision: 3309
Log:
Create branches/VEX_JIT_HACKS as a copy of trunk r3308.
Added:
branches/VEX_JIT_HACKS/ (props changed)
- copied from r3308, trunk/
|
|
From: <sv...@va...> - 2017-03-11 07:38:17
|
Author: iraisr
Date: Sat Mar 11 07:38:08 2017
New Revision: 16263
Log:
Create branches/VALGRIND_JIT_HACKS as a copy of trunk r16262.
Added:
branches/VALGRIND_JIT_HACKS/ (props changed)
- copied from r16262, trunk/
|
|
From: <sv...@va...> - 2017-03-10 20:10:56
|
Author: carll
Date: Fri Mar 10 20:10:49 2017
New Revision: 16262
Log:
PowerPC: Fix incorrect register pair check for lxv, stxv, stxsd, stxssp, lxsd,
lxssp instructions
The lfdpx, stdpx, lfdp and stfdp instructions work on a register pair. The
register pair test must only be applied to these instructions in the
dis_fp_pair() function.
Updating NEWS file for the commit
VEX commit 3308 makes the fix in VEX/priv/guest_ppc_toIR.c
bugzilla 377427
Modified:
trunk/NEWS
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Mar 10 20:10:49 2017
@@ -138,6 +138,7 @@
376611 ppc64 and arm64 don't know about prlimit64 syscall
376729 PPC64, remove R2 from the clobber list
== 371668
+377427 PPC64, lxv instruction failing on odd destination register
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
From: <sv...@va...> - 2017-03-10 20:07:22
|
Author: carll
Date: Fri Mar 10 20:07:09 2017
New Revision: 3308
Log:
PowerPC: Fix incorrect register pair check for lxv, stxv, stxsd, stxssp, lxsd,
lxssp instructions
The lfdpx, stdpx, lfdp and stfdp instructions work on a register pair. The
register pair test must only be applied to these instructions in the
dis_fp_pair() function.
bugzilla 377427
Modified:
trunk/priv/guest_ppc_toIR.c
Modified: trunk/priv/guest_ppc_toIR.c
==============================================================================
--- trunk/priv/guest_ppc_toIR.c (original)
+++ trunk/priv/guest_ppc_toIR.c Fri Mar 10 20:07:09 2017
@@ -11310,13 +11310,16 @@
UChar b0 = ifieldBIT0(theInstr);
Bool is_load = 0;
- if ((frT_hi_addr %2) != 0) {
- vex_printf("dis_fp_pair(ppc) : odd frT register\n");
- return False;
- }
-
switch (opc1) {
case 0x1F: // register offset
+ /* These instructions work on a pair of registers. The specified
+ * register must be even.
+ */
+ if ((frT_hi_addr %2) != 0) {
+ vex_printf("dis_fp_pair(ppc) ldpx or stdpx: odd frT register\n");
+ return False;
+ }
+
switch(opc2) {
case 0x317: // lfdpx (FP Load Double Pair X-form, ISA 2.05 p125)
DIP("ldpx fr%u,r%u,r%u\n", frT_hi_addr, rA_addr, rB_addr);
@@ -11346,6 +11349,14 @@
switch(opc2) {
case 0x0: // lfdp (FP Load Double Pair DS-form, ISA 2.05 p125)
+ /* This instruction works on a pair of registers. The specified
+ * register must be even.
+ */
+ if ((frT_hi_addr %2) != 0) {
+ vex_printf("dis_fp_pair(ppc) lfdp : odd frT register\n");
+ return False;
+ }
+
DIP("lfdp fr%u,%d(r%u)\n", frT_hi_addr, simm16, rA_addr);
assign( EA_hi, ea_rAor0_simm( rA_addr, simm16 ) );
is_load = 1;
@@ -11390,6 +11401,14 @@
switch(opc2) {
case 0x0:
// stfdp (FP Store Double Pair DS-form, ISA 2.05 p125)
+ /* This instruction works on a pair of registers. The specified
+ * register must be even.
+ */
+ if ((frT_hi_addr %2) != 0) {
+ vex_printf("dis_fp_pair(ppc) stfdp : odd frT register\n");
+ return False;
+ }
+
DIP("stfdp fr%u,%d(r%u)\n", frT_hi_addr, simm16, rA_addr);
assign( EA_hi, ea_rAor0_simm( rA_addr, simm16 ) );
break;
|
|
From: <sv...@va...> - 2017-03-08 16:30:26
|
Author: petarj
Date: Wed Mar 8 16:30:19 2017
New Revision: 16261
Log:
mips: do not unmap vDSO
vDSO cannot be unmaped for mips architecture because there is no
support for custom signal restorer since kernel 2.5.
It should fix KDE Bug #376142.
Patch by Tamara Vlahovic.
Modified:
trunk/coregrind/m_initimg/initimg-linux.c
Modified: trunk/coregrind/m_initimg/initimg-linux.c
==============================================================================
--- trunk/coregrind/m_initimg/initimg-linux.c (original)
+++ trunk/coregrind/m_initimg/initimg-linux.c Wed Mar 8 16:30:19 2017
@@ -789,7 +789,8 @@
break;
# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) \
- && !defined(VGP_ppc64le_linux)
+ && !defined(VGP_ppc64le_linux) \
+ && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux)
case AT_SYSINFO_EHDR: {
/* Trash this, because we don't reproduce it */
const NSegment* ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr);
|
|
From: <sv...@va...> - 2017-03-06 20:04:33
|
Author: sewardj
Date: Mon Mar 6 20:04:24 2017
New Revision: 16260
Log:
Finished importing new bugs and made a first pass through all of them.
Modified:
trunk/NEWS
trunk/docs/internals/3_12_BUGSTATUS.txt
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Mar 6 20:04:24 2017
@@ -123,6 +123,7 @@
372600 process loops forever when fatal signals are arriving quickly
372794 LibVEX (arm32 front end): 'Assertion szBlg2 <= 3' failed
373046 Stacks registered by core are never deregistered
+373069 memcheck/tests/leak_cpp_interior fails with GCC 5.1+
373192 Calling posix_spawn in glibc 2.24 completely broken
373488 Support for fanotify API on ARM64 architecture
== 368864 WARNING: unhandled arm64-linux syscall: 262 (fanotify_init)
Modified: trunk/docs/internals/3_12_BUGSTATUS.txt
==============================================================================
--- trunk/docs/internals/3_12_BUGSTATUS.txt (original)
+++ trunk/docs/internals/3_12_BUGSTATUS.txt Mon Mar 6 20:04:24 2017
@@ -432,47 +432,35 @@
372779 valgrind will hang
372828 vex amd64->IR: 0x66 0x4D 0xF 0x38 0xF6 0xD2 0x66 0x4D
372861 Test pselect_alarm for Bug 359871 seg faults on RHEL 4
---Q
Fri 25 Nov 11:47:59 CET 2016
-372909] New: glibc 2.23+ fopen/printf change causes valgrind to report 1024
-byte allocation
-373046] New: Stacks registered by core are never deregistered
-373069] New: memcheck/tests/leak_cpp_interior fails with GCC 5.1+
-373166] New: drd and helgrind will crash wth vex amd64->IR: unhandled instruction bytes 0xFF 0xFF 0x48 0x85 0xC0 0x74 0x8 0x4D 0x89 0xE7
-373176] New: Invalid stack trace
-373192] New: Calling posix_spawn completely broken
-373488] New: Support for fanotify API on ARM64 architecture
-373555] New: rename BBPTR to GSPTR as it denotes guest state only
-373938] New: const IRExpr arguments to matchIRExpr()
-373990] New: Potential shift left overflow in guest_arm_toIR.c
-374482] New: the 'impossible' happened: run_innerloop detected host state invariant failure
-374719] New: some spelling fixes
-374814] New: VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
-374850] New: The Impossible Happened
-374940] New: i386: Stack access at -1(%%esp)
-374963] New: increase valgrind's load address to prevent mmap failure
-375008] New: amd64->IR: unhandled instruction bytes: 0x8F 0x6A 0x78 0x10 0xD8 0x4 0x4 0x0 0x0 0x8F
-375150] New: Assertion 'tres.status == VexTransOK' failed - Ubuntu, Mint, and Fedora (OS tested so far)
-375171] New: Crash when running "hello world"
-375415] New: free list of blocks, mempool blocks and describe addr do not work properly together
-375514] New: valgrind_get_tls_addr() does not work in case of static TLS
-375772] New: +1 error in get_elf_symbol_info() when computing value of 'hi' address for ML_(find_rx_mapping)
-375839] New: Temporary storage exhusted , when long sequence of vfmadd231ps instructions to be executed
-375845] New: Unrecognised instruction using std::random_device
-376257] New: helgrind history full speed up using a cached stack
-376455] New: Solaris 11.3 : unhandled syscall meminfo() : 180
- 376611] New: ppc64 and arm64 don't know about prlimit64 syscall
- 376729] New: PPC64, remove R2 from the clobber list
-376869] New: unhandled syscall: 531
-376870] New: The impossible happened on Mavericks 10.9
-376956] New: Memcheck crashes on access(NULL, F_OK) done by Free Pascal application
-377006] New: valgrind/memcheck segfaults under certain kernel versions (amd64) but not others.
-377066] New: Some Valgrind unit tests fail to compile on Ubuntu 16.10 with PIE enabled by default
-377159] New: "vex: the `impossible' happened" still present
+
+373166 vex amd64->IR: 0xFF 0xFF 0x48 0x85 0xC0 0x74 0x8 0x4D 0x89 0xE7
+373990 Potential shift left overflow in guest_arm_toIR.c
+375171 VG_(scheduler): run_innerloop detected host state invariant failure
+ == 374482
+ == 374850
+374719 some spelling fixes
+374814 VALGRIND INTERNAL ERROR: signal 11 (SIGSEGV) - exiting
+374963 increase valgrind's load address to prevent mmap failure
+375008 amd64->IR: 0x8F 0x6A 0x78 0x10 0xD8 0x4 0x4 0x0 0x0 0x8F
+375415 free list of blocks, mempool blocks and describe addr
+ do not work properly together
+375839 Temporary storage exhausted, with long sequence of vfmadd231ps insns
+ == 377159 "vex: the `impossible' happened" still present
+ == 375150 Assertion 'tres.status == VexTransOK' failed
+376257 helgrind history full speed up using a cached stack
+376870 The impossible happened on Mavericks 10.9
+376956 Memcheck crashes on access(NULL, F_OK) done by Free Pascal application
+377006 valgrind/memcheck segfaults under certain kernel versions (amd64)
+ but not others.
+377066 Some Valgrind unit tests fail to compile on Ubuntu 16.10 with
+ PIE enabled by default
other stuff to fix: annoying duplicate brk() message
+Mon 6 Mar 21:02:39 CET 2017
+
========================================================================
========================================================================
@@ -710,5 +698,7 @@
16258 Fix two safe_to_deref/sizeof mismatches in
sys_sigaction/sys_rt_sigaction.
+Mon 6 Mar 21:02:39 CET 2017
+
========================================================================
========================================================================
|
|
From: <sv...@va...> - 2017-03-06 14:50:47
|
Author: sewardj
Date: Mon Mar 6 14:50:38 2017
New Revision: 16259
Log:
Update. Slowly working through huge bug backlog.
Modified:
trunk/NEWS
trunk/docs/internals/3_12_BUGSTATUS.txt
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Mar 6 14:50:38 2017
@@ -95,6 +95,7 @@
162848 --log-file output isn't split when a program forks
342040 Valgrind mishandles clone with CLONE_VFORK | CLONE_VM that clones
to a different stack.
+344139 x86 stack-seg overrides, needed by the Wine people
348616 Wine/valgrind: noted but unhandled ioctl 0x5390 [..] (DVD_READ_STRUCT)
352395 Please provide SVN revision info in --version -v
352767 Wine/valgrind: noted but unhandled ioctl 0x5307 [..] (CDROMSTOP)
@@ -112,11 +113,15 @@
370635 arm64 missing syscall getcpu
371225 Fix order of timer_{gettime,getoverrun,settime} syscalls on arm64
371412 Rename wrap_sys_shmat to sys_shmat like other wrappers
+371471 Valgrind complains about non legit memory leaks on placement new (C++)
371869 support '%' in symbol Z-encoding
371916 execution tree xtree concept
372120 c++ demangler demangles symbols which are not c++
+372185 Support of valgrind on ARMv8 with 32 bit executable
+372195 Power PC, xxsel instruction is not always recognized.
372504 Hanging on exit_group
372600 process loops forever when fatal signals are arriving quickly
+372794 LibVEX (arm32 front end): 'Assertion szBlg2 <= 3' failed
373046 Stacks registered by core are never deregistered
373192 Calling posix_spawn in glibc 2.24 completely broken
373488 Support for fanotify API on ARM64 architecture
@@ -131,6 +136,7 @@
376518 Solaris: unhandled fast trap getlgrp(6)
376611 ppc64 and arm64 don't know about prlimit64 syscall
376729 PPC64, remove R2 from the clobber list
+ == 371668
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/docs/internals/3_12_BUGSTATUS.txt
==============================================================================
--- trunk/docs/internals/3_12_BUGSTATUS.txt (original)
+++ trunk/docs/internals/3_12_BUGSTATUS.txt Mon Mar 6 14:50:38 2017
@@ -365,26 +365,17 @@
Thu 15 Sep 12:55:21 CEST 2016
-368863 WARNING: unhandled arm64-linux syscall: 100
-368864 WARNING: unhandled arm64-linux syscall: 262
-368865 WARNING: unhandled arm64-linux syscall: 272
-368866 WARNING: unhandled arm64-linux syscall: 238
+368866 WARNING: unhandled arm64-linux syscall: 238 (migrate_pages)
368868 disInstr(arm64): unhandled instruction 0xD53BE000 = cntfrq_el0 (ARMv8)
(should fix this for 3.12.1)
368873 Please add FreeBSD to supported OS list
368913 WARNING: unhandled arm64-linux syscall: 117
368914 WARNING: unhandled arm64-linux syscall: 142
368916 WARNING: unhandled arm64-linux syscall: 234
-368917 WARNING: unhandled arm64-linux syscall: 218
-368918 WARNING: unhandled arm64-linux syscall: 127
368919 WARNING: unhandled arm64-linux syscall: 274
368920 WARNING: unhandled arm64-linux syscall: 275
368921 WARNING: unhandled arm64-linux syscall: 162
-368922 WARNING: unhandled arm64-linux syscall: 161
368923 WARNING: unhandled arm64-linux syscall: 268
-368924 WARNING: unhandled arm64-linux syscall: 84
-368925 WARNING: unhandled arm64-linux syscall: 130
-368926 WARNING: unhandled arm64-linux syscall: 97
368960 WARNING: unhandled amd64-linux syscall: 163
369026 WARNING: unhandled amd64-linux syscall: 169
369027 WARNING: unhandled amd64-linux syscall: 216 (remap_file_pages)
@@ -416,48 +407,69 @@
370635 arm64 missing syscall getcpu
(should fix this for 3.12.1)
-371065 www: add CfP for FOSDEM 2017 in valgrind.org NEWS section
-
Wed 19 Oct 17:07:42 CEST 2016
-371128 BCD add and subtract insns on Power BE in 32-bit mode do not work.
-371225 Fix order of timer_{gettime,getoverrun,settime} syscalls on arm64
371227 Clean AArch64 syscall table
371396 helgrind and drd pth_cond_destroy_busy testcase hang with
- new glibc cond var implementation
-! 344139 x86 stack-seg overrides, needed by the Wine people
+ new glibc cond var implementation (workaround committed as 16097)
371411 Unify fstat64/fstatat64 wrappers
371439 Get coredump working on arm64
-371471 Valgrind complains about non legit memory leaks on placement new (C++)
371491 handleAddrOverrides() is truncating the segment base address when
- ASO prefix is used
+ ASO prefix is used (EASY FIX)
371503 disInstr(arm64): unhandled instruction 0xF89F0000
-371668 ppc64 clobbering of R2 is invalid.
-371770 Memleak trace back for overwritten or freed memory pointers
-371869 support '%' in symbol Z-encodin
-371916 execution tree xtree concept
+371770 Memleak trace back for overwritten or freed memory pointers (WISHLIST)
+371916 execution tree xtree concept (SHOULD BE CLOSED?)
371966 No uninitialised values reported with PGI -Mstack_arrays
371989 PCMPISTRM $0x72 validity bit propagation is imprecise
-372120 c++ demangler demangles symbols which are not c++
372182 Support more languages/demangling styles than just C++ (and Rust)
-372185 Support of valgrind on ARMv8 with 32 bit executable
-372188 vex amd64->IR: 0x66 0xF 0x3A 0x62 0x4A 0x10 0x10 0x48 0x83 0xC2
-372195 Power PC, xxsel instruction is not always recognized.
-372358 vex amd64->IR: 0xC5 0xFA 0x7F 0x45 0x80 0xC5 0xFA 0x7F 0x4D 0x90
-372504 Hanging on exit_group
+372188 vex amd64->IR: 0x66 0xF 0x3A 0x62 0x4A 0x10 0x10 0x48 (PCMPxSTRx $0x10)
372513 WARNING: unhandled ppc64be-linux syscall: 251
-372600 process loops forever when fatal signals are arriving quickly
Mon 21 Nov 13:13:47 CET 2016
n-i-bz major perf problems w/ stack registration + stack recycling
372772 Brew doesn't allow for Valgrind 3.12.0 installation on Sierra OSX
372779 valgrind will hang
-372794 LibVEX (arm32 front end): 'Assertion szBlg2 <= 3' failed
372828 vex amd64->IR: 0x66 0x4D 0xF 0x38 0xF6 0xD2 0x66 0x4D
372861 Test pselect_alarm for Bug 359871 seg faults on RHEL 4
+--Q
Fri 25 Nov 11:47:59 CET 2016
+372909] New: glibc 2.23+ fopen/printf change causes valgrind to report 1024
+byte allocation
+373046] New: Stacks registered by core are never deregistered
+373069] New: memcheck/tests/leak_cpp_interior fails with GCC 5.1+
+373166] New: drd and helgrind will crash wth vex amd64->IR: unhandled instruction bytes 0xFF 0xFF 0x48 0x85 0xC0 0x74 0x8 0x4D 0x89 0xE7
+373176] New: Invalid stack trace
+373192] New: Calling posix_spawn completely broken
+373488] New: Support for fanotify API on ARM64 architecture
+373555] New: rename BBPTR to GSPTR as it denotes guest state only
+373938] New: const IRExpr arguments to matchIRExpr()
+373990] New: Potential shift left overflow in guest_arm_toIR.c
+374482] New: the 'impossible' happened: run_innerloop detected host state invariant failure
+374719] New: some spelling fixes
+374814] New: VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
+374850] New: The Impossible Happened
+374940] New: i386: Stack access at -1(%%esp)
+374963] New: increase valgrind's load address to prevent mmap failure
+375008] New: amd64->IR: unhandled instruction bytes: 0x8F 0x6A 0x78 0x10 0xD8 0x4 0x4 0x0 0x0 0x8F
+375150] New: Assertion 'tres.status == VexTransOK' failed - Ubuntu, Mint, and Fedora (OS tested so far)
+375171] New: Crash when running "hello world"
+375415] New: free list of blocks, mempool blocks and describe addr do not work properly together
+375514] New: valgrind_get_tls_addr() does not work in case of static TLS
+375772] New: +1 error in get_elf_symbol_info() when computing value of 'hi' address for ML_(find_rx_mapping)
+375839] New: Temporary storage exhusted , when long sequence of vfmadd231ps instructions to be executed
+375845] New: Unrecognised instruction using std::random_device
+376257] New: helgrind history full speed up using a cached stack
+376455] New: Solaris 11.3 : unhandled syscall meminfo() : 180
+ 376611] New: ppc64 and arm64 don't know about prlimit64 syscall
+ 376729] New: PPC64, remove R2 from the clobber list
+376869] New: unhandled syscall: 531
+376870] New: The impossible happened on Mavericks 10.9
+376956] New: Memcheck crashes on access(NULL, F_OK) done by Free Pascal application
+377006] New: valgrind/memcheck segfaults under certain kernel versions (amd64) but not others.
+377066] New: Some Valgrind unit tests fail to compile on Ubuntu 16.10 with PIE enabled by default
+377159] New: "vex: the `impossible' happened" still present
other stuff to fix: annoying duplicate brk() message
@@ -539,5 +551,164 @@
Fri 25 Nov 12:30:15 CET 2016
+16156 include/valgrind.h: Fix spelling in a source code comment
+16157 Ensure the 'too early msg to use vgdb stop at valgrind abnormal exit' is produced
+16158 Addition of helgrind client request VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN
+* 16159 Fix 373046 - Stacks registered by core are never deregistered
+16160 Use NULL_STK_ID consistently throughout whole Valgrind.
+16161 Fix compiler warning on Solaris.
+? 16162 mips32: fix fadvise64 system call
+? 16163 mips64: fix fadvise64 syscall wrappers
+16164 352395 - Please provide SVN revision info in --version -v
+16165 Update NEWS for the fixing of 358213 helgrind/drd bar_bad
+? 16166 mips: fix call_on_new_stack_0_1 code
+16167 Small optimisation: no need to have a syscall wrapper unless collect systime is yes
+? 16168 Stacks registered by core are never deregistered (macOS-specific follow-up). Refer r16159.
+
+16169 Fix typo in syswrap-darwin log output. n-i-bz.
+16170 Update SVN ignore propset for include/vgversion.h. n-i-bz.
+16171 Update SVN ignore propset for tests/libc_test. n-i-bz. Refer r16097.
+16172 mips: implement CLEAR_CALLER_SAVED_REGS for memcheck tests
+
+16173Add CLEAR_CALLER_SAVED_REGS in leak-tree test
+16174Remove second definition of typedef âTimeâ
+16175mips: add regression test for fadvise64
+
+16176Some housekeeping related to recent r16175.
+16177Adjust line number in mcblocklistsearch.stderrB.exp.
+
+16178mips: add fadvise64 to svn ignore list
+16179Update memcheck/tests/amd64-linux ignore list
+16180 mips: fix VG_(gdbserver_report_signal) arguments (dep 15248)
+16181 mips32: allow execution of round_fpu64 test for fpxx
+
+16182 mips32: minor style change to r16181
+3286 missingmips: small changes in VexGuestMIPS{32|64}State structs
+3287 Rename BBPTR to GSPTR as it denotes guest state pointer only
+16183mips64: add cvm_atomic.stdout.exp-BE
+16184Add placeholders for all new macOS 10.12 syscalls. Related to bz#365327.
+16185Add placeholders for all new OS X 10.11 syscalls. Related to bz#348909.
+
+16186Fix 342040 Valgrind mishandles clone with CLONE_VFORK | CLONE_VM that clones to a different stack
+Fix 373192 Calling posix_spawn in glibc 2.24 completely broken
+
+16187Add missing EXTRA_DIST clonev.stdout.exp
+
+16188mips: remove some old cruft from clone functions
+16189Rename BBPTR to GSPTR as it denotes guest state pointer only
+Fixes BZ#373555.
+16190mips: fix "cast-equal" warnings in coredump-elf.cRelated BZ#370028
+16191Update NEWS for recent VEX commit r3288.
+16192 Add Solaris specific notes on running regression tests
+16193 xtree: minor updates to documentation, comments and indentation, no functional change.
+3288 missingconst IRExpr arguments for matchIRExpr()BZ#373938
+* 3289 Fix assertion failure in decode_V8_instruction. Fixes #372794.
+--
+16194 Add test cases for 32-bit v8 FP and SIMD insns.
+16195 xtree: CALLED_FLF must be called only up to ips[0] + minor doc update
+16196 missingAdd a format marker to callgrind files
+16197 Fix comments in m_trampoline.S for amd64/Solaris redirs.
+16198 Make this compile for both ARM and Thumb encodings,
+16199 Do not capture the free stacktrace in memcheck, ..
+3290 Implement ARMv8 VSEL<c>.F64 d_d_d, VSEL<c>.F32 s_s_s.
+16200 Fix a bug when --log-file output isn't split when a program forks. BZ#162848
+3291 Implement VRINT{A,N,P,M}.F64 d_d, VRINT{A,N,P,M}.F32 s_s.
+3292 Implement:
+ VRINT{Z,R}.F64.F64 d_d, VRINT{Z,R}.F32.F32 s_s
+ VCVT{A,N,P,M}{.S32,.U32}{.F64,.F32}
+16201 mips64: update exp file for test_math
+3293 Implement
+ V{MIN,MAX}NM.F64 Dd, Dn, Dm
+ V{MIN,MAX}NM.F32 Sd, Sn, Sm
+16202 Add support for Iop_MaxNumF64, Iop_MinNumF64, Iop_MaxNumF32 and
+Iop_MinNumF32, as introduced in vex r3293.
+3294 Implement VRINTX.F64.F64 d_d, VRINTX.F32.F32 s_s.
+3295 dis_neon_data_3same: don't silently accept invalid instructions.
+3296 Implement V{MAX,MIN}NM{.F32 d_d_d, .F32 q_q_q}.
+3297 Implement:
+ VCVT{A,N,P,M}{.F32 d_d, .F32 q_q}
+ VRINT{A,N,P,M,X,Z}{.F32 d_d, .F32 q_q}
+16203 Connect the v8 FP and SIMD tests to the build system.
+16204 x86-linux: Initialize x86 system GDT on first use. Bug 344139 comment
+3.
+3298 Small comment fix: point at the correct file name
+3299 x86: Recognize the SS segment prefix on x86. Bug 344139 comment 4.
+16205 Allow memcheck to output the leak results as a callgrind xtree file.
+16206 xtree leak.
+As option --xtree-leak=yes is useless without a full leak report,
+16207 Fix --help for --xtree-leak-file
+16208 Similar to xtree memory, give a user msg with the xtree leak filename
+16209 xtree: use "UnknownFile???" and "UnknownFn???" instead of "???"
+and "file ???"
+16210 Document limitation of --log-file when a program forks.
+Follow up to r16200 and BZ#162848.
+
+16211 mips32: add support for ptrace syscall
+16212 mips: fix target_get_drv() function
+16213 Adding new filter to memcheck/tests/filter_stderr
+16214 Samll changes on xtree leak event short names
+16215 missingmips: implement calculation for static TLS Related issue #375514.
+
+* 16216 Fix +1 error in get_elf_symbol_info() when computing value of 'hi' address for ML_(find_rx_mapping)()
+Fixes BZ#375772
+16217 missingforce old implementation of std::string for leak_cpp_interior
+test Related issue #373069
+
+16218 Add PROT_READ flag to mmap, as Valgrind needs to be able to read the
+code before it executes it.
+16219 add suppression for helgrind/tests/tc22_exit_w_lock
+16220 fix leak-segv-jmp test for platforms with 64K pagesize
+16221 am_munmap_both_wrk: safely initialise out-param for all return paths.
+3300mips: rewrite mips_irgen_load_and_add32|64 and code around it
+3301Fix non-mips build breakage from VEX r3300
+3302Handle unknown HINT instructions on aarch64 by ignoring them. BZ#376279.
+3303Add comment about HINT instructions.
+
+3304 mips64: do correct 32-bit comparison for Iop_CmpNE32
+16223 add none/tests/linux/clonev to svn:ignore list
+16224 Solaris: Add syscall wrapper for lgrpsys(180)
+Fixes BZ#376455.
+16225 Solaris: Add additional subcodes for lgrpsys(180) syscall
+Fixes BZ#376455.
+16226 missingSolaris: include <sys/lgrp_user_impl.h> only on newer Solaris. BZ#376455.
+16227 Solaris: Add syscall wrapper for fast trap getlgrp(6)
+Fixes BZ#376518.
+16228 Bug 376611 - ppc64 and arm64 don't know about prlimit64 syscall.
+16229 fix order of timer_* syscalls on aarch64 - bug #371225
+16230 aarch64: add missing syscalls into table
+16231 aarch64: remove bogus syscall part
+16232 aarch64: enable pivot_root syscall (generic wrapper)
+16233 aarch64: enable sync_file_range syscall (generic wrapper)
+16234 aarch64: enable unshare syscall (generic wrapper)
+16235 aarch64: enable get_robust_list syscall (generic wrapper)
+16236 aarch64: enable delete_module syscall (generic wrapper)
+16237 aarch64: enable sched_rr_get_interval syscall (generic wrapper)
+16238 aarch64: enable tkill syscall (generic wrapper)
+16239 aarch64: enable request_key syscall (generic wrapper)
+16240 aarch64: enable move_pages syscall (generic wrapper)
+16241 aarch64: enable rt_tgsigqueueinfo syscall (generic wrapper)
+16242 aarch64: enable fanotify_init syscall (generic wrapper)
+16243 missingaarch64: enable fanotify_mark syscall (generic wrapper)
+16244 aarch64: enable clock_adjtime syscall (generic wrapper)
+16245 aarch64: enable kcmp syscall (generic wrapper)
+16246 aarch64: enable getcpu syscall (generic wrapper)
+16247 aarch64: enable sethostname syscall (generic wrapper)
+16248 aarch64: mark not implemented syscalls as such
+16249 Remove arm64 specific (unused) setup_child () and assign_guest_tls ().
+16250 Update NEWS with bug numbers of recently implemented linux-arm64 syscalls.
+16251 modifty sleepers to have easier evaluation of interaction between cpu freq scaling
+and scheduler lock (pipe based or futex based)
+16252 Fix sr_EQ() comparison on Solaris syscall failure
+16253 Follow up to SVN r16251
+Fix expected output for gdbserver_tests/solaris/nlcontrolc.
+16254 Thusly, remove R2 from the clobber list. Bugzilla is 376729.
+3305 Push some spec rules for amd64 that have been sitting around for a while:
+16255 Follow up to SVN r16253 (fix expected output of gdbserver_tests/solaris/nlcontrolc)
+16256 Introduce macro ASSUME_ALIGNED and use it in vki-linux.h.
+3306 Fix incorrect variable type (IRTemp->IRType)
+16257 Update trunk/docs/internals/3_12_BUGSTATUS.txt
+16258 Fix two safe_to_deref/sizeof mismatches in
+sys_sigaction/sys_rt_sigaction.
+
========================================================================
========================================================================
|
|
From: Matthias S. <zz...@ge...> - 2017-03-02 21:48:48
|
Am 01.03.2017 um 14:24 schrieb Ivo Raisr: > 2017-02-27 21:45 GMT+01:00 Matthias Schwarzott <zz...@ge...>: >> >> I wonder if the parameter 10 in --abbrev=10 should be skipped, now that >> git has an automatic estimation for the number of digits to be used. > > Are you referring to "--short=10" command line option for "git rev-parse"? Exactly. > The manual [1] states that if no length is specified than 7 is used. > Could you give us a reference where the automatic length estimation is > described? > I. > > [1] https://git-scm.com/docs/git-rev-parse/ > Documentation can be seen here (only for the config value): https://git-scm.com/docs/git-config#git-config-coreabbrev I did not find more documentation. The new behaviour was added to git with this merge commit: https://github.com/git/git/commit/d7ae013a3173c621a3556be6834d459ece60e130 A description can be found here: https://github.com/git/git/commit/e6c587c733b4634030b353f4024794b08bc86892 I think the new behaviour it is contained since at least git v2.11 Regards Matthias |
|
From: <sv...@va...> - 2017-03-02 11:14:46
|
Author: mjw
Date: Thu Mar 2 11:14:36 2017
New Revision: 16258
Log:
Fix two safe_to_deref/sizeof mismatches in sys_sigaction/sys_rt_sigaction.
Before dereferencing the sigaction pointer and reading the fields we
need to make sure the whole struct is safe_to_deref. We were using the
size of the pointer, but needed the size of the struct.
Modified:
trunk/coregrind/m_syswrap/syswrap-linux.c
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Thu Mar 2 11:14:36 2017
@@ -3715,7 +3715,7 @@
PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
- if (ML_(safe_to_deref)(sa,sizeof(sa))
+ if (ML_(safe_to_deref)(sa,sizeof(struct vki_old_sigaction))
&& (sa->sa_flags & VKI_SA_RESTORER))
PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
}
@@ -3828,7 +3828,7 @@
PRE_MEM_READ( "rt_sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
PRE_MEM_READ( "rt_sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
PRE_MEM_READ( "rt_sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
- if (ML_(safe_to_deref)(sa,sizeof(sa))
+ if (ML_(safe_to_deref)(sa,sizeof(vki_sigaction_toK_t))
&& (sa->sa_flags & VKI_SA_RESTORER))
PRE_MEM_READ( "rt_sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
}
|
|
From: <sv...@va...> - 2017-03-01 18:44:29
|
Author: iraisr
Date: Wed Mar 1 18:44:21 2017
New Revision: 3307
Log:
Minor refactoring for assignedOnce_Stmt().
No functional change.
n-i-bz
Modified:
trunk/priv/ir_defs.c
Modified: trunk/priv/ir_defs.c
==============================================================================
--- trunk/priv/ir_defs.c (original)
+++ trunk/priv/ir_defs.c Wed Mar 1 18:44:21 2017
@@ -3918,6 +3918,22 @@
}
static
+void assignedOnce_Temp(const IRSB *bb, const IRStmt *stmt, IRTemp tmp,
+ Int *def_counts, UInt n_def_counts,
+ const HChar *err_msg_out_of_range,
+ const HChar *err_msg_assigned_more_than_once)
+{
+ if (tmp < 0 || tmp >= n_def_counts) {
+ sanityCheckFail(bb, stmt, err_msg_out_of_range);
+ }
+
+ def_counts[tmp]++;
+ if (def_counts[tmp] > 1) {
+ sanityCheckFail(bb, stmt, err_msg_assigned_more_than_once);
+ }
+}
+
+static
void useBeforeDef_Expr ( const IRSB* bb, const IRStmt* stmt,
const IRExpr* expr, Int* def_counts )
{
@@ -4065,6 +4081,58 @@
}
static
+void assignedOnce_Stmt(const IRSB *bb, const IRStmt *stmt,
+ Int *def_counts, UInt n_def_counts)
+{
+ switch (stmt->tag) {
+ case Ist_WrTmp:
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.WrTmp.tmp, def_counts, n_def_counts,
+ "IRStmt.Tmp: destination tmp is out of range",
+ "IRStmt.Tmp: destination tmp is assigned more than once");
+ break;
+ case Ist_LoadG:
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.LoadG.details->dst, def_counts, n_def_counts,
+ "IRStmt.LoadG: destination tmp is out of range",
+ "IRStmt.LoadG: destination tmp is assigned more than once");
+ break;
+ case Ist_Dirty:
+ if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) {
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.Dirty.details->tmp, def_counts, n_def_counts,
+ "IRStmt.Dirty: destination tmp is out of range",
+ "IRStmt.Dirty: destination tmp is assigned more than once");
+ }
+ break;
+ case Ist_CAS:
+ if (stmt->Ist.CAS.details->oldHi != IRTemp_INVALID) {
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.CAS.details->oldHi, def_counts, n_def_counts,
+ "IRStmt.CAS: destination tmpHi is out of range",
+ "IRStmt.CAS: destination tmpHi is assigned more than once");
+ }
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.CAS.details->oldLo, def_counts, n_def_counts,
+ "IRStmt.CAS: destination tmpLo is out of range",
+ "IRStmt.CAS: destination tmpLo is assigned more than once");
+ break;
+ case Ist_LLSC:
+ assignedOnce_Temp(
+ bb, stmt, stmt->Ist.LLSC.result, def_counts, n_def_counts,
+ "IRStmt.LLSC: destination tmp is out of range",
+ "IRStmt.LLSC: destination tmp is assigned more than once");
+ break;
+ // Ignore all other cases
+ case Ist_NoOp: case Ist_IMark: case Ist_AbiHint: case Ist_Put: case Ist_PutI:
+ case Ist_Store: case Ist_StoreG: case Ist_MBE: case Ist_Exit:
+ break;
+ default:
+ vassert(0);
+ }
+}
+
+static
void tcExpr ( const IRSB* bb, const IRStmt* stmt, const IRExpr* expr,
IRType gWordTy )
{
@@ -4614,79 +4682,12 @@
useBeforeDef_Stmt(bb,stmt,def_counts);
/* Now make note of any temps defd by this statement. */
- switch (stmt->tag) {
- case Ist_WrTmp:
- if (stmt->Ist.WrTmp.tmp < 0 || stmt->Ist.WrTmp.tmp >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.Tmp: destination tmp is out of range");
- def_counts[stmt->Ist.WrTmp.tmp]++;
- if (def_counts[stmt->Ist.WrTmp.tmp] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.Tmp: destination tmp is assigned more than once");
- break;
- case Ist_LoadG: {
- const IRLoadG* lg = stmt->Ist.LoadG.details;
- if (lg->dst < 0 || lg->dst >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.LoadG: destination tmp is out of range");
- def_counts[lg->dst]++;
- if (def_counts[lg->dst] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.LoadG: destination tmp is assigned more than once");
- break;
- }
- case Ist_Dirty: {
- const IRDirty* d = stmt->Ist.Dirty.details;
- if (d->tmp != IRTemp_INVALID) {
- if (d->tmp < 0 || d->tmp >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.Dirty: destination tmp is out of range");
- def_counts[d->tmp]++;
- if (def_counts[d->tmp] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.Dirty: destination tmp is assigned more than once");
- }
- break;
- }
- case Ist_CAS: {
- const IRCAS* cas = stmt->Ist.CAS.details;
- if (cas->oldHi != IRTemp_INVALID) {
- if (cas->oldHi < 0 || cas->oldHi >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.CAS: destination tmpHi is out of range");
- def_counts[cas->oldHi]++;
- if (def_counts[cas->oldHi] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.CAS: destination tmpHi is assigned more than once");
- }
- if (cas->oldLo < 0 || cas->oldLo >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.CAS: destination tmpLo is out of range");
- def_counts[cas->oldLo]++;
- if (def_counts[cas->oldLo] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.CAS: destination tmpLo is assigned more than once");
- break;
- }
- case Ist_LLSC:
- if (stmt->Ist.LLSC.result < 0 || stmt->Ist.LLSC.result >= n_temps)
- sanityCheckFail(bb, stmt,
- "IRStmt.LLSC: destination tmp is out of range");
- def_counts[stmt->Ist.LLSC.result]++;
- if (def_counts[stmt->Ist.LLSC.result] > 1)
- sanityCheckFail(bb, stmt,
- "IRStmt.LLSC: destination tmp is assigned more than once");
- break;
- default:
- /* explicitly handle the rest, so as to keep gcc quiet */
- break;
- }
+ assignedOnce_Stmt(bb, stmt, def_counts, n_temps);
}
/* Typecheck everything. */
for (i = 0; i < bb->stmts_used; i++)
- if (bb->stmts[i])
- tcStmt( bb, bb->stmts[i], guest_word_size );
+ tcStmt(bb, bb->stmts[i], guest_word_size);
if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size)
sanityCheckFail(bb, NULL, "bb->next field has wrong type");
/* because it would intersect with host_EvC_* */
|
|
From: <sv...@va...> - 2017-03-01 14:28:46
|
Author: sewardj
Date: Wed Mar 1 14:28:38 2017
New Revision: 16257
Log:
Update.
Modified:
trunk/docs/internals/3_12_BUGSTATUS.txt
Modified: trunk/docs/internals/3_12_BUGSTATUS.txt
==============================================================================
--- trunk/docs/internals/3_12_BUGSTATUS.txt (original)
+++ trunk/docs/internals/3_12_BUGSTATUS.txt Wed Mar 1 14:28:38 2017
@@ -450,7 +450,94 @@
Mon 21 Nov 13:13:47 CET 2016
+n-i-bz major perf problems w/ stack registration + stack recycling
+372772 Brew doesn't allow for Valgrind 3.12.0 installation on Sierra OSX
+372779 valgrind will hang
+372794 LibVEX (arm32 front end): 'Assertion szBlg2 <= 3' failed
+372828 vex amd64->IR: 0x66 0x4D 0xF 0x38 0xF6 0xD2 0x66 0x4D
+372861 Test pselect_alarm for Bug 359871 seg faults on RHEL 4
+
+Fri 25 Nov 11:47:59 CET 2016
+
+other stuff to fix: annoying duplicate brk() message
========================================================================
========================================================================
+Stuff that we should merge (trunk -> 3.12.1)
+
+372504 Hanging on exit_group
+372600 process loops forever when fatal signals are arriving quickly
+n-i-bz Demangle Rust
+n-i-bz major perf problems w/ stack registration + stack recycling
+
+========================================================================
+========================================================================
+
+Summary of commits after the 3.12.0 release (3282, 16098) to see which
+we might want to merge for 3.12.1.
+
+16098 .. 16102 tag/release artefacts (nothing interesting)
+
+"*" marks possible merge candidates
+
+* 16103 bzero is non-POSIX (deprecated), accordingly __bzero template required for all macOS versions. n-i-bz.
+16104 perf/vg_perf --outer-args: either replace the predefined outer args,
+* 16105 Solaris: Add wrapper for fcntl(F_DUPFD_CLOEXEC) n-i-bz
+16106 Add some more comments in pub_tool_debuginfo.h about memory persistence/ownership
+* 16107 Follow up to SVN r16105. Forgot to include scalar.stderr.exp changes in the commit.
+16108 Now that 3.12 is out, update version under development to 3.13.0.SVN
+16109 371412 Rename wrap_sys_shmat to sys_shmat like other wrappers
+* 16110 mips: add POST function to sys_prctl. Add missing POST wrapper for sys_prctl. This fixes regressions from r15934 (on MIPS32 platforms) and r16003 (on MIPS64 platforms).
+16111 Some small optimisation+some code reformatting
+* 16112 Support '%' in symbol Z-encoding. Fixes BZ #371869.
+16113 Fix compiler warning about unused function on Solaris
+16114 Move scalar test of lwp_private syscall to platform specific directories. n-i-bz
+* 16115 Add demangling support for Rust symbols. Derived from a patch by
+David Tolnay <dt...@gm...>. n-i-bz.
+16116 Fix compile error on macOS introduced in r16111. n-i-bz.
+* 16117 mips: Add redir for index function in ld.so.1
+* 16118 Bug #372120 - c++ demangler demangles symbols which are not c++.
+* 3284 Fix xxsel parsing error.
+* 3285 Fix xxsel parsing error, update.
+16120 Support pool of unique string in pub_tool_deduppoolalloc.h [xtree]
+16121 Implement a cache 'address -> symbol name' in m_debuginfo.c [xtree]
+16122 Add VG_(strIsMemberXA) in pub_tool_xarray.h [xtree]
+16124 Addition of the options --xtree-memory and --xtree-memory-file [xtree]
+? 16125 Small changes in callgrind_annotate and callgrind manual
+16126 Locally define vgPlain_scrcmp in 2 unit tests [xtree]
+16127 Support for xtree memory profiling and xtmemory gdbsrv monitor command in helgrind [xtree]
+16128 Support for xtree memory profiling and xtmemory gdbsrv monitor command in memcheck [xtree]
+16129 Update massif implementation to xtree
+16130 Provide Solaris specifics in coregrind/m_gdbserver/README_DEVELOPERS. n-i-bz
+16131 Update documentation and NEWS for xtree concept. [xtree]
+16132 Provide a paragraph about Solaris agent thread in advanced concepts. n-i-bz
+16133 Outer/inner setup : allow append to outer args, use a bigger --num-callers
+16134 Cleanup none/tests/nocwd.vgtest tmp dirs.
+16135 When --show-below-main=no, search main from the outermost stackframe
+16136 Fix sym name cache: handles the difference between text and data, + match in symbol
+* sym name cache to cache the 'isText' characteristic of the cached sym_name
+16137 Activate perf tests on arm64
+16138 Add typedef Alloc_Fn_t/Free_Fn_t in pub_tool_basics.h, use them everywhere
+16139 Improve the outer/inner setup: have the outer reporting the inner guest stacktrace
+* 16140 Fix Bug 372600 - process loops forever when fatal signals are arriving quickly
+* 16141 Fix 372504 Hanging on exit_group
+? 16142 Fix the configure test for presense of __xpg[4,6] symbols
+16143 Disable test none/tests/pth_2sig on Solaris for now until it is investigated
+16144 *? Solaris: Add syscall wrapper for sigsuspend(95). NB: this includes the sigsuspend masking fix, for Solaris
+16145 Solaris: Add syscall wrapper for sigsendsys(108) n-i-bz
+16146 xtree: some documentation and --help-debug fine tuning
+16147 Fix test none/tests/pth_2sig on Solaris.
+16148 Fix none/tests/pth_2sig.c build with (default) -std=gnu90.
+16149 Update (of 3_11_BUGSTATUS.txt)
+16150 Add a tracking file for bugs in 3.12.
+16151 Comments change only: add the profile of the hook called by the gnat runtime
+* 16152 Bug 352767 - Wine/valgrind: Warning: noted but unhandled ioctl 0x5307 with no size/direction hints. (CDROMSTOP).
+* 16153 Bug 348616 - Wine/valgrind: Warning: noted but unhandled ioctl 0x5390 with no size/direction hints. (DVD_READ_STRUCT)
+16154 make bar_bad tests more deterministic
+16155 Update (NEWS)
+
+Fri 25 Nov 12:30:15 CET 2016
+
+========================================================================
+========================================================================
|
|
From: Ivo R. <iv...@iv...> - 2017-03-01 13:24:49
|
2017-02-27 21:45 GMT+01:00 Matthias Schwarzott <zz...@ge...>: > > I wonder if the parameter 10 in --abbrev=10 should be skipped, now that > git has an automatic estimation for the number of digits to be used. Are you referring to "--short=10" command line option for "git rev-parse"? The manual [1] states that if no length is specified than 7 is used. Could you give us a reference where the automatic length estimation is described? I. [1] https://git-scm.com/docs/git-rev-parse/ |