示例#1
0
        public TADomain this [SymValue symbol]
        {
            get
            {
                symbol = Find(symbol);
                if (this.abs_map.ContainsKey(symbol))
                {
                    return(this.abs_map [symbol]);
                }

                return(this.UnderlyingTopValue);
            }
            set
            {
                SymValue newSym = Find(symbol);
                if (this [symbol].Equals(value))
                {
                    return;
                }
                AddAbstractValueUpdate(newSym);
                if (value.IsTop)
                {
                    this.abs_map = this.abs_map.Remove(newSym);
                }
                else
                {
                    this.abs_map = this.abs_map.Add(newSym, value);
                }
            }
        }
示例#2
0
        public override void Replay(MergeInfo <TFunc, TAbstractDomain> merge)
        {
            if (!merge.IsCommon(this.from))
            {
                return;
            }

            SymValue sv1 = merge.Graph1.LookupWithoutManifesting(this.from, this.function);
            SymValue sv2 = merge.Graph2.LookupWithoutManifesting(this.from, this.function);

            if (sv1 != null && sv2 != null)
            {
                return;
            }
            if (sv1 != null)
            {
                if (DebugOptions.Debug)
                {
                    Console.WriteLine("---SymGraph changed due to EliminateEdgeUpdate {0}-{1} " +
                                      "-> that is only in G1", this.from, this.function);
                }
                merge.Changed = true;
            }

            bool noEdgeInResult = merge.Result.LookupWithoutManifesting(this.from, this.function) == null;

            if (noEdgeInResult)
            {
                return;
            }

            merge.Result.Eliminate(this.function, this.from);
        }
示例#3
0
        private SymGraph(TADomain topValue, TADomain bottomValue, bool _)
        {
            this.egraph_id  = egraphIdGenerator++;
            this.const_root = FreshSymbol();

            TermMap = DoubleImmutableMap <SymValue, TFunc, SymValue> .Empty(SymValue.GetUniqueKey);

            MultiEdgeMap = DoubleImmutableMap <SymValue, MultiEdge <TFunc, TADomain>, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey);

            this.abs_map = ImmutableIntKeyMap <SymValue, TADomain> .Empty(SymValue.GetUniqueKey);

            this.forw_map = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey);

            EqualTermsMap = ImmutableIntKeyMap <SymValue, Sequence <SymGraphTerm <TFunc> > > .Empty(SymValue.GetUniqueKey);

            EqualMultiTermsMap = ImmutableIntKeyMap <SymValue, SymGraphTerm <TFunc> > .Empty(SymValue.GetUniqueKey);

            this.BottomPlaceHolder = FreshSymbol();
            this.abs_map           = this.abs_map.Add(this.BottomPlaceHolder, bottomValue);
            this.is_immutable      = false;
            this.history_size      = 1;
            this.Parent            = null;
            this.root_graph        = this;
            Updates = null;
            this.UnderlyingTopValue      = topValue;
            this.underlying_bottom_value = bottomValue;
        }
示例#4
0
        public SymValue LookupOrBottomPlaceHolder(SymValue arg, TFunc function, out bool isPlaceHolder)
        {
            SymValue result = LookupWithoutManifesting(arg, function);

            isPlaceHolder = result == null;
            return(isPlaceHolder ? this.BottomPlaceHolder : result);
        }
示例#5
0
        private static bool UpdateTrigger(SymValue sv, MultiEdge <TFunc, TADomain> edge, ref IImmutableMap <SymValue, int> triggers)
        {
            int val = triggers [sv] + 1;

            triggers = triggers.Add(sv, val);
            return(val == edge.Arity);
        }
示例#6
0
 private void AddAbstractValueUpdate(SymValue sv)
 {
     if (!IsOldSymbol(sv))
     {
         return;
     }
     AddUpdate(new AbstractDomainUpdate <TFunc, TADomain> (sv));
 }
示例#7
0
 private void AddEqualityUpdate(SymValue sv1, SymValue sv2)
 {
     if (!IsOldSymbol(sv1) || !IsOldSymbol(sv2))
     {
         return;
     }
     AddUpdate(new EqualityUpdate <TFunc, TADomain> (sv1, sv2));
 }
