private bool IsClearlySafe(MethodCallInstruction instruction) { //TODO: can this be done better? var method = instruction.Method; var mtype = method.ContainingType; if (mtype.FullName() == "ScopeRuntime.Row" || mtype.FullName() == "ScopeRuntime.RowSet" || mtype.FullName() == "ScopeRuntime.ColumnData") { return(true); } if (instruction.Arguments.Count != 1) { return(false); } var name = mtype.NestedName(); if (name.StartsWith("IEnumerator<") || name.StartsWith("IEnumerable<") || name.StartsWith("List<") || name.StartsWith("HashSet<") || name.StartsWith("Dictionary<") || name.StartsWith("Queue<") || name.StartsWith("Stack<") || name.StartsWith("LinkedList<") || name.StartsWith("SortedList<") || name.StartsWith("SortedSet<")) { return(true); } return(false); }
public override void Visit(MethodCallInstruction instruction) { if (instruction.HasResult) { instruction.Result.Type = instruction.Method.Type; } }
private void ProcessJsonCall(MethodCallInstruction methodCall) { if (methodCall.Method.Name.Value == "DeserializeObject") { ptAnalysis.ProcessJSonAlloc(State, methodCall.Offset, methodCall.Result); } }
private void ProcessDelegateCtor(MethodCallInstruction methodCall) { if (methodCall.Arguments.Any()) { var arg0Type = methodCall.Arguments[0].Type; if (arg0Type.IsDelegateType()) { State.RemoveRootEdges(methodCall.Arguments[0]); if (methodCall.Arguments.Count == 3) { // instance delegate foreach (var dn in State.GetTargets(methodCall.Arguments[2]).OfType <DelegateNode>()) { dn.Instance = methodCall.Arguments[1]; State.PointsTo(methodCall.Arguments[0], dn); } } else { foreach (var dn in State.GetTargets(methodCall.Arguments[1]).OfType <DelegateNode>()) { State.PointsTo(methodCall.Arguments[0], dn); } } } } }
public override void Visit(MethodCallInstruction instruction) { if (instruction.HasResult) { // If we have Schema.IndexOf(param) and param is a constant, then we remember param // as return value. if (IsSchemaGetColumnIndex(instruction)) { SavePreState(instruction, FreshCurrent()); var nstate = FreshCurrent(); UpdateStateCopy(nstate, instruction.Result, instruction.Arguments.ElementAt(1)); SetCurrent(nstate); SavePostState(instruction, FreshCurrent()); } else { // Here we explicitly handle string concatenation. In other words, if we have // String.Concat method and both arguments are finite set of constants, then // we do cross-product concatenation. Column string concat happens in Scope scripts. if (IsStringConcatenationPossible(instruction, State)) { var cons1 = State.Constants(instruction.Arguments.ElementAt(0)); var cons2 = State.Constants(instruction.Arguments.ElementAt(1)); var strings = new HashSet <string>(); foreach (var c1 in cons1.Elements) { foreach (var c2 in cons2.Elements) { var s1 = c1.Value == null ? String.Empty : c1.Value.ToString(); var s2 = c2.Value == null ? String.Empty : c2.Value.ToString(); strings.Add(s1 + s2); } } var cpd = ConstantSetDomain.Bottom; foreach (var s in strings) { cpd.Add(new Constant(s)); } SavePreState(instruction, FreshCurrent()); var nstate = FreshCurrent(); nstate.Set(instruction.Result, cpd); SetCurrent(nstate); SavePostState(instruction, FreshCurrent()); } else { DefaultVarTop(instruction, instruction.Result); } } } else { Default(instruction); } }
public virtual void VisitMethodCall(MethodCallInstruction x) { foreach (var arg in x.Arguments) { arg.VisitMe(this); } x.ThisObject.VisitMe(this); VisitInstruction(x); }
public override void Visit(MethodCallInstruction instruction) { var methodCall = instruction as MethodCallInstruction; // Hack for mapping delegates to nodes if (methodCall.Method.Name == ".ctor" && this.analyzeNextDelegateCtor) { ProcessDelegateCtor(methodCall); this.analyzeNextDelegateCtor = false; } }
public override void Visit(MethodCallInstruction instruction) { if (instruction.HasResult) { DefaultVarTop(instruction, instruction.Result); } else { Default(instruction); } }
public override void VisitMethodCall(MethodCallInstruction x) { var thisObj = getValue(x.ThisObject); var args = new List <Expression>(); foreach (var arg in x.Arguments) { args.Add(getValue(arg)); } emit(_compiler.MethodCall(x.IsStatic(), thisObj, x.Method, args)); }
private bool IsGetOrSetProp(MethodCallInstruction m) { if (!m.Method.Type.Equals(Types.Instance.PlatformType.SystemVoid) && m.Method.Name.Value.StartsWith("get_")) { return(true); } if (m.Method.Type.Equals(Types.Instance.PlatformType.SystemVoid) && m.Method.Name.Value.StartsWith("set_")) { return(true); } return(false); }
public override void Visit(MethodCallInstruction instruction) { // We don't classify rows as escaped if they are passed // to whitelisted trusted methods. if (IsClearlySafe(instruction)) { SavePreState(instruction, FreshCurrent()); SetCurrent(FreshCurrent()); SavePostState(instruction, FreshCurrent()); } else { VisitMethodInvocation(instruction, instruction.Result, instruction.Arguments, instruction.HasResult, instruction.Method.IsStatic); } }
public override void Visit(MethodCallInstruction instruction) { var methodCall = instruction as MethodCallInstruction; // Hack for mapping delegates to nodes if (methodCall.Method.Name.Value == ".ctor" && this.analyzeNextDelegateCtor) { ProcessDelegateCtor(methodCall); this.analyzeNextDelegateCtor = false; } // DIEGODIEGO: Maybe this is no longer necessary //if (methodCall.Method.ContainingType.GetName().Contains("JsonConvert")) //{ // ProcessJsonCall(methodCall); //} }
/// <summary> /// Check if a method stands for accessing a column and soundly compute /// what columns are actually accessed. /// </summary> /// <param name="arguments"></param> /// <returns></returns> private ColumnsDomain GetCols(MethodCallInstruction instruction) { var ct = instruction.Method.ContainingType; // The methods must belong to Row. if (rowTypes.All(rt => ct != null && !ct.SubtypeOf(rt, host))) { return(ColumnsDomain.Bottom); } // If we don't trust the method, then only safe thing to do is to // set all columns have been used. if (!trustedRowMethods.Contains(instruction.Method.Name.Value)) { Utils.WriteLine("USED COLUMNS untrusted method: " + instruction.ToString()); return(ColumnsDomain.Top); } // get_Schema function is safe. if (instruction.Arguments.Count == 1) { return(ColumnsDomain.Bottom); } var arg = instruction.Arguments.ElementAt(1); var cons = constInfo.GetConstants(instruction, arg); // If we don't know the initial value of the variable or the // variable cannot take value from a finite set of constants, // then we cannot say what column was used here, and in general. if (cons == null || cons.Count() == 0) { Utils.WriteLine("USED COLUMNS top|bottom: " + instruction.ToString()); return(ColumnsDomain.Top); } else { UpdateColumnAccessesStats(arg.Type); var cols = ColumnsDomain.Bottom; foreach (var c in cons) { cols.Add(c); } return(cols); } }
public override void Visit(MethodCallInstruction instruction) { var methodCall = instruction; if (methodCall.Method.Name.Equals(".ctor") && methodCall.HasResult) { var variable = methodCall.Arguments[0] as IVariable; var lastDefs = depAnalysis.LastDefGet(variable); depAnalysis.SetDataDependency((int)methodCall.Offset, lastDefs); depAnalysis.LastDefSet(methodCall.Result, (int)methodCall.Offset); } else { MyDefault(instruction); // base.Visit(instruction); } }
/// <summary> /// Method that conservatively checks if the current method is string concatenation /// and parameters are known string constants. /// </summary> /// <param name="instruction"></param> /// <param name="state"></param> /// <returns></returns> private bool IsStringConcatenationPossible(MethodCallInstruction instruction, ConstantPropagationDomain state) { if (!instruction.HasResult) { return(false); } if (instruction.Arguments.Count != 2) { return(false); } if (instruction.Method.ContainingType.FullName() != "System.String") { return(false); } if (instruction.Method.Name.Value != "Concat") { return(false); } var arg0 = instruction.Arguments.ElementAt(0); var arg1 = instruction.Arguments.ElementAt(1); if (arg0.Type.FullName() != "System.String" || arg1.Type.FullName() != "System.String") { return(false); } var cons1 = state.Constants(arg0); var cons2 = state.Constants(arg1); if (cons1.IsBottom || cons2.IsBottom || cons1.IsTop || cons2.IsTop) { return(false); } return(true); }
public bool IsInMethodCallAsRef(IVariable var) { // if we found a method call instruction that uses var as a ref parameter, then return true // manuel: test behavior with out parameters for (int i = instructionIndex + 1; i < methodBody.Instructions.Count(); i++) { MethodCallInstruction methodCallIns = methodBody.Instructions[i] as MethodCallInstruction; if (methodCallIns != null) { if (!methodCallIns.Method.IsStatic && methodCallIns.Arguments.Count() == 1) // only 'this' { continue; } if (methodCallIns.Arguments.IndexOf(var) != -1) { // subtract one because of the "this" argument var idx = methodCallIns.Arguments.IndexOf(var) + (!methodCallIns.Method.IsStatic ? -1 : 0); // This is null if (idx == -1) { return(false); } // not sure what happens to out parameters // here 'this' is not listed if (methodCallIns.Method.Parameters.ElementAt(idx).IsByReference) { return(true); } } } } return(false); }
public override void Visit(MethodCallInstruction instruction) { if (instruction.HasResult) { instruction.Result.Type = instruction.Method.Type; } // Skip implicit "this" parameter. var offset = instruction.Method.IsStatic ? 0 : 1; for (var i = offset; i < instruction.Arguments.Count; ++i) { var argument = instruction.Arguments[i]; var parameter = instruction.Method.Parameters.ElementAt(i - offset); // Set the null variable a type. if (argument.Type == null || parameter.Type.TypeCode == PrimitiveTypeCode.Boolean) { argument.Type = parameter.Type; } } }
private bool IsSchemaGetColumnIndex(MethodCallInstruction instruction) { if (!instruction.HasResult || instruction.Arguments.Count != 2) { return(false); } if (!IsConstantType(instruction.Arguments.ElementAt(1).Type)) { return(false); } if (instruction.Method.Name.Value != "get_Item" && instruction.Method.Name.Value != "IndexOf") { return(false); } if (!parent.IsSchema(instruction.Method.ContainingType)) { return(false); } return(true); }
public static void Inline(this MethodBody callerBody, MethodCallInstruction methodCall, MethodBody calleeBody) { // TODO: Fix local variables (and parameters) name clashing var index = callerBody.Instructions.IndexOf(methodCall); callerBody.Instructions.RemoveAt(index); Instruction nextInstruction = null; if (callerBody.Instructions.Count > index) { // The caller method has more instructions after the method call nextInstruction = callerBody.Instructions[index]; } for (var i = 0; i < calleeBody.Parameters.Count; ++i) { var parameter = calleeBody.Parameters[i]; var argument = methodCall.Arguments[i]; var copy = new LoadInstruction(methodCall.Offset, parameter, argument); copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label); callerBody.Instructions.Insert(index, copy); index++; } var lastCalleeInstructionIndex = calleeBody.Instructions.Count - 1; for (var i = 0; i < calleeBody.Instructions.Count; ++i) { var instruction = calleeBody.Instructions[i]; if (instruction is ReturnInstruction) { var ret = instruction as ReturnInstruction; if (ret.HasOperand && methodCall.HasResult) { // Copy the return value of the callee to the result variable of the method call var copy = new LoadInstruction(ret.Offset, methodCall.Result, ret.Operand); copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label); callerBody.Instructions.Insert(index, copy); index++; } if (nextInstruction != null && i < lastCalleeInstructionIndex) { // Jump to the instruction after the method call var branch = new UnconditionalBranchInstruction(ret.Offset, nextInstruction.Offset); branch.Label = string.Format("{0}_{1}", methodCall.Label, branch.Label); callerBody.Instructions.Insert(index, branch); index++; } } else { // TODO: Fix! We should clone the instruction // so the original is not modified // and calleeBody remain intacted if (instruction is BranchInstruction) { var branch = instruction as BranchInstruction; branch.Target = string.Format("{0}_{1}", methodCall.Label, branch.Target); } else if (instruction is SwitchInstruction) { var branch = instruction as SwitchInstruction; for (var j = 0; j < branch.Targets.Count; ++j) { var target = branch.Targets[j]; branch.Targets[j] = string.Format("{0}_{1}", methodCall.Label, target); } } instruction.Label = string.Format("{0}_{1}", methodCall.Label, instruction.Label); callerBody.Instructions.Insert(index, instruction); index++; } } }
public virtual void Visit(MethodCallInstruction instruction) { Default(instruction); }
public virtual void Visit(MethodCallInstruction instruction) { }
public Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> > ComputePotentialCallees(MethodCallInstruction instruction, SimplePointsToGraph ptg) { var resolvedCallees = new HashSet <IMethodDefinition>(); var unresolvedCallees = new HashSet <IMethodReference>(); var potentalDelegateCall = instruction.Method; // If it is a delegate if (potentalDelegateCall.Name.Value == "Invoke") { var classDef = (potentalDelegateCall.ContainingType.ResolvedType) as INamedTypeDefinition; if (classDef != null && classDef.IsDelegate) { var delegateVar = instruction.Arguments[0]; return(ComputeDelegate(delegateVar, ptg)); //var potentialDelegates = ptg.GetTargets(delegateVar); //var resolvedInvocations = potentialDelegates.OfType<DelegateNode>() // .Select(d => this.host.FindMethodImplementation(d.Instance.Type as BasicType, d.Method) as IMethodReference); //resolvedCallees.UnionWith(resolvedInvocations.OfType<MethodDefinition>()); //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !resolvedCallees.Contains(c))); } } else { if (!instruction.Method.IsStatic && instruction.Method.Name.Value != ".ctor") { var receiver = instruction.Arguments[0]; var types = ptg.GetTargets(receiver, false).Where(n => n.Kind != SimplePTGNodeKind.Null && n.Type != null).Select(n => n.Type); var candidateCalless = types.Select(t => t.FindMethodImplementation(instruction.Method)); var resolvedInvocations = candidateCalless.Select(c => c.ResolvedMethod as IMethodReference); resolvedCallees.UnionWith(resolvedInvocations.OfType <IMethodDefinition>()); unresolvedCallees.UnionWith(candidateCalless.Where(c => !resolvedInvocations.Contains(c) && (c.Name.Value != "Dispose" && c.ContainingType.ContainingAssembly() == "mscorlib"))); //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !(c is MethodDefinition))); } else { var candidateCalee = instruction.Method.ContainingType.FindMethodImplementation(instruction.Method); var resolvedCalle = candidateCalee.ResolvedMethod; if (resolvedCalle != null) { resolvedCallees.Add(resolvedCalle); } } } return(new Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> >(resolvedCallees, unresolvedCallees)); }
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(); } } } }