Пример #1
0
 /// <summary>
 /// Creates a LocalVariableTable from a SerLocalVariableTable.
 /// </summary>
 /// <param name="serTable">Deserialized data.</param>
 /// <param name="contentVersion">Serialization version.</param>
 /// <param name="report">Error report object.</param>
 /// <param name="outLvt">Created LocalVariableTable</param>
 /// <returns>True on success.</returns>
 private static bool CreateLocalVariableTable(SerLocalVariableTable serTable,
                                              int contentVersion, FileLoadReport report, out LocalVariableTable outLvt)
 {
     outLvt = new LocalVariableTable();
     outLvt.ClearPrevious = serTable.ClearPrevious;
     foreach (SerDefSymbol serDef in serTable.Variables)
     {
         // Force the "has width" field to true for local variables, because it's
         // non-optional there.  This is really only needed for loading projects
         // created in v1.3, which didn't have the "has width" property.
         serDef.HasWidth = true;
         if (!CreateDefSymbol(serDef, contentVersion, report, out DefSymbol defSym))
         {
             return(false);
         }
         if (!defSym.IsVariable)
         {
             // not expected to happen; skip it
             Debug.WriteLine("Found local variable with bad source: " +
                             defSym.SymbolSource);
             string str = string.Format(Res.Strings.ERR_BAD_LOCAL_VARIABLE_FMT,
                                        defSym);
             report.Add(FileLoadItem.Type.Warning, str);
             continue;
         }
         outLvt.AddOrReplace(defSym);
     }
     return(true);
 }
Пример #2
0
            public SerLocalVariableTable(LocalVariableTable varTab)
            {
                Variables = new List <SerDefSymbol>(varTab.Count);
                for (int i = 0; i < varTab.Count; i++)
                {
                    DefSymbol defSym = varTab[i];
                    Variables.Add(new SerDefSymbol(defSym));
                }

                ClearPrevious = varTab.ClearPrevious;
            }
Пример #3
0
        /// <summary>
        /// Copy constructor.
        /// </summary>
        /// <param name="src">Object to clone.</param>
        public LocalVariableTable(LocalVariableTable src) : this()
        {
            ClearPrevious = src.ClearPrevious;

            foreach (KeyValuePair <string, DefSymbol> kvp in src.mVarByLabel)
            {
                mVarByLabel[kvp.Value.Label] = kvp.Value;
                mVarByValue.Add(kvp.Value);
            }

            Debug.Assert(this == src);
        }
Пример #4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="lvTables">List of tables from the DisasmProject.</param>
        /// <param name="symbolTable">Full SymbolTable from the DisasmProject.  Used to
        ///   generate globally unique symbol names.</param>
        /// <param name="project">Project reference.</param>
        /// <param name="uniquify">Set to true if variable names cannot be redefined.</param>
        public LocalVariableLookup(SortedList <int, LocalVariableTable> lvTables,
                                   DisasmProject project, bool uniquify)
        {
            mLvTables    = lvTables;
            mSymbolTable = project.SymbolTable;
            mProject     = project;
            mDoUniquify  = uniquify;

            mCurrentTable = new LocalVariableTable();
            mDupRemap     = new Dictionary <string, string>();
            if (uniquify)
            {
                mUniqueLabels = new Dictionary <string, UniqueLabel>();
            }
            Reset();
        }
Пример #5
0
        /// <summary>
        /// Creates an UndoableChange for a local variable table update.
        /// </summary>
        /// <param name="offset">Affected offset.</param>
        /// <param name="oldLvTable">Old table.</param>
        /// <param name="newLvTable">New table.</param>
        /// <returns>Change record.</returns>
        public static UndoableChange CreateLocalVariableTableChange(int offset,
                                                                    LocalVariableTable oldLvTable, LocalVariableTable newLvTable)
        {
            if (oldLvTable == newLvTable)
            {
                Debug.WriteLine("No-op local variable table change");
            }

            UndoableChange uc = new UndoableChange();

            uc.Type               = ChangeType.SetLocalVariableTable;
            uc.Offset             = offset;
            uc.OldValue           = oldLvTable;
            uc.NewValue           = newLvTable;
            uc.ReanalysisRequired = ReanalysisScope.DataOnly;   // update dfds in Anattribs
            return(uc);
        }