示例#8
0
 private void AddEliminateEdgeUpdate(SymValue from, TFunc function)
 {
     if (!IsOldSymbol(from))
     {
         return;
     }
     AddUpdate(new EliminateEdgeUpdate <TFunc, TADomain> (from, function));
 }
示例#9
0
 private TADomain Graph2ADomain(SymValue sv)
 {
     if (sv != null)
     {
         return(this.Graph2 [sv]);
     }
     return(this.Graph2.UnderlyingTopValue.ForManifestedField());
 }
示例#10
0
        public void EliminateAll(SymValue arg)
        {
            SymValue value = Find(arg);

            AddEliminateAllUpdate(value);
            TermMap    = TermMap.RemoveAll(value);
            this [arg] = this.UnderlyingTopValue;
        }
示例#11
0
        public SymValue LookupOrManifest(TFunc function, SymValue arg, out bool fresh)
        {
            int      oldCnt = IdGenerator;
            SymValue result = this [function, arg];

            fresh = oldCnt < IdGenerator;
            return(result);
        }
示例#12
0
 private bool IsOldSymbol(SymValue sv)
 {
     if (this.Parent == null)
     {
         return(false);
     }
     return(sv.UniqueId <= this.Parent.LastSymbolId);
 }
示例#13
0
 private static bool VisitedBefore(SymValue sv2,
                                   IImmutableSet <SymValue> backwardManifested,
                                   IImmutableMap <SymValue, SymValue> backward,
                                   out SymValue sv1)
 {
     sv1 = backward [sv2];
     return(sv1 != null || backwardManifested.Contains(sv2));
 }
示例#14
0
        private SymValue LookupMapping(SymValue v1, SymValue v2)
        {
            if (v1 == null || v2 == null)
            {
                return(null);
            }

            return(this.mappings [v1, v2]);
        }
示例#15
0
        private bool IsMappingAlreadyAdded(SymValue v1, SymValue v2)
        {
            if (v1 != null)
            {
                return(this.visited_key1.Contains(v1) || this.mappings.ContainsKey1(v1));
            }

            return(this.visited_key1.Contains(v2));
        }
示例#16
0
        public IEnumerable <SymGraphTerm <TFunc> > EqMultiTerms(SymValue sv)
        {
            SymGraphTerm <TFunc> term = EqualMultiTermsMap [sv];

            if (term.Args != null && IsValidMultiTerm(term))
            {
                yield return(term);
            }
        }
示例#17
0
        public bool HasAllBottomFields(SymValue sv)
        {
            if (sv == null)
            {
                return(false);
            }

            return(this [sv].HasAllBottomFields);
        }
示例#18
0
        public void Commit()
        {
            if (Changed)
            {
                return;
            }

            bool needContinue = false;

            foreach (var edge in this.Graph1.ValidMultiTerms)
            {
                SymGraphTerm <TFunc> term = edge.Value;
                var args = new SymValue[term.Args.Length];

                for (int i = 0; i < args.Length; ++i)
                {
                    SymValue sv = term.Args[i];
                    if (IsMappingAlreadyAdded(sv, null))
                    {
                        if (this.mappings.Keys2(sv) != null && this.mappings.Keys2(sv).Count() == 1)
                        {
                            args[i] = this.mappings[sv, this.mappings.Keys2(sv).First()];
                        }
                    }
                    else
                    {
                        needContinue = true;
                        break;
                    }

                    if (args[i] == null)
                    {
                        Changed = true;
                        return;
                    }
                }

                if (needContinue)
                {
                    continue;
                }

                SymValue symbol = this.Result.LookupWithoutManifesting(args, term.Function);
                if (symbol != null)
                {
                    SymValue key = edge.Key;
                    if (this.mappings.Keys2(key) != null && this.mappings.Keys2(key).Count() == 1 && this.mappings[key, this.mappings.Keys2(key).First()] == symbol)
                    {
                        continue;
                    }
                }

                Changed = true;
                return;
            }
        }
