Exemple #1
0
 private static MethodBodyBlock CreateBody(MethodEx methodEx)
 {
     if(!methodEx.IsVerified)
         return null;
     MethodBodyBlock body;
     body = Converter.Convert(methodEx);
     return(body);
 }
Exemple #2
0
		private static void ProcessLeave(int iNum,MethodEx method,StackTypes stack)
		{
			CheckCanLeave(method.EHClauses, iNum, (int)method[iNum].Param);
			ProcessLeave(stack);
			ProcessBranch(iNum,(int)method[iNum].Param,method,stack);
		}
Exemple #3
0
		private static void ProcessSwitch(int iNum,MethodEx method,StackTypes stack)
		{
			int[] INums = (int[])method[iNum].Param;
			for(int i = 0;i<INums.Length;i++)
			{
				CheckSameBlock(method.EHClauses, iNum, INums[i]);
				ProcessBranch(iNum,INums[i],method,stack);
			}
		}
Exemple #4
0
		private static void ProcessBr(int iNum,MethodEx method,StackTypes stack)
		{
			CheckSameBlock(method.EHClauses, iNum, (int)method[iNum].Param);
			ProcessBranch(iNum, (int)method[iNum].Param, method, stack);
		}
Exemple #5
0
		private static void ProcessBranch(int iNum,int INum,MethodEx method,StackTypes stack)
		{
			Instruction I = method[INum];
			if(INum > iNum)
				I.SetStack(MergeStacks(I.Stack,stack));
			else 
				CheckStacks(I.Stack,stack);
		}
