예제 #1
0
        /// <summary>
        /// Checks whether there is a definition from the beginning to the use node
        /// </summary>
        /// <param name="fdef"></param>
        /// <param name="otherDefinedOffsets"></param>
        /// <returns></returns>
        private bool HasDefinitionFromRootToUseNode(DUCoverStore dcs, FieldDefUseStore fuse, HashSet <int> otherDefinedOffsets)
        {
            DEFUSE_FEASIBILITY_TYPE feasibilityVal;

            if (this.feasibilityDicCache.TryGetValue(fuse, out feasibilityVal))
            {
                if (feasibilityVal == DEFUSE_FEASIBILITY_TYPE.USE_FEASIBLE)
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            InstructionGraph    ig  = dcs.GetInstructionGraph(fuse.Method);
            DepthFirstTraversal dft = new DepthFirstTraversal(ig);
            InstructionVertex   iv  = ig.GetVertex(fuse.Offset);
            var result = dft.HasDefClearPathFromBeginning(iv, otherDefinedOffsets);

            if (result)
            {
                this.feasibilityDicCache[fuse] = DEFUSE_FEASIBILITY_TYPE.USE_FEASIBLE;
            }
            else
            {
                this.feasibilityDicCache[fuse] = DEFUSE_FEASIBILITY_TYPE.USE_INFEASIBLE;
            }

            return(!result);
        }
예제 #2
0
        public void AddToDefOrUseList(Method md, int useoffset, Method unknownSideEffectMethod)
        {
            FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, useoffset);

            fdus.UnknownSideEffectMethod = unknownSideEffectMethod;
            this.defOrUseSet.Add(fdus);
        }
예제 #3
0
        private bool UpdateDUCoverTable(Field field, out FieldDefUseStore llfs)
        {
            if (this.lastFieldDefsDic.TryGetValue(field.GlobalIndex, out llfs))
            {
                TypeEx declType;
                if (!field.TryGetDeclaringType(out declType))
                {
                    logger.Error("Failed to retrieve declaring type for the field " + field.FullName);
                    return(false);
                }

                DeclClassEntity dce;
                if (!this.dcs.DeclEntityDic.TryGetValue(declType.FullName, out dce))
                {
                    logger.Error("Failed to retrieve DeclClassEntity for the class " + declType.FullName);
                    return(false);
                }

                DeclFieldEntity dfe;
                if (!dce.FieldEntities.TryGetValue(field.FullName, out dfe))
                {
                    logger.Error("Failed to retrieve DeclFieldEntity for the field " + field.FullName);
                    return(false);
                }

                return(dfe.UpdateDUCoverageTable(llfs.Method, llfs.Offset, this.GetCurrentMethod(), this.currOffset));
            }
            else
            {
                //logger.Warn("Encountered load field on " + field.FullName + " at " + this.GetCurrentMethod().FullName
                //    + "(" + this.currOffset + ") without any field definition");
                return(false);
            }
        }
예제 #4
0
        public void ComputeDUCoverage(out int totalDUPairs, out int coveredDUPairs, out int totalDefs, out int coveredDefs, out int totalUses, out int coveredUses)
        {
            totalDUPairs   = this.duCoverageTable.Count;
            coveredDUPairs = coveredDefs = coveredUses = 0;
            totalDefs      = this.defDic.Count;
            totalUses      = this.useDic.Count;

            //Computing def-uses
            foreach (var dcse in this.duCoverageTable.Keys)
            {
                var value = this.duCoverageTable[dcse];
                if (value > 0)
                {
                    coveredDUPairs++;
                    var defpart          = new FieldDefUseStore(dcse.Field, dcse.DefMethod, dcse.DefOffset);
                    var existingDefValue = 0;
                    if (this.defDic.TryGetValue(defpart, out existingDefValue))
                    {
                        this.defDic[defpart] = existingDefValue + 1;
                    }

                    var usepart          = new FieldDefUseStore(dcse.Field, dcse.UseMethod, dcse.UseOffset);
                    var existingUseValue = 0;
                    if (this.useDic.TryGetValue(usepart, out existingUseValue))
                    {
                        this.useDic[usepart] = existingUseValue + 1;
                    }
                }
            }

            //Computing defs. A def is considered as covered if it is exercised by one use
            foreach (var defvalue in this.defDic.Values)
            {
                if (defvalue > 0)
                {
                    coveredDefs++;
                }
            }

            //Computing uses. A use is considered as covered if all its pairs with defs are covered
            foreach (var usevalue in this.useDic.Values)
            {
                if (usevalue >= totalDefs)
                {
                    coveredUses++;
                }
            }

            this.TotalDUPairs   = totalDUPairs;
            this.CoveredDUPairs = coveredDUPairs;
            this.TotalDefs      = totalDefs;
            this.CoveredDefs    = coveredDefs;
            this.TotalUses      = totalUses;
            this.CoveredUses    = coveredUses;
        }