示例#19
0
 public IEnumerable <SymGraphTerm <TFunc> > EqTerms(SymValue sv)
 {
     foreach (var term in EqualTermsMap[Find(sv)].AsEnumerable())
     {
         if (TryLookup(term.Function, term.Args) == sv)
         {
             yield return(term);
         }
     }
 }
示例#20
0
        public SymValue AddJointEdge(SymValue v1Target, SymValue v2Target, TFunc function, SymValue[] resultArgs)
        {
            SymValue result  = LookupMapping(v1Target, v2Target);
            bool     newEdge = false;

            if (result == null)
            {
                if (IsMappingAlreadyAdded(v1Target, v2Target))
                {
                    if (DebugOptions.Debug)
                    {
                        Console.WriteLine("---SymGraph changed due to pre-existing mapping in G1 of {0}", v1Target);
                    }
                    Changed = true;
                    if (v1Target == null || v2Target == null)
                    {
                        return(null);
                    }
                }
                newEdge = true;
                result  = v1Target == null || v1Target.UniqueId > this.LastCommonVariable || v1Target != v2Target?this.Result.FreshSymbol() : v1Target;

                AddMapping(v1Target, v2Target, result);
            }
            else if (this.Result.LookupWithoutManifesting(resultArgs, function) == result)
            {
                return(null);
            }
            this.Result[resultArgs, function] = result;
            TADomain val1 = Graph1ADomain(v1Target);
            TADomain val2 = Graph2ADomain(v2Target);

            bool     weaker;
            TADomain joinValue = val1.Join(val2, this.Widen, out weaker);

            this.Result[result] = joinValue;
            if (weaker)
            {
                if (DebugOptions.Debug)
                {
                    Console.WriteLine("----SymGraph changed due to join of abstract values of [{0}, {1}] (prev {2}, new {3}, join {4}",
                                      v1Target, v2Target,
                                      val1, val2, joinValue);
                }
                Changed = true;
            }

            if (DebugOptions.Debug)
            {
                Console.WriteLine("AddJointEdge: ({0}) -{1} -> [{2},{3},{4}]",
                                  resultArgs.ToString(", "), function,
                                  v1Target, v2Target, result);
            }
            return(newEdge ? result : null);
        }
示例#21
0
 private void AddEliminateAllUpdate(SymValue from)
 {
     if (!IsOldSymbol(from))
     {
         return;
     }
     foreach (TFunc function in TermMap.Keys2(from))
     {
         AddUpdate(new EliminateEdgeUpdate <TFunc, TADomain> (from, function));
     }
 }
示例#22
0
        private SymValue Find(SymValue v)
        {
            SymValue forw = this.forw_map [v];

            if (forw == null)
            {
                return(v);
            }

            return(Find(forw));
        }
示例#23
0
        public void Eliminate(TFunc function, SymValue arg)
        {
            SymValue value = Find(arg);
            DoubleImmutableMap <SymValue, TFunc, SymValue> newTermMap = TermMap.Remove(value, function);

            if (newTermMap == TermMap)
            {
                return;
            }
            TermMap = newTermMap;
            AddEliminateEdgeUpdate(value, function);
        }
示例#24
0
        public void AssumeEqual(SymValue v1, SymValue v2)
        {
            var      workList = new WorkList <EqualityPair <TFunc, TADomain> > ();
            SymValue sv1      = Find(v1);
            SymValue sv2      = Find(v2);

            if (TryPushEquality(workList, sv1, sv2))
            {
                AddEqualityUpdate(sv1, sv2);
            }

            DrainEqualityWorkList(workList);
        }
示例#25
0
        public override void Replay(MergeInfo <TFunc, TAbstractDomain> merge)
        {
            int len = this.from.Length;

            for (int i = 0; i < len; i++)
            {
                SymValue sv = this.from [i];
                if (merge.IsCommon(sv))
                {
                    merge.JoinMultiEdge(sv, sv, new MultiEdge <TFunc, TAbstractDomain> (this.function, i, len));
                }
            }
        }
