mirror of
https://github.com/fadden/6502bench.git
synced 2025-02-08 20:30:47 +00:00
Apply relocation data to unformatted data
Works well for things like jump tables. Seeing a bunch of these scattered in a chunk of data is a decent signal that it's actually code. In a bold move, we now exclude PEA operands from auto-label gen when they don't have relocation data. This is very useful for things like Int2Hex for which constants are typically pushed with PEA. Reworked the "use reloc data" setting so it defaults to false and is explicitly set to true when converting OMF. This provides a minor optimization since we now check the boolean and skip doing a lookup in an empty table.
This commit is contained in:
parent
a6700e9062
commit
0fa77cba75
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the operand offset from a data item. Only useful for numeric/Address
|
||||
/// and numeric/Symbol.
|
||||
|
@ -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) {
|
||||
|
@ -131,7 +131,7 @@ limitations under the License.
|
||||
<system:String x:Key="str_NoFilesAvailable">no files available</system:String>
|
||||
<system:String x:Key="str_NoExportedSymbolsFound">No exported symbols found.</system:String>
|
||||
<system:String x:Key="str_OmfSegCommentFmt">Segment {0:D2}: Kind={1}, Attrs={2}, Name='{3}'</system:String>
|
||||
<system:String x:Key="str_OmfSegHdrCommentFmt">Segment {0:D2}: {3} {1,-9} Name='{2}'</system:String>
|
||||
<system:String x:Key="str_OmfSegHdrCommentFmt">Segment {0:D2}: {3} {1,-9} Name='{2}', Length={4}</system:String>
|
||||
<system:String x:Key="str_OmfSegNoteFmt">Seg{0:D2}: {1} '{2}'</system:String>
|
||||
<system:String x:Key="str_OpenDataDoesntExist">The file doesn't exist.</system:String>
|
||||
<system:String x:Key="str_OpenDataEmpty">File is empty</system:String>
|
||||
|
@ -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<int, DisasmProject.RelocData> 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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user