예제 #1
0
        void ComputeInstructionData(IDictionary visited, int stackHeight, InstructionBlock block)
        {
            if (visited.Contains(block))
            {
                return;
            }
            visited.Add(block, block);

            foreach (Instruction instruction in block)
            {
                stackHeight = ComputeInstructionData(stackHeight, instruction);
            }

            foreach (InstructionBlock successor in block.Successors)
            {
                ComputeInstructionData(visited, stackHeight, successor);
            }
        }
		static InstructionBlock GetThen (InstructionBlock block)
		{
			return block.Successors [0];
		}
		void MarkProcessed (InstructionBlock block)
		{
			_processed [block] = block;
		}
		static bool IsFalse (InstructionBlock block)
		{
			return block.FirstInstruction == block.LastInstruction
				&& block.FirstInstruction.OpCode.Value == OpCodes.Ldc_I4_0.Value;
		}
		void ProcessNestedExpression (InstructionBlock block)
		{
			switch (block.Successors.Length) {
			case 1:
				BuildExpression (block);
				break;

			case 2:
				ProcessLogicalExpressionBlock (block);
				break;

			default:
				throw new ArgumentException ("block");
			}
		}
		void ProcessNotAnd (InstructionBlock block)
		{
			BuildNegateExpression (block);
			ProcessNestedExpression (GetElse (block));
			_expressionDecompiler.PushBinaryExpression (BinaryOperator.LogicalAnd);
		}
		static ExpressionPattern DetectExpressionPattern (InstructionBlock block)
		{
			InstructionBlock then = GetThen (block);
			if (IsTrue (then)) return ExpressionPattern.SimpleOr;
			if (IsFalse (then)) return ExpressionPattern.SimpleNotAnd;

			// the following flow graph patterns are described in
			// Decompilation of .NET Bytecode, Computer Science Tripos Part II
			// Trinity Hall, May 13, 2004
			// Fig. 3.10 on pg. 43

			// pattern 4: !x && y
			if (GetElse (GetElse (block)) == then) return ExpressionPattern.NestedNotAnd;
			return ExpressionPattern.Unknown;
		}
		void ProcessSimpleBlock (InstructionBlock block)
		{
			foreach (Instruction instruction in block) {
				_expressionDecompiler.Visit (instruction);
				if (0 == GetStackAfter (instruction)) {
					CreateActionBlock (instruction);
					_current = instruction.Next;
				}
			}
		}
		void ConnectBlock (InstructionBlock block)
		{
			if (block.LastInstruction == null)
				throw new ApplicationException ("Undelimited block at offset " + block.FirstInstruction.Offset);

			Instruction instruction = block.LastInstruction;
			switch (instruction.OpCode.FlowControl) {
			case FlowControl.Branch:
			case FlowControl.Cond_Branch: {
				if (HasMultipleBranches (instruction)) {
					InstructionBlock [] blocks = GetBranchTargetsBlocks (instruction);
					if (instruction.Next != null)
						blocks = AddBlock (GetBlock (instruction.Next), blocks);

					block.SetSuccessors (blocks);
					break;
				}

				InstructionBlock target = GetBranchTargetBlock (instruction);
				if (instruction.OpCode.FlowControl == FlowControl.Cond_Branch && instruction.Next != null)
					block.SetSuccessors (new InstructionBlock [] { target, GetBlock (instruction.Next) });
				else
					block.SetSuccessors (new InstructionBlock [] { target });
				break;
			}
			case FlowControl.Call:
			case FlowControl.Next:
				if (null != instruction.Next)
					block.SetSuccessors (new InstructionBlock [] { GetBlock (instruction.Next) });

				break;
			case FlowControl.Return:
				break;
			default:
				throw new ApplicationException (
					string.Format ("Unhandled instruction flow behavior {0}: {1}",
					               instruction.OpCode.FlowControl,
					               Formatter.FormatInstruction (instruction)));
			}
		}
		void ComputeInstructionData (IDictionary visited, int stackHeight, InstructionBlock block)
		{
			if (visited.Contains (block)) return;
			visited.Add (block, block);

			foreach (Instruction instruction in block) {
				stackHeight = ComputeInstructionData (stackHeight, instruction);
			}

			foreach (InstructionBlock successor in block.Successors) {
				ComputeInstructionData (visited, stackHeight, successor);
			}
		}
		void MarkBlockStart (Instruction instruction)
		{
			InstructionBlock block = GetBlock (instruction);
			if (null != block) return;

			block = new InstructionBlock (instruction);
			RegisterBlock (block);
		}
