mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-01 07:50:37 +00:00
Add code hints to OMF jump tables
We now put a code hint on the JML instruction in each jump table entry. This is necessary to ensure that the target address is recognized as code, since a dynamic segment won't otherwise be referenced. Also, fiddle with the note/comment formatting some more.
This commit is contained in:
parent
4d06bb24eb
commit
190f68d1f8
@ -130,8 +130,9 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_MsgVisualizationIgnored">Visualization ignored</system:String>
|
<system:String x:Key="str_MsgVisualizationIgnored">Visualization ignored</system:String>
|
||||||
<system:String x:Key="str_NoFilesAvailable">no files available</system:String>
|
<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_NoExportedSymbolsFound">No exported symbols found.</system:String>
|
||||||
<system:String x:Key="str_OmfSegCommentFmt">Segment {0:D2}: {3} Kind={1}, SegName='{2}'</system:String>
|
<system:String x:Key="str_OmfSegCommentFmt">Segment {0:D2}: Kind={1}, Attrs={2}, Name='{3}'</system:String>
|
||||||
<system:String x:Key="str_OmfSegNoteFmt">Segment {0:D2}: {1} '{2}'</system:String>
|
<system:String x:Key="str_OmfSegHdrCommentFmt">Segment {0:D2}: {3} {1,-9} Name='{2}'</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_OpenDataDoesntExist">The file doesn't exist.</system:String>
|
||||||
<system:String x:Key="str_OpenDataEmpty">File is empty</system:String>
|
<system:String x:Key="str_OpenDataEmpty">File is empty</system:String>
|
||||||
<system:String x:Key="str_OpenDataFailCaption">Unable to load data file</system:String>
|
<system:String x:Key="str_OpenDataFailCaption">Unable to load data file</system:String>
|
||||||
|
@ -243,6 +243,8 @@ namespace SourceGen.Res {
|
|||||||
(string)Application.Current.FindResource("str_NoExportedSymbolsFound");
|
(string)Application.Current.FindResource("str_NoExportedSymbolsFound");
|
||||||
public static string OMF_SEG_COMMENT_FMT =
|
public static string OMF_SEG_COMMENT_FMT =
|
||||||
(string)Application.Current.FindResource("str_OmfSegCommentFmt");
|
(string)Application.Current.FindResource("str_OmfSegCommentFmt");
|
||||||
|
public static string OMF_SEG_HDR_COMMENT_FMT =
|
||||||
|
(string)Application.Current.FindResource("str_OmfSegHdrCommentFmt");
|
||||||
public static string OMF_SEG_NOTE_FMT =
|
public static string OMF_SEG_NOTE_FMT =
|
||||||
(string)Application.Current.FindResource("str_OmfSegNoteFmt");
|
(string)Application.Current.FindResource("str_OmfSegNoteFmt");
|
||||||
public static string OPEN_DATA_DOESNT_EXIST =
|
public static string OPEN_DATA_DOESNT_EXIST =
|
||||||
|
@ -304,7 +304,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ent.Segment.Kind == OmfSegment.SegmentKind.JumpTable) {
|
if (ent.Segment.Kind == OmfSegment.SegmentKind.JumpTable) {
|
||||||
if (!RelocJumpTable(ent, data, bufOffset)) {
|
if (!RelocJumpTable(ent, data, bufOffset, cs)) {
|
||||||
// Could treat this as non-fatal, but it really ought to work.
|
// Could treat this as non-fatal, but it really ought to work.
|
||||||
Debug.WriteLine("Jump Table reloc failed");
|
Debug.WriteLine("Jump Table reloc failed");
|
||||||
return false;
|
return false;
|
||||||
@ -320,13 +320,21 @@ namespace SourceGen.Tools.Omf {
|
|||||||
// can straddle multiple pages.)
|
// can straddle multiple pages.)
|
||||||
AddAddressEntries(proj, ent, bufOffset, cs);
|
AddAddressEntries(proj, ent, bufOffset, cs);
|
||||||
|
|
||||||
// Add a note identifying the segment.
|
// Add a comment identifying the segment and its attributes.
|
||||||
string segCmt = string.Format(Res.Strings.OMF_SEG_NOTE_FMT,
|
string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT,
|
||||||
ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.SegName);
|
ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.Attrs, ent.Segment.SegName);
|
||||||
UndoableChange uc = UndoableChange.CreateNoteChange(bufOffset, null,
|
UndoableChange uc = UndoableChange.CreateLongCommentChange(bufOffset, null,
|
||||||
new MultiLineComment(segCmt));
|
new MultiLineComment(segCmt));
|
||||||
cs.Add(uc);
|
cs.Add(uc);
|
||||||
|
|
||||||
|
// Add a note identifying the segment.
|
||||||
|
string segNote = string.Format(Res.Strings.OMF_SEG_NOTE_FMT,
|
||||||
|
ent.Segment.SegNum, mFormatter.FormatAddress(ent.Address, true),
|
||||||
|
ent.Segment.SegName);
|
||||||
|
uc = UndoableChange.CreateNoteChange(bufOffset, null,
|
||||||
|
new MultiLineComment(segNote));
|
||||||
|
cs.Add(uc);
|
||||||
|
|
||||||
bufOffset += ent.Segment.Length;
|
bufOffset += ent.Segment.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +356,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
if (ent == null) {
|
if (ent == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT,
|
string segCmt = string.Format(Res.Strings.OMF_SEG_HDR_COMMENT_FMT,
|
||||||
ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.SegName,
|
ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.SegName,
|
||||||
mFormatter.FormatAddress(ent.Address, true));
|
mFormatter.FormatAddress(ent.Address, true));
|
||||||
sb.AppendLine(segCmt);
|
sb.AppendLine(segCmt);
|
||||||
@ -431,7 +439,8 @@ namespace SourceGen.Tools.Omf {
|
|||||||
/// Edits the data file, essentially putting the jump table entries into the
|
/// Edits the data file, essentially putting the jump table entries into the
|
||||||
/// "loaded" state.
|
/// "loaded" state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool RelocJumpTable(SegmentMapEntry ent, byte[] data, int bufOffset) {
|
private bool RelocJumpTable(SegmentMapEntry ent, byte[] data, int bufOffset,
|
||||||
|
ChangeSet cs) {
|
||||||
const int ENTRY_LEN = 14;
|
const int ENTRY_LEN = 14;
|
||||||
|
|
||||||
byte[] srcData = ent.Segment.GetConstData();
|
byte[] srcData = ent.Segment.GetConstData();
|
||||||
@ -445,6 +454,9 @@ namespace SourceGen.Tools.Omf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypedRangeSet newSet = new TypedRangeSet();
|
||||||
|
TypedRangeSet undoSet = new TypedRangeSet();
|
||||||
|
|
||||||
for (int i = 8; i + 4 <= ent.Segment.Length; i += ENTRY_LEN) {
|
for (int i = 8; i + 4 <= ent.Segment.Length; i += ENTRY_LEN) {
|
||||||
int userId = RawData.GetWord(data, bufOffset + i, 2, false);
|
int userId = RawData.GetWord(data, bufOffset + i, 2, false);
|
||||||
int fileNum = RawData.GetWord(data, bufOffset + i + 2, 2, false);
|
int fileNum = RawData.GetWord(data, bufOffset + i + 2, 2, false);
|
||||||
@ -473,21 +485,31 @@ namespace SourceGen.Tools.Omf {
|
|||||||
if (segNum < 0 || segNum >= mSegmentMap.Count || mSegmentMap[segNum] == null) {
|
if (segNum < 0 || segNum >= mSegmentMap.Count || mSegmentMap[segNum] == null) {
|
||||||
Debug.WriteLine("JumpTab: invalid SegNum=" + segNum);
|
Debug.WriteLine("JumpTab: invalid SegNum=" + segNum);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
if (data[bufOffset + i + 10] != 0x22) {
|
|
||||||
Debug.WriteLine("JumpTab: did not find expected JSL at off=" + i);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int addr = mSegmentMap[segNum].Address + segOff;
|
|
||||||
data[bufOffset + i + 10] = 0x5c; // JML
|
|
||||||
data[bufOffset + i + 11] = (byte)addr;
|
|
||||||
data[bufOffset + i + 12] = (byte)(addr >> 8);
|
|
||||||
data[bufOffset + i + 13] = (byte)(addr >> 16);
|
|
||||||
//Debug.WriteLine("JumpTab: off=" + i + " -> " +
|
|
||||||
// mFormatter.FormatAddress(addr, true));
|
|
||||||
}
|
}
|
||||||
|
if (data[bufOffset + i + 10] != 0x22) {
|
||||||
|
Debug.WriteLine("JumpTab: did not find expected JSL at off=" + i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addr = mSegmentMap[segNum].Address + segOff;
|
||||||
|
int jmlOffset = bufOffset + i + 10;
|
||||||
|
data[jmlOffset] = 0x5c; // JML
|
||||||
|
data[jmlOffset + 1] = (byte)addr;
|
||||||
|
data[jmlOffset + 2] = (byte)(addr >> 8);
|
||||||
|
data[jmlOffset + 3] = (byte)(addr >> 16);
|
||||||
|
//Debug.WriteLine("JumpTab: off=" + i + " -> " +
|
||||||
|
// mFormatter.FormatAddress(addr, true));
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UndoableChange uc = UndoableChange.CreateTypeHintChange(undoSet, newSet);
|
||||||
|
cs.Add(uc);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user