Exemple #6
0
		internal static bool Check(MethodEx methodRepr)
		{
			//Attention: the `null` value on stack means a null reference that is of any object type 
			//As `typeof(object)` is the most general Type, so `null` is the most exact object type 
			FreeStacks(methodRepr);
			try
			{
				Instruction lastI = methodRepr[methodRepr.Count-1]; 
				if(    lastI.Code != InstructionCode.RET 
					&& lastI.Code != InstructionCode.BR
					&& lastI.Code != InstructionCode.THROW
					&& lastI.Code != InstructionCode.RETHROW
					&& lastI.Code != InstructionCode.LEAVE
					&& lastI.Code != InstructionCode.ENDFINALLY
					&& lastI.Code != InstructionCode.ENDFILTER )
						throw new VerifierException();
				MethodInfoExtention method = new MethodInfoExtention(methodRepr.Method);
				StackTypes stack = new StackTypes(); //initially the stack is empty
				int nextHandler = FindNextHandler(-1,methodRepr.EHClauses);
				CheckBlockExits(methodRepr);
				for (int iNum = 0; iNum < methodRepr.Count ; iNum ++)
				{  
					Instruction i = methodRepr[iNum]; 
					i.SetStack(MergeStacks(i.Stack,stack));
					if(nextHandler == iNum)
					{
						PushExceptionOnStack(iNum,i.Stack,methodRepr.EHClauses);
						nextHandler = FindNextHandler(iNum,methodRepr.EHClauses);
					}
					stack = i.Stack.Clone() as StackTypes;  
					switch(i.Code)
					{
						case InstructionCode.DUP :    
						{
							stack.Push(stack.Peek()); 
						} break;
						case InstructionCode.LDARG : 
						{
							stack.Push(method.GetArgType((Int32)i.Param));
						} break;
						case InstructionCode.LDARGA : 
						{
							TypeEx t = method.GetArgType((Int32)i.Param).BuildRefType();
							stack.Push(t);
						} break;
						case InstructionCode.LDLOCA : 
						{
							TypeEx t = new TypeEx(TypeEx.BuildRefType(methodRepr.Locals[(Int32)i.Param]));
							stack.Push(t);
						} break;
						case InstructionCode.LDLOC : 
						{
							stack.Push(new TypeEx(methodRepr.Locals[(Int32)i.Param]));
						} break;
						case InstructionCode.LDIND :
						{
							ProcessLdInd(i.TypeBySuffixOrParam(), stack);
						} break;
						case InstructionCode.LDC:
						{
							stack.Push(new TypeEx(i.TypeBySuffixOrParam()));
						} break;
						case InstructionCode.LDNULL:
						{
							stack.Push(new TypeEx(null));//see `Attention` at the top of the method.
						} break;
						case InstructionCode.LDFLD:
						{
							ProcessLdFld(stack, i.Param as FieldInfo,false);
						} break;
						case InstructionCode.LDFLDA:
						{
							ProcessLdFld(stack, i.Param as FieldInfo,true);
						} break;
						case InstructionCode.LDSFLD:
						{
							stack.Push(new TypeEx((i.Param as FieldInfo).FieldType)); 
						} break;
						case InstructionCode.LDSFLDA:
						{
							stack.Push(TypeEx.BuildRefType((i.Param as FieldInfo).FieldType)); 
						} break;
						case InstructionCode.LDELEM:
						{
							ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), false);
						} break;
						case InstructionCode.LDELEMA:
						{
							ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), true);
						} break;
						case InstructionCode.LDLEN :
						{
							ProcessLdLen(stack);
						} break;
						case InstructionCode.LDOBJ :
						{
							ProcessLdObj(stack, i.Param as Type);
						} break;
						case InstructionCode.LDSTR:
						{
							if(!(i.Param is string)) 
								throw new VerifierException();
							stack.Push(typeof(string));
						} break;
						case InstructionCode.LDFTN:
						{
							stack.Push(new TypeEx(typeof(IntPtr))); 
						} break;
						case InstructionCode.LDVIRTFTN:
						{
							TypeEx obj = stack.Pop();
							MethodInfo methodInfo = i.Param as MethodInfo;
							if(!methodInfo.IsVirtual)
								throw new VerifierException();
							TypeChecker.CheckAssignment(new TypeEx(methodInfo.DeclaringType , true), obj);
							stack.Push(typeof(IntPtr));
						} break;
						case InstructionCode.LDTOKEN:
						{
							if(i.Param is Type)
								stack.Push(typeof(System.RuntimeTypeHandle));
							else if(i.Param is MethodBase)
								stack.Push(typeof(System.RuntimeMethodHandle));
							else if(i.Param is FieldInfo)
								stack.Push(typeof(System.RuntimeFieldHandle));
							else
								throw new VerifierException();
						} break;
						case InstructionCode.SIZEOF :
						{
							ProcessSizeOf(stack,i.Param as Type);
						} break;

						case InstructionCode.CLT: 
						case InstructionCode.CGT:
						case InstructionCode.CEQ:
						{
              ProcessBinOp(OpType.Compare,stack);
						} break;

						case InstructionCode.BLE:
						case InstructionCode.BLT: 
						case InstructionCode.BGE:
						case InstructionCode.BGT:
						case InstructionCode.BEQ:
						case InstructionCode.BNE:
						{
							TypeEx t1 = stack.Pop();
							TypeEx t2 = stack.Pop();
							Arithmetics.CheckTypes(t1,t2);
							ProcessBr(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
							//Andrew: mb wrong, we may let equal stacks to be the same object
						} break;
						case InstructionCode.BRTRUE:
						case InstructionCode.BRFALSE:
						{
							ProcessBrTrueFalse(stack);
							ProcessBr(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
							//Andrew: mb wrong, we may let equal stacks to be the same object
						} break;
						case InstructionCode.BR : 
						{
							ProcessBr(iNum,methodRepr,stack);
							stack = null; 
						} break;

						case InstructionCode.SWITCH:
						{
							ProcessSwitch(stack);
							ProcessSwitch(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
						} break;
            
						case InstructionCode.THROW :
						{
							ProcessThrow(stack);
							stack = null;
						}break;
            
						case InstructionCode.RETHROW :
						{
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Catch)
								throw new VerifierException();
							stack = null;
						}break;

						case InstructionCode.LEAVE : 
						{
							BlockType blockType = GetNearestBlock(methodRepr.EHClauses,iNum).type;
							if(blockType != BlockType.Catch && blockType != BlockType.Try)
								throw new VerifierException();
							ProcessLeave(iNum,methodRepr,stack);
							stack = null; 
						} break;

						case InstructionCode.ENDFINALLY : 
						{ 
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Finally)
								throw new VerifierException();
							ProcessLeave(stack);
							stack = null; 
						} break;

						case InstructionCode.ENDFILTER : 
						{ 
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Filter)
								throw new VerifierException();
							ProcessEndFilter(stack);
							stack = null; 
						} break;

						case InstructionCode.NOT:
						{
							ProcessNot(stack);
						} break;

						case InstructionCode.NEG:
						{
							ProcessNeg(stack);
						} break;
              
						case InstructionCode.CKFINITE :
						{ 
							ProcessCkFinite(stack);
						} break;

						case InstructionCode.CONV:
						{
							ProcessConv(i.TypeBySuffixOrParam(), stack);
						} break;

						case InstructionCode.SUB: 
						case InstructionCode.ADD: 
						case InstructionCode.MUL: 
						case InstructionCode.DIV: 
						case InstructionCode.REM: 
						case InstructionCode.XOR:
						case InstructionCode.OR:
						case InstructionCode.AND:
						{
							ProcessBinOp(IsFloatOperation(i) ? OpType.FloatOrInt : OpType.Int , stack);
						} break;

						case InstructionCode.SHL:
						case InstructionCode.SHR:
						{
							ProcessBinOp(OpType.Shift , stack);
						} break;

						case InstructionCode.CPOBJ :
						{
							ProcessCpObj(stack, i.Param as Type);
						} break;

						case InstructionCode.STARG : 
						{
							ProcessSt(method.GetArgType((Int32)i.Param) , stack);
						} break;
						case InstructionCode.STLOC : 
						{
							ProcessSt(new TypeEx(methodRepr.Locals[(Int32)i.Param]) , stack);
						} break;
						case InstructionCode.STIND :
						{
							ProcessStInd(i.TypeBySuffixOrParam() , stack);
						} break;
						case InstructionCode.STFLD:
						{
							ProcessStFld(stack, i.Param as FieldInfo);
						} break;
						case InstructionCode.STSFLD:
						{
							ProcessStSFld(stack, i.Param as FieldInfo);
						} break;
						case InstructionCode.STELEM:
						{
							ProcessStElem(stack, new TypeEx(i.TypeBySuffixOrParam()));
						} break;
						case InstructionCode.STOBJ :
						{
							ProcessStObj(stack, i.Param as Type);
						} break;

						case InstructionCode.RET : 
						{
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Global)
								throw new VerifierException();
							ProcessRet(method.GetReturnType(), stack);
							stack = null;  
						} break;
						case InstructionCode.CALL : 
						case InstructionCode.CALLVIRT :
						case InstructionCode.NEWOBJ :
						{
							//constructor may be invoked using either CALL or NEWOBJ instructions
							MethodBase callee = i.Param as MethodBase; 
							if(i.Code == InstructionCode.NEWOBJ && callee.IsConstructor && IsDelegate(callee.DeclaringType))
								ProcessDelegateConstruction(methodRepr,iNum,stack);
							else
							  ProcessCallOrNewobj(new MethodInfoExtention(callee,i.Code == InstructionCode.CALLVIRT), stack, i.Code == InstructionCode.NEWOBJ);
                            if(i.HasTail && methodRepr[iNum+1].Code != InstructionCode.RET)
								throw new VerifierException();
						} break;
						case InstructionCode.INITOBJ :
						{
							ProcessInitObj(stack, i.Param as Type);
						} break;
						case InstructionCode.NEWARR :
						{
							ProcessNewArr(stack, i.Param as Type);
						} break;
						case InstructionCode.ISINST :
						case InstructionCode.CASTCLASS :
						{
							ProcessCastClass(stack, new TypeEx(i.Param as Type , true));
						} break;

						case InstructionCode.BOX :
						{
							ProcessBox(stack, i.Param as Type);
						} break;

						case InstructionCode.UNBOX :
						{
							ProcessUnBox(stack, i.Param as Type);
						} break;

						case InstructionCode.POP :
						{
							stack.Pop(); 
						} break;

						case InstructionCode.NOP :
						case InstructionCode.BREAK :
							break;

						default: 
						{
							throw new VerifierException();
							//Instruction is not supported yet...
						}
					}  
				}
				return(true);
			}
			catch(VerifierException )
			{ 
				FreeStacks(methodRepr);
				return(false);
			}
			//catch(NullReferenceException ) //Andrew: ZaLyaPa :( waiting for Sergey to patch NEWOBJ (delegate construction)
			//{
			//	FreeStacks(methodRepr);
			//	return(false);
			//}
		}