예제 #5
0
        /// <summary>
        /// Registers the last definition of the field
        /// </summary>
        /// <param name="field"></param>
        private void AddToFieldDefinitionStore(Field field)
        {
            var peekmethod = this.methodStack.Peek();

            //Set method is already been handled
            if (peekmethod.ShortName.StartsWith("set_") && this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
            {
                return;
            }
            FieldDefUseStore llfs = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);

            this.lastFieldDefsDic[field.GlobalIndex] = llfs;
        }
예제 #6
0
        /// <summary>
        /// Gets all other offsets within the method, where the field is defined
        /// </summary>
        /// <param name="method"></param>
        /// <param name="safeSet"></param>
        /// <returns></returns>
        private HashSet <int> GetOtherDefOffsetsInMethod(Method method, FieldDefUseStore currfdef)
        {
            HashSet <int> otherOffsets = new HashSet <int>();

            foreach (var fdef in this.defDic.Keys)
            {
                if (fdef.Equals(currfdef))
                {
                    continue;
                }

                if (fdef.Method.Equals(method))
                {
                    otherOffsets.Add(fdef.Offset);
                }
            }

            return(otherOffsets);
        }
예제 #7
0
        /// <summary>
        /// Checks whether a definition and use are in different methods
        /// </summary>
        /// <param name="dcse"></param>
        /// <returns></returns>
        private bool IsFeasibleDUCoverEntry(DUCoverStore dcs, FieldDefUseStore fdef, FieldDefUseStore fuse)
        {
            //if (fdef.Method.FullName.Contains("AddVertex") && fuse.Method.FullName.Contains("AddVertex") && fdef.Field.FullName.Contains("m_VertexOutEdges")
            //    && fdef.Offset == 13 && fuse.Offset == 2)
            //{
            //    int i = 0;
            //}

            //check whether the def and use are in the same method
            if (fdef.Method.Equals(fuse.Method))
            {
                var otherFDefOffsets    = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                InstructionGraph    ig  = dcs.GetInstructionGraph(fdef.Method);
                DepthFirstTraversal dft = new DepthFirstTraversal(ig);
                var source = ig.GetVertex(fdef.Offset);
                var target = ig.GetVertex(fuse.Offset);
                return(dft.HasDefClearPathBetweenNodes(source, target, otherFDefOffsets));
            }
            else
            {
                var otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                if (otherFDefOffsets.Count > 0)
                {
                    if (this.HasRedefinition(dcs, fdef, otherFDefOffsets))
                    {
                        return(false);
                    }
                }

                otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fuse.Method, fdef);
                if (otherFDefOffsets.Count > 0)
                {
                    if (this.HasDefinitionFromRootToUseNode(dcs, fuse, otherFDefOffsets))
                    {
                        return(false);
                    }
                }

                return(true);
            }
        }
예제 #8
0
 public void AddToUseList(Method md, int useoffset)
 {
     FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, useoffset);
     this.useDic[fdus] = 0;
 }
예제 #9
0
        private bool UpdateDUCoverTable(Field field, out FieldDefUseStore llfs)
        {
            if (this.lastFieldDefsDic.TryGetValue(field.GlobalIndex, out llfs))
            {
                TypeEx declType;
                if (!field.TryGetDeclaringType(out declType))
                {
                    logger.Error("Failed to retrieve declaring type for the field " + field.FullName);
                    return false;
                }

                DeclClassEntity dce;
                if (!this.dcs.DeclEntityDic.TryGetValue(declType.FullName, out dce))
                {
                    logger.Error("Failed to retrieve DeclClassEntity for the class " + declType.FullName);
                    return false;
                }

                DeclFieldEntity dfe;
                if (!dce.FieldEntities.TryGetValue(field.FullName, out dfe))
                {
                    logger.Error("Failed to retrieve DeclFieldEntity for the field " + field.FullName);
                    return false;
                }

                return dfe.UpdateDUCoverageTable(llfs.Method, llfs.Offset, this.GetCurrentMethod(), this.currOffset);
            }
            else
            {
                //logger.Warn("Encountered load field on " + field.FullName + " at " + this.GetCurrentMethod().FullName
                //    + "(" + this.currOffset + ") without any field definition");
                return false;
            }
        }
