diff --git a/SourceGen/Anattrib.cs b/SourceGen/Anattrib.cs index 5a5065e..5ee423b 100644 --- a/SourceGen/Anattrib.cs +++ b/SourceGen/Anattrib.cs @@ -48,7 +48,7 @@ namespace SourceGen { Visited = 1 << 16, // has the analyzer visited this byte? Changed = 1 << 17, // set/cleared as the analyzer works - Hinted = 1 << 18, // was this byte affected by a type hint? + ATagged = 1 << 18, // was this byte affected by an analyzer tag? } // Flags indicating what type of data is here. Use the following Is* properties @@ -219,15 +219,15 @@ namespace SourceGen { } } } - public bool IsHinted { + public bool HasAnalyzerTag { get { - return (mAttribFlags & AttribFlags.Hinted) != 0; + return (mAttribFlags & AttribFlags.ATagged) != 0; } set { if (value) { - mAttribFlags |= AttribFlags.Hinted; + mAttribFlags |= AttribFlags.ATagged; } else { - mAttribFlags &= ~AttribFlags.Hinted; + mAttribFlags &= ~AttribFlags.ATagged; } } } @@ -381,7 +381,7 @@ namespace SourceGen { StringBuilder sb = new StringBuilder(5); char blank = '.'; sb.Append(IsEntryPoint ? '@' : blank); - sb.Append(IsHinted ? 'T' : blank); + sb.Append(HasAnalyzerTag ? 'T' : blank); sb.Append(DoesNotBranch ? '!' : blank); sb.Append(DoesNotContinue ? '#' : blank); sb.Append(IsBranchTarget ? '>' : blank); diff --git a/SourceGen/CodeAnalysis.cs b/SourceGen/CodeAnalysis.cs index 785f9f5..50f4536 100644 --- a/SourceGen/CodeAnalysis.cs +++ b/SourceGen/CodeAnalysis.cs @@ -34,35 +34,38 @@ namespace SourceGen { /// See the comments at the top of UndoableChange for a list of things that can /// mandate code re-analysis. /// + /// + /// This invokes methods in extension scripts to handle things like inline data + /// following a JSR. The added cost is generally low, because the AppDomain security + /// sandbox doesn't add a lot of overhead. Unfortunately this approach is deprecated + /// by Microsoft and may break or become unavailable. If that happens, and we have to + /// switch to a sandbox approach with significant overhead, we will most likely want + /// to move the code analyzer itself into the sandbox. + /// + /// For this reason it's best to minimize direct interaction between the code here and + /// that elsewhere in the program. + /// public class CodeAnalysis { /// - /// Type hints are specified by the user. The identify a region as being code - /// or data. The code analyzer will stop at data-hinted regions, and will - /// process any code-hinted regions during the dead-code pass. - /// - /// The hints are not used directly by the data analyzer, but the effects they + /// Analyzer tags are specified by the user. They identify an offset as being the + /// start or end of an executable code region, or part of an inline data block. + /// + /// The tags are not used directly by the data analyzer, but the effects they /// have on the Anattrib array are. /// /// - /// This invokes methods in extension scripts to handle things like inline data - /// following a JSR. The added cost is generally low, because the AppDomain security - /// sandbox doesn't add a lot of overhead. Unfortunately this approach is deprecated - /// by Microsoft and may break or become unavailable. If that happens, and we have to - /// switch to a sandbox approach with significant overhead, we will most likely want - /// to move the code analyzer itself into the sandbox. - /// - /// For this reason it's best to minimize direct interaction between the code here and - /// that elsewhere in the program. + /// THESE VALUES ARE SERIALIZED to the project data file. They cannot be renamed + /// without writing a translator in ProjectFile. /// - public enum TypeHint : sbyte { - // No hint. Default value populated in new arrays. - NoHint = 0, + public enum AnalyzerTag : sbyte { + // No tag. Default value populated in new arrays. + None = 0, // Byte is an instruction. If the code analyzer doesn't find this // naturally, it will be scanned. Code, - // Byte is inline data. Execution continues "through" the byte. + // Byte is inline data. Execution skips over the byte. InlineData, // Byte is data. Execution halts. @@ -147,9 +150,9 @@ namespace SourceGen { private Anattrib[] mAnattribs; /// - /// Reference to type hint array, one hint per byte. + /// Reference to analyzer tag array, one entry per byte. /// - private TypeHint[] mTypeHints; + private AnalyzerTag[] mAnalyzerTags; /// /// Reference to status flag override array, one entry per byte. @@ -180,7 +183,7 @@ namespace SourceGen { /// Anattrib array. Expected to be newly allocated, all /// entries set to default values. /// Map of offsets to addresses. - /// Type hints, one per byte. + /// Analyzer tags, one per byte. /// Status flag overrides for instruction-start /// bytes. /// Status flags to use at code entry points. @@ -188,14 +191,14 @@ namespace SourceGen { /// Analysis parameters. /// Object that receives debug log messages. public CodeAnalysis(byte[] data, CpuDef cpuDef, Anattrib[] anattribs, - AddressMap addrMap, TypeHint[] hints, StatusFlags[] statusFlagOverrides, + AddressMap addrMap, AnalyzerTag[] atags, StatusFlags[] statusFlagOverrides, StatusFlags entryFlags, ProjectProperties.AnalysisParameters parms, ScriptManager scriptMan, DebugLog debugLog) { mFileData = data; mCpuDef = cpuDef; mAnattribs = anattribs; mAddrMap = addrMap; - mTypeHints = hints; + mAnalyzerTags = atags; mStatusFlagOverrides = statusFlagOverrides; mEntryFlags = entryFlags; mScriptManager = scriptMan; @@ -263,19 +266,19 @@ namespace SourceGen { SetAddresses(); - // Set the "is data" and "is inline data" flags on anything that the user has - // flagged as being such. This tells us to stop processing or skip over bytes - // as we work. We don't need to flag code hints explicitly for analysis, but - // we want to be able to display the flags in the info window. + // Set values in the anattrib array based on the user-specified analyzer tags. + // This tells us to stop processing or skip over bytes as we work. We set values + // for the code start tags so we can show them in the "info" window. // // The data recognizers may spot additional inline data offsets as we work. This // can cause a race if it mis-identifies code that is also a branch target; // whichever marks the code first will win. - UnpackTypeHints(); + UnpackAnalyzerTags(); - // Find starting place, based on type hints. + // Find starting place, based on analyzer tags. + // // We only set the "visited" flag on the instruction start, so if the user - // puts a code hint in the middle of an instruction, we will find it and + // puts a code start in the middle of an instruction, we will find it and // treat it as an entry point. (This is useful for embedded instructions // that are branched to by code we aren't able to detect.) int searchStart = FindFirstUnvisitedInstruction(0); @@ -363,37 +366,36 @@ namespace SourceGen { } /// - /// Sets the "is xxxxx" flags on type-hinted entries, so that the code analyzer + /// Sets the "is xxxxx" flags on analyzer-tagged entries, so that the code analyzer /// can find them easily. /// - private void UnpackTypeHints() { - Debug.Assert(mTypeHints.Length == mAnattribs.Length); + private void UnpackAnalyzerTags() { + Debug.Assert(mAnalyzerTags.Length == mAnattribs.Length); int offset = 0; - foreach (TypeHint hint in mTypeHints) { - switch (hint) { - case TypeHint.Code: + foreach (AnalyzerTag atag in mAnalyzerTags) { + switch (atag) { + case AnalyzerTag.Code: // Set the IsInstruction flag to prevent inline data from being // placed here. OpDef op = mCpuDef.GetOpDef(mFileData[offset]); if (op == OpDef.OpInvalid) { - LogI(offset, "Ignoring code hint on illegal opcode"); + LogI(offset, "Ignoring code start tag on illegal opcode"); } else { - mAnattribs[offset].IsHinted = true; + mAnattribs[offset].HasAnalyzerTag = true; mAnattribs[offset].IsInstruction = true; } break; - case TypeHint.Data: - // Tells the code analyzer to stop. Does not define a data analyzer - // "uncategorized data" boundary. - mAnattribs[offset].IsHinted = true; + case AnalyzerTag.Data: + // Tells the code analyzer to stop. + mAnattribs[offset].HasAnalyzerTag = true; mAnattribs[offset].IsData = true; break; - case TypeHint.InlineData: + case AnalyzerTag.InlineData: // Tells the code analyzer to walk across these. - mAnattribs[offset].IsHinted = true; + mAnattribs[offset].HasAnalyzerTag = true; mAnattribs[offset].IsInlineData = true; break; - case TypeHint.NoHint: + case AnalyzerTag.None: break; default: Debug.Assert(false); @@ -404,21 +406,21 @@ namespace SourceGen { } /// - /// Finds the first offset that is hinted as code but hasn't yet been visited. - /// + /// Finds the first offset that is tagged as code start but hasn't yet been visited. + /// /// This might be in the middle of an already-visited instruction. /// /// Offset at which to start the search. /// Offset found. private int FindFirstUnvisitedInstruction(int start) { for (int i = start; i < mAnattribs.Length; i++) { - if (mAnattribs[i].IsHinted && mTypeHints[i] == TypeHint.Code && + if (mAnattribs[i].HasAnalyzerTag && mAnalyzerTags[i] == AnalyzerTag.Code && !mAnattribs[i].IsVisited) { - LogD(i, "Unvisited code hint"); + LogD(i, "Unvisited code start tag"); if (mAnattribs[i].IsData || mAnattribs[i].IsInlineData) { - // Maybe the user put a code hint on something that was + // Maybe the user put a code start tag on something that was // later recognized as inline data? Shouldn't have been allowed. - LogW(i, "Weird: code hint on data/inline"); + LogW(i, "Weird: code start tag on data/inline"); continue; } return i; @@ -498,7 +500,7 @@ namespace SourceGen { } else if (mAnattribs[offset].IsInlineData) { // Generally this won't happen, because we ignore branches into inline data // areas, we reject attempts to convert code to inline data, and we can't - // start in an inline area because the hint is wrong. However, it's possible + // start in an inline area because the tag is wrong. However, it's possible // for a JSR to a new section to be registered, and then before we get to // it an extension script formats the area as inline data. In that case // the inline data "wins", and we stop here. @@ -545,8 +547,8 @@ namespace SourceGen { // instruction, but bytes within the instruction are marked as data. The // easiest thing to do here is steamroll the data flags. // - // (To cause this, hint a 3-byte instruction as data/inline-data, then - // hint the first byte of the instruction as code.) + // (To cause this, tag a 3-byte instruction as code-stop/inline-data, then + // tag the first byte of the instruction as code.) mAnattribs[offset].IsInstructionStart = true; mAnattribs[offset].Length = instrLen; for (int i = offset; i < offset + instrLen; i++) { @@ -1113,12 +1115,12 @@ namespace SourceGen { } // Don't allow formatting of any bytes that are identified as instructions or - // were hinted by the user as something other than inline data. If the code + // were tagged by the user as something other than inline data. If the code // analyzer comes crashing through later they'll just stomp on what we've done. for (int i = offset; i < offset + length; i++) { - if (mTypeHints[i] != TypeHint.NoHint && mTypeHints[i] != TypeHint.InlineData) { - LogW(offset, "SIDF rej: already a hint at " + i.ToString("x6") + - " (" + mTypeHints[i] + ")"); + if (mAnalyzerTags[i] != AnalyzerTag.None && mAnalyzerTags[i] != AnalyzerTag.InlineData) { + LogW(offset, "SIDF rej: already an atag at " + i.ToString("x6") + + " (" + mAnalyzerTags[i] + ")"); return false; } if (mAnattribs[offset].IsInstruction) { diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index be481cb..ebafcca 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -60,9 +60,9 @@ namespace SourceGen { public AddressMap AddrMap { get; private set; } /// - /// Type hints. Default value is "no hint". + /// Analyzer tags. Default value is "none". /// - public CodeAnalysis.TypeHint[] TypeHints { get; private set; } + public CodeAnalysis.AnalyzerTag[] AnalyzerTags { get; private set; } /// /// Status flag overrides. Default value is "all unspecified". @@ -272,8 +272,8 @@ namespace SourceGen { AddrMap = new AddressMap(fileDataLen); AddrMap.Set(0, 0x1000); // default load address to $1000; override later - // Default value is "no hint". - TypeHints = new CodeAnalysis.TypeHint[fileDataLen]; + // Default value is "no tag". + AnalyzerTags = new CodeAnalysis.AnalyzerTag[fileDataLen]; // Default value is "unspecified" for all bits. StatusFlagOverrides = new StatusFlags[fileDataLen]; @@ -358,7 +358,7 @@ namespace SourceGen { // Mark the first byte as code so we have something to do. This may get // overridden later. - TypeHints[0] = CodeAnalysis.TypeHint.Code; + AnalyzerTags[0] = CodeAnalysis.AnalyzerTag.Code; } /// @@ -401,8 +401,8 @@ namespace SourceGen { AddrMap.Set(2, loadAddr); OperandFormats[0] = FormatDescriptor.Create(2, FormatDescriptor.Type.NumericLE, FormatDescriptor.SubType.None); - TypeHints[0] = CodeAnalysis.TypeHint.NoHint; - TypeHints[2] = CodeAnalysis.TypeHint.Code; + AnalyzerTags[0] = CodeAnalysis.AnalyzerTag.None; + AnalyzerTags[2] = CodeAnalysis.AnalyzerTag.Code; } else { int loadAddr = SystemDefaults.GetLoadAddress(sysDef); AddrMap.Set(0, loadAddr); @@ -832,7 +832,7 @@ namespace SourceGen { reanalysisTimer.StartTask("CodeAnalysis.Analyze"); CodeAnalysis ca = new CodeAnalysis(mFileData, CpuDef, mAnattribs, AddrMap, - TypeHints, StatusFlagOverrides, ProjectProps.EntryFlags, + AnalyzerTags, StatusFlagOverrides, ProjectProps.EntryFlags, ProjectProps.AnalysisParams, mScriptManager, debugLog); ca.Analyze(); @@ -987,10 +987,10 @@ namespace SourceGen { /// /// /// In an ideal world, this would be a trivial function. In practice it's possible for - /// all sorts of weird edge cases to arise, e.g. if you hint something as data, apply - /// formats, and then hint it as code, many strange things are possible. We don't want - /// to delete user data if it seems out of place, but we do want to ignore anything - /// that's going to confuse the source generator later on. + /// all sorts of weird edge cases to arise, e.g. if you put a code-stop flag, apply + /// formats, and then change it to code-start, many strange things are possible. We + /// don't want to delete user data if it seems out of place, but we do want to ignore + /// anything that's going to confuse the source generator later on. /// /// Problem reports are written to a log (which is shown by the Analyzer Output /// window) and the Problems list. Once the latter is better established we can @@ -1253,8 +1253,8 @@ namespace SourceGen { /// /// Removes user labels from the symbol table if they're in the middle of an - /// instruction or multi-byte data area. (Easy way to cause this: hint a 3-byte - /// instruction as data, add a label to the middle byte, remove hints.) + /// instruction or multi-byte data area. (Easy way to cause this: tag a 3-byte + /// instruction as data, add a label to the middle byte, remove atags.) /// /// Call this after the code and data analysis passes have completed. Any /// references to the hidden labels will just fall through. It will be possible @@ -1527,9 +1527,9 @@ namespace SourceGen { try { labelList.Add(attr.Symbol.Label, offset); } catch (ArgumentException ex) { - // Duplicate UserLabel entries are stripped when projects are loaded, - // but it might be possible to cause this by hiding/unhiding a - // label (e.g. using hints to place it in the middle of an instruction). + // Duplicate UserLabel entries are stripped when projects are loaded, but + // it might be possible to cause this by hiding/unhiding a label (e.g. + // using a code start tag to place it in the middle of an instruction). // Just ignore the duplicate. Debug.WriteLine("Xref ignoring duplicate label '" + attr.Symbol.Label + "': " + ex.Message); @@ -2166,9 +2166,9 @@ namespace SourceGen { UndoableChange.ReanalysisScope.CodeAndData); } break; - case UndoableChange.ChangeType.SetTypeHint: { + case UndoableChange.ChangeType.SetAnalyzerTag: { // Always requires full code+data re-analysis. - ApplyTypeHints((TypedRangeSet)oldValue, (TypedRangeSet)newValue); + ApplyAnalyzerTags((TypedRangeSet)oldValue, (TypedRangeSet)newValue); // ignore affectedOffsets Debug.Assert(uc.ReanalysisRequired == UndoableChange.ReanalysisScope.CodeAndData); @@ -2558,24 +2558,20 @@ namespace SourceGen { /// - /// Applies the values in the set to the project hints. + /// Applies the values in the set to the project's atags. /// /// Previous values; must match current contents. /// Values to apply. - private void ApplyTypeHints(TypedRangeSet oldSet, TypedRangeSet newSet) { - CodeAnalysis.TypeHint[] hints = TypeHints; + private void ApplyAnalyzerTags(TypedRangeSet oldSet, TypedRangeSet newSet) { + CodeAnalysis.AnalyzerTag[] atags = AnalyzerTags; foreach (TypedRangeSet.Tuple tuple in newSet) { - CodeAnalysis.TypeHint curType = hints[tuple.Value]; + CodeAnalysis.AnalyzerTag curType = atags[tuple.Value]; if (!oldSet.GetType(tuple.Value, out int oldType) || oldType != (int)curType) { Debug.WriteLine("Type mismatch at " + tuple.Value); Debug.Assert(false); } - //Debug.WriteLine("Set +" + tuple.Value.ToString("x6") + " to " + - // (CodeAnalysis.TypeHint)tuple.Type + " (was " + - // curType + ")"); - - hints[tuple.Value] = (CodeAnalysis.TypeHint)tuple.Type; + atags[tuple.Value] = (CodeAnalysis.AnalyzerTag)tuple.Type; } } diff --git a/SourceGen/LineListGen.cs b/SourceGen/LineListGen.cs index ac1ee0c..28a495b 100644 --- a/SourceGen/LineListGen.cs +++ b/SourceGen/LineListGen.cs @@ -222,7 +222,7 @@ namespace SourceGen { /// multiple offsets, this seems like reasonable behavior. /// /// We can't precisely restore the selection in terms of which file offsets - /// are selected. If you select one byte and apply a code hint, we'll restore + /// are selected. If you select one byte and apply an analyzer tag, we'll restore /// the selection to a line with 1-4 bytes. This gets weird if you hit "undo", /// as you will then have 1-4 bytes selected rather than the original one. It /// might be better to just clear the selection on "undo". @@ -291,7 +291,7 @@ namespace SourceGen { continue; } Line line = lineList[i]; - // Code hinting can transform code to data and vice-versa, so we + // Code start/stop tags can transform code to data and vice-versa, so we // want the tag to reflect the fact that both could exist. Line.Type lineType = line.LineType; if (lineType == Line.Type.Code || lineType == Line.Type.Data) { @@ -317,7 +317,7 @@ namespace SourceGen { // you do a sequence like: // - Open a file that starts with a JMP followed by data. // - Click on the blank line below the code, which has the code's offset, - // and select "remove hint". This causes the blank line to vanish, + // and select "remove atags". This causes the blank line to vanish, // so the Restore() won't select anything. // - Click "undo". Debug.WriteLine("NOTE: no selection found"); diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 5a43b58..218fdf3 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -2695,23 +2695,23 @@ namespace SourceGen { cs.Add(uc); } - // Apply code hints. - if (dlg.WantCodeHints) { + // Apply analyzer tags. + if (dlg.WantCodeStartPoints) { TypedRangeSet newSet = new TypedRangeSet(); TypedRangeSet undoSet = new TypedRangeSet(); foreach (int offset in dlg.AllTargetOffsets) { if (!mProject.GetAnattrib(offset).IsInstruction) { - CodeAnalysis.TypeHint oldType = mProject.TypeHints[offset]; - if (oldType == CodeAnalysis.TypeHint.Code) { + CodeAnalysis.AnalyzerTag oldType = mProject.AnalyzerTags[offset]; + if (oldType == CodeAnalysis.AnalyzerTag.Code) { continue; // already set } undoSet.Add(offset, (int)oldType); - newSet.Add(offset, (int)CodeAnalysis.TypeHint.Code); + newSet.Add(offset, (int)CodeAnalysis.AnalyzerTag.Code); } } if (newSet.Count != 0) { - cs.Add(UndoableChange.CreateTypeHintChange(undoSet, newSet)); + cs.Add(UndoableChange.CreateAnalyzerTagChange(undoSet, newSet)); } } @@ -2990,7 +2990,7 @@ namespace SourceGen { } else if (uc.Type == UndoableChange.ChangeType.SetProjectProperties) { // some chance it modified the EQU statements... jump there offset = 0; - } else if (uc.Type == UndoableChange.ChangeType.SetTypeHint) { + } else if (uc.Type == UndoableChange.ChangeType.SetAnalyzerTag) { TypedRangeSet newSet = (TypedRangeSet)uc.NewValue; if (newSet.Count == 0) { // unexpected @@ -3141,14 +3141,14 @@ namespace SourceGen { public int mBlankLines; public int mControlLines; - public int mCodeHints; - public int mDataHints; - public int mInlineDataHints; - public int mNoHints; + public int mCodeStartTags; + public int mCodeStopTags; + public int mInlineDataTags; + public int mNoTags; }; /// - /// Gathers a count of different line types and hints that are currently selected. + /// Gathers a count of different line types and atags that are currently selected. /// /// If a single line is selected, pass the index in. /// Otherwise, pass -1 to traverse the entire line list. @@ -3156,9 +3156,9 @@ namespace SourceGen { private EntityCounts GatherEntityCounts(int singleLineIndex) { //DateTime startWhen = DateTime.Now; int codeLines, dataLines, blankLines, controlLines; - int codeHints, dataHints, inlineDataHints, noHints; + int codeStartTags, codeStopTags, inlineDataTags, noTags; codeLines = dataLines = blankLines = controlLines = 0; - codeHints = dataHints = inlineDataHints = noHints = 0; + codeStartTags = codeStopTags = inlineDataTags = noTags = 0; int startIndex, endIndex; if (singleLineIndex < 0) { @@ -3189,15 +3189,15 @@ namespace SourceGen { break; default: // These are only editable as single-line items. We do allow mass - // code hint selection to include them (they will be ignored). + // atag selection to include them (they will be ignored). // org, equ, rwid, long comment... controlLines++; break; } // A single line can span multiple offsets, each of which could have a - // different hint. Note the code/data hints are only applied to the first - // byte of each selected line, so we're not quite in sync with that. + // different analyzer tag. Note the code start/stop tags are only applied to the + // first byte of each selected line, so we're not quite in sync with that. // // For multi-line items, the OffsetSpan of the first item covers the entire // item (it's the same for all Line instances), so we only want to do this for @@ -3205,18 +3205,18 @@ namespace SourceGen { if (line.SubLineIndex == 0) { for (int offset = line.FileOffset; offset < line.FileOffset + line.OffsetSpan; offset++) { - switch (mProject.TypeHints[offset]) { - case CodeAnalysis.TypeHint.Code: - codeHints++; + switch (mProject.AnalyzerTags[offset]) { + case CodeAnalysis.AnalyzerTag.Code: + codeStartTags++; break; - case CodeAnalysis.TypeHint.Data: - dataHints++; + case CodeAnalysis.AnalyzerTag.Data: + codeStopTags++; break; - case CodeAnalysis.TypeHint.InlineData: - inlineDataHints++; + case CodeAnalysis.AnalyzerTag.InlineData: + inlineDataTags++; break; - case CodeAnalysis.TypeHint.NoHint: - noHints++; + case CodeAnalysis.AnalyzerTag.None: + noTags++; break; default: Debug.Assert(false); @@ -3235,10 +3235,10 @@ namespace SourceGen { mDataLines = dataLines, mBlankLines = blankLines, mControlLines = controlLines, - mCodeHints = codeHints, - mDataHints = dataHints, - mInlineDataHints = inlineDataHints, - mNoHints = noHints + mCodeStartTags = codeStartTags, + mCodeStopTags = codeStopTags, + mInlineDataTags = inlineDataTags, + mNoTags = noTags }; } @@ -3363,11 +3363,11 @@ namespace SourceGen { } /// - /// Handles the four Actions > edit hint commands. + /// Handles the four analyzer tag commands. /// - /// Type of hint to apply. - /// If set, only the first byte on each line is hinted. - public void MarkAsType(CodeAnalysis.TypeHint hint, bool firstByteOnly) { + /// Type of tag to apply. + /// If set, only the first byte on each line is tagged. + public void MarkAsType(CodeAnalysis.AnalyzerTag atag, bool firstByteOnly) { RangeSet sel; if (firstByteOnly) { @@ -3375,7 +3375,7 @@ namespace SourceGen { foreach (int index in mMainWin.CodeDisplayList.SelectedIndices) { int offset = CodeLineList[index].FileOffset; if (offset >= 0) { - // Not interested in the header stuff for hinting. + // Ignore the header lines. sel.Add(offset); } } @@ -3391,20 +3391,20 @@ namespace SourceGen { // header comment continue; } - CodeAnalysis.TypeHint oldType = mProject.TypeHints[offset]; - if (oldType == hint) { + CodeAnalysis.AnalyzerTag oldType = mProject.AnalyzerTags[offset]; + if (oldType == atag) { // no change, don't add to set continue; } undoSet.Add(offset, (int)oldType); - newSet.Add(offset, (int)hint); + newSet.Add(offset, (int)atag); } if (newSet.Count == 0) { - Debug.WriteLine("No changes found (" + hint + ", " + sel.Count + " offsets)"); + Debug.WriteLine("No changes found (" + atag + ", " + sel.Count + " offsets)"); return; } - UndoableChange uc = UndoableChange.CreateTypeHintChange(undoSet, newSet); + UndoableChange uc = UndoableChange.CreateAnalyzerTagChange(undoSet, newSet); ChangeSet cs = new ChangeSet(uc); ApplyUndoableChanges(cs); @@ -3534,7 +3534,7 @@ namespace SourceGen { /// We don't split based on existing data format items. That would make it impossible /// to convert from (say) a collection of single bytes to a collection of double bytes /// or a string. It should not be possible to select part of a formatted section, - /// unless the user has been playing weird games with type hints to get overlapping + /// unless the user has been playing weird games with analyzer tags to get overlapping /// format descriptors. /// /// The type values used in the TypedRangeSet may not be contiguous. They're only @@ -4070,17 +4070,17 @@ namespace SourceGen { //sb.Append("DEBUG: opAddr=" + attr.OperandAddress.ToString("x4") + // " opOff=" + attr.OperandOffset.ToString("x4") + "\r\n"); - if (attr.IsHinted) { + if (attr.HasAnalyzerTag) { sb.Append("\u2022 Analyzer Tags: "); for (int i = 0; i < line.OffsetSpan; i++) { - switch (mProject.TypeHints[line.FileOffset + i]) { - case CodeAnalysis.TypeHint.Code: + switch (mProject.AnalyzerTags[line.FileOffset + i]) { + case CodeAnalysis.AnalyzerTag.Code: sb.Append("S"); // S)tart break; - case CodeAnalysis.TypeHint.Data: + case CodeAnalysis.AnalyzerTag.Data: sb.Append("E"); // E)nd break; - case CodeAnalysis.TypeHint.InlineData: + case CodeAnalysis.AnalyzerTag.InlineData: sb.Append("I"); // I)nline break; default: @@ -4540,7 +4540,8 @@ namespace SourceGen { } // Make sure this is the start of an instruction or data item. (If you - // haven't finished hinting code, it's best to disable the string/fill finder.) + // haven't finished tagging code start points, it's best to disable the + // string/fill finder.) Anattrib attr = mProject.GetAnattrib(offset); if (!attr.IsStart) { Debug.WriteLine("Found match at non-start +" + offset.ToString("x6") + diff --git a/SourceGen/ProjectFile.cs b/SourceGen/ProjectFile.cs index 243d9de..e507d1d 100644 --- a/SourceGen/ProjectFile.cs +++ b/SourceGen/ProjectFile.cs @@ -459,20 +459,20 @@ namespace SourceGen { spf.AddressMap.Add(new SerAddressMap(ent)); } - // Reduce TypeHints to a collection of ranges. Output the type enum as a string - // so we're not tied to a specific value. + // Reduce analyzer tags (formerly known as "type hints") to a collection of ranges. + // Output the type enum as a string so we're not tied to a specific numeric value. spf.TypeHints = new List(); TypedRangeSet trs = new TypedRangeSet(); - for (int i = 0; i < proj.TypeHints.Length; i++) { - trs.Add(i, (int)proj.TypeHints[i]); + for (int i = 0; i < proj.AnalyzerTags.Length; i++) { + trs.Add(i, (int)proj.AnalyzerTags[i]); } IEnumerator iter = trs.RangeListIterator; while (iter.MoveNext()) { - if (iter.Current.Type == (int)CodeAnalysis.TypeHint.NoHint) { + if (iter.Current.Type == (int)CodeAnalysis.AnalyzerTag.None) { continue; } spf.TypeHints.Add(new SerTypeHintRange(iter.Current.Low, iter.Current.High, - ((CodeAnalysis.TypeHint)iter.Current.Type).ToString())); + ((CodeAnalysis.AnalyzerTag)iter.Current.Type).ToString())); } // Convert StatusFlagOverrides to serializable form. Just write the state out @@ -672,26 +672,27 @@ namespace SourceGen { proj.AddrMap.Set(addr.Offset, addr.Addr); } - // Deserialize type hints. Default value in new array as NoHint, so we don't - // need to write those. They should not have been recorded in the file. + // Deserialize analyzer tags (formerly known as "type hints"). The default value + // for new array entries is None, so we don't need to write those. They should not + // have been recorded in the file. foreach (SerTypeHintRange range in spf.TypeHints) { if (range.Low < 0 || range.High >= spf.FileDataLength || range.Low > range.High) { report.Add(FileLoadItem.Type.Warning, Res.Strings.ERR_BAD_RANGE + - ": " + Res.Strings.PROJECT_FIELD_TYPE_HINT + + ": " + Res.Strings.PROJECT_FIELD_ANALYZER_TAG + " +" + range.Low.ToString("x6") + " - +" + range.High.ToString("x6")); continue; } - CodeAnalysis.TypeHint hint; + CodeAnalysis.AnalyzerTag hint; try { - hint = (CodeAnalysis.TypeHint) Enum.Parse( - typeof(CodeAnalysis.TypeHint), range.Hint); + hint = (CodeAnalysis.AnalyzerTag) Enum.Parse( + typeof(CodeAnalysis.AnalyzerTag), range.Hint); } catch (ArgumentException) { - report.Add(FileLoadItem.Type.Warning, Res.Strings.ERR_BAD_TYPE_HINT + + report.Add(FileLoadItem.Type.Warning, Res.Strings.ERR_BAD_ANALYZER_TAG + ": " + range.Hint); continue; } for (int i = range.Low; i <= range.High; i++) { - proj.TypeHints[i] = hint; + proj.AnalyzerTags[i] = hint; } } diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml index 6ea6a80..dab306a 100644 --- a/SourceGen/Res/Strings.xaml +++ b/SourceGen/Res/Strings.xaml @@ -56,7 +56,7 @@ limitations under the License. Malformed label in symbol Unknown Source or Type in symbol Bad symbol reference part - Analyzer tag not recognized + Analyzer tag not recognized Invalid visualization item: {0} Invalid visualization set at +{0:x6} Unable to create directory {0}: {1} @@ -162,7 +162,7 @@ limitations under the License. operand format reloc data status flag override - analyzer tag + analyzer tag user-defined label This project was created by a newer version of SourceGen. It may contain data that will be lost if the project is edited. diff --git a/SourceGen/Res/Strings.xaml.cs b/SourceGen/Res/Strings.xaml.cs index 3a354a4..d767707 100644 --- a/SourceGen/Res/Strings.xaml.cs +++ b/SourceGen/Res/Strings.xaml.cs @@ -93,8 +93,8 @@ namespace SourceGen.Res { (string)Application.Current.FindResource("str_ErrBadSymbolSt"); public static string ERR_BAD_SYMREF_PART = (string)Application.Current.FindResource("str_ErrBadSymrefPart"); - public static string ERR_BAD_TYPE_HINT = - (string)Application.Current.FindResource("str_ErrBadTypeHint"); + public static string ERR_BAD_ANALYZER_TAG = + (string)Application.Current.FindResource("str_ErrBadAnalyzerTag"); public static string ERR_BAD_VISUALIZATION_FMT = (string)Application.Current.FindResource("str_ErrBadVisualizationFmt"); public static string ERR_BAD_VISUALIZATION_SET_FMT = @@ -305,8 +305,8 @@ namespace SourceGen.Res { (string)Application.Current.FindResource("str_ProjectFieldRelocData"); public static string PROJECT_FIELD_STATUS_FLAGS = (string)Application.Current.FindResource("str_ProjectFieldStatusFlags"); - public static string PROJECT_FIELD_TYPE_HINT = - (string)Application.Current.FindResource("str_ProjectFieldTypeHint"); + public static string PROJECT_FIELD_ANALYZER_TAG = + (string)Application.Current.FindResource("str_ProjectFieldAnalyzerTag"); public static string PROJECT_FIELD_USER_LABEL = (string)Application.Current.FindResource("str_ProjectFieldUserLabel"); public static string PROJECT_FROM_NEWER_APP = diff --git a/SourceGen/Tools/Omf/Loader.cs b/SourceGen/Tools/Omf/Loader.cs index 4014878..423577c 100644 --- a/SourceGen/Tools/Omf/Loader.cs +++ b/SourceGen/Tools/Omf/Loader.cs @@ -404,7 +404,7 @@ namespace SourceGen.Tools.Omf { uc = UndoableChange.CreateProjectPropertiesChange(proj.ProjectProps, newProps); cs.Add(uc); - // TODO(someday): by default we apply a code hint to offset 0 of the first + // TODO(someday): by default we apply a code start tag to offset 0 of the first // segment. The placement should take the segment's ENTRY into account. Debug.WriteLine("Applying " + cs.Count + " changes"); @@ -586,12 +586,12 @@ namespace SourceGen.Tools.Omf { // It seems to be fairly common for jump table entries to not be referenced // from the program, which can leave whole dynamic segments unreferenced. Set - // a code hint on the JML instruction. - undoSet.Add(jmlOffset, (int)CodeAnalysis.TypeHint.NoHint); - newSet.Add(jmlOffset, (int)CodeAnalysis.TypeHint.Code); + // a code start tag on the JML instruction. + undoSet.Add(jmlOffset, (int)CodeAnalysis.AnalyzerTag.None); + newSet.Add(jmlOffset, (int)CodeAnalysis.AnalyzerTag.Code); } - UndoableChange uc = UndoableChange.CreateTypeHintChange(undoSet, newSet); + UndoableChange uc = UndoableChange.CreateAnalyzerTagChange(undoSet, newSet); cs.Add(uc); return true; diff --git a/SourceGen/UndoableChange.cs b/SourceGen/UndoableChange.cs index d5f16f4..7498350 100644 --- a/SourceGen/UndoableChange.cs +++ b/SourceGen/UndoableChange.cs @@ -23,8 +23,8 @@ using CommonUtil; *** When is a full (code+data) re-analysis required? - Adding/removing/changing an address change (ORG directive). This has a significant impact on the code analyzer, as blocks of code may become reachable or unreachable. -- Adding/removing/changing a type hint. These can affect whether a given offset is treated -as code, which can have a dramatic effect on code analysis (consider the offset 0 code hint). +- Adding/removing/changing an analyzer tag. These can affect whether a given offset is treated +as executable code, which can have a dramatic effect on code analysis. - Adding/removing/changing a status flag override. This can affect whether a branch is always taken or never taken, and the M/X flags affect instruction interpretation. (It may be possible to do an "incremental" code analysis here, working from the point of the change @@ -83,8 +83,8 @@ namespace SourceGen { // Adds, updates, or removes a data bank register value. SetDataBank, - // Changes the type hint. - SetTypeHint, + // Changes the analyzer tag. + SetAnalyzerTag, // Adds, updates, or removes a processor status flag override. SetStatusFlagOverride, @@ -133,8 +133,8 @@ namespace SourceGen { public ChangeType Type { get; private set; } /// - /// The "root offset". For example, changing the type hint for a 4-byte - /// instruction from code to data will actually affect 4 offsets, but we + /// The "root offset". For example, changing the analyzer tag for a 4-byte + /// instruction from "start" to "stop" will actually affect 4 offsets, but we /// only need to specify the root item. /// public int Offset { get; private set; } @@ -162,7 +162,7 @@ namespace SourceGen { get { switch (Type) { case ChangeType.Dummy: - case ChangeType.SetTypeHint: + case ChangeType.SetAnalyzerTag: case ChangeType.SetProjectProperties: return false; default: @@ -231,27 +231,27 @@ namespace SourceGen { } /// - /// Creates an UndoableChange for a type hint update. Rather than adding a + /// Creates an UndoableChange for an analyzer tag update. Rather than adding a /// separate UndoableChange for each affected offset -- which could span the /// entire file -- we use range sets to record the before/after state. /// /// Current values. /// New values. /// Change record. - public static UndoableChange CreateTypeHintChange(TypedRangeSet undoSet, + public static UndoableChange CreateAnalyzerTagChange(TypedRangeSet undoSet, TypedRangeSet newSet) { Debug.Assert(undoSet != null && newSet != null); if (newSet.Count == 0) { - Debug.WriteLine("Empty hint change?"); + Debug.WriteLine("Empty atag change?"); } UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetTypeHint; + uc.Type = ChangeType.SetAnalyzerTag; uc.Offset = -1; uc.OldValue = undoSet; uc.NewValue = newSet; - // Any hint change can affect whether something is treated as code. + // Any analyzer tag change can affect whether something is treated as code. // Either we're deliberately setting it as code or non-code, or we're - // setting it to "no hint", which means the code analyzer gets + // setting it to "none", which means the code analyzer gets // to make the decision now. This requires a full code+data re-analysis. uc.ReanalysisRequired = ReanalysisScope.CodeAndData; return uc; diff --git a/SourceGen/WpfGui/EditInstructionOperand.xaml.cs b/SourceGen/WpfGui/EditInstructionOperand.xaml.cs index cbdbd19..ce4d590 100644 --- a/SourceGen/WpfGui/EditInstructionOperand.xaml.cs +++ b/SourceGen/WpfGui/EditInstructionOperand.xaml.cs @@ -619,7 +619,7 @@ namespace SourceGen.WpfGui { } // NOTE: it's entirely possible to have a weird format (e.g. string) if the - // instruction used to be hinted as data. Handle it gracefully. + // instruction used to be tagged as code-stop. Handle it gracefully. switch (dfd.FormatType) { case FormatDescriptor.Type.NumericLE: switch (dfd.FormatSubType) { diff --git a/SourceGen/WpfGui/FormatAddressTable.xaml b/SourceGen/WpfGui/FormatAddressTable.xaml index 212ebe6..16b0c32 100644 --- a/SourceGen/WpfGui/FormatAddressTable.xaml +++ b/SourceGen/WpfGui/FormatAddressTable.xaml @@ -116,7 +116,7 @@ limitations under the License. + IsChecked="{Binding WantCodeStartPoints}"/> diff --git a/SourceGen/WpfGui/FormatAddressTable.xaml.cs b/SourceGen/WpfGui/FormatAddressTable.xaml.cs index 0e5ee3b..da0cfa2 100644 --- a/SourceGen/WpfGui/FormatAddressTable.xaml.cs +++ b/SourceGen/WpfGui/FormatAddressTable.xaml.cs @@ -64,16 +64,16 @@ namespace SourceGen.WpfGui { private bool mIsSplitTable; /// - /// If set, caller will add code entry hints to targets. + /// If set, caller will add code start points to targets. /// - public bool WantCodeHints { - get { return mWantCodeHints; } + public bool WantCodeStartPoints { + get { return mWantCodeStartPoints; } set { - mWantCodeHints = value; + mWantCodeStartPoints = value; OnPropertyChanged(); } } - private bool mWantCodeHints; + private bool mWantCodeStartPoints; /// /// Set to true to make the "incompatible with selection" message visible. diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml index 00f63c6..76b5fac 100644 --- a/SourceGen/WpfGui/MainWindow.xaml +++ b/SourceGen/WpfGui/MainWindow.xaml @@ -340,7 +340,7 @@ limitations under the License. - + diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs index a1bfc56..e0a1c93 100644 --- a/SourceGen/WpfGui/MainWindow.xaml.cs +++ b/SourceGen/WpfGui/MainWindow.xaml.cs @@ -1088,7 +1088,7 @@ namespace SourceGen.WpfGui { } MainController.EntityCounts counts = mMainCtrl.SelectionAnalysis.mEntityCounts; e.CanExecute = (counts.mDataLines > 0 || counts.mCodeLines > 0) && - (counts.mDataHints != 0 || counts.mInlineDataHints != 0 || counts.mNoHints != 0); + (counts.mCodeStopTags != 0 || counts.mInlineDataTags != 0 || counts.mNoTags != 0); } private void CanTagAsCodeStopPoint(object sender, CanExecuteRoutedEventArgs e) { if (!IsProjectOpen()) { @@ -1097,7 +1097,7 @@ namespace SourceGen.WpfGui { } MainController.EntityCounts counts = mMainCtrl.SelectionAnalysis.mEntityCounts; e.CanExecute = (counts.mDataLines > 0 || counts.mCodeLines > 0) && - (counts.mCodeHints != 0 || counts.mInlineDataHints != 0 || counts.mNoHints != 0); + (counts.mCodeStartTags != 0 || counts.mInlineDataTags != 0 || counts.mNoTags != 0); } private void CanTagAsInlineData(object sender, CanExecuteRoutedEventArgs e) { if (!IsProjectOpen()) { @@ -1106,7 +1106,7 @@ namespace SourceGen.WpfGui { } MainController.EntityCounts counts = mMainCtrl.SelectionAnalysis.mEntityCounts; e.CanExecute = (counts.mDataLines > 0 || counts.mCodeLines > 0) && - (counts.mCodeHints != 0 || counts.mDataHints != 0 || counts.mNoHints != 0); + (counts.mCodeStartTags != 0 || counts.mCodeStopTags != 0 || counts.mNoTags != 0); } private void CanRemoveAnalyzerTags(object sender, CanExecuteRoutedEventArgs e) { if (!IsProjectOpen()) { @@ -1115,7 +1115,7 @@ namespace SourceGen.WpfGui { } MainController.EntityCounts counts = mMainCtrl.SelectionAnalysis.mEntityCounts; e.CanExecute = (counts.mDataLines > 0 || counts.mCodeLines > 0) && - (counts.mCodeHints != 0 || counts.mDataHints != 0 || counts.mInlineDataHints != 0); + (counts.mCodeStartTags != 0 || counts.mCodeStopTags != 0 || counts.mInlineDataTags != 0); } private void CanJumpToOperand(object sender, CanExecuteRoutedEventArgs e) { @@ -1285,17 +1285,17 @@ namespace SourceGen.WpfGui { private void TagAsCodeStartPointCmd_Executed(object sender, ExecutedRoutedEventArgs e) { Debug.WriteLine("tag as code start point"); - mMainCtrl.MarkAsType(CodeAnalysis.TypeHint.Code, true); + mMainCtrl.MarkAsType(CodeAnalysis.AnalyzerTag.Code, true); } private void TagAsCodeStopPointCmd_Executed(object sender, ExecutedRoutedEventArgs e) { Debug.WriteLine("tag as code stop point"); - mMainCtrl.MarkAsType(CodeAnalysis.TypeHint.Data, true); + mMainCtrl.MarkAsType(CodeAnalysis.AnalyzerTag.Data, true); } private void TagAsInlineDataCmd_Executed(object sender, ExecutedRoutedEventArgs e) { Debug.WriteLine("tag as inline data"); - mMainCtrl.MarkAsType(CodeAnalysis.TypeHint.InlineData, false); + mMainCtrl.MarkAsType(CodeAnalysis.AnalyzerTag.InlineData, false); } private void JumpToOperandCmd_Executed(object sender, ExecutedRoutedEventArgs e) { @@ -1345,7 +1345,7 @@ namespace SourceGen.WpfGui { private void RemoveAnalyzerTagsCmd_Executed(object sender, ExecutedRoutedEventArgs e) { Debug.WriteLine("remove atags"); - mMainCtrl.MarkAsType(CodeAnalysis.TypeHint.NoHint, false); + mMainCtrl.MarkAsType(CodeAnalysis.AnalyzerTag.None, false); } private void SaveCmd_Executed(object sender, ExecutedRoutedEventArgs e) {