From 3c3209b67fb595123418931460b7439cd0741cff Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 4 Oct 2019 16:53:31 -0700 Subject: [PATCH] Expand set of symbols available to plugins We were providing platform symbols to plugins through the PlatSym list, which allowed them to find constants and well-known addresses. We now pass all project symbols and user labels in as well. The name "PlatSym" is no longer accurate, so the class has been renamed. Also, added a bunch of things to the problem list viewer, and added some more info to the Info panel. Also, added a minor test to 2011-hinting that does not affect the output (which is the point). --- PluginCommon/Interfaces.cs | 9 +- PluginCommon/PlSymbol.cs | 142 ++++++++++++++++++ PluginCommon/PlatSym.cs | 84 ----------- PluginCommon/PluginManager.cs | 4 +- SourceGen/DisasmProject.cs | 76 ++++++++-- SourceGen/FormatDescriptor.cs | 78 ++++++---- SourceGen/ProblemList.cs | 2 + SourceGen/RuntimeData/Apple/GSOS.cs | 8 +- SourceGen/RuntimeData/Apple/IIgs-Toolbox.cs | 8 +- SourceGen/RuntimeData/Apple/ProDOS8.cs | 8 +- SourceGen/RuntimeData/Apple/SOS.cs | 8 +- SourceGen/SGTestData/2011-hinting.cs | 2 +- SourceGen/SGTestData/2011-hinting.dis65 | 2 + SourceGen/Sandbox/ScriptManager.cs | 62 ++++++-- SourceGen/Symbol.cs | 3 +- SourceGen/SymbolTable.cs | 6 + SourceGen/Tools/WpfGui/ProblemListViewer.xaml | 2 + .../Tools/WpfGui/ProblemListViewer.xaml.cs | 6 + 18 files changed, 339 insertions(+), 171 deletions(-) create mode 100644 PluginCommon/PlSymbol.cs delete mode 100644 PluginCommon/PlatSym.cs diff --git a/PluginCommon/Interfaces.cs b/PluginCommon/Interfaces.cs index b78f6b7..497a545 100644 --- a/PluginCommon/Interfaces.cs +++ b/PluginCommon/Interfaces.cs @@ -28,11 +28,6 @@ namespace PluginCommon { /// string Identifier { get; } - /// - /// Returns true if this plugin checks JSR/JSL for inline data. - /// - //bool HasInlineDataAnalyzer { get; } - /// /// Initializes the plugin with an application reference and a buffer with file /// data. Called before each analysis pass. @@ -43,8 +38,8 @@ namespace PluginCommon { /// /// Reference to application interface. /// 65xx code and data. - /// Platform symbols, in no particular order. - void Prepare(IApplication appRef, byte[] fileData, List platSyms); + /// Symbols available to plugins, in no particular order. + void Prepare(IApplication appRef, byte[] fileData, List plSyms); } public interface IPlugin_InlineJsr { diff --git a/PluginCommon/PlSymbol.cs b/PluginCommon/PlSymbol.cs new file mode 100644 index 0000000..33765c4 --- /dev/null +++ b/PluginCommon/PlSymbol.cs @@ -0,0 +1,142 @@ +/* + * Copyright 2018 faddenSoft + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PluginCommon { + /// + /// Plugin-accessible symbol, for use in extension scripts. + /// + /// Instances are immutable. + /// + [Serializable] + public class PlSymbol { + /// + /// Subset of Symbol.Source. Does not include auto-generated labels or variables. + /// + public enum Source { + Unknown = 0, + User, + Project, + Platform + } + + /// + /// Subset of Symbol.Type. Does not specify local vs. global or export. + /// + public enum Type { + Unknown = 0, + Address, + Constant + } + + /// + /// Label sent to assembler. + /// + public string Label { get; private set; } + + /// + /// Symbol's numeric value. + /// + public int Value { get; private set; } + + /// + /// Symbol origin. + /// + private Source SymbolSource { get; set; } + public bool IsUserSymbol { get { return SymbolSource == Source.User; } } + public bool IsProjectSymbol { get { return SymbolSource == Source.Project; } } + public bool IsPlatformSymbol { get { return SymbolSource == Source.Platform; } } + + /// + /// Symbol type. + /// + private Type SymbolType { get; set; } + public bool IsAddress { get { return SymbolType == Type.Address; } } + public bool IsConstant { get { return SymbolType == Type.Constant; } } + + /// + /// Platform/project symbols only: width, in bytes, of data at symbol. Will be -1 + /// for user labels. + /// + public int Width { get; private set; } + + /// + /// Platform symbols only: tag used to organize symbols into groups.. + /// + public string Tag { get; private set; } + + + /// + /// Nullary constructor, for deserialization. + /// + private PlSymbol() { } + + /// + /// Constructor. + /// + /// Symbol label. + /// Symbol value. + /// Symbol group tag. + public PlSymbol(string label, int value, int width, Source source, Type type, string tag) { + Label = label; + Value = value; + Width = width; + SymbolSource = source; + SymbolType = type; + Tag = tag; + } + + /// + /// Generates a dictionary of platform symbols, keyed by value. Only symbols with + /// a matching tag are included. If more than one symbol has the same value, only + /// one will be included; which one it will be is undefined. + /// + /// List of platform symbols to select from. + /// Tag to match, or null to collect all symbols. + /// Application reference, for debug log output. + /// Dictionary of matching platform symbols. + public static Dictionary GeneratePlatformValueList(List ppuSyms, + string tag, IApplication appRef) { + Dictionary dict = new Dictionary(); + + foreach (PlSymbol ps in ppuSyms) { + if (ps.SymbolSource != Source.Platform) { + continue; + } + if (tag == null || tag == ps.Tag) { + try { + dict.Add(ps.Value, ps); + } catch (ArgumentException) { + appRef.DebugLog("WARNING: GenerateValueList: multiple entries with " + + "value " + ps.Value.ToString("x4")); + } + } + } + + if (dict.Count == 0) { + appRef.DebugLog("PlSymbol: no symbols found for tag=" + tag); + } + + return dict; + } + + public override string ToString() { + return Label + "=" + Value.ToString("x4") + " [" + Tag + "]"; + } + } +} diff --git a/PluginCommon/PlatSym.cs b/PluginCommon/PlatSym.cs deleted file mode 100644 index 9862100..0000000 --- a/PluginCommon/PlatSym.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Text; - -namespace PluginCommon { - /// - /// Symbols loaded from platform symbol files, for use in extension scripts. - /// - /// Instances are immutable. - /// - [Serializable] - public class PlatSym { - public string Label { get; private set; } - public int Value { get; private set; } - public string Tag { get; private set; } - - /// - /// Nullary constructor, for deserialization. - /// - private PlatSym() { } - - /// - /// Constructor. - /// - /// Symbol label. - /// Symbol value. - /// Symbol group tag. - public PlatSym(string label, int value, string tag) { - Label = label; - Value = value; - Tag = tag; - } - - /// - /// Generates a dictionary of platform symbols, keyed by value. Only symbols with - /// a matching tag are included. If more than one symbol has the same value, only - /// one will be included; which one it will be is undefined. - /// - /// List of platform symbols to select from. - /// Tag to match, or null to collect all symbols. - /// Application reference, for debug log output. - /// - public static Dictionary GenerateValueList(List platSyms, - string tag, IApplication appRef) { - Dictionary dict = new Dictionary(); - - foreach (PlatSym ps in platSyms) { - if (tag == null || tag == ps.Tag) { - try { - dict.Add(ps.Value, ps); - } catch (ArgumentException) { - appRef.DebugLog("WARNING: GenerateValueList: multiple entries with " + - "value " + ps.Value.ToString("x4")); - } - } - } - - if (dict.Count == 0) { - appRef.DebugLog("PlatSym: no symbols found for tag=" + tag); - } - - return dict; - } - - public override string ToString() { - return Label + "=" + Value.ToString("x4") + " [" + Tag + "]"; - } - } -} diff --git a/PluginCommon/PluginManager.cs b/PluginCommon/PluginManager.cs index bc13afb..f86b77e 100644 --- a/PluginCommon/PluginManager.cs +++ b/PluginCommon/PluginManager.cs @@ -152,9 +152,9 @@ namespace PluginCommon { /// Invokes the Prepare() method on all active plugins. /// /// Reference to host object providing app services. - public void PreparePlugins(IApplication appRef, List platSyms) { + public void PreparePlugins(IApplication appRef, List plSyms) { foreach (KeyValuePair kvp in mActivePlugins) { - kvp.Value.Prepare(appRef, mFileData, platSyms); + kvp.Value.Prepare(appRef, mFileData, plSyms); } } diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index 000d610..abdd658 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -823,7 +823,8 @@ namespace SourceGen { /// /// Log for debug messages. private void ApplyFormatDescriptors(DebugLog genLog) { - // TODO: add these to ProblemList + genLog.LogI("Applying format descriptors"); + foreach (KeyValuePair kvp in OperandFormats) { int offset = kvp.Key; @@ -834,16 +835,29 @@ namespace SourceGen { // Check offset. if (offset < 0 || offset >= mAnattribs.Length) { - genLog.LogE("Invalid offset +" + offset.ToString("x6") + - "(desc=" + kvp.Value + ")"); + string msg = "invalid offset (desc=" + kvp.Value + ")"; + genLog.LogE("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Error, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidOffsetOrLength, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); Debug.Assert(false); continue; // ignore this one } // Make sure it doesn't run off the end if (offset + kvp.Value.Length > mAnattribs.Length) { - genLog.LogE("Invalid offset+len +" + offset.ToString("x6") + - " len=" + kvp.Value.Length + " file=" + mAnattribs.Length); + string msg = "invalid offset+len: len=" + kvp.Value.Length + + " file=" + mAnattribs.Length; + genLog.LogE("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Error, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidOffsetOrLength, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); Debug.Assert(false); continue; // ignore this one } @@ -853,25 +867,50 @@ namespace SourceGen { // a bunch of bytes as single-byte data items and then add a code entry // point. if (kvp.Value.Length != mAnattribs[offset].Length) { - genLog.LogW("+" + offset.ToString("x6") + - ": unexpected length on instr format descriptor (" + - kvp.Value.Length + " vs " + mAnattribs[offset].Length + ")"); + string msg = "unexpected length on instr format descriptor (" + + kvp.Value.Length + " vs " + mAnattribs[offset].Length + ")"; + genLog.LogW("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Warning, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidOffsetOrLength, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); continue; // ignore this one } if (kvp.Value.Length == 1) { // No operand to format! - genLog.LogW("+" + offset.ToString("x6") + - ": unexpected format descriptor on single-byte op"); + string msg = "unexpected format descriptor on single-byte op"; + genLog.LogW("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Warning, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidDescriptor, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); continue; // ignore this one } if (!kvp.Value.IsValidForInstruction) { - genLog.LogW("Descriptor not valid for instruction: " + kvp.Value); + string msg = "descriptor not valid for instruction: " + kvp.Value; + genLog.LogW("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Warning, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidDescriptor, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); continue; // ignore this one } } else if (mAnattribs[offset].IsInstruction) { // Mid-instruction format. - genLog.LogW("+" + offset.ToString("x6") + - ": unexpected mid-instruction format descriptor"); + string msg = "unexpected mid-instruction format descriptor"; + genLog.LogW("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Warning, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidDescriptor, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); continue; // ignore this one } else { // Data or inline data. The data analyzer hasn't run yet. We want to @@ -889,8 +928,15 @@ namespace SourceGen { bool overlap = false; for (int i = offset; i < offset + kvp.Value.Length; i++) { if (mAnattribs[i].IsInstruction) { - genLog.LogW("+" + offset.ToString("x6") + - ": data format descriptor overlaps code at +" + i.ToString("x6")); + string msg = + "data format descriptor overlaps code at +" + i.ToString("x6"); + genLog.LogW("+" + offset.ToString("x6") + ": " + msg); + Problems.Add(new ProblemList.ProblemEntry( + ProblemList.ProblemEntry.SeverityLevel.Warning, + offset, + ProblemList.ProblemEntry.ProblemType.InvalidDescriptor, + msg, + ProblemList.ProblemEntry.ProblemResolution.FormatDescriptorIgnored)); overlap = true; break; } diff --git a/SourceGen/FormatDescriptor.cs b/SourceGen/FormatDescriptor.cs index 7b0cdb2..0cf3e7c 100644 --- a/SourceGen/FormatDescriptor.cs +++ b/SourceGen/FormatDescriptor.cs @@ -370,49 +370,50 @@ namespace SourceGen { public string ToUiString() { // NOTE: this should be made easier to localize + string retstr = Length + "-byte "; + if (IsString) { - string descr; switch (FormatSubType) { case SubType.Ascii: - descr = "ASCII"; + retstr += "ASCII"; break; case SubType.HighAscii: - descr = "ASCII (high)"; + retstr += "ASCII (high)"; break; case SubType.C64Petscii: - descr = "C64 PETSCII"; + retstr += "C64 PETSCII"; break; case SubType.C64Screen: - descr = "C64 Screen"; + retstr += "C64 Screen"; break; default: - descr = "???"; + retstr += "???"; break; } switch (FormatType) { case Type.StringGeneric: - descr += " string"; + retstr += " string"; break; case Type.StringReverse: - descr += " string (reverse)"; + retstr += " string (reverse)"; break; case Type.StringNullTerm: - descr += " string (null term)"; + retstr += " string (null term)"; break; case Type.StringL8: - descr += " string (1-byte len)"; + retstr += " string (1-byte len)"; break; case Type.StringL16: - descr += " string (2-byte len)"; + retstr += " string (2-byte len)"; break; case Type.StringDci: - descr += " string (DCI)"; + retstr += " string (DCI)"; break; default: - descr += " ???"; + retstr += " ???"; break; } - return descr; + return retstr; } switch (FormatSubType) { @@ -420,43 +421,60 @@ namespace SourceGen { switch (FormatType) { case Type.Default: case Type.NumericLE: - return "Numeric (little-endian)"; + retstr += "Numeric (little-endian)"; + break; case Type.NumericBE: - return "Numeric (big-endian)"; + retstr += "Numeric (big-endian)"; + break; case Type.Dense: - return "Dense"; + retstr += "Dense"; + break; case Type.Fill: - return "Fill"; + retstr += "Fill"; + break; default: // strings handled earlier - return "???"; + retstr += "???"; + break; } + break; case SubType.Hex: - return "Numeric, Hex"; + retstr += "Numeric, Hex"; + break; case SubType.Decimal: - return "Numeric, Decimal"; + retstr += "Numeric, Decimal"; + break; case SubType.Binary: - return "Numeric, Binary"; + retstr += "Numeric, Binary"; + break; case SubType.Address: - return "Address"; + retstr += "Address"; + break; case SubType.Symbol: if (SymbolRef.IsVariable) { - return "Local var \"" + SymbolRef.Label + "\""; + retstr += "Local var \"" + SymbolRef.Label + "\""; } else { - return "Symbol \"" + SymbolRef.Label + "\""; + retstr += "Symbol \"" + SymbolRef.Label + "\""; } + break; case SubType.Ascii: - return "Numeric, ASCII"; + retstr += "Numeric, ASCII"; + break; case SubType.HighAscii: - return "Numeric, ASCII (high)"; + retstr += "Numeric, ASCII (high)"; + break; case SubType.C64Petscii: - return "Numeric, C64 PETSCII"; + retstr += "Numeric, C64 PETSCII"; + break; case SubType.C64Screen: - return "Numeric, C64 Screen"; + retstr += "Numeric, C64 Screen"; + break; default: - return "???"; + retstr += "???"; + break; } + return retstr; } public override string ToString() { diff --git a/SourceGen/ProblemList.cs b/SourceGen/ProblemList.cs index f29f9f7..7606202 100644 --- a/SourceGen/ProblemList.cs +++ b/SourceGen/ProblemList.cs @@ -47,6 +47,8 @@ namespace SourceGen { Unknown = 0, HiddenLabel, UnresolvedWeakRef, + InvalidOffsetOrLength, + InvalidDescriptor, } public ProblemType Problem { get; private set; } diff --git a/SourceGen/RuntimeData/Apple/GSOS.cs b/SourceGen/RuntimeData/Apple/GSOS.cs index 72cfc86..c0c80b0 100644 --- a/SourceGen/RuntimeData/Apple/GSOS.cs +++ b/SourceGen/RuntimeData/Apple/GSOS.cs @@ -40,7 +40,7 @@ namespace RuntimeData.Apple { private IApplication mAppRef; private byte[] mFileData; - private Dictionary mFunctionList; + private Dictionary mFunctionList; public string Identifier { get { @@ -48,14 +48,14 @@ namespace RuntimeData.Apple { } } - public void Prepare(IApplication appRef, byte[] fileData, List platSyms) { + public void Prepare(IApplication appRef, byte[] fileData, List plSyms) { mAppRef = appRef; mFileData = fileData; mAppRef.DebugLog("GSOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()"); //System.Diagnostics.Debugger.Break(); - mFunctionList = PlatSym.GenerateValueList(platSyms, GSOS_FUNC_TAG, appRef); + mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, GSOS_FUNC_TAG, appRef); } public void CheckJsl(int offset, out bool noContinue) { @@ -71,7 +71,7 @@ namespace RuntimeData.Apple { ", cmd=$" + req.ToString("x4") + " addr=$" + addr.ToString("x6")); } - PlatSym sym; + PlSymbol sym; if (mFunctionList.TryGetValue(req, out sym)) { mAppRef.SetInlineDataFormat(offset + 4, 2, DataType.NumericLE, DataSubType.Symbol, sym.Label); diff --git a/SourceGen/RuntimeData/Apple/IIgs-Toolbox.cs b/SourceGen/RuntimeData/Apple/IIgs-Toolbox.cs index 1b62bbb..d2f5742 100644 --- a/SourceGen/RuntimeData/Apple/IIgs-Toolbox.cs +++ b/SourceGen/RuntimeData/Apple/IIgs-Toolbox.cs @@ -33,7 +33,7 @@ namespace RuntimeData.Apple { private IApplication mAppRef; private byte[] mFileData; - private Dictionary mFunctionList; + private Dictionary mFunctionList; public string Identifier { get { @@ -41,13 +41,13 @@ namespace RuntimeData.Apple { } } - public void Prepare(IApplication appRef, byte[] fileData, List platSyms) { + public void Prepare(IApplication appRef, byte[] fileData, List plSyms) { mAppRef = appRef; mFileData = fileData; mAppRef.DebugLog("IIgsToolbox(id=" + AppDomain.CurrentDomain.Id + "): prepare()"); - mFunctionList = PlatSym.GenerateValueList(platSyms, TOOLBOX_FUNC_TAG, appRef); + mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, TOOLBOX_FUNC_TAG, appRef); } public void CheckJsl(int offset, out bool noContinue) { @@ -67,7 +67,7 @@ namespace RuntimeData.Apple { ", func=$" + func.ToString("x4")); } - PlatSym sym; + PlSymbol sym; if (mFunctionList.TryGetValue(func, out sym)) { mAppRef.SetOperandFormat(offset - 3, DataSubType.Symbol, sym.Label); } diff --git a/SourceGen/RuntimeData/Apple/ProDOS8.cs b/SourceGen/RuntimeData/Apple/ProDOS8.cs index 25138f0..09e4f09 100644 --- a/SourceGen/RuntimeData/Apple/ProDOS8.cs +++ b/SourceGen/RuntimeData/Apple/ProDOS8.cs @@ -35,7 +35,7 @@ namespace RuntimeData.Apple { private IApplication mAppRef; private byte[] mFileData; - private Dictionary mFunctionList; + private Dictionary mFunctionList; public string Identifier { get { @@ -43,14 +43,14 @@ namespace RuntimeData.Apple { } } - public void Prepare(IApplication appRef, byte[] fileData, List platSyms) { + public void Prepare(IApplication appRef, byte[] fileData, List plSyms) { mAppRef = appRef; mFileData = fileData; mAppRef.DebugLog("ProDOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()"); //System.Diagnostics.Debugger.Break(); - mFunctionList = PlatSym.GenerateValueList(platSyms, P8_MLI_TAG, appRef); + mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, P8_MLI_TAG, appRef); } public void CheckJsr(int offset, out bool noContinue) { @@ -66,7 +66,7 @@ namespace RuntimeData.Apple { ", cmd=$" + req.ToString("x2") + " addr=$" + addr.ToString("x4")); } - PlatSym sym; + PlSymbol sym; if (mFunctionList.TryGetValue(req, out sym)) { mAppRef.SetInlineDataFormat(offset + 3, 1, DataType.NumericLE, DataSubType.Symbol, sym.Label); diff --git a/SourceGen/RuntimeData/Apple/SOS.cs b/SourceGen/RuntimeData/Apple/SOS.cs index b0765a0..31ca1bb 100644 --- a/SourceGen/RuntimeData/Apple/SOS.cs +++ b/SourceGen/RuntimeData/Apple/SOS.cs @@ -35,7 +35,7 @@ namespace RuntimeData.Apple { private IApplication mAppRef; private byte[] mFileData; - private Dictionary mFunctionList; + private Dictionary mFunctionList; public string Identifier { get { @@ -43,14 +43,14 @@ namespace RuntimeData.Apple { } } - public void Prepare(IApplication appRef, byte[] fileData, List platSyms) { + public void Prepare(IApplication appRef, byte[] fileData, List plSyms) { mAppRef = appRef; mFileData = fileData; mAppRef.DebugLog("SOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()"); //System.Diagnostics.Debugger.Break(); - mFunctionList = PlatSym.GenerateValueList(platSyms, SOS_MLI_TAG, appRef); + mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, SOS_MLI_TAG, appRef); } public void CheckBrk(int offset, out bool noContinue) { @@ -70,7 +70,7 @@ namespace RuntimeData.Apple { ", cmd=$" + req.ToString("x2") + " addr=$" + addr.ToString("x4")); } - PlatSym sym; + PlSymbol sym; if (!mFunctionList.TryGetValue(req, out sym)) { return; } diff --git a/SourceGen/SGTestData/2011-hinting.cs b/SourceGen/SGTestData/2011-hinting.cs index 7323043..453e645 100644 --- a/SourceGen/SGTestData/2011-hinting.cs +++ b/SourceGen/SGTestData/2011-hinting.cs @@ -17,7 +17,7 @@ namespace RuntimeData.Test2011 { } } - public void Prepare(IApplication appRef, byte[] fileData, List platSyms) { + public void Prepare(IApplication appRef, byte[] fileData, List plSymbols) { mAppRef = appRef; mFileData = fileData; diff --git a/SourceGen/SGTestData/2011-hinting.dis65 b/SourceGen/SGTestData/2011-hinting.dis65 index 6b7b8f1..ec1f70e 100644 --- a/SourceGen/SGTestData/2011-hinting.dis65 +++ b/SourceGen/SGTestData/2011-hinting.dis65 @@ -26,6 +26,8 @@ "UserLabels":{ }, "OperandFormats":{ +"13":{ +"Length":1,"Format":"NumericLE","SubFormat":"Decimal","SymbolRef":null}, "51":{ "Length":3,"Format":"Dense","SubFormat":"None","SymbolRef":null}, "66":{ diff --git a/SourceGen/Sandbox/ScriptManager.cs b/SourceGen/Sandbox/ScriptManager.cs index b166568..2f8d7b3 100644 --- a/SourceGen/Sandbox/ScriptManager.cs +++ b/SourceGen/Sandbox/ScriptManager.cs @@ -156,39 +156,73 @@ namespace SourceGen.Sandbox { /// /// Reference to object providing app services. public void PrepareScripts(IApplication appRef) { - List platSyms = GeneratePlatSymList(); + List plSyms = GeneratePlSymbolList(); if (DomainMgr == null) { foreach (KeyValuePair kvp in mActivePlugins) { - kvp.Value.Prepare(appRef, mProject.FileData, platSyms); + kvp.Value.Prepare(appRef, mProject.FileData, plSyms); } } else { - DomainMgr.PluginMgr.PreparePlugins(appRef, platSyms); + DomainMgr.PluginMgr.PreparePlugins(appRef, plSyms); } } /// /// Gathers a list of platform symbols from the project's symbol table. /// - private List GeneratePlatSymList() { - List platSyms = new List(); + private List GeneratePlSymbolList() { + List plSymbols = new List(); SymbolTable symTab = mProject.SymbolTable; foreach (Symbol sym in symTab) { - if (!(sym is DefSymbol)) { - // ignore user labels - continue; + PlSymbol.Source plsSource; + switch (sym.SymbolSource) { + case Symbol.Source.Platform: + plsSource = PlSymbol.Source.Platform; + break; + case Symbol.Source.Project: + plsSource = PlSymbol.Source.Project; + break; + case Symbol.Source.User: + plsSource = PlSymbol.Source.User; + break; + case Symbol.Source.Variable: + case Symbol.Source.Auto: + // don't forward these to plugins + continue; + default: + Debug.Assert(false); + continue; } - DefSymbol defSym = sym as DefSymbol; - if (defSym.SymbolSource != Symbol.Source.Platform) { - // ignore project symbols - continue; + PlSymbol.Type plsType; + switch (sym.SymbolType) { + case Symbol.Type.LocalOrGlobalAddr: + case Symbol.Type.GlobalAddr: + case Symbol.Type.GlobalAddrExport: + case Symbol.Type.ExternalAddr: + plsType = PlSymbol.Type.Address; + break; + case Symbol.Type.Constant: + plsType = PlSymbol.Type.Constant; + break; + default: + Debug.Assert(false); + continue; } - platSyms.Add(new PlatSym(defSym.Label, defSym.Value, defSym.Tag)); + int width = -1; + string tag = string.Empty; + if (sym is DefSymbol) { + DefSymbol defSym = sym as DefSymbol; + width = defSym.DataDescriptor.Length; + tag = defSym.Tag; + } + + + plSymbols.Add(new PlSymbol(sym.Label, sym.Value, width, plsSource, plsType, tag)); } - return platSyms; + return plSymbols; } /// diff --git a/SourceGen/Symbol.cs b/SourceGen/Symbol.cs index 70c6c57..bc5fed5 100644 --- a/SourceGen/Symbol.cs +++ b/SourceGen/Symbol.cs @@ -52,11 +52,10 @@ namespace SourceGen { /// /// True if the symbol's type is an internal label (auto or user). Will be false - /// for external addresses and constants. + /// for external addresses (including variables) and constants. /// public bool IsInternalLabel { get { - // Could also check Type instead. Either works for now. return SymbolSource == Source.User || SymbolSource == Source.Auto; } } diff --git a/SourceGen/SymbolTable.cs b/SourceGen/SymbolTable.cs index 71eff91..fe30895 100644 --- a/SourceGen/SymbolTable.cs +++ b/SourceGen/SymbolTable.cs @@ -252,8 +252,14 @@ namespace SourceGen { // These have a width of 1 and can't overlap with anything meaningful... even // if there's a project symbol for the address, it won't be used, because it's // an in-file address. So we can just remove the entry. + // + // Note we do this *a lot* when the fancier auto labels are enabled, because we + // generate plain labels and then replace them with annotated labels. mSymbolsByAddress.Remove(sym.Value); + return; } + + // Removing a project/platform symbol requires re-evaluating the by-address table. RegenerateAddressTable(); } diff --git a/SourceGen/Tools/WpfGui/ProblemListViewer.xaml b/SourceGen/Tools/WpfGui/ProblemListViewer.xaml index 8150bd2..c4e1779 100644 --- a/SourceGen/Tools/WpfGui/ProblemListViewer.xaml +++ b/SourceGen/Tools/WpfGui/ProblemListViewer.xaml @@ -29,6 +29,8 @@ limitations under the License. Hidden label Ref'd symbol not found + Invalid offset or len + Invalid format desc Label ignored Format ignored diff --git a/SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs b/SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs index 541183f..a140d4a 100644 --- a/SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs +++ b/SourceGen/Tools/WpfGui/ProblemListViewer.xaml.cs @@ -101,6 +101,12 @@ namespace SourceGen.Tools.WpfGui { case ProblemList.ProblemEntry.ProblemType.UnresolvedWeakRef: problem = (string)FindResource("str_UnresolvedWeakRef"); break; + case ProblemList.ProblemEntry.ProblemType.InvalidOffsetOrLength: + problem = (string)FindResource("str_InvalidOffsetOrLength"); + break; + case ProblemList.ProblemEntry.ProblemType.InvalidDescriptor: + problem = (string)FindResource("str_InvalidDescriptor"); + break; default: problem = "???"; break;