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); } } }
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); }
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; }
public SymValue LookupOrBottomPlaceHolder(SymValue arg, TFunc function, out bool isPlaceHolder) { SymValue result = LookupWithoutManifesting(arg, function); isPlaceHolder = result == null; return(isPlaceHolder ? this.BottomPlaceHolder : result); }
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); }
private void AddAbstractValueUpdate(SymValue sv) { if (!IsOldSymbol(sv)) { return; } AddUpdate(new AbstractDomainUpdate <TFunc, TADomain> (sv)); }
private void AddEqualityUpdate(SymValue sv1, SymValue sv2) { if (!IsOldSymbol(sv1) || !IsOldSymbol(sv2)) { return; } AddUpdate(new EqualityUpdate <TFunc, TADomain> (sv1, sv2)); }
private void AddEliminateEdgeUpdate(SymValue from, TFunc function) { if (!IsOldSymbol(from)) { return; } AddUpdate(new EliminateEdgeUpdate <TFunc, TADomain> (from, function)); }
private TADomain Graph2ADomain(SymValue sv) { if (sv != null) { return(this.Graph2 [sv]); } return(this.Graph2.UnderlyingTopValue.ForManifestedField()); }
public void EliminateAll(SymValue arg) { SymValue value = Find(arg); AddEliminateAllUpdate(value); TermMap = TermMap.RemoveAll(value); this [arg] = this.UnderlyingTopValue; }
public SymValue LookupOrManifest(TFunc function, SymValue arg, out bool fresh) { int oldCnt = IdGenerator; SymValue result = this [function, arg]; fresh = oldCnt < IdGenerator; return(result); }
private bool IsOldSymbol(SymValue sv) { if (this.Parent == null) { return(false); } return(sv.UniqueId <= this.Parent.LastSymbolId); }
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)); }
private SymValue LookupMapping(SymValue v1, SymValue v2) { if (v1 == null || v2 == null) { return(null); } return(this.mappings [v1, v2]); }
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)); }
public IEnumerable <SymGraphTerm <TFunc> > EqMultiTerms(SymValue sv) { SymGraphTerm <TFunc> term = EqualMultiTermsMap [sv]; if (term.Args != null && IsValidMultiTerm(term)) { yield return(term); } }
public bool HasAllBottomFields(SymValue sv) { if (sv == null) { return(false); } return(this [sv].HasAllBottomFields); }
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; } }
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); } } }
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); }
private void AddEliminateAllUpdate(SymValue from) { if (!IsOldSymbol(from)) { return; } foreach (TFunc function in TermMap.Keys2(from)) { AddUpdate(new EliminateEdgeUpdate <TFunc, TADomain> (from, function)); } }
private SymValue Find(SymValue v) { SymValue forw = this.forw_map [v]; if (forw == null) { return(v); } return(Find(forw)); }
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); }
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); }
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)); } } }
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); }
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)); }
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); }
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); }
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); } }
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; }
// 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"); }
// 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) }
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 }
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; }