Exemple #7
0
		static private void ProcessDelegateConstruction(MethodEx method,int iNum,StackTypes stack)
		{
			if(!(IsInstanceDispatch(method,iNum) || IsVirtualDispatch(method,iNum)))
			  throw new VerifierException();
			TypeEx intPtr = stack.Pop();
			MethodInfo ftn = method[iNum-1].Param as MethodInfo;
			ConstructorInfo ctor = method[iNum].Param as ConstructorInfo;
			ProcessDelegateConstruction(stack,ftn,ctor);

		}
Exemple #8
0
		static public bool IsVirtualDispatch(MethodEx body,int iNum)
		{
			Instruction i0 = body[iNum-2];
			Instruction i1 = body[iNum-1];
			Instruction i2 = body[iNum];
			if(i2.Code != InstructionCode.NEWOBJ)
				return(false);
			if(i1.Code != InstructionCode.LDVIRTFTN)
				return(false);
			if(i0.Code != InstructionCode.DUP)
				return(false);
			return(true);
		}
Exemple #9
0
		static public bool IsInstanceDispatch(MethodEx body,int iNum)
		{
			Instruction i1 = body[iNum-1];
			Instruction i2 = body[iNum];
			if(i2.Code != InstructionCode.NEWOBJ)
				 return(false);
			if(i1.Code != InstructionCode.LDFTN)
				return(false);
			return(true);
		}
