public override CILInstruction Execute(ThreadState threadState) { // correctness check, only needed in debug if (CanExecute(threadState) == false) throw new Exception("This ceq instruction is not ready to execute"); // gets the two values and compare them VMValue topOfStack = threadState.GetValue(threadState.ThreadStack.Peek()); VMValue_int32 ret = (VMValue_int32)threadState.SystemState.Values.MakeValue(new CILVar_int32("")); if (topOfStack is VMValue_int32) { VMValue_int32 value2 = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_int32 value1 = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop()); if (value1.Value > value2.Value) ret.Value = 1; else ret.Value = 0; } else throw new Exception("Unsupported data type for instruction cgt"); ret.IsThreadLocal = true; ret.IsConcrete = true; threadState.ThreadStack.Push(ret.GUID); return threadState.CurrentMethod.GetNextInstruction(this); }
public override CILInstruction Execute(ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("This add instruction is not ready to execute"); if(threadState.GetValue(threadState.ThreadStack.Peek()) is VMValue_int32) { VMValue_int32 value1 = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_int32 value2 = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_int32 sum = (VMValue_int32)threadState.SystemState.Values.MakeValue(new CILVar_int32("")); sum.Value = value1.Value * value2.Value; sum.IsThreadLocal = true; sum.IsConcrete = true; threadState.ThreadStack.Push(sum.GUID); } else if(threadState.GetValue(threadState.ThreadStack.Peek()) is VMValue_double) { VMValue_double value1 = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_double value2 = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_double sum = (VMValue_double)threadState.SystemState.Values.MakeValue(new CILVar_double("")); sum.Value = value1.Value * value2.Value; sum.IsThreadLocal = true; sum.IsConcrete = true; threadState.ThreadStack.Push(sum.GUID); }else throw new Exception("Unknown value type on stack for mul"); return threadState.CurrentMethod.GetNextInstruction(this); }
public override CILInstruction Execute(ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("FATAL: Calling execute on an unexecutable instruction state"); // thread special data type // .ThreadStart // .Thread if(classType.Name == "[mscorlib]System.Threading.ThreadStart") { VMValue_ftn method = (VMValue_ftn)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_object theobj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_threadstart ts = threadState.SystemState.Values.MakeThreadStartValue(theobj, method); ts.IsConcrete = true; VMValue_object ret = (VMValue_object)threadState.SystemState.Values.MakeValue(new CILVar_object("", new CILClass("[mscorlib]System.Threading.ThreadStart"))); ret.ValueGUID = ts.GUID; ret.IsThreadLocal = true; ret.IsConcrete = true; threadState.ThreadStack.Push(ret.GUID); } else if(classType.Name == "[mscorlib]System.Threading.Thread") { VMValue_object o = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_thread thethread = threadState.SystemState.Values.MakeThreadValue((VMValue_threadstart)threadState.GetValue(o.ValueGUID)); thethread.IsConcrete = true; VMValue_object ret = (VMValue_object)threadState.SystemState.Values.MakeValue(new CILVar_object("", new CILClass("[mscorlib]System.Threading.Thread"))); ret.ValueGUID = thethread.GUID; ret.IsThreadLocal = true; ret.IsConcrete = true; // TODO: be careful if we support enumeration of threads // then created threads are not local, maybe not here // because the thread has not started and cannot be // enumerated but it may have connection. threadState.ThreadStack.Push(ret.GUID); } else { // TODONOW: call the constructor function // right now we only make the data for the object instance and clean the stack, put the new obj on if(ctorSig.Equals("()") == false) { int counter = 1; int i; for(i = 0; i < ctorSig.Length; i++) if(ctorSig[i] == ',') counter++; for(i = 0; i < counter; i++) threadState.ThreadStack.Pop(); } VMValue_object obj = (VMValue_object)threadState.SystemState.Values.MakeValue(new CILVar_object("", classType)); VMValue_objectinst objinst = (VMValue_objectinst)threadState.SystemState.Values.MakeObjectInstance(new CILVar_object("", classType)); objinst.IsConcrete = true; obj.ValueGUID = objinst.GUID; obj.IsThreadLocal = true; obj.IsConcrete = true; threadState.ThreadStack.Push(obj.GUID); return threadState.CallFunction(classType.GetMethod(".ctor", "()")); } return threadState.CurrentMethod.GetNextInstruction(this); }
public override bool CanExecute(ThreadState threadState) { // this can be considered as an "arithmetic operation", so can't be executed // until both necessary values are ready VMValue v1 = threadState.GetValue(threadState.ThreadStack.Peek()); VMValue v2 = threadState.GetValue(threadState.ThreadStack.Peek(1)); return (v1.IsConcrete && v2.IsConcrete); }
/// <summary> /// Push a null pointer value onto the stack /// </summary> /// <param name="threadState"></param> /// <returns></returns> public override CILInstruction Execute(ThreadState threadState) { VMValue_object v = (VMValue_object)threadState.SystemState.Values.MakeNullValue(); v.IsThreadLocal = true; v.IsConcrete = true; threadState.ThreadStack.Push(v.GUID); return threadState.CurrentMethod.GetNextInstruction(this); }
/// <summary> /// Push a 4-byte-int onto the stack /// </summary> /// <param name="threadState"></param> /// <returns></returns> public override CILInstruction Execute(ThreadState threadState) { VMValue_int32 theConstant = (VMValue_int32)threadState.SystemState.Values.MakeValue(new CILVar_int32("")); theConstant.Value = value; theConstant.IsThreadLocal = true; theConstant.IsConcrete = true; threadState.ThreadStack.Push(theConstant.GUID); return threadState.CurrentMethod.GetNextInstruction(this); }
/// <summary> /// Execute a ldloc /// Initiate a DelayedRead and schedule it to the thread's queue /// </summary> /// <param name="threadState"></param> /// <returns></returns> public override CILInstruction Execute(ThreadState threadState) { VMValue source = threadState.GetLocalVariable(localVarIndex); VMValue target = threadState.SystemState.Values.MakeValue(source); target.IsThreadLocal = true; DelayedRead dr = new DelayedRead(target.GUID, source.GUID, this); dr.SourceInstruction = this; threadState.ThreadStack.Push(target.GUID); threadState.AddPendingAction(dr); return threadState.CurrentMethod.GetNextInstruction(this); }
/// <summary> /// Execute a stloc /// It will initiate a write and schedule it to the thread's queue /// </summary> /// <param name="threadState"></param> /// <returns></returns> public override CILInstruction Execute(ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("Can't execute this stloc now"); VMValue source = threadState.GetValue((int)threadState.ThreadStack.Pop()); VMValue target = threadState.GetLocalVariable(localVarIndex); DelayedWrite dw = new DelayedWrite(target.GUID, source.GUID, this); dw.SourceInstruction = this; threadState.AddPendingAction(dw); return threadState.CurrentMethod.GetNextInstruction(this); }
public override CILInstruction Execute(ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("This add instruction is not ready to execute"); VMValue_int64 value1 = (VMValue_int64)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_int32 newvalue = (VMValue_int32)threadState.SystemState.Values.MakeValue(new CILVar_int32("")); newvalue.Value = (int)value1.Value; newvalue.IsThreadLocal = true; newvalue.IsConcrete = true; threadState.ThreadStack.Push(newvalue.GUID); return threadState.CurrentMethod.GetNextInstruction(this); }
public override CILInstruction Execute(ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("This add instruction is not ready to execute"); VMValue_int32 value1 = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_arrayinst arrayInst = threadState.SystemState.Values.MakeArrayInst(value1.Value, elementType); VMValue_array arr = threadState.SystemState.Values.MakeArray(); arr.ArrayInstGuid = arrayInst.GUID; arr.IsConcrete = true; arr.IsThreadLocal = true; threadState.ThreadStack.Push(arr.GUID); return threadState.CurrentMethod.GetNextInstruction(this); }
public VMLocalVariableBlock Duplicate(ThreadState oldState, ThreadState newState) { VMLocalVariableBlock ret = new VMLocalVariableBlock(); ret.threadState = newState; for(int i = 0; i < variables.Count; i++) ret.variables.Add(variables[i]); for(int i = 0; i < arguments.Count; i++) ret.arguments.Add(arguments[i]); return ret; }
public VMLocalVariableBlock(ThreadState threadState, CILMethod method) { this.threadState = threadState; IEnumerator iter = method.GetLocalVariableEnumerator(); while(iter.MoveNext()) { CILVariable variable = (CILVariable)iter.Current; VMValue v = threadState.SystemState.Values.MakeValue(variable); v.IsThreadLocal = true; v.IsConcrete = true; variables.Add(v.GUID); } }
public override bool CanExecute(ThreadState threadState) { if(ctorSig.Equals("()")) return true; else { int counter = 1; for(int i = 0; i < ctorSig.Length; i++) if(ctorSig[i] == ',') counter++; FreeStack<int> fs = threadState.ThreadStack; for(int i = 1; i <= counter; i++) if(((VMValue)threadState.GetValue(fs[fs.Count - i])).IsConcrete == false) return false; return true; } }
public override bool CanExecute(ThreadState threadState) { // can always load a constant onto the stack return true; }
/// <summary> /// Add a new thread to this state /// This is called when a new thread is started /// </summary> /// <param name="newThread">Reference to the ThreadState object</param> public void AddThread(ThreadState newThread) { threads.Add(newThread); }
public static State MakeInitialState(CILProgram program) { State state = new State(); state.values = new VMValueManager(); state.heap = new VMGlobalVariables(state); state.program = program; VMValue_ftn ftn = state.Values.MakeFtnValue(program.EntryPoint); ftn.IsConcrete = true; VMValue_object obj = (VMValue_object)state.Values.MakeValue(new CILVar_object("", program.GetClass("[mscorlib]System.Object"))); obj.IsConcrete = true; VMValue_threadstart ts = state.Values.MakeThreadStartValue(obj, ftn); ts.IsConcrete = true; VMValue_thread threadobj = state.Values.MakeThreadValue(ts); threadobj.IsConcrete = true; ThreadState initThread = new ThreadState(state, threadobj); state.AddThread(initThread); state.TakeSnapshot(); return state; }
public override bool CanExecute(ThreadState threadState) { VMValue v1 = threadState.GetValue(threadState.ThreadStack.Peek()); return v1.IsConcrete; }
public override CILInstruction Execute(mmchecker.vm.ThreadState threadState) { if(CanExecute(threadState) == false) throw new Exception("This instruction is not ready to start"); if(theMethod.ParentClass.Name == "[mscorlib]System.Threading.Thread") { if(theMethod.Name == "Start") { // Gets the needed details and then add the thread to global datastructure // The new thread is ready to be executed in the next step // TODO: Do POR on initial bytecodes of the thread to reduce one step VMValue_object threadptr = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop()); VMValue_thread threadobj = (VMValue_thread)threadState.GetValue(threadptr.ValueGUID); ThreadState newThread = new ThreadState(threadState.SystemState, threadobj); // no need to refer back // TODO: we may need the details later, but it causes problems for dynamic escape analysis // by letting the original thread keep the pointer to the object threadobj.ThreadStartGUID = -1; threadState.SystemState.AddThread(newThread); return threadState.CurrentMethod.GetNextInstruction(this); } else if(theMethod.Name == "Join") { // Only need to pop the thread id, because the CanExecute() already // make sure the thread that this thread must join has already ended threadState.ThreadStack.Pop(); return threadState.CurrentMethod.GetNextInstruction(this); }else throw new Exception("Not supported yet"); } else { return threadState.CallFunction(theMethod); } }
public override bool CanExecute(ThreadState threadState) { // TODO: Can be more relaxed but not important now, check semantic later VMValue v1 = threadState.GetValue(threadState.ThreadStack.Peek()); return v1.IsConcrete; }
/// <summary> /// stloc can always be executed, even if the value on the stack /// is not concrete yet /// </summary> /// <param name="threadState"></param> /// <returns></returns> public override bool CanExecute(ThreadState threadState) { return true; }
public ThreadState Duplicate(State oldState, State newState) { ThreadState ret = new ThreadState(); ret.systemState = newState; ret.threadID = threadID; ret.syncState = syncState; ret.waitingOn = waitingOn; for(int i = 0; i < threadStack.Count; i++) ret.threadStack.Add(threadStack[i]); for(int i = 0; i < localVariableBlocks.Count; i++) ret.localVariableBlocks.Push(localVariableBlocks[i].Duplicate(this, ret)); IEnumerator<DelayedAction> iter = pendingActions.GetEnumerator(); while(iter.MoveNext()) ret.pendingActions.Add(iter.Current.Duplicate()); ret.returnAddresses = new FreeStack<ReturnAddress>(); foreach(ReturnAddress ra in returnAddresses) ret.returnAddresses.Add(ra.Duplicate()); ret.currentMethod = currentMethod; ret.pc = pc; return ret; }