Пример #1
0
        /// <summary>
        /// Appends a method store to the current one
        /// </summary>
        /// <param name="sem"></param>
        public void AppendMethodStore(SEMethodStore sem, int offset)
        {
            foreach (var defelem in sem.DefinedFieldSet.Values)
            {
                SEFieldStore sef;
                if (!this.defFieldSet.TryGetValue(defelem.FullName, out sef))
                {
                    sef = new SEFieldStore(defelem.FullName);
                    sef.OptionalField = defelem.OptionalField;
                    this.defFieldSet[defelem.FullName] = sef;
                }

                sef.AllOffsets.Add(offset);
            }

            foreach (var useelem in sem.UsedFieldSet.Values)
            {
                SEFieldStore sef;
                if (!this.useFieldSet.TryGetValue(useelem.FullName, out sef))
                {
                    sef = new SEFieldStore(useelem.FullName);
                    sef.OptionalField = useelem.OptionalField;
                    this.useFieldSet[useelem.FullName] = sef;
                }

                sef.AllOffsets.Add(offset);
            }
        }
Пример #2
0
        public override bool Equals(object obj)
        {
            SEMethodStore other = obj as SEMethodStore;

            if (other == null)
            {
                return(false);
            }

            return(this.methodName == other.methodName);
        }
Пример #3
0
        /// <summary>
        /// Adds that method defines the field
        /// </summary>
        /// <param name="method"></param>
        /// <param name="field"></param>
        public void AddFieldDefinition(Method method, Field field, int offset)
        {
            //Prevent adding information not related to current assembly
            if (this.CurrAssembly == null || method.Definition.Module.Assembly != this.CurrAssembly)
            {
                return;
            }

            SEMethodStore sem;

            if (!this.methodStore.TryGetValue(method.FullName, out sem))
            {
                sem = new SEMethodStore(method.FullName);
                sem.OptionalMethod = method;
                this.methodStore[method.FullName] = sem;
            }

            sem.AddToDefinedList(field, offset);
        }
Пример #4
0
        /// <summary>
        /// Appends a method store to the one in the repository
        /// </summary>
        /// <param name="sem"></param>
        public void AppendMethodStore(SEMethodStore sem)
        {
            //Prevent adding information not related to current assembly
            if (this.CurrAssembly == null || sem.OptionalMethod.Definition.Module.Assembly != this.CurrAssembly)
            {
                return;
            }

            SEMethodStore repositoryStore;

            if (!this.methodStore.TryGetValue(sem.MethodName, out repositoryStore))
            {
                repositoryStore = new SEMethodStore(sem.MethodName);
                repositoryStore.OptionalMethod   = sem.OptionalMethod;
                this.methodStore[sem.MethodName] = repositoryStore;
            }

            //Append fields that are within our assembly
            foreach (var deffield in sem.DefinedFieldSet.Values)
            {
                if (deffield.OptionalField.Definition.Module.Assembly != this.CurrAssembly)
                {
                    continue;
                }
                repositoryStore.DefinedFieldSet[deffield.FullName] = deffield;
            }

            foreach (var usefield in sem.UsedFieldSet.Values)
            {
                if (usefield.OptionalField.Definition.Module.Assembly != this.CurrAssembly)
                {
                    continue;
                }
                repositoryStore.UsedFieldSet[usefield.FullName] = usefield;
            }
        }
