public void VisitLocals(MethodBody mBody) { ISet <IVariable> localVarSet = mBody.Variables; foreach (IVariable lclVar in localVarSet) { if (!lclVar.IsParameter && lclVar.Type.ResolvedType.IsStruct) { Stubber.CheckAndAdd(lclVar.Type.ResolvedType); } } return; }
public static IMethodDefinition GetInstantiatedMeth(IMethodDefinition templateMeth, IMethodDefinition instMeth) { IGenericMethodInstance genericM = instMeth as IGenericMethodInstance; IEnumerable <ITypeReference> genericArgs = genericM.GenericArguments; IList <ITypeReference> stubbedArgList = new List <ITypeReference>(); foreach (ITypeReference garg in genericArgs) { ITypeDefinition addedType = Stubber.CheckAndAdd(garg.ResolvedType); if (addedType != null) { stubbedArgList.Add(addedType); } else { stubbedArgList.Add(garg.ResolvedType); } } string argStr = GetGenericArgStr(stubbedArgList); IDictionary <string, IMethodDefinition> instMap; if (ClassAndMethodVisitor.genericMethodMap.ContainsKey(templateMeth)) { instMap = ClassAndMethodVisitor.genericMethodMap[templateMeth]; } else { instMap = new Dictionary <string, IMethodDefinition>(); ClassAndMethodVisitor.genericMethodMap[templateMeth] = instMap; } if (instMap.ContainsKey(argStr)) { return(instMap[argStr]); } else { GenericMethodInstanceReference newInstMethRef = new GenericMethodInstanceReference(templateMeth, genericArgs, internFactory); IMethodDefinition newInstMeth = newInstMethRef.ResolvedMethod; instMap[argStr] = newInstMeth; return(newInstMeth); } }
private void ProcessStaticConstructors(ITypeDefinition ty) { if (!rtaAnalyzer.clinitProcessedClasses.Contains(ty) && !Stubber.SuppressM(ty)) { rtaAnalyzer.clinitProcessedClasses.Add(ty); IMethodDefinition clinitMeth = Utils.GetStaticConstructor(ty); if (clinitMeth != null) { Stubber.CheckAndAdd(clinitMeth); } if (ty.BaseClasses.Any()) { ITypeDefinition baseTy = ty.BaseClasses.Single().ResolvedType; ProcessStaticConstructors(baseTy); } foreach (ITypeReference itf in ty.Interfaces) { ITypeDefinition itfD = itf.ResolvedType; ProcessStaticConstructors(itfD); } } }
public void Traverse(IMethodDefinition methodDefinition) { ControlFlowGraph cfg; MethodBody methodBody; IList <CatchExceptionHandler> ehInfoList; if (methodToCfgAndTacMap.ContainsKey(methodDefinition)) { MethodCfgAndTac mct = methodToCfgAndTacMap[methodDefinition]; if (mct == null) { return; } cfg = mct.cfg; methodBody = mct.methodBody; ehInfoList = mct.ehInfoList; } else { MethodCfgAndTac mct = AnalyzeIntraProcedural(methodDefinition); methodToCfgAndTacMap[methodDefinition] = mct; if (mct == null) { return; } cfg = mct.cfg; methodBody = mct.methodBody; ehInfoList = mct.ehInfoList; } if (rtaAnalyzer != null) { if (rtaAnalyzer.entryPtClasses.Contains(methodDefinition.ContainingTypeDefinition)) { if (rtaAnalyzer.rootIsExe) { // Add only the Main method as entry point if (Utils.IsMainMethod(methodDefinition)) { rtaAnalyzer.rtaLogSW.WriteLine("Adding main method: {0}", methodDefinition.FullName()); IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition); // The assumption is that addedMeth is not a template method. Here it is safe because it holds for the main method. if (addedMeth != null) { rtaAnalyzer.entryPtMethods.Add(addedMeth); } } } else { if (methodDefinition.Visibility == TypeMemberVisibility.Public || methodDefinition.Visibility == TypeMemberVisibility.Family) { // Otherwise, add all public methods as entry points IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition); rtaAnalyzer.rtaLogSW.WriteLine("Adding method: {0}", methodDefinition.FullName()); // The assumption here is that addedMeth is not a template method. // TODO: It may be the case that this assumption does not hold in some cases. if (addedMeth != null) { rtaAnalyzer.entryPtMethods.Add(addedMeth); } } } } if (rtaAnalyzer.methods.Contains(methodDefinition) && !rtaAnalyzer.visitedMethods.Contains(methodDefinition)) { rtaAnalyzer.visitedMethods.Add(methodDefinition); // rtaAnalyzer.rtaLogSW.WriteLine("SRK_DBG: Visiting method: {0}", methodDefinition.GetName()); rtaAnalyzer.VisitMethod(methodBody, cfg); } else { rtaAnalyzer.ignoredMethods.Add(methodDefinition); } } else if (factGen != null) { if (factGen.methods.Contains(methodDefinition)) { factGen.GenerateFacts(methodBody, cfg, ehInfoList); } } }
public void VisitMethod(MethodBody mBody, ControlFlowGraph cfg) { VisitLocals(mBody); // Going through the instructions via cfg nodes instead of directly iterating over the instructions // of the methodBody becuase Phi instructions may not have been inserted in the insts of the methodBody. foreach (var node in cfg.Nodes) { foreach (var instruction in node.Instructions) { // System.Console.WriteLine("{0}", instruction.ToString()); // System.Console.WriteLine("{0}", instruction.GetType().FullName()); // System.Console.WriteLine(); if (instruction is LoadInstruction) { LoadInstruction lInst = instruction as LoadInstruction; IValue rhsOperand = lInst.Operand; if (rhsOperand is StaticFieldAccess) { StaticFieldAccess rhsAcc = rhsOperand as StaticFieldAccess; IFieldReference fld = rhsAcc.Field; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); } // Note: calls to static methods and instance methods appear as a StaticMethodReference else if (rhsOperand is StaticMethodReference) { StaticMethodReference sMethAddr = rhsOperand as StaticMethodReference; IMethodDefinition tgtMeth = sMethAddr.Method.ResolvedMethod; ITypeDefinition containingTy = tgtMeth.ContainingTypeDefinition; Stubber.CheckAndAdd(containingTy); IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth); // addrTakenMethods do not contain templates. if (addedMeth != null) { addrTakenMethods.Add(addedMeth); } } //Note: calls to virtual, abstract or interface methods appear as VirtualMethodReference else if (rhsOperand is VirtualMethodReference) { VirtualMethodReference sMethAddr = rhsOperand as VirtualMethodReference; IMethodDefinition tgtMeth = sMethAddr.Method.ResolvedMethod; ITypeDefinition containingTy = tgtMeth.ContainingTypeDefinition; ITypeDefinition addedTy = Stubber.CheckAndAdd(containingTy); IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth); if (addedTy != null && addedMeth != null) { // addrTakenMethods do not contain templates. addrTakenMethods.Add(addedMeth); ProcessVirtualInvoke(addedMeth, addedTy, true); } } else if (rhsOperand is Reference) { Reference rhsRef = rhsOperand as Reference; IReferenceable refOf = rhsRef.Value; if (refOf is StaticFieldAccess) { StaticFieldAccess refAcc = refOf as StaticFieldAccess; IFieldDefinition fld = refAcc.Field.ResolvedField; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); addrTakenStatFlds.Add(fld); } else if (refOf is IVariable) { IVariable refVar = refOf as IVariable; if (!refVar.Type.IsValueType || refVar.Type.ResolvedType.IsStruct) { addrTakenLocals.Add(refVar); } } else if (refOf is InstanceFieldAccess) { InstanceFieldAccess refAcc = refOf as InstanceFieldAccess; IFieldDefinition fld = refAcc.Field.ResolvedField; addrTakenInstFlds.Add(fld); } else if (refOf is ArrayElementAccess) { // All arrays will be added into domX as potential address taken. } } } else if (instruction is StoreInstruction) { StoreInstruction sInst = instruction as StoreInstruction; IAssignableValue lhs = sInst.Result; if (lhs is StaticFieldAccess) { StaticFieldAccess lhsAcc = lhs as StaticFieldAccess; IFieldReference fld = lhsAcc.Field; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); } } else if (instruction is CreateObjectInstruction) { CreateObjectInstruction newObjInst = instruction as CreateObjectInstruction; ITypeReference objType = newObjInst.AllocationType; ITypeDefinition objTypeDef = objType.ResolvedType; if (objTypeDef is IGenericTypeInstance) { objTypeDef = objTypeDef.ResolvedType; } ITypeDefinition addedTy = Stubber.CheckAndAdd(objTypeDef); if (addedTy != null && !allocClasses.Contains(addedTy)) { allocClasses.Add(addedTy); } } else if (instruction is CreateArrayInstruction) { CreateArrayInstruction newArrInst = instruction as CreateArrayInstruction; ITypeReference elemType = newArrInst.ElementType; ITypeDefinition elemTypeDef = elemType.ResolvedType; ITypeDefinition addedTy = Stubber.CheckAndAdd(elemTypeDef); if (addedTy != null && !allocClasses.Contains(addedTy)) { allocClasses.Add(addedTy); } } else if (instruction is MethodCallInstruction) { MethodCallInstruction invkInst = instruction as MethodCallInstruction; IMethodReference callTgt = invkInst.Method; ITypeReference containingType = callTgt.ContainingType; ITypeDefinition declType = containingType.ResolvedType; IMethodDefinition callTgtDef = callTgt.ResolvedMethod; ITypeDefinition addedType = Stubber.CheckAndAdd(declType); IMethodDefinition addedMeth = Stubber.CheckAndAdd(callTgtDef); MethodCallOperation callType = invkInst.Operation; if (callType == MethodCallOperation.Virtual && addedType != null && addedMeth != null) { ProcessVirtualInvoke(addedMeth, addedType, false); } } else { // System.Console.WriteLine("{0}", instruction.ToString()); // System.Console.WriteLine("Not currently handled: {0}", instruction.GetType().ToString()); // System.Console.WriteLine(); } } } }
public void ProcessVirtualInvoke(IMethodDefinition mCallee, ITypeDefinition calleeClass, bool isAddrTaken) { // mCallee is an ordinary method - never a template method. // calleeClass and mCallee are either both stubbed or, both unstubbed - i.e. they are consistent. bool isInterface = calleeClass.IsInterface; IMethodDefinition calleeTemplate = null; if (mCallee is IGenericMethodInstance) { calleeTemplate = (mCallee as IGenericMethodInstance).GenericMethod.ResolvedMethod; } foreach (ITypeDefinition cl in allocClasses) { if (cl is IArrayTypeReference) { continue; } if (!Stubber.SuppressM(cl)) { bool process = false; if (isInterface && Utils.ImplementsInterface(cl, calleeClass)) { process = true; } if (Utils.ExtendsClass(cl, calleeClass)) { process = true; } if (!process) { continue; } IMethodDefinition calleeArg; if (mCallee is IGenericMethodInstance) { calleeArg = calleeTemplate; } else { calleeArg = mCallee; } IMethodDefinition meth = Utils.GetMethodSignMatchRecursive(cl, calleeArg); if (meth == null) { continue; } if (meth.IsGeneric && calleeTemplate != null) { IMethodDefinition instMeth = GenericMethods.RecordInfo(meth, mCallee, /* createIfReqd = */ true); IMethodDefinition addedMeth = Stubber.CheckAndAdd(instMeth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } else if (meth.IsGeneric && calleeTemplate == null) { continue; } else if (!meth.IsGeneric && calleeTemplate != null) { continue; } else // meth is not generic and calleeTemplate is null { IMethodDefinition addedMeth = Stubber.CheckAndAdd(meth); if (addedMeth != null && isAddrTaken) { addrTakenMethods.Add(addedMeth); } } } } }