示例#26
0
        private IImmutableMap <SymValue, Sequence <SymValue> > GetForwardGraphMap(Func <Tuple <SymValue, SymValue, SymValue>, SymValue> sourceSelector)
        {
            IImmutableMap <SymValue, Sequence <SymValue> > res = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey);

            foreach (var tuple in this.merge_triples.AsEnumerable())
            {
                SymValue sv = sourceSelector(tuple);
                if (sv != null)
                {
                    res = res.Add(sv, res [sv].Cons(tuple.Item3));
                }
            }
            return(res);
        }
示例#27
0
        public SymValue LookupWithoutManifesting(SymValue sv, TFunc function)
        {
            if (sv == null)
            {
                return(null);
            }
            sv = Find(sv);
            SymValue result = TermMap [sv, function];

            if (result == null)
            {
                return(null);
            }
            return(Find(result));
        }
示例#28
0
        private bool UpdatePendingCount(SymValue xi, SymValue yi, int arity)
        {
            int result;

            this.pending_counts.TryGetValue(xi, yi, out result);
            result = result + 1;

            this.pending_counts [xi, yi] = result;
            if (result == arity)
            {
                return(true);
            }

            return(false);
        }
示例#29
0
        public void AddMapping(SymValue v1, SymValue v2, SymValue result)
        {
            if (v1 != null && v2 != null)
            {
                this.mappings = this.mappings.Add(v1, v2, result);
            }
            else if (v2 == null)
            {
                this.visited_key1 = this.visited_key1.Add(v1);
            }
            else
            {
                this.visited_key1 = this.visited_key1.Add(v2);
            }

            AddMergeTriple(v1, v2, result);
        }
示例#30
0
        private void JoinMultiEdges(SymValue sv1, SymValue sv2)
        {
            if (sv1 == null || sv2 == null)
            {
                return;
            }

            IEnumerable <MultiEdge <TFunc, TADomain> > edges =
                this.Graph1.MultiEdgeMap.Keys2Count(sv1) > this.Graph2.MultiEdgeMap.Keys2Count(sv2)
                                        ? this.Graph2.MultiEdgeMap.Keys2(sv2)
                                        : this.Graph1.MultiEdgeMap.Keys2(sv1);

            foreach (var edge in edges)
            {
                JoinMultiEdge(sv1, sv2, edge);
            }
        }
示例#31
0
 int GetSizeByName(string pName, bool bNoTypeOK /* = false */)
 {
     SymValue Val = new SymValue();
     bool bSuccess = ValueByName(pName, ref Val, bNoTypeOK);
     if (bSuccess)
     {
         m_iLastSize = Val.iSymSize;
         m_uLastAddr = Val.uSymAddr;
         return Val.iSymSize;
     }
     else return 0;
 }
示例#32
0
        // Search for the given symbol. First search .symtab (if present); if not found or the table has been stripped,
        // search .dynstr

        bool SearchValueByName(string pName, SymValue pVal)
        {
            if (SearchValueByName(pName, pVal, ".symtab", ".strtab"))
                return true;
            return SearchValueByName(pName, pVal, ".dynsym", ".dynstr");
        }
示例#33
0
        // Lookup the symbol table using linear searching. See comments above for why this appears to be needed.
        bool SearchValueByName(string pName, SymValue pVal, string pSectName, string pStrName)
        {
#if NYI
            // Note: this assumes .symtab. Many files don't have this section!!!
            SectionInfo pSect, pStrSect;

            pSect = GetSectionInfoByName(pSectName);
            if (pSect == 0) return false;
            pStrSect = GetSectionInfoByName(pStrName);
            if (pStrSect == 0) return false;
            string pStr = (string)pStrSect.uHostAddr;
            // Find number of symbols
            int n = pSect.uSectionSize / pSect.uSectionEntrySize;
            Elf32_Sym* pSym = (Elf32_Sym*)pSect.uHostAddr;
            // Search all the symbols. It may be possible to start later than index 0
            for (int i = 0; i < n; i++)
            {
                int idx = elfRead4(&pSym[i].st_name);
                if (strcmp(pName, pStr + idx) == 0)
                {
                    // We have found the symbol
                    pVal.uSymAddr = elfRead4((int*)&pSym[i].st_value);
                    int e_type = elfRead2(&((Elf32_Ehdr*)m_pImage)->e_type);
                    if (e_type == E_REL)
                    {
                        int nsec = elfRead2(&pSym[i].st_shndx);
                        if (nsec >= 0 && nsec < m_iNumSections)
                            pVal.uSymAddr += GetSectionInfo(nsec)->uNativeAddr;
                    }
                    pVal.iSymSize = elfRead4(&pSym[i].st_size);
                    return true;
                }
            }
#endif
            return false; // Not found (this table)
        }
