private BlockFlow CreateBlockFlow(Block block, Frame frame) { return new BlockFlow( block, prog.Architecture.CreateRegisterBitset(), new SymbolicEvaluationContext(prog.Architecture, frame)); }
private void ReplaceJumpWithBranch(Block b1, Block b2) { Branch br = b2.Statements.Last.Instruction as Branch; proc.ControlGraph.RemoveEdge(b1, b2); b1.Statements.Add(b2.Statements.Last.LinearAddress, new Branch(br.Condition, b2.Succ[1])); proc.ControlGraph.AddEdge(b1, b2.Succ[0]); proc.ControlGraph.AddEdge(b1, b2.Succ[1]); }
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; }
private bool EndsInBranch(Block block) { if (block.Succ.Count != 2) return false; if (block.Statements.Count < 1) return false; return block.Statements.Last.Instruction is Branch; }
/// <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 bool IsLiveAtCopyPoint(Identifier id, Block b) { if (b.Statements.Count == 0) return sla.IsLiveOut(id, b); int i = IndexOfInsertedCopy(b); if (i >= b.Statements.Count) return sla.IsLiveOut(id, b.Statements[i-1]); else return sla.IsLiveIn(id, b.Statements[i]); }
public int IndexOfInsertedCopy(Block b) { int i = b.Statements.Count; if (i > 0) { if (b.Statements[i-1].Instruction.IsControlFlow) --i; } return i; }
public void Analyze(Block b) { curBlock = b; foreach (var stm in b.Statements) { if (flow[b].TerminatesProcess) return; stm.Instruction.Accept(this); } }
private BlockFlow CreateBlockFlow(Block block, Frame frame) { var bflow = new BlockFlow( block, prog.Architecture.CreateRegisterBitset(), new SymbolicEvaluationContext( prog.Architecture, frame)); flow[block] = bflow; return bflow; }
public void EarInsertFrameReference() { Procedure proc = new Procedure("foo", new Frame(PrimitiveType.Word32)); Block b = new Block(proc, "foo_1"); proc.ControlGraph.AddEdge(proc.EntryBlock, b); proc.ControlGraph.AddEdge(b, proc.ExitBlock); EscapedAccessRewriter ear = new EscapedAccessRewriter(proc); ear.InsertFramePointerAssignment(new Mocks.FakeArchitecture()); Block x = proc.EntryBlock.Succ[0]; Assert.AreEqual(1, x.Statements.Count); Assert.AreEqual("fp = &foo_frame", x.Statements[0].Instruction.ToString()); }
public static void Coalesce(Block block, Block next) { foreach (Statement stm in next.Statements) { block.Statements.Add(stm); } block.Succ = new List<Block>(next.Succ); ReplaceJumpsFrom(next, block); next.Pred.Clear(); next.Statements.Clear(); next.Succ.Clear(); }
public static bool ReplaceJumpsFrom(Block block, Block next) { bool change = false; foreach (Block s in block.Succ) { for (int i = 0; i < s.Pred.Count; ++i) { if (s.Pred[i] == block) { s.Pred[i] = next; change = true; } } } return change; }
public void CreateStatements() { using (FileUnitTester fut = new FileUnitTester("Core/BlockCreateStatements.txt")) { Block bl = new Block(null, "block0"); bl.Statements.Add(0, new Assignment( new Identifier("id3", PrimitiveType.Word16, null), new Identifier("id4", PrimitiveType.Word16, null))); bl.Statements.Add(4, new Assignment( new Identifier("id4", PrimitiveType.Word16, null), Constant.Word16(3))); bl.Write(fut.TextWriter); fut.AssertFilesEqual(); } }
private void BuildCompoundCondition( Block blockFirst, Block blockSecond, BinaryOperator op, bool fInvertFirst, bool fInvertSecond) { Branch brFirst = (Branch) blockFirst.Statements.Last.Instruction; Branch brSecond = (Branch) blockSecond.Statements.Last.Instruction; if (fInvertFirst) { brFirst.Condition = brFirst.Condition.Invert(); } if (fInvertSecond) { brSecond.Condition = brSecond.Condition.Invert(); } brFirst.Condition = new BinaryExpression(op, PrimitiveType.Bool, brFirst.Condition, brSecond.Condition); }
public void Setup() { mr = new MockRepository(); prog = new Program(); proc = new Procedure("testProc", new Frame(PrimitiveType.Word32)); block = proc.AddBlock("l00100000"); trace = new RtlTrace(0x00100000); r0 = new Identifier("r0", PrimitiveType.Word32, new RegisterStorage("r0", 0, PrimitiveType.Word32)); r1 = new Identifier("r1", PrimitiveType.Word32, new RegisterStorage("r1", 0, PrimitiveType.Word32)); r2 = new Identifier("r2", PrimitiveType.Word32, new RegisterStorage("r2", 0, PrimitiveType.Word32)); grf = proc.Frame.EnsureFlagGroup(3, "SCZ", PrimitiveType.Byte); scanner = mr.StrictMock<IScanner>(); arch = mr.DynamicMock<IProcessorArchitecture>(); arch.Stub(s => s.PointerType).Return(PrimitiveType.Pointer32); arch.Stub(s => s.CreateRegisterBitset()).Return(new BitSet(32)); prog.Architecture = arch; arch.Replay(); prog.Platform = new DefaultPlatform(null, arch); arch.BackToRecord(); }
/// <summary> /// Walks backward along the <paramref name="block"/>, recording the operations done to the idx register. /// </summary> /// <param name="block"></param> /// <returns></returns> public List<BackwalkOperation> BackWalk(Block block) { if (Stride > 1) Operations.Add(new BackwalkOperation(BackwalkOperator.mul, Stride)); bool continueBackwalking = BackwalkInstructions(Index, block); if ((Index == null || Index == RegisterStorage.None) && IndexExpression == null) return null; // unable to find guard. if (continueBackwalking) { block = host.GetSinglePredecessor(block); if (block == null) return null; // seems unguarded to me. BackwalkInstructions(Index, block); if (Index == null && IndexExpression == null) return null; } Operations.Reverse(); return Operations; }
public void BranchCc(ConditionCode cc, string label) { Identifier f; switch (cc) { case ConditionCode.EQ: case ConditionCode.NE: f = Flags("Z"); break; default: throw new ArgumentOutOfRangeException("Condition code: " + cc); } branchBlock = BlockOf(label); Emit(new Branch(new TestCondition(cc, f), branchBlock)); TerminateBlock(); }
private void TerminateBlock() { if (Block != null) { lastBlock = Block; Block = null; } }
public void Switch(Expression e, params string[] labels) { Block[] blox = new Block[labels.Length]; for (int i = 0; i < blox.Length; ++i) { blox[i] = BlockOf(labels[i]); } Emit(new SwitchInstruction(e, blox)); for (int i = 0; i < blox.Length; ++i) { Procedure.ControlGraph.AddEdge(this.Block, blox[i]); } lastBlock = null; Block = null; }
public override void Return(Expression exp) { base.Return(exp); Procedure.ControlGraph.AddEdge(Block, Procedure.ExitBlock); TerminateBlock(); lastBlock = null; }
private Block EnsureBlock(string name) { if (Block != null) return Block; if (name == null) { name = string.Format("l{0}", ++numBlock); } Block = BlockOf(name); if (Procedure.EntryBlock.Succ.Count == 0) { Procedure.ControlGraph.AddEdge(Procedure.EntryBlock, Block); } if (lastBlock != null) { if (branchBlock != null) { Procedure.ControlGraph.AddEdge(lastBlock, Block); Procedure.ControlGraph.AddEdge(lastBlock, branchBlock); branchBlock = null; } else { Procedure.ControlGraph.AddEdge(lastBlock, Block); } lastBlock = null; } return Block; }
public Statement BranchIf(Expression expr, string label) { Block b = EnsureBlock(null); branchBlock = BlockOf(label); TerminateBlock(); Statement stm = new Statement(0, new Branch(expr, branchBlock), b); b.Statements.Add(stm); return stm; }
/// <summary> /// Splits the given block at the specified address, yielding two blocks. The first block is the original block, /// now truncated, with a single out edge to the new block. The second block receives the out edges of the first block. /// </summary> /// <param name="block"></param> /// <param name="addr"></param> /// <returns>The newly created, empty second block</returns> public Block SplitBlock(Block blockToSplit, Address addr) { var graph = blockToSplit.Procedure.ControlGraph; var blockNew = AddBlock(addr, blockToSplit.Procedure, GenerateBlockName(addr)); foreach (var succ in graph.Successors(blockToSplit)) { graph.AddEdge(blockNew, succ); } foreach (var succ in graph.Successors(blockNew)) { graph.RemoveEdge(blockToSplit, succ); } var linAddr = addr.ToLinear(); var stmsToMove = blockToSplit.Statements.FindAll(s => s.LinearAddress >= linAddr).ToArray(); if (blockToSplit.Statements.Count > 0 && blockToSplit.Statements.Last.LinearAddress >= linAddr) { graph.AddEdge(blockToSplit, blockNew); blockToSplit.Statements.RemoveAll(s => s.LinearAddress >= linAddr); } blockNew.Statements.AddRange(stmsToMove); foreach (var stm in stmsToMove) { stm.Block = blockNew; } blocks[blockStarts[blockToSplit]].End = linAddr; return blockNew; }
/// <summary> /// Determines whether a block is a linear sequence of assignments followed by a return /// statement. /// </summary> /// <param name="block"></param> /// <returns></returns> public bool IsLinearReturning(Block block) { for (; ; ) { if (block.Statements.Count == 0) return false; if (block.Statements.Last.Instruction is ReturnInstruction) return true; if (!(block.Statements.Last.Instruction is Assignment)) return false; if (block.Succ.Count == 0) return false; block = block.Succ[0]; } }
private Block CloneBlockIntoOtherProcedure(Block block, Procedure proc) { Debug.Print("Cloning {0} to {1}", block.Name, proc); var clonedBlock = new BlockCloner(block, proc, program.CallGraph).Execute(); //ReplaceSuccessorsWith(pred, block, clonedBlock); //pred.Procedure.ControlGraph.Blocks.Remove(block); return clonedBlock; }
public bool IsBlockLinearProcedureExit(Block block) { if (block.Statements.Count == 0) return false; return block.Statements.Last.Instruction is ReturnInstruction; }
public PromoteBlockWorkItem CreatePromoteWorkItem(Address addrStart, Block block, Procedure procNew) { return new PromoteBlockWorkItem { Scanner = this, Program = program, Address = addrStart, Block = block, ProcNew = procNew, }; }
/// <summary> /// Terminates the <paramref name="block"/> at /// </summary> /// <param name="block"></param> /// <param name="addr"></param> public void TerminateBlock(Block block, Address addr) { BlockRange range; if (blocks.TryGetLowerBound(addr, out range) && range.Start < addr.ToLinear()) range.End = addr.ToLinear(); imageMap.TerminateItem(addr); }
/// <summary> /// Adds a new basic block to the procedure <paramref name="proc"/>. /// </summary> /// <param name="addr"></param> /// <param name="proc"></param> /// <param name="blockName"></param> /// <returns></returns> public Block AddBlock(Address addr, Procedure proc, string blockName) { Block b = new Block(proc, blockName) { Address = addr }; blocks.Add(addr, new BlockRange(b, addr.ToLinear(), image.BaseAddress.ToLinear() + (uint)image.Bytes.Length)); blockStarts.Add(b, addr); proc.ControlGraph.Blocks.Add(b); imageMap.AddItem(addr, new ImageMapBlock { Block = b }); return b; }
/// <summary> /// Creates a block range. A (linear) address addr is considered part of the block if it /// satisifies the conditions Start <= addr < End. /// </summary> /// <param name="block"></param> /// <param name="start">Linear start address of the block</param> /// <param name="end">Linear address of the byte/word beyond the block's end.</param> public BlockRange(Block block, ulong start, ulong end) { if (block == null) throw new ArgumentNullException("block"); this.Block = block; this.Start = start; this.End = end; }