Пример #5
0
        /// <summary>
        /// Reads from the database
        /// </summary>
        /// <returns></returns>
        public static SideEffectStore ReadFromDatabase()
        {
            try
            {
                var filename = Path.Combine(DUCoverConstants.DUCoverStoreLocation, DUCoverConstants.SideEffectStoreDebugFile);
                SideEffectStore ses = new SideEffectStore();
                if (!File.Exists(filename))
                    return ses;

                using (StreamReader sr = new StreamReader(filename))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        line.Trim();
                        string methodname = line;
                        SEMethodStore sem = new SEMethodStore(methodname);
                        ses.MethodStore[methodname] = sem;

                        //Reading defined
                        line = sr.ReadLine().Trim();
                        string[] parts = line.Split(' ');

                        int numDefined = Convert.ToInt32(parts[1]);
                        for (int count = 0; count < numDefined; count++)
                        {
                            line = sr.ReadLine().Trim();
                            string[] lineparts = line.Split(' ');

                            SEFieldStore sef = new SEFieldStore(lineparts[0]);
                            sem.DefinedFieldSet[lineparts[0]] = sef;
                            for (int tcount = 1; tcount < lineparts.Length; tcount++)
                            {
                                sef.AllOffsets.Add(Convert.ToInt32(lineparts[tcount]));
                            }
                        }

                        //Reading used
                        line = sr.ReadLine().Trim();
                        parts = line.Split(' ');

                        int numUsed = Convert.ToInt32(parts[1]);
                        for (int count = 0; count < numUsed; count++)
                        {
                            line = sr.ReadLine().Trim();
                            string[] lineparts = line.Split(' ');

                            SEFieldStore sef = new SEFieldStore(lineparts[0]);
                            sem.UsedFieldSet[lineparts[0]] = sef;
                            for (int tcount = 1; tcount < lineparts.Length; tcount++)
                            {
                                sef.AllOffsets.Add(Convert.ToInt32(lineparts[tcount]));
                            }
                        }
                    }
                }

                Console.WriteLine("Number of entries read: " + ses.MethodStore.Count);
                return ses;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to deserialize");
                logger.ErrorException("Error occurred while reading from file " + ex.StackTrace, ex);
            }

            return new SideEffectStore();
        }
Пример #6
0
        /// <summary>
        /// Appends a method store to the one in the repository
        /// </summary>
        /// <param name="sem"></param>
        public void AppendMethodStore(SEMethodStore sem)
        {
            //Prevent adding information not related to current assembly
            if (this.CurrAssembly == null || sem.OptionalMethod.Definition.Module.Assembly != this.CurrAssembly)
                return;

            SEMethodStore repositoryStore;
            if(!this.methodStore.TryGetValue(sem.MethodName, out repositoryStore))
            {
                repositoryStore = new SEMethodStore(sem.MethodName);
                repositoryStore.OptionalMethod = sem.OptionalMethod;
                this.methodStore[sem.MethodName] = repositoryStore;
            }

            //Append fields that are within our assembly
            foreach (var deffield in sem.DefinedFieldSet.Values)
            {
                if (deffield.OptionalField.Definition.Module.Assembly != this.CurrAssembly)
                    continue;
                repositoryStore.DefinedFieldSet[deffield.FullName] = deffield;
            }

            foreach (var usefield in sem.UsedFieldSet.Values)
            {
                if (usefield.OptionalField.Definition.Module.Assembly != this.CurrAssembly)
                    continue;
                repositoryStore.UsedFieldSet[usefield.FullName] = usefield;
            }
        }
Пример #7
0
        /// <summary>
        /// Adds that method modifies the field
        /// </summary>
        /// <param name="method"></param>
        /// <param name="field"></param>
        public void AddFieldUsage(Method method, Field field, int offset)
        {
            //Prevent adding information not related to current assembly
            if (this.CurrAssembly == null || method.Definition.Module.Assembly != this.CurrAssembly)
                return;

            SEMethodStore sem;
            if (!this.methodStore.TryGetValue(method.FullName, out sem))
            {
                sem = new SEMethodStore(method.FullName);
                sem.OptionalMethod = method;
                this.methodStore[method.FullName] = sem;
            }

            sem.AddToUsedList(field, offset);
        }
Пример #8
0
        /// <summary>
        /// Appends a method store to the current one
        /// </summary>
        /// <param name="sem"></param>
        public void AppendMethodStore(SEMethodStore sem, int offset)
        {
            foreach (var defelem in sem.DefinedFieldSet.Values)
            {
                SEFieldStore sef;
                if (!this.defFieldSet.TryGetValue(defelem.FullName, out sef))
                {
                    sef = new SEFieldStore(defelem.FullName);
                    sef.OptionalField = defelem.OptionalField;
                    this.defFieldSet[defelem.FullName] = sef;
                }

                sef.AllOffsets.Add(offset);
            }

            foreach (var useelem in sem.UsedFieldSet.Values)
            {
                SEFieldStore sef;
                if (!this.useFieldSet.TryGetValue(useelem.FullName, out sef))
                {
                    sef = new SEFieldStore(useelem.FullName);
                    sef.OptionalField = useelem.OptionalField;
                    this.useFieldSet[useelem.FullName] = sef;
                }

                sef.AllOffsets.Add(offset);
            }
        }