예제 #12
0
 void RegisterBlock(InstructionBlock block)
 {
     _blocks.Add(block.FirstInstruction.Offset, block);
 }
		void MarkProcessed (InstructionBlock block)
		{
			_processed.Add (block);
		}
		/// <summary>
		/// Checks if the subgraph starting at block represents
		/// a logical expression.
		/// </summary>
		/// <param name="block"></param>
		/// <returns></returns>
		bool IsLogicalExpression (InstructionBlock block)
		{
			return IsLogicalExpression (new HashSet<InstructionBlock> (), block);
		}
		InstructionBlock [] ToArray (InstructionBlock [] blocks)
		{
			_blocks.Values.CopyTo (blocks, 0);
			Array.Sort (blocks);
			return blocks;
		}
		static InstructionBlock [] AddBlock (InstructionBlock block, InstructionBlock [] blocks)
		{
			InstructionBlock [] result = new InstructionBlock [blocks.Length + 1];
			Array.Copy (blocks, result, blocks.Length);
			result [result.Length - 1] = block;

			return result;
		}
예제 #17
0
		bool IsLogicalExpression (Hashtable visited, InstructionBlock block)
		{
			if (visited.Contains (block)) return false;
			visited.Add (block, block);
			foreach (InstructionBlock successor in block.Successors) {
				if (GetStackAfter (successor.LastInstruction) > 0) return true;
				if (IsLogicalExpression (visited, successor)) return true;
			}

			return false;
		}
		InstructionBlock [] GetBranchTargetsBlocks (Instruction instruction)
		{
			Instruction [] targets = GetBranchTargets (instruction);
			InstructionBlock [] blocks = new InstructionBlock [targets.Length];
			for (int i = 0; i < targets.Length; i++)
				blocks [i] = GetBlock (targets [i]);

			return blocks;
		}
예제 #19
0
		void ProcessLogicalExpressionBlock (InstructionBlock block)
		{
			switch (DetectExpressionPattern (block)) {
			case ExpressionPattern.SimpleOr:
				ProcessOr (block);
				break;

			case ExpressionPattern.SimpleNotAnd:
				ProcessNotAnd (block);
				break;

			case ExpressionPattern.NestedNotAnd:
				ProcessNestedNotAnd (block);
				break;

			default:
				throw new ArgumentException ("Unknown expression pattern starting at " + Formatter.FormatInstruction (block.FirstInstruction), "block");
			}
			MarkProcessed (block.Successors);
		}
		void RegisterBlock (InstructionBlock block)
		{
			_blocks.Add (block.FirstInstruction.Offset, block);
		}
예제 #21
0
		void ProcessOr (InstructionBlock block)
		{
			BuildExpression (block);
			ProcessNestedExpression (GetElse (block));
			_expressionDecompiler.PushBinaryExpression (BinaryOperator.LogicalOr);
		}
예제 #22
0
		internal void SetSuccessors (InstructionBlock [] successors)
		{
			_successors = successors;
		}
예제 #23
0
		void BuildNegateExpression (InstructionBlock block)
		{
			BuildExpression (block);
			_expressionDecompiler.Negate ();
		}
예제 #24
0
 private static int GetBlockId(ControlFlowGraph cfg, InstructionBlock block)
 {
     return ((IList) cfg.Blocks).IndexOf (block) + 1;
 }
예제 #25
0
		void BuildExpression (InstructionBlock block)
		{
			if (WasProcessed (block)) return;
			foreach (Instruction instruction in block) {
				_expressionDecompiler.Visit (instruction);
			}
			MarkProcessed (block);
		}
예제 #26
0
		void ProcessBlock (InstructionBlock block)
		{
			switch (block.Successors.Length) {
			case 0:
			case 1:
				ProcessSimpleBlock (block);
				break;

			case 2:
				ProcessTwoWayBlock (block);
				break;

			default:
				throw new ArgumentException ("n-way block not supported", "block");
			}

			MarkProcessed (block);
		}
예제 #27
0
		void MarkProcessed (InstructionBlock [] blocks)
		{
			foreach (InstructionBlock block in blocks) {
				MarkProcessed (block);
			}
		}
예제 #28
0
		void ProcessTwoWayBlock (InstructionBlock block)
		{
			if (IsLogicalExpression (block)) {
				ProcessLogicalExpressionBlock (block);
			} else {
				ProcessSimpleBlock (block);
			}
		}
예제 #29
0
		bool WasProcessed (InstructionBlock block)
		{
			return _processed.Contains (block);
		}
예제 #30
0
		/// <summary>
		/// Checks if the subgraph starting at block represents
		/// a logical expression.
		/// </summary>
		/// <param name="block"></param>
		/// <returns></returns>
		bool IsLogicalExpression (InstructionBlock block)
		{
			return IsLogicalExpression (new Hashtable (), block);
		}
예제 #31
0
		static InstructionBlock GetElse (InstructionBlock block)
		{
			return block.Successors [1];
		}
		public ControlFlowGraph (MethodBody body, InstructionBlock [] blocks, IDictionary instructionData)
		{
			_body = body;
			_blocks = blocks;
			_data = instructionData;
		}