public StatementNavigator(Program program, Statement stm, IServiceProvider services) { this.program = program; this.Statement = stm; this.services = services; this.Text = program.SegmentMap.MapLinearAddressToAddress(stm.LinearAddress).ToString(); }
public void DisplayStatement(Program program, Statement stm) { var pane = new CombinedCodeViewInteractor(); var windowType = typeof(CombinedCodeViewInteractor).Name; var proc = stm.Block.Procedure; var frame = ShowWindow(windowType, proc.Name, proc, pane); ((CombinedCodeViewInteractor)frame.Pane).DisplayStatement(program, stm); }
public Identifier InsertAssignmentNewId(Identifier idOld, Block b, int i) { Statement stm = new Statement(0, null, b); SsaIdentifier sidNew = ssaIds.Add((Identifier)ssaIds[idOld].OriginalIdentifier, stm, idOld, false); stm.Instruction = new Assignment(sidNew.Identifier, idOld); b.Statements.Insert(i, stm); return sidNew.Identifier; }
/// <summary> /// Creates a phi statement with slots for each predecessor block, then /// inserts the phi statement as the first statement of the block. /// </summary> /// <param name="b">Block into which the phi statement is inserted</param> /// <param name="v">Destination variable for the phi assignment</param> /// <returns>The inserted phi Assignment</returns> private Instruction InsertPhiStatement(Block b, Identifier v) { var stm = new Statement( 0, new PhiAssignment(v, b.Pred.Count), b); b.Statements.Insert(0, stm); return stm.Instruction; }
public void Test2() { BinaryExpression b = m.IAdd(id, m.UMul(id, 5)); Assignment ass = new Assignment(x, b); Statement stm = new Statement(0, ass, null); Add_mul_id_c_id_Rule rule = new Add_mul_id_c_id_Rule(new SsaEvaluationContext(ssaIds)); Assert.IsTrue(rule.Match(b)); ass.Src = rule.Transform(); Assert.AreEqual("x = id *u 0x00000006", ass.ToString()); }
public void DisplayStatement(Program program, Statement stm) { this.program = program; this.proc = stm.Block.Procedure; this.showProcedures = true; ProgramChanged(); if (program != null) { var addr = program.SegmentMap.MapLinearAddressToAddress(stm.LinearAddress); SelectedAddress = addr; } }
public SsaIdentifier(Identifier id, Identifier eOrig, Statement stmDef, Expression exprDef, bool isSideEffect) { if (id == null) throw new ArgumentNullException("id"); if (eOrig == null) throw new ArgumentNullException("eOrig"); this.Identifier = id; this.OriginalIdentifier = eOrig; this.DefStatement = stmDef; this.DefExpression = exprDef; this.IsSideEffect = isSideEffect; this.Uses = new List<Statement>(); }
public void Test1() { BinaryExpression b = m.Shl(m.SMul(id, 3), 2); Assignment ass = new Assignment(x, b); Statement stm = new Statement(0, ass, null); ssaIds[id].Uses.Add(stm); ssaIds[id].Uses.Add(stm); var rule = new Shl_mul_e_Rule(null); Assert.IsTrue(rule.Match(b)); ass.Src = rule.Transform(); Assert.AreEqual("x = id *s 0x0000000C", ass.ToString()); }
public bool AreConstrained(Statement def, Statement use) { SideEffectFlags defFlags = FindSideEffect(def.Instruction); int iUse = use.Block.Statements.IndexOf(use); for (int i = def.Block.Statements.IndexOf(def) + 1; i < def.Block.Statements.Count; ++i) { if (i == iUse) return false; if (Conflict(defFlags, FindSideEffect(def.Block.Statements[i].Instruction))) return true; } return true; }
private void SetDefStatement(Statement stm, SsaIdentifier sid) { List<SsaIdentifier> sids; if (defsByStatement.TryGetValue(sid.DefStatement, out sids)) { sids.Remove(sid); } if (!defsByStatement.TryGetValue(stm, out sids)) { sids = new List<SsaIdentifier>(); defsByStatement.Add(stm, sids); } sids.Add(sid); }
/// <summary> /// Rewrites CALL instructions to function applications. /// </summary> /// <remarks> /// Converts an opcode: /// <code> /// call procExpr /// </code> /// to one of: /// <code> /// ax = procExpr(bindings); /// procEexpr(bindings); /// </code> /// </remarks> /// <param name="proc">Procedure in which the CALL instruction exists</param> /// <param name="stm">The particular statement of the call instruction</param> /// <param name="call">The actuall CALL instruction.</param> /// <returns>True if the conversion was possible, false if the procedure didn't have /// a signature yet.</returns> public bool RewriteCall(Procedure proc, Statement stm, CallInstruction call) { var callee = call.Callee as ProcedureConstant; if (callee == null) return false; //$REVIEW: what happens with indirect calls? var procCallee = callee.Procedure; var sigCallee = GetProcedureSignature(procCallee); var fn = new ProcedureConstant(Program.Platform.PointerType, procCallee); if (sigCallee == null || !sigCallee.ParametersValid) return false; var ab = new ApplicationBuilder(Program.Architecture, proc.Frame, call.CallSite, fn, sigCallee, true); stm.Instruction = ab.CreateInstruction(); return true; }
public Expression Transform(Statement stm) { if (binLeft.Operator == Operator.ISub) cLeftRight = cLeftRight.Negate(); if (bin.Operator == Operator.ISub) cRight = cRight.Negate(); BinaryOperator op = Operator.IAdd; Constant c = ExpressionSimplifier.SimplifyTwoConstants(op, cLeftRight, cRight); if (c.IsNegative) { c = c.Negate(); op = Operator.ISub; } return new BinaryExpression(op, bin.DataType, binLeft.Left, c); }
public void Test1() { BinaryExpression b = m.IAdd(m.SMul(id, 4), id); Assignment ass = new Assignment(x, b); Statement stm = new Statement(0, ass, null); ssaIds[id].Uses.Add(stm); ssaIds[id].Uses.Add(stm); ctx.Statement = stm; Add_mul_id_c_id_Rule rule = new Add_mul_id_c_id_Rule(ctx); Assert.IsTrue(rule.Match(b)); Assert.AreEqual(2, ssaIds[id].Uses.Count); ass.Src = rule.Transform(); Assert.AreEqual("x = id *s 0x00000005", ass.ToString()); Assert.AreEqual(1, ssaIds[id].Uses.Count); }
public void Creation() { CallGraph g = new CallGraph(); Procedure p1 = new Procedure("p1000", null); Procedure p2 = new Procedure("p2000", null); Procedure p3 = new Procedure("p3000", null); Procedure p4 = new Procedure("p4000", null); var pc1 = new ProcedureConstant(PrimitiveType.Pointer32, p1); var pc2 = new ProcedureConstant(PrimitiveType.Pointer32, p2); var pc3 = new ProcedureConstant(PrimitiveType.Pointer32, p3); var pc4 = new ProcedureConstant(PrimitiveType.Pointer32, p4); Statement s11 = new Statement(0, CreateCall(pc2), p1.EntryBlock); Statement s12 = new Statement(0, CreateCall(pc2), p1.EntryBlock); Statement s13 = new Statement(0, CreateCall(pc3), p1.EntryBlock); p1.EntryBlock.Statements.Add(s11); p1.EntryBlock.Statements.Add(s12); p1.EntryBlock.Statements.Add(s13); Statement s21 = new Statement(0, CreateCall(pc3), p2.EntryBlock); Statement s22 = new Statement(0, CreateCall(pc4), p2.EntryBlock); p2.EntryBlock.Statements.Add(s21); p2.EntryBlock.Statements.Add(s22); Statement s31 = new Statement(0, CreateCall(pc4), p3.EntryBlock); p3.EntryBlock.Statements.Add(s31); Statement s41 = new Statement(0, CreateCall(pc4), p4.EntryBlock); g.AddEntryPoint(p1); g.AddEdge(s11, p2); g.AddEdge(s12, p2); g.AddEdge(s13, p3); g.AddEdge(s21, p3); g.AddEdge(s22, p4); g.AddEdge(s31, p4); g.AddEdge(s41, p4); // recursion! //$TODO: need Count // Assert.IsTrue(g.Callees(p1).Count == 3); // Assert.IsTrue(g.CallerStatements(p4).Count == 3); }
/// <summary> /// Chases a chain statements to locate the expression that /// defines the value of a condition code. /// </summary> /// <param name="sid"></param> /// <returns></returns> public void FindDefiningExpression(SsaIdentifier sid) { this.sid = sid; negated = false; stm = sid.DefStatement; if (stm != null) { Statement stmOld = null; defExpr = null; while (stm != null && defExpr == null) { stmOld = stm; stm = null; stmOld.Instruction.Accept(this); } } }
private void RewriteCall(Statement stm, CallInstruction call) { var e = expander.Expand(call.Callee); var pt = e.Accept(asc) as Pointer; if (pt == null) return; var ft = pt.Pointee as FunctionType; if (ft == null) return; var returnId = ft.ReturnValue.DataType is VoidType ? null : ft.ReturnValue; var sigCallee = new FunctionType(returnId, ft.Parameters); var ab = new ApplicationBuilder( program.Architecture, proc.Frame, call.CallSite, call.Callee, sigCallee, true); stm.Instruction = ab.CreateInstruction(); ssaIdTransformer.Transform(stm, call); }
/// <summary> /// Inserts the instr d of the identifier v at statement S. /// </summary> /// <param name="d"></param> /// <param name="v"></param> /// <param name="S"></param> public void Insert(Instruction d, Identifier v, Statement S) { // Insert new phi-functions. foreach (var dfFode in DomGraph.DominatorFrontier(S.Block)) { // If there is no phi-function for v // create new phi-function for v. (which is an insert, so call self recursively) // All input operands of the new phi-finctions are initually assumed to be // uses of r. // Update uses sets for all uses dominated by S, or the new phi statements. // This is done by walking down the dominator tree from each def and find uses // that along wit the def match property 1. // Update each use that is a parameter of a newly created phi-function, according // to property 2. } }
public void ReplaceDefinitionsWithOutParameter(Identifier id, Identifier idOut) { this.idOut = idOut; wl = new WorkList<Identifier>(); wl.Add(id); var visited = new HashSet<Statement>(); while (wl.GetWorkItem(out id)) { ssa = ssaIds[id]; stmDef = ssa.DefStatement; if (stmDef != null && !visited.Contains(stmDef)) { visited.Add(stmDef); iStmDef = stmDef.Block.Statements.IndexOf(stmDef); stmDef.Instruction = stmDef.Instruction.Accept(this); } } }
public void Transform() { foreach (var s in ssaIds) { sidGrf = s; if (!IsLocallyDefinedFlagGroup(sidGrf)) continue; var uses = new HashSet<Statement>(); aliases = new HashSet<SsaIdentifier>(); ClosureOfUsingStatements(sidGrf, sidGrf.DefExpression, uses, aliases); if (trace.TraceInfo) Debug.WriteLine(string.Format("Tracing {0}", sidGrf.DefStatement.Instruction)); foreach (var u in uses) { useStm = u; if (trace.TraceInfo) Debug.WriteLine(string.Format(" used {0}", useStm.Instruction)); useStm.Instruction.Accept(this); if (trace.TraceInfo) Debug.WriteLine(string.Format(" now {0}", useStm.Instruction)); } } }
public List<Identifier> IdentifiersDefinedAtStatement(Statement stm) { if (stm == null) return null; return defined[stm]; }
public void ReplaceDefinitions(Statement stmOld, Statement stmNew) { foreach (var sid in Identifiers) { if (sid.DefStatement == stmOld) sid.DefStatement = stmNew; } }
private Block PrecedingPhiBlock(Identifier u, Statement stm) { PhiAssignment phi = stm.Instruction as PhiAssignment; if (phi == null) return null; for (int i = 0; i < phi.Src.Arguments.Length; ++i) { if (u == phi.Src.Arguments[i]) return stm.Block.Pred[i]; } return null; }
private Dictionary<SsaIdentifier,SsaIdentifier> VariablesDefinedByStatement(Statement stm) { Dictionary<SsaIdentifier,SsaIdentifier> W = new Dictionary<SsaIdentifier,SsaIdentifier>(); foreach (SsaIdentifier sid in ssa) { if (sid.DefStatement == stm) W[sid] = sid; } return W; }
public PhiFunction GetPhiFunction(Statement stm) { PhiAssignment ass = stm.Instruction as PhiAssignment; if (ass == null) return null; return ass.Src; }
// Returns true if v is also live in before executing s. public bool LiveOutAtStatement(Statement s, SsaIdentifier v) { // v is live-out at s. List<Identifier> ids = this.IdentifiersDefinedAtStatement(s); if (ids != null) { foreach (Identifier id in ids) { if (id != v.Identifier) interference.Add(id, v.Identifier); } } return (v.DefStatement != s); }
public bool IsLiveOut(Identifier id, Statement stm) { bool live = records[stm.Block].LiveOut.Contains(ssaIds[id]); for (int i = stm.Block.Statements.Count - 1; i >= 0; --i) { Statement s = stm.Block.Statements[i]; if (s == stm) return live; if (ssaIds[id].DefStatement == s) return false; if (!(s.Instruction is PhiAssignment) && ssaIds[id].Uses.Contains(s)) live = true; } return live; }
public bool IsFirstStatementInBlock(Statement stm, Block block) { return block.Statements.IndexOf(stm) == 0; }
public bool IsDefinedAtStatement(SsaIdentifier v, Statement stm) { return (v.DefStatement == stm); }
public void AddCallEdge(Procedure caller, Statement stm, Procedure callee) { }
public IEnumerable <object> Callees(Statement stm) { return(graphStms.Successors(stm)); }
public void RemoveUses(Statement stm) { foreach (var sid in Identifiers) { List<Statement> uses = sid.Uses; int jTo = 0; for (int j = 0; j < uses.Count; ++j) { if (uses[j] != stm) { uses[jTo] = uses[j]; ++jTo; } } uses.RemoveRange(jTo, uses.Count - jTo); } }