Пример #9
0
        /// <summary>
        /// Reads from the database
        /// </summary>
        /// <returns></returns>
        public static SideEffectStore ReadFromDatabase()
        {
            try
            {
                var             filename = Path.Combine(DUCoverConstants.DUCoverStoreLocation, DUCoverConstants.SideEffectStoreDebugFile);
                SideEffectStore ses      = new SideEffectStore();
                if (!File.Exists(filename))
                {
                    return(ses);
                }

                using (StreamReader sr = new StreamReader(filename))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        line.Trim();
                        string        methodname = line;
                        SEMethodStore sem        = new SEMethodStore(methodname);
                        ses.MethodStore[methodname] = sem;

                        //Reading defined
                        line = sr.ReadLine().Trim();
                        string[] parts = line.Split(' ');

                        int numDefined = Convert.ToInt32(parts[1]);
                        for (int count = 0; count < numDefined; count++)
                        {
                            line = sr.ReadLine().Trim();
                            string[] lineparts = line.Split(' ');

                            SEFieldStore sef = new SEFieldStore(lineparts[0]);
                            sem.DefinedFieldSet[lineparts[0]] = sef;
                            for (int tcount = 1; tcount < lineparts.Length; tcount++)
                            {
                                sef.AllOffsets.Add(Convert.ToInt32(lineparts[tcount]));
                            }
                        }

                        //Reading used
                        line  = sr.ReadLine().Trim();
                        parts = line.Split(' ');

                        int numUsed = Convert.ToInt32(parts[1]);
                        for (int count = 0; count < numUsed; count++)
                        {
                            line = sr.ReadLine().Trim();
                            string[] lineparts = line.Split(' ');

                            SEFieldStore sef = new SEFieldStore(lineparts[0]);
                            sem.UsedFieldSet[lineparts[0]] = sef;
                            for (int tcount = 1; tcount < lineparts.Length; tcount++)
                            {
                                sef.AllOffsets.Add(Convert.ToInt32(lineparts[tcount]));
                            }
                        }
                    }
                }

                Console.WriteLine("Number of entries read: " + ses.MethodStore.Count);
                return(ses);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to deserialize");
                logger.ErrorException("Error occurred while reading from file " + ex.StackTrace, ex);
            }

            return(new SideEffectStore());
        }
Пример #10
0
        /// <summary>
        /// Propagates the changes made by a called method to its caller, based on the lastLoadedFields        
        /// For example, if the called method modifies any fields, then the related parent fields in the caller method
        /// are marked as updated
        /// </summary>
        /// <param name="callerMStore"></param>
        /// <param name="calledMethodStore"></param>
        private void PropagateModificationsToCaller(SEMethodStore callerMStore, SEMethodStore calledMethodStore, Method calledMethod)
        {
            if (this.lastLoadedFields.Count == 0)
                return;

            //Idenitfy relevant fields from the last loadedFields
            SafeList<Field> fieldsProcessed = new SafeList<Field>();
            Field receiverField = null;

            //Check whether the current method call is actually on the field previously loaded
            TypeEx methodDeclType;
            if (!calledMethod.TryGetDeclaringType(out methodDeclType))
            {
                logger.Error("Failed to get the declaring type of the method: " + calledMethod.FullName);
                return;
            }

            if (methodDeclType.FullName == "System.String" || methodDeclType.FullName == "System.string")
            {
                return; //Do not process string types.
            }

            //Check whether the declaring type is in the fields list
            foreach (var field in this.lastLoadedFields)
            {
                var fieldType = field.Type;
                if (fieldType == methodDeclType || fieldType.IsAssignableTo(methodDeclType) || methodDeclType.IsAssignableTo(fieldType))
                {
                    fieldsProcessed.Add(field);
                    receiverField = field;
                    break;
                }
            }

            if (receiverField == null)
            {
                //Failed to identify the reciver field of this method
                return;
            }

            //Identify arguments of the current method call
            foreach (var argtype in calledMethod.ParameterTypes)
            {
                foreach (var field in this.lastLoadedFields)
                {
                    if (field == receiverField)
                        continue;

                    var fieldType = field.Type;
                    if (fieldType == argtype || fieldType.IsAssignableTo(argtype) || argtype.IsAssignableTo(fieldType))
                    {
                        fieldsProcessed.Add(field);
                        break;
                    }
                }
            }

            if (calledMethodStore.DefinedFieldSet.Count == 0)
            {
                //If the called method does not define any field, all current fields are just loaded fields
                foreach (var field in fieldsProcessed)
                {
                    callerMStore.AddToUsedList(field, this.currOffset);
                    this.lastLoadedFields.Remove(field);
                }
            }
            else
            {
                //process each defined field
                foreach (var deffield in calledMethodStore.DefinedFieldSet.Values)
                {
                    TypeEx deffieldType;
                    if (deffield.OptionalField.TryGetDeclaringType(out deffieldType))
                    {
                        //Identify the related field in the lastLoadedFields
                        Field processedField = null;
                        foreach (var field in fieldsProcessed)
                        {
                            var fieldType = field.Type;
                            if (fieldType == deffieldType || fieldType.IsAssignableTo(deffieldType) || deffieldType.IsAssignableTo(fieldType))
                            {
                                processedField = field;
                                callerMStore.AddToDefinedList(field, this.currOffset);
                                break;
                            }
                        }

                        if (processedField != null)
                        {
                            fieldsProcessed.Remove(processedField);
                            this.lastLoadedFields.Remove(processedField);
                        }
                    }
                }

                //Consider the remaining fields at usedfields and remove them from lastLoadedFields
                foreach (var field in fieldsProcessed)
                {
                    callerMStore.AddToUsedList(field, this.currOffset);
                    this.lastLoadedFields.Remove(field);
                }
            }
        }