Пример #6
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="lvTables">List of tables from the DisasmProject.</param>
        /// <param name="project">Project reference.</param>
        /// <param name="labelMap">Label map dictionary, used to rename the labels in
        ///   the project symbol table.  May be null.</param>
        /// <param name="maskLeadingUnderscores">If true, labels with leading underscores
        ///   will be prefixed.</param>
        /// <param name="uniquify">Set to true if variable names cannot be redefined.</param>
        public LocalVariableLookup(SortedList <int, LocalVariableTable> lvTables,
                                   DisasmProject project, Dictionary <string, string> labelMap,
                                   bool maskLeadingUnderscores, bool uniquify)
        {
            mLvTables = lvTables;
            mProject  = project;
            mLabelMap = labelMap;
            mMaskLeadingUnderscores = maskLeadingUnderscores;
            mDoUniquify             = uniquify;

            mCurrentTable = new LocalVariableTable();
            mDupRemap     = new Dictionary <string, string>();
            if (uniquify)
            {
                mUniqueLabels = new Dictionary <string, UniqueLabel>();
            }
            Reset();
        }
Пример #7
0
        /// <summary>
        /// Updates internal state to reflect the state of the world at the specified offset.
        /// </summary>
        /// <remarks>
        /// When the offset is greater than or equal to its value on a previous call, we can
        /// do an incremental update.  If the offset moves backward, we have to reset and walk
        /// forward again.
        /// </remarks>
        /// <param name="targetOffset">Target offset.</param>
        private void AdvanceToOffset(int targetOffset)
        {
            if (mNextLvtIndex < 0)
            {
                return;
            }
            if (targetOffset < mRecentOffset)
            {
                // We went backwards.
                Reset();
            }
            while (mNextLvtOffset <= targetOffset)
            {
                if (!mProject.GetAnattrib(mNextLvtOffset).IsStart)
                {
                    // Hidden table, ignore it.
                    Debug.WriteLine("Ignoring LvTable at +" + mNextLvtOffset.ToString("x6"));
                }
                else
                {
                    // Process this table.
                    LocalVariableTable lvt = mLvTables.Values[mNextLvtIndex];
                    if (lvt.ClearPrevious)
                    {
                        mCurrentTable.Clear();
                    }

                    // Create a list for GetVariablesDefinedAtOffset
                    mRecentSymbols = new List <DefSymbol>();
                    mRecentOffset  = mNextLvtOffset;

                    // Merge the new entries into the work table.  This automatically
                    // discards entries that clash by name or value.
                    for (int i = 0; i < lvt.Count; i++)
                    {
                        DefSymbol defSym = lvt[i];

                        // Look for non-variable symbols with the same label.  Ordinarily the
                        // editor prevents this from happening, but there are ways to trick
                        // the system (e.g. add a symbol while the LvTable is hidden).  We
                        // deal with it here.
                        if (mSymbolTable.TryGetNonVariableValue(defSym.Label, out Symbol unused))
                        {
                            Debug.WriteLine("Detected duplicate non-var label " + defSym.Label +
                                            " at +" + mNextLvtOffset.ToString("x6"));
                            string newLabel = DeDupLabel(defSym.Label);
                            mDupRemap[defSym.Label] = newLabel;
                            defSym = new DefSymbol(defSym, newLabel);
                        }

                        if (mDoUniquify)
                        {
                            if (mUniqueLabels.TryGetValue(defSym.Label, out UniqueLabel ulab))
                            {
                                // We've seen this label before; generate a unique version by
                                // increasing the appended number.
                                ulab.MakeUnique(mSymbolTable);
                                defSym = new DefSymbol(defSym, ulab.Label);
                            }
                            else
                            {
                                // Haven't seen this before.  Add it to the unique-labels table.
                                mUniqueLabels.Add(defSym.Label, new UniqueLabel(defSym.Label));
                            }
                        }
                        mCurrentTable.AddOrReplace(defSym);

                        mRecentSymbols.Add(defSym);
                    }

                    //mCurrentTable.DebugDump(mNextLvtOffset);
                }

                // Update state to look for next table.
                mNextLvtIndex++;
                if (mNextLvtIndex < mLvTables.Keys.Count)
                {
                    mNextLvtOffset = mLvTables.Keys[mNextLvtIndex];
                }
                else
                {
                    mNextLvtOffset = mProject.FileDataLength;   // never reached
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Updates internal state to reflect the state of the world at the specified offset.
        /// </summary>
        /// <remarks>
        /// When the offset is greater than or equal to its value on a previous call, we can
        /// do an incremental update.  If the offset moves backward, we have to reset and walk
        /// forward again.
        /// </remarks>
        /// <param name="targetOffset">Target offset.</param>
        private void AdvanceToOffset(int targetOffset)
        {
            if (mNextLvtIndex < 0)
            {
                return;
            }
            if (targetOffset < mRecentOffset)
            {
                // We went backwards.
                Reset(false);
            }
            while (mNextLvtOffset <= targetOffset)
            {
                if (!mProject.GetAnattrib(mNextLvtOffset).IsStart)
                {
                    // Hidden table, ignore it.
                    Debug.WriteLine("Ignoring LvTable at +" + mNextLvtOffset.ToString("x6"));
                }
                else
                {
                    // Process this table.
                    LocalVariableTable lvt = mLvTables.Values[mNextLvtIndex];
                    if (lvt.ClearPrevious)
                    {
                        mCurrentTable.Clear();
                    }

                    // Create a list for GetVariablesDefinedAtOffset
                    mRecentSymbols = new List <DefSymbol>();
                    mRecentOffset  = mNextLvtOffset;

                    // Merge the new entries into the work table.  This automatically
                    // discards entries that clash by name or value.
                    for (int i = 0; i < lvt.Count; i++)
                    {
                        DefSymbol defSym   = lvt[i];
                        string    newLabel = defSym.Label;

                        if (mMaskLeadingUnderscores && newLabel[0] == '_')
                        {
                            newLabel = AsmGen.LabelLocalizer.NO_UNDER_PFX + newLabel;
                        }

                        // Look for non-variable symbols with the same label.  Ordinarily the
                        // editor prevents this from happening, but there are ways to trick
                        // the system (e.g. add a symbol while the LvTable is hidden, or have
                        // a non-unique local promoted to global).  We deal with it here.
                        //
                        // TODO(someday): this is not necessary for assemblers like Merlin 32
                        // that put variables in a separate namespace.
                        if (mAllNvSymbols.TryGetValue(newLabel, out Symbol unused))
                        {
                            Debug.WriteLine("Detected duplicate non-var label " + newLabel +
                                            " at +" + mNextLvtOffset.ToString("x6"));
                            newLabel = GenerateDeDupLabel(newLabel);
                        }

                        if (newLabel != defSym.Label)
                        {
                            mDupRemap[defSym.Label] = newLabel;
                            defSym = new DefSymbol(defSym, newLabel);
                        }

                        if (mDoUniquify)
                        {
                            if (mUniqueLabels.TryGetValue(defSym.Label, out UniqueLabel ulab))
                            {
                                // We've seen this label before; generate a unique version by
                                // increasing the appended number.
                                ulab.MakeUnique(mAllNvSymbols);
                                defSym = new DefSymbol(defSym, ulab.Label);
                            }
                            else
                            {
                                // Haven't seen this before.  Add it to the unique-labels table.
                                mUniqueLabels.Add(defSym.Label, new UniqueLabel(defSym.Label));
                            }
                        }
                        mCurrentTable.AddOrReplace(defSym);

                        mRecentSymbols.Add(defSym);
                    }

                    //mCurrentTable.DebugDump(mNextLvtOffset);
                }

                // Update state to look for next table.
                mNextLvtIndex++;
                if (mNextLvtIndex < mLvTables.Keys.Count)
                {
                    mNextLvtOffset = mLvTables.Keys[mNextLvtIndex];
                }
                else
                {
                    mNextLvtOffset = mProject.FileDataLength;   // never reached
                }
            }
        }