コード例 #1
0
 private BlockFlow CreateBlockFlow(Block block, Frame frame)
 {
     return new BlockFlow(
         block,
         prog.Architecture.CreateRegisterBitset(),
         new SymbolicEvaluationContext(prog.Architecture, frame));
 }
コード例 #2
0
		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]);
		}
コード例 #3
0
ファイル: LiveCopyInserter.cs プロジェクト: killbug2004/reko
		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;
		}
コード例 #4
0
		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;
		}
コード例 #5
0
ファイル: SsaTransform.cs プロジェクト: killbug2004/reko
		/// <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;
		}
コード例 #6
0
ファイル: LiveCopyInserter.cs プロジェクト: killbug2004/reko
		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]);
		}
コード例 #7
0
ファイル: LiveCopyInserter.cs プロジェクト: killbug2004/reko
		public int IndexOfInsertedCopy(Block b)
		{
			int i = b.Statements.Count;
			if (i > 0)
			{
				if (b.Statements[i-1].Instruction.IsControlFlow)
					--i;
			}
			return i;
		}
コード例 #8
0
 public void Analyze(Block b)
 {
     curBlock = b;
     foreach (var stm in b.Statements)
     {
         if (flow[b].TerminatesProcess)
             return;
         stm.Instruction.Accept(this);
     }
 }
コード例 #9
0
 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;
 }
コード例 #10
0
		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());
		}
コード例 #11
0
ファイル: Block.cs プロジェクト: killbug2004/reko
		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();
		}
コード例 #12
0
ファイル: Block.cs プロジェクト: killbug2004/reko
		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;
		}
コード例 #13
0
ファイル: BlockTests.cs プロジェクト: killbug2004/reko
		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();
			}
		}
コード例 #14
0
		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);
		}
コード例 #15
0
        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();
        }
コード例 #16
0
ファイル: Backwalker.cs プロジェクト: killbug2004/reko
        /// <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;
        }
コード例 #17
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
 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();
 }
コード例 #18
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
 private void TerminateBlock()
 {
     if (Block != null)
     {
         lastBlock = Block;
         Block = null;
     }
 }
コード例 #19
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
        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;
        }
コード例 #20
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
 public override void Return(Expression exp)
 {
     base.Return(exp);
     Procedure.ControlGraph.AddEdge(Block, Procedure.ExitBlock);
     TerminateBlock();
     lastBlock = null;
 }
コード例 #21
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
        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;
        }
コード例 #22
0
ファイル: ProcedureBuilder.cs プロジェクト: killbug2004/reko
        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;
        }
コード例 #23
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
        /// <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;
        }
コード例 #24
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 /// <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];
     }
 }
コード例 #25
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 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;
 }
コード例 #26
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 public bool IsBlockLinearProcedureExit(Block block)
 {
     if (block.Statements.Count == 0)
         return false;
     return block.Statements.Last.Instruction is ReturnInstruction;
 }
コード例 #27
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 public PromoteBlockWorkItem CreatePromoteWorkItem(Address addrStart, Block block, Procedure procNew)
 {
     return new PromoteBlockWorkItem
     {
         Scanner = this,
         Program = program,
         Address = addrStart,
         Block = block,
         ProcNew = procNew,
     };
 }
コード例 #28
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 /// <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);
 }
コード例 #29
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
        /// <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;
        }
コード例 #30
0
ファイル: Scanner.cs プロジェクト: killbug2004/reko
 /// <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;
 }