/// <summary> /// Identifies the LocalVariableTable that defined the symbol reference. /// </summary> /// <param name="offset">Offset at which the symbol was referenced.</param> /// <param name="symRef">Reference to symbol.</param> /// <returns>Table index, or -1 if not found.</returns> public int GetDefiningTableOffset(int offset, WeakSymbolRef symRef) { // symRef is the non-uniquified, non-de-duplicated symbol that was generated // during the analysis pass. This matches the contents of the tables, so we don't // need to transform it at all. // // Walk backward through the list of tables until we find a match. IList <int> keys = mLvTables.Keys; for (int i = keys.Count - 1; i >= 0; i--) { if (keys[i] > offset) { // table comes after the point of reference continue; } if (mLvTables.Values[i].GetByLabel(symRef.Label) != null) { // found it return(keys[i]); } } // if we didn't find it, it doesn't exist... right? Debug.Assert(mCurrentTable.GetByLabel(symRef.Label) == null); return(-1); }
/// <summary> /// Gets the symbol associated with a symbol reference. If uniquification is enabled, /// the unique-label map for the specified offset will be used to transform the /// symbol reference. /// </summary> /// <param name="offset">Offset of start of instruction.</param> /// <param name="symRef">Reference to symbol.</param> /// <returns>Symbol, or null if no match found.</returns> public DefSymbol GetSymbol(int offset, WeakSymbolRef symRef) { AdvanceToOffset(offset); // The symRef uses the non-uniquified symbol, so we need to get the unique value at // the current offset. We may need to do this even when variables can be // redefined, because we might have a variable that's a duplicate of a user label // or project symbol. // Start by applying the de-duplication map. string label = symRef.Label; if (mDupRemap.TryGetValue(symRef.Label, out string remap)) { label = remap; } //Debug.WriteLine("GetSymbol " + symRef.Label + " -> " + label); if (mUniqueLabels != null && mUniqueLabels.TryGetValue(label, out UniqueLabel ulab)) { //Debug.WriteLine(" Unique var " + symRef.Label + " -> " + ulab.Label); label = ulab.Label; } DefSymbol defSym = mCurrentTable.GetByLabel(label); // In theory this is okay, but in practice the only things asking for symbols are // entirely convinced that the symbol exists here. So this is probably a bug. Debug.Assert(defSym != null); return(defSym); }
/// <summary> /// Identifies the LocalVariableTable that defined the symbol reference. /// </summary> /// <param name="offset">Offset at which the symbol was referenced.</param> /// <param name="symRef">Reference to symbol.</param> /// <returns>Table index, or -1 if not found.</returns> public int GetDefiningTableOffset(int offset, WeakSymbolRef symRef) { // Get mDupRemap et. al. into the right state. AdvanceToOffset(offset); // symRef is the non-uniquified, de-duplicated symbol that was generated // during the analysis pass. We either need to un-de-duplicate the label, // or de-duplicate what we pull out of the Lv tables. The former requires // a linear string search but will be faster if there are a lot of tables. string label = UnDeDuplicate(symRef.Label); // Walk backward through the list of tables until we find a match. IList <int> keys = mLvTables.Keys; for (int i = keys.Count - 1; i >= 0; i--) { if (keys[i] > offset) { // table comes after the point of reference continue; } if (mLvTables.Values[i].GetByLabel(label) != null) { // found it return(keys[i]); } } // if we didn't find it, it doesn't exist... right? Debug.Assert(mCurrentTable.GetByLabel(label) == null); return(-1); }
/// <summary> /// Constructor for symbol item. /// </summary> /// <param name="length">Length, in bytes.</param> /// <param name="sym">Weak symbol reference.</param> /// <param name="isBigEndian">Set to true for big-endian data.</param> private FormatDescriptor(int length, WeakSymbolRef sym, bool isBigEndian) { Debug.Assert(sym != null); Debug.Assert(length > 0 && length <= MAX_NUMERIC_LEN); Length = length; FormatType = isBigEndian ? Type.NumericBE : Type.NumericLE; FormatSubType = SubType.Symbol; SymbolRef = sym; }
public SerWeakSymbolRef(WeakSymbolRef weakSym) { Label = weakSym.Label; Part = weakSym.ValuePart.ToString(); }
/// <summary> /// Returns a descriptor with a symbol. /// </summary> /// <param name="length">Length, in bytes.</param> /// <param name="sym">Weak symbol reference.</param> /// <param name="isBigEndian">Set to true for big-endian data.</param> /// <returns>New or pre-allocated descriptor.</returns> public static FormatDescriptor Create(int length, WeakSymbolRef sym, bool isBigEndian) { DebugCreateCount++; return(new FormatDescriptor(length, sym, isBigEndian)); }