diff --git a/SourceGen/DataAnalysis.cs b/SourceGen/DataAnalysis.cs index 4049394..7853a80 100644 --- a/SourceGen/DataAnalysis.cs +++ b/SourceGen/DataAnalysis.cs @@ -163,10 +163,11 @@ namespace SourceGen { } // Check for a relocation. It'll be at offset+1 because it's on the operand, - // not the opcode byte. - if (mAnalysisParams.UseRelocData && mProject.RelocList.TryGetValue(offset + 1, - out DisasmProject.RelocData reloc)) { - if (reloc.Value != attr.OperandAddress) { + // not the opcode byte. (Make sure to check the length, or an RTS followed + // by relocated data will freak out.) + if (mAnalysisParams.UseRelocData) { + if (attr.Length > 1 && mProject.RelocList.TryGetValue(offset + 1, + out DisasmProject.RelocData reloc)) { // The relocation address differs from what the analyzer came up // with. This may be because of incorrect assumptions about the // bank (assuming B==K) or because the partial address refers to @@ -174,28 +175,33 @@ namespace SourceGen { // address is different, attr.OperandOffset will also be different. int relOperandOffset = mProject.AddrMap.AddressToOffset(offset, reloc.Value); - if (relOperandOffset >= 0 && relOperandOffset != attr.OperandOffset) { + if (relOperandOffset >= 0) { // Determined a different offset. Use that instead. //Debug.WriteLine("REL +" + offset.ToString("x6") + " " + // reloc.Value.ToString("x6") + " vs. " + // attr.OperandAddress.ToString("x6")); - WeakSymbolRef.Part part = WeakSymbolRef.Part.Low; - if (reloc.Shift == -8) { - part = WeakSymbolRef.Part.High; - } else if (reloc.Shift == -16) { - part = WeakSymbolRef.Part.Bank; - } + WeakSymbolRef.Part part = ShiftToPart(reloc.Shift); SetDataTarget(offset, attr.Length, relOperandOffset, part); continue; } } + + // No reloc for this instruction. If it's a relative branch we need + // to do the usual stuff, but if it's a PEA we want to treat it like + // an immediate value. The safest thing to do is blacklist PEA and + // let everything else proceed like it does without reloc data enabled. + OpDef op = mProject.CpuDef.GetOpDef(mProject.FileData[offset]); + if (op == OpDef.OpPEA_StackAbs) { + //Debug.WriteLine("NoPEA +" + offset.ToString("x6")); + continue; + } } int operandOffset = attr.OperandOffset; if (operandOffset >= 0) { - // This is an offset reference: a branch or data access instruction whose - // target is inside the file. Create a FormatDescriptor for it, and - // generate a label at the target if one is not already present. + // This is an offset reference: a branch or data access instruction + // whose target is inside the file. Create a FormatDescriptor for it, + // and generate a label at the target if one is not already present. SetDataTarget(offset, attr.Length, operandOffset, WeakSymbolRef.Part.Low); } @@ -237,10 +243,43 @@ namespace SourceGen { // There shouldn't be any data items inside other data items, so we // can just skip forward. offset += mAnattribs[offset].DataDescriptor.Length - 1; + } else if (mAnalysisParams.UseRelocData && + !attr.IsInstruction && !attr.IsData && !attr.IsInlineData && + mProject.RelocList.TryGetValue(offset, + out DisasmProject.RelocData reloc)) { + // Byte is unformatted, but there's relocation data here. If the full + // range of bytes is unformatted, create a symbolic reference. + bool allClear = true; + for (int i = 1; i < reloc.Width; i++) { + if (mAnattribs[offset + i].DataDescriptor != null) { + allClear = false; + break; + } + } + if (allClear) { + int operandOffset = mProject.AddrMap.AddressToOffset(offset, reloc.Value); + if (operandOffset >= 0) { + //Debug.WriteLine("DREL +" + offset.ToString("x6") + " val=" + + // reloc.Value.ToString("x6") + + // " opOff=" + operandOffset.ToString("x6")); + SetDataTarget(offset, reloc.Width, operandOffset, + ShiftToPart(reloc.Shift)); + } + } } } } + private static WeakSymbolRef.Part ShiftToPart(int shift) { + if (shift == -16) { + return WeakSymbolRef.Part.Bank; + } else if (shift == -8) { + return WeakSymbolRef.Part.High; + } else { + return WeakSymbolRef.Part.Low; + } + } + /// /// Extracts the operand offset from a data item. Only useful for numeric/Address /// and numeric/Symbol. diff --git a/SourceGen/ProjectProperties.cs b/SourceGen/ProjectProperties.cs index 9bc4737..d188621 100644 --- a/SourceGen/ProjectProperties.cs +++ b/SourceGen/ProjectProperties.cs @@ -61,7 +61,7 @@ namespace SourceGen { DefaultTextScanMode = TextScanMode.LowHighAscii; MinCharsForString = DataAnalysis.DEFAULT_MIN_STRING_LENGTH; SeekNearbyTargets = true; - UseRelocData = true; + UseRelocData = false; SmartPlpHandling = true; } public AnalysisParameters(AnalysisParameters src) { diff --git a/SourceGen/Res/Strings.xaml b/SourceGen/Res/Strings.xaml index fd4b84c..ff3a8b8 100644 --- a/SourceGen/Res/Strings.xaml +++ b/SourceGen/Res/Strings.xaml @@ -131,7 +131,7 @@ limitations under the License. no files available No exported symbols found. Segment {0:D2}: Kind={1}, Attrs={2}, Name='{3}' - Segment {0:D2}: {3} {1,-9} Name='{2}' + Segment {0:D2}: {3} {1,-9} Name='{2}', Length={4} Seg{0:D2}: {1} '{2}' The file doesn't exist. File is empty diff --git a/SourceGen/Tools/Omf/Loader.cs b/SourceGen/Tools/Omf/Loader.cs index 5ba5814..b1b01a7 100644 --- a/SourceGen/Tools/Omf/Loader.cs +++ b/SourceGen/Tools/Omf/Loader.cs @@ -299,6 +299,7 @@ namespace SourceGen.Tools.Omf { ChangeSet cs = new ChangeSet(mSegmentMap.Count * 2); AddHeaderComment(proj, cs); + UndoableChange uc; // Load the segments, and add entries to the project. int bufOffset = 0; @@ -327,7 +328,7 @@ namespace SourceGen.Tools.Omf { // Add a comment identifying the segment and its attributes. string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT, ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.Attrs, ent.Segment.SegName); - UndoableChange uc = UndoableChange.CreateLongCommentChange(bufOffset, null, + uc = UndoableChange.CreateLongCommentChange(bufOffset, null, new MultiLineComment(segCmt)); cs.Add(uc); @@ -343,11 +344,19 @@ namespace SourceGen.Tools.Omf { } proj.PrepForNew(data, "new_proj"); - proj.ApplyChanges(cs, false, out _); foreach (KeyValuePair kvp in mRelocData) { proj.RelocList.Add(kvp.Key, kvp.Value); } + // Enable "use reloc" in the analysis parameters. + ProjectProperties newProps = new ProjectProperties(proj.ProjectProps); + newProps.AnalysisParams.UseRelocData = true; + uc = UndoableChange.CreateProjectPropertiesChange(proj.ProjectProps, newProps); + cs.Add(uc); + + Debug.WriteLine("Applying " + cs.Count + " changes"); + proj.ApplyChanges(cs, false, out _); + mLoadedData = data; mNewProject = proj; return true; @@ -365,7 +374,7 @@ namespace SourceGen.Tools.Omf { } string segCmt = string.Format(Res.Strings.OMF_SEG_HDR_COMMENT_FMT, ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.SegName, - mFormatter.FormatAddress(ent.Address, true)); + mFormatter.FormatAddress(ent.Address, true), ent.Segment.Length); sb.AppendLine(segCmt); }