示例#34
0
        bool ValueByName(string pName, ref SymValue pVal, bool bNoTypeOK /* = false */)
        {
            throw new NotImplementedException();
#if NYI
            int hash, numBucket, numChain, y;
            int* pBuckets;
            int* pChains; // For symbol table work
            int found;
            int [] pHash; // Pointer to hash table
            Elf32_Sym* pSym; // Pointer to the symbol table
            int iStr; // Section index of the string table
            PSectionInfo pSect;

            pSect = GetSectionInfoByName(".dynsym");
            if (pSect == 0)
            {
                // We have a file with no .dynsym section, and hence no .hash section (from my understanding - MVE).
                // It seems that the only alternative is to linearly search the symbol tables.
                // This must be one of the big reasons that linking is so slow! (at least, for statically linked files)
                // Note MVE: We can't use m_SymTab because we may need the size
                return SearchValueByName(pName, pVal);
            }
            pSym = (Elf32_Sym)pSect.uHostAddr;
            if (pSym == null) return false;
            pSect = GetSectionInfoByName(".hash");
            if (pSect == 0) return false;
            pHash = (int[])pSect.uHostAddr;
            iStr = GetSectionIndexByName(".dynstr");

            // First organise the hash table
            numBucket = elfRead4(&pHash[0]);
            numChain = elfRead4(&pHash[1]);
            pBuckets = &pHash[2];
            pChains = &pBuckets[numBucket];

            // Hash the symbol
            hash = elf_hash(pName) % numBucket;
            y = elfRead4(&pBuckets[hash]); // Look it up in the bucket list
            // Beware of symbol tables with 0 in the buckets, e.g. libstdc++.
            // In that case, set found to false.
            found = (y != 0);
            if (y)
            {
                while (strcmp(pName, GetStrPtr(iStr, elfRead4(&pSym[y].st_name))) != 0)
                {
                    y = elfRead4(&pChains[y]);
                    if (y == 0)
                    {
                        found = false;
                        break;
                    }
                }
            }
            // Beware of symbols with STT_NOTYPE, e.g. "open" in libstdc++ !
            // But sometimes "main" has the STT_NOTYPE attribute, so if bNoTypeOK is passed as true, return true
            if (found && (bNoTypeOK || (ELF32_ST_TYPE(pSym[y].st_info) != STT_NOTYPE)))
            {
                pVal.uSymAddr = elfRead4((int*)&pSym[y].st_value);
                int e_type = elfRead2(&((Elf32_Ehdr*)m_pImage)->e_type);
                if (e_type == E_REL)
                {
                    int nsec = elfRead2(&pSym[y].st_shndx);
                    if (nsec >= 0 && nsec < m_iNumSections)
                        pVal.uSymAddr += GetSectionInfo(nsec)->uNativeAddr;
                }
                pVal.iSymSize = elfRead4(&pSym[y].st_size);
                return true;
            }
            else
            {
                // We may as well do a linear search of the main symbol table. Some symbols (e.g. init_dummy) are
                // in the main symbol table, but not in the hash table
                return SearchValueByName(pName, pVal);
            }
#endif
        }
示例#35
0
 ADDRESS GetAddressByName(string pName,
     bool bNoTypeOK /* = false */)
 {
     var Val = new SymValue ();
     bool bSuccess = ValueByName(pName, ref Val, bNoTypeOK);
     if (bSuccess)
     {
         m_iLastSize = Val.iSymSize;
         m_uLastAddr = Val.uSymAddr;
         return Val.uSymAddr;
     }
     else return NO_ADDRESS;
 }