Exemple #10
0
		private static void CheckBlockExits(MethodEx methodRepr)
		{
			foreach(EHClause c in methodRepr.EHClauses)
			{
				int handlerEnd = c.HandlerStart + c.HandlerLength - 1;
				int tryEnd = c.TryStart + c.TryLength - 1;
        
				if(!IsTryExit(methodRepr[tryEnd].Code))
					throw new VerifierException();
				if(c.Kind == EHClauseKind.FinallyHandler ? !IsFinallyExit(methodRepr[handlerEnd].Code) :
					!IsCatchExit(methodRepr[handlerEnd].Code) )
					throw new VerifierException();
				if(c.Kind == EHClauseKind.UserFilteredHandler)
					if(!IsFilterExit(methodRepr[c.HandlerStart - 1].Code))
						throw new VerifierException();
			}
		}
Exemple #11
0
		static internal void FreeStacks(MethodEx method)
		{
			foreach(Instruction i in method)
				i.SetStack(null);
		}
Exemple #12
0
        private static void ProcessMethod(ILGenerator generator, MethodEx methodEx, MethodBase method, MetaDataMapper mapper)
        {
            if(method.IsAbstract)
                return;
            MethodBodyBlock body = null;
            if(methodEx == null)
                throw new ExportException();

            body = CreateBody(methodEx);
            if(body == null)
                throw new ExportException();

            MetaDataResolver.Map(body,mapper);
            bool verified = CFGVerifier.Check(body);
            if(!verified)
                throw new ExportException();

            Emitter.Emit(generator,body);
        }