예제 #10
0
        /// <summary>
        /// Handles a method call.
        /// </summary>
        /// <param name="method"></param>
        private void HandleMethodCall(Method method)
        {
            if (lastLoadedFields.Count != 0)
            {
                bool bSuccessfulUpdate = true;
                //handling method calls on fields of this class
                if (method.ShortName.StartsWith("set_"))
                {
                    //Update definition table with the current offsets these fields are modified here
                    foreach (var field in lastLoadedFields)
                    {
                        FieldDefUseStore fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                        this.lastFieldDefsDic[field.GlobalIndex] = fdus;
                    }
                }
                else if (method.ShortName.StartsWith("get_"))
                {
                    //Register all usages
                    foreach (var field in lastLoadedFields)
                    {
                        FieldDefUseStore fdus;
                        this.UpdateDUCoverTable(field, out fdus);
                    }
                }
                else
                {
                    foreach (var field in lastLoadedFields)
                    {
                        bool defined, used;
                        if (ses.TryGetFieldDefOrUseByMethod(this.GetCurrentMethod(), field, this.currOffset, out defined, out used))
                        {
                            FieldDefUseStore fdus;
                            if (used)
                            {
                                //This field is used by this method
                                if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
                                {
                                    this.UpdateDUCoverTable(field, out fdus);
                                }
                            }

                            if (defined)
                            {
                                //This field is defined by this method
                                fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                                this.lastFieldDefsDic[field.GlobalIndex] = fdus;

                                if (used)
                                {
                                    //Since it is both used and defined.
                                    this.UpdateDUCoverTable(field, out fdus);
                                }
                            }
                        }
                        else
                        {
                            //Backup option: declaring as both used and defined.
                            //In general, control cannot come over here
                            FieldDefUseStore fdus;
                            if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
                            {
                                bSuccessfulUpdate = this.UpdateDUCoverTable(field, out fdus);
                            }

                            if (bSuccessfulUpdate)
                            {
                                //Override the current definition, since this field is being modified here
                                fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                                this.lastFieldDefsDic[field.GlobalIndex] = fdus;

                                //also add a self def-use
                                this.UpdateDUCoverTable(field, out fdus);
                            }
                        }
                    }
                }

                if(bSuccessfulUpdate)
                    lastLoadedFields.Clear();
            }
            else
            {
                var shortname = method.ShortName;
                if (shortname.StartsWith("set_"))
                {
                    Field definedField;
                    if (DeclEntityCollector.TryGetFieldOfSetter(method, out definedField))
                    {
                        //Override if there is any previous definition of this field
                        FieldDefUseStore fdus = new FieldDefUseStore(definedField, this.GetCurrentMethod(), this.currOffset);
                        this.lastFieldDefsDic[definedField.GlobalIndex] = fdus;
                    }
                }
                else if (shortname.StartsWith("get_"))
                {
                    int foffset;
                    Field usedField;
                    if (DeclEntityCollector.TryGetFieldOfGetter(method, out usedField, out foffset))
                    {
                        FieldDefUseStore llfs;
                        this.UpdateDUCoverTable(usedField, out llfs);
                        this.lastLoadedFields.Add(usedField);
                    }
                }
            }
        }
예제 #11
0
 /// <summary>
 /// Registers the last definition of the field
 /// </summary>
 /// <param name="field"></param>
 private void AddToFieldDefinitionStore(Field field)
 {
     var peekmethod = this.methodStack.Peek();
     //Set method is already been handled
     if (peekmethod.ShortName.StartsWith("set_") && this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
         return;
     FieldDefUseStore llfs = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
     this.lastFieldDefsDic[field.GlobalIndex] = llfs;
 }
예제 #12
0
        /// <summary>
        /// Checks whether a definition and use are in different methods
        /// </summary>
        /// <param name="dcse"></param>
        /// <returns></returns>
        private bool IsFeasibleDUCoverEntry(DUCoverStore dcs, FieldDefUseStore fdef, FieldDefUseStore fuse)
        {
            //if (fdef.Method.FullName.Contains("AddVertex") && fuse.Method.FullName.Contains("AddVertex") && fdef.Field.FullName.Contains("m_VertexOutEdges")
            //    && fdef.Offset == 13 && fuse.Offset == 2)
            //{
            //    int i = 0;
            //}

            //check whether the def and use are in the same method
            if (fdef.Method.Equals(fuse.Method))
            {
                var otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                InstructionGraph ig = dcs.GetInstructionGraph(fdef.Method);
                DepthFirstTraversal dft = new DepthFirstTraversal(ig);
                var source = ig.GetVertex(fdef.Offset);
                var target = ig.GetVertex(fuse.Offset);
                return dft.HasDefClearPathBetweenNodes(source, target, otherFDefOffsets);
            }
            else
            {
                var otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fdef.Method, fdef);
                if (otherFDefOffsets.Count > 0)
                {
                    if (this.HasRedefinition(dcs, fdef, otherFDefOffsets))
                        return false;
                }

                otherFDefOffsets = this.GetOtherDefOffsetsInMethod(fuse.Method, fdef);
                if (otherFDefOffsets.Count > 0)
                {
                    if (this.HasDefinitionFromRootToUseNode(dcs, fuse, otherFDefOffsets))
                        return false;
                }

                return true;
            }
        }