Пример #11
0
        public override void LeaveMethod()
        {
            if (!bStartMonitoring)
                return;

            if (this.methodStack.Count == 0)
                return;

            var poppedMethod = this.methodStack.Pop();
            this.currOffset = this.offsetStack.Pop();

            var previousLoadedFields = this.lastLoadedFieldsStack.Pop();
            //If the last method call is a getter, add the field just loaded by that getter method
            //Or any other remaining loaded fields
            if (poppedMethod.ShortName.StartsWith("get_"))
            {
                Field usedField;
                int foffset;
                if (DeclEntityCollector.TryGetFieldOfGetter(poppedMethod, out usedField, out foffset))
                {
                    previousLoadedFields.AddRange(usedField);
                }
            }
            this.lastLoadedFields.Clear();
            this.lastLoadedFields.AddRange(previousLoadedFields);

            //Updating the defined and used field list
            if (this.methodStoreStack.Count > 0)
            {
                ses.AppendMethodStore(currSEMethodStore);
                var poppedStore = this.methodStoreStack.Pop();
                if (!poppedMethod.ShortName.StartsWith("get_"))
                {
                    //Do not propogate for getter methods
                    PropagateModificationsToCaller(poppedStore, currSEMethodStore, poppedMethod);
                }
                poppedStore.AppendMethodStore(currSEMethodStore, this.currOffset);
                currSEMethodStore = poppedStore;
            }

            if (poppedMethod.ShortName.Equals("Main") || poppedMethod.ShortName.Equals("DUCoverTerminate"))
            {
                ses.DumpToDatabase();
                bStartMonitoring = false;
            }
        }
Пример #12
0
        public override EnterMethodFlags EnterMethod(Method method)
        {
            //Console.WriteLine(method.FullName);

            if (this.methodStack.Count == 0 && !bStartMonitoring)
            {
                var assemblyShortname = method.Definition.Module.Assembly.ShortName;
                if (assemblyShortname == this.currentAssemblyLoc)
                {
                    //Whereever the main method, it is the assembly under analysis,
                    //since our tool assumes that there is only one assembly
                    var assembly = method.Definition.Module.Assembly;
                    ses.CurrAssembly = assembly;
                    bStartMonitoring = true;
                }
            }

            if (bStartMonitoring)
            {
                this.methodStack.Push(method);

                if (currSEMethodStore != null)
                    this.methodStoreStack.Push(currSEMethodStore);
                currSEMethodStore = new SEMethodStore(method.FullName);
                currSEMethodStore.OptionalMethod = method;

                var tempLastLoadedFields = new SafeList<Field>();
                tempLastLoadedFields.AddRange(lastLoadedFields);
                this.lastLoadedFieldsStack.Push(tempLastLoadedFields);
                this.lastLoadedFields.Clear();

                this.offsetStack.Push(this.currOffset);
            }

            return base.EnterMethod(method); // 'true' indicates that we want callbacks for the argument values
        }