예제 #13
0
        /// <summary>
        /// Checks whether the fdef has a redefinition from the current not to the end of the method
        /// </summary>
        /// <param name="fdef"></param>
        /// <param name="otherDefinedOffsets"></param>
        /// <returns></returns>
        private bool HasRedefinition(DUCoverStore dcs, FieldDefUseStore fdef, HashSet<int> otherDefinedOffsets)
        {
            DEFUSE_FEASIBILITY_TYPE feasibilityVal;
            if (this.feasibilityDicCache.TryGetValue(fdef, out feasibilityVal))
            {
                if (feasibilityVal == DEFUSE_FEASIBILITY_TYPE.DEF_FEASIBLE)
                    return false;
                else
                    return true;
            }

            InstructionGraph ig = dcs.GetInstructionGraph(fdef.Method);
            DepthFirstTraversal dft = new DepthFirstTraversal(ig);
            InstructionVertex iv = ig.GetVertex(fdef.Offset);
            var result = dft.HasDefClearPathToEnd(iv, otherDefinedOffsets);

            if (result)
                this.feasibilityDicCache[fdef] = DEFUSE_FEASIBILITY_TYPE.DEF_FEASIBLE;
            else
                this.feasibilityDicCache[fdef] = DEFUSE_FEASIBILITY_TYPE.DEF_INFEASIBLE;

            return !result;
        }
예제 #14
0
        /// <summary>
        /// Gets all other offsets within the method, where the field is defined
        /// </summary>
        /// <param name="method"></param>
        /// <param name="safeSet"></param>
        /// <returns></returns>
        private HashSet<int> GetOtherDefOffsetsInMethod(Method method, FieldDefUseStore currfdef)
        {
            HashSet<int> otherOffsets = new HashSet<int>();
            foreach (var fdef in this.defDic.Keys)
            {
                if (fdef.Equals(currfdef))
                    continue;

                if (fdef.Method.Equals(method))
                    otherOffsets.Add(fdef.Offset);
            }

            return otherOffsets;
        }
예제 #15
0
        public void AddToUseList(Method md, int useoffset)
        {
            FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, useoffset);

            this.useDic[fdus] = 0;
        }
예제 #16
0
        /// <summary>
        /// Handles a method call.
        /// </summary>
        /// <param name="method"></param>
        private void HandleMethodCall(Method method)
        {
            if (lastLoadedFields.Count != 0)
            {
                bool bSuccessfulUpdate = true;
                //handling method calls on fields of this class
                if (method.ShortName.StartsWith("set_"))
                {
                    //Update definition table with the current offsets these fields are modified here
                    foreach (var field in lastLoadedFields)
                    {
                        FieldDefUseStore fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                        this.lastFieldDefsDic[field.GlobalIndex] = fdus;
                    }
                }
                else if (method.ShortName.StartsWith("get_"))
                {
                    //Register all usages
                    foreach (var field in lastLoadedFields)
                    {
                        FieldDefUseStore fdus;
                        this.UpdateDUCoverTable(field, out fdus);
                    }
                }
                else
                {
                    foreach (var field in lastLoadedFields)
                    {
                        bool defined, used;
                        if (ses.TryGetFieldDefOrUseByMethod(this.GetCurrentMethod(), field, this.currOffset, out defined, out used))
                        {
                            FieldDefUseStore fdus;
                            if (used)
                            {
                                //This field is used by this method
                                if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
                                {
                                    this.UpdateDUCoverTable(field, out fdus);
                                }
                            }

                            if (defined)
                            {
                                //This field is defined by this method
                                fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                                this.lastFieldDefsDic[field.GlobalIndex] = fdus;

                                if (used)
                                {
                                    //Since it is both used and defined.
                                    this.UpdateDUCoverTable(field, out fdus);
                                }
                            }
                        }
                        else
                        {
                            //Backup option: declaring as both used and defined.
                            //In general, control cannot come over here
                            FieldDefUseStore fdus;
                            if (this.lastFieldDefsDic.ContainsKey(field.GlobalIndex))
                            {
                                bSuccessfulUpdate = this.UpdateDUCoverTable(field, out fdus);
                            }

                            if (bSuccessfulUpdate)
                            {
                                //Override the current definition, since this field is being modified here
                                fdus = new FieldDefUseStore(field, this.GetCurrentMethod(), this.currOffset);
                                this.lastFieldDefsDic[field.GlobalIndex] = fdus;

                                //also add a self def-use
                                this.UpdateDUCoverTable(field, out fdus);
                            }
                        }
                    }
                }

                if (bSuccessfulUpdate)
                {
                    lastLoadedFields.Clear();
                }
            }
            else
            {
                var shortname = method.ShortName;
                if (shortname.StartsWith("set_"))
                {
                    Field definedField;
                    if (DeclEntityCollector.TryGetFieldOfSetter(method, out definedField))
                    {
                        //Override if there is any previous definition of this field
                        FieldDefUseStore fdus = new FieldDefUseStore(definedField, this.GetCurrentMethod(), this.currOffset);
                        this.lastFieldDefsDic[definedField.GlobalIndex] = fdus;
                    }
                }
                else if (shortname.StartsWith("get_"))
                {
                    int   foffset;
                    Field usedField;
                    if (DeclEntityCollector.TryGetFieldOfGetter(method, out usedField, out foffset))
                    {
                        FieldDefUseStore llfs;
                        this.UpdateDUCoverTable(usedField, out llfs);
                        this.lastLoadedFields.Add(usedField);
                    }
                }
            }
        }
예제 #17
0
 public void AddToDefOrUseList(Method md, int useoffset, Method unknownSideEffectMethod)
 {
     FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, useoffset);
     fdus.UnknownSideEffectMethod = unknownSideEffectMethod;
     this.defOrUseSet.Add(fdus);
 }
예제 #18
0
 public void AddToDefList(Method md, int defoffset)
 {
     FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, defoffset);
     this.defDic[fdus] = 0;
 }
예제 #19
0
        public void ComputeDUCoverage(out int totalDUPairs, out int coveredDUPairs, out int totalDefs, out int coveredDefs, out int totalUses, out int coveredUses)
        {
            totalDUPairs = this.duCoverageTable.Count;
            coveredDUPairs = coveredDefs = coveredUses = 0;
            totalDefs = this.defDic.Count;
            totalUses = this.useDic.Count;

            //Computing def-uses
            foreach (var dcse in this.duCoverageTable.Keys)
            {
                var value = this.duCoverageTable[dcse];
                if (value > 0)
                {
                    coveredDUPairs++;
                    var defpart = new FieldDefUseStore(dcse.Field, dcse.DefMethod, dcse.DefOffset);
                    var existingDefValue = 0;
                    if (this.defDic.TryGetValue(defpart, out existingDefValue))
                        this.defDic[defpart] = existingDefValue + 1;

                    var usepart = new FieldDefUseStore(dcse.Field, dcse.UseMethod, dcse.UseOffset);
                    var existingUseValue = 0;
                    if (this.useDic.TryGetValue(usepart, out existingUseValue))
                        this.useDic[usepart] = existingUseValue + 1;
                }
            }

            //Computing defs. A def is considered as covered if it is exercised by one use
            foreach (var defvalue in this.defDic.Values)
            {
                if (defvalue > 0)
                    coveredDefs++;
            }

            //Computing uses. A use is considered as covered if all its pairs with defs are covered
            foreach (var usevalue in this.useDic.Values)
            {
                if (usevalue >= totalDefs)
                    coveredUses++;
            }

            this.TotalDUPairs = totalDUPairs;
            this.CoveredDUPairs = coveredDUPairs;
            this.TotalDefs = totalDefs;
            this.CoveredDefs = coveredDefs;
            this.TotalUses = totalUses;
            this.CoveredUses = coveredUses;
        }
예제 #20
0
        public void AddToDefList(Method md, int defoffset)
        {
            FieldDefUseStore fdus = new FieldDefUseStore(this.fd, md, defoffset);

            this.defDic[fdus] = 0;
        }