mirror of
https://github.com/fadden/6502bench.git
synced 2025-02-13 06:31:06 +00:00
Store reduced OMF relocation data in project file
A "cooked" form of the relocation data is added to the project, for use during data analysis. Also, changed the data grids in the segment viewer to allow multi- select, so users can copy & paste the contents.
This commit is contained in:
parent
190f68d1f8
commit
327ad4fbbc
@ -119,6 +119,28 @@ namespace SourceGen {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ProjectProperties ProjectProps { get; private set; }
|
public ProjectProperties ProjectProps { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Cooked" form of relocation data (e.g. OmfReloc). This does not contain the file
|
||||||
|
/// offset, as that's expected to be used as the dictionary key.
|
||||||
|
///
|
||||||
|
/// Will be null unless the project was generated from a relocatable source.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class RelocData {
|
||||||
|
public byte Width; // width of area written by relocator
|
||||||
|
public byte Shift; // amount to shift the value
|
||||||
|
public int Value; // value used (unshifted, full width)
|
||||||
|
|
||||||
|
public RelocData() { } // for deserialization
|
||||||
|
|
||||||
|
public RelocData(byte width, byte shift, int value) {
|
||||||
|
Width = width;
|
||||||
|
Shift = shift;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Dictionary<int, RelocData> RelocList { get; set; }
|
||||||
|
|
||||||
#endregion // data to save & restore
|
#endregion // data to save & restore
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace SourceGen {
|
|||||||
// ignore stuff that's in one side but not the other. However, if we're opening a
|
// ignore stuff that's in one side but not the other. However, if we're opening a
|
||||||
// newer file in an older program, it's worth letting the user know that some stuff
|
// newer file in an older program, it's worth letting the user know that some stuff
|
||||||
// may get lost as soon as they save the file.
|
// may get lost as soon as they save the file.
|
||||||
public const int CONTENT_VERSION = 3;
|
public const int CONTENT_VERSION = 4;
|
||||||
|
|
||||||
private static readonly bool ADD_CRLF = true;
|
private static readonly bool ADD_CRLF = true;
|
||||||
|
|
||||||
@ -417,6 +417,7 @@ namespace SourceGen {
|
|||||||
public List<SerVisualization> Visualizations { get; set; }
|
public List<SerVisualization> Visualizations { get; set; }
|
||||||
public List<SerVisBitmapAnimation> VisualizationAnimations { get; set; }
|
public List<SerVisBitmapAnimation> VisualizationAnimations { get; set; }
|
||||||
public Dictionary<string, SerVisualizationSet> VisualizationSets { get; set; }
|
public Dictionary<string, SerVisualizationSet> VisualizationSets { get; set; }
|
||||||
|
public Dictionary<string, DisasmProject.RelocData> RelocList { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes a DisasmProject into an augmented JSON string.
|
/// Serializes a DisasmProject into an augmented JSON string.
|
||||||
@ -525,6 +526,15 @@ namespace SourceGen {
|
|||||||
|
|
||||||
spf.ProjectProps = new SerProjectProperties(proj.ProjectProps);
|
spf.ProjectProps = new SerProjectProperties(proj.ProjectProps);
|
||||||
|
|
||||||
|
if (proj.RelocList != null) {
|
||||||
|
// The objects can serialize directly, but the Dictionary key can't be an int.
|
||||||
|
spf.RelocList =
|
||||||
|
new Dictionary<string, DisasmProject.RelocData>(proj.RelocList.Count);
|
||||||
|
foreach (KeyValuePair<int, DisasmProject.RelocData> kvp in proj.RelocList) {
|
||||||
|
spf.RelocList.Add(kvp.Key.ToString(), kvp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JavaScriptSerializer ser = new JavaScriptSerializer();
|
JavaScriptSerializer ser = new JavaScriptSerializer();
|
||||||
string cereal = ser.Serialize(spf);
|
string cereal = ser.Serialize(spf);
|
||||||
sb.Append(cereal);
|
sb.Append(cereal);
|
||||||
@ -832,6 +842,19 @@ namespace SourceGen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deserialize relocation data. This was added in v1.7.
|
||||||
|
if (spf.RelocList != null) {
|
||||||
|
proj.RelocList = new Dictionary<int, DisasmProject.RelocData>();
|
||||||
|
foreach (KeyValuePair<string, DisasmProject.RelocData> kvp in spf.RelocList) {
|
||||||
|
if (!ParseValidateKey(kvp.Key, spf.FileDataLength,
|
||||||
|
Res.Strings.PROJECT_FIELD_RELOC_DATA, report, out int intKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
proj.RelocList.Add(intKey, kvp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_ProjectFieldLvTable">local variable table</system:String>
|
<system:String x:Key="str_ProjectFieldLvTable">local variable table</system:String>
|
||||||
<system:String x:Key="str_ProjectFieldNote">note</system:String>
|
<system:String x:Key="str_ProjectFieldNote">note</system:String>
|
||||||
<system:String x:Key="str_ProjectFieldOperandFormat">operand format</system:String>
|
<system:String x:Key="str_ProjectFieldOperandFormat">operand format</system:String>
|
||||||
|
<system:String x:Key="str_ProjectFieldRelocData">reloc data</system:String>
|
||||||
<system:String x:Key="str_ProjectFieldStatusFlags">status flag override</system:String>
|
<system:String x:Key="str_ProjectFieldStatusFlags">status flag override</system:String>
|
||||||
<system:String x:Key="str_ProjectFieldTypeHint">type hint</system:String>
|
<system:String x:Key="str_ProjectFieldTypeHint">type hint</system:String>
|
||||||
<system:String x:Key="str_ProjectFieldUserLabel">user-defined label</system:String>
|
<system:String x:Key="str_ProjectFieldUserLabel">user-defined label</system:String>
|
||||||
|
@ -291,6 +291,8 @@ namespace SourceGen.Res {
|
|||||||
(string)Application.Current.FindResource("str_ProjectFieldNote");
|
(string)Application.Current.FindResource("str_ProjectFieldNote");
|
||||||
public static string PROJECT_FIELD_OPERAND_FORMAT =
|
public static string PROJECT_FIELD_OPERAND_FORMAT =
|
||||||
(string)Application.Current.FindResource("str_ProjectFieldOperandFormat");
|
(string)Application.Current.FindResource("str_ProjectFieldOperandFormat");
|
||||||
|
public static string PROJECT_FIELD_RELOC_DATA =
|
||||||
|
(string)Application.Current.FindResource("str_ProjectFieldRelocData");
|
||||||
public static string PROJECT_FIELD_STATUS_FLAGS =
|
public static string PROJECT_FIELD_STATUS_FLAGS =
|
||||||
(string)Application.Current.FindResource("str_ProjectFieldStatusFlags");
|
(string)Application.Current.FindResource("str_ProjectFieldStatusFlags");
|
||||||
public static string PROJECT_FIELD_TYPE_HINT =
|
public static string PROJECT_FIELD_TYPE_HINT =
|
||||||
|
@ -48,11 +48,15 @@ namespace SourceGen.Tools.Omf {
|
|||||||
}
|
}
|
||||||
private List<SegmentMapEntry> mSegmentMap;
|
private List<SegmentMapEntry> mSegmentMap;
|
||||||
|
|
||||||
|
private Dictionary<int, DisasmProject.RelocData> mRelocData =
|
||||||
|
new Dictionary<int, DisasmProject.RelocData>();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="omfFile">OMF file to load.</param>
|
/// <param name="omfFile">OMF file to load.</param>
|
||||||
|
/// <param name="formatter">Text formatter.</param>
|
||||||
public Loader(OmfFile omfFile, Formatter formatter) {
|
public Loader(OmfFile omfFile, Formatter formatter) {
|
||||||
Debug.Assert(omfFile.OmfFileKind == OmfFile.FileKind.Load);
|
Debug.Assert(omfFile.OmfFileKind == OmfFile.FileKind.Load);
|
||||||
|
|
||||||
@ -83,7 +87,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
Debug.Assert(i == ent.Segment.SegNum);
|
Debug.Assert(i == ent.Segment.SegNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GenerateOutput()) {
|
if (!GenerateDataAndProject()) {
|
||||||
mSegmentMap = null;
|
mSegmentMap = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -258,7 +262,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GenerateOutput() {
|
private bool GenerateDataAndProject() {
|
||||||
// Sum up the segment lengths to get the total project size.
|
// Sum up the segment lengths to get the total project size.
|
||||||
int totalLen = 0;
|
int totalLen = 0;
|
||||||
foreach (SegmentMapEntry ent in mSegmentMap) {
|
foreach (SegmentMapEntry ent in mSegmentMap) {
|
||||||
@ -339,7 +343,8 @@ namespace SourceGen.Tools.Omf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proj.PrepForNew(data, "new_proj");
|
proj.PrepForNew(data, "new_proj");
|
||||||
proj.ApplyChanges(cs, false, out RangeSet unused);
|
proj.ApplyChanges(cs, false, out _);
|
||||||
|
proj.RelocList = mRelocData;
|
||||||
|
|
||||||
mLoadedData = data;
|
mLoadedData = data;
|
||||||
mNewProject = proj;
|
mNewProject = proj;
|
||||||
@ -401,6 +406,10 @@ namespace SourceGen.Tools.Omf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (omfRel.Shift < -32 || omfRel.Shift > 32) {
|
||||||
|
Debug.WriteLine("Invalid reloc shift " + omfRel.Shift);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (omfRel.Shift < 0) {
|
if (omfRel.Shift < 0) {
|
||||||
relocAddr >>= -omfRel.Shift;
|
relocAddr >>= -omfRel.Shift;
|
||||||
} else if (omfRel.Shift > 0) {
|
} else if (omfRel.Shift > 0) {
|
||||||
@ -430,6 +439,9 @@ namespace SourceGen.Tools.Omf {
|
|||||||
Debug.WriteLine("Invalid reloc width " + omfRel.Width);
|
Debug.WriteLine("Invalid reloc width " + omfRel.Width);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRelocData.Add(bufOffset + omfRel.Offset,
|
||||||
|
new DisasmProject.RelocData((byte)omfRel.Width, (byte)omfRel.Shift, relocAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -439,10 +451,17 @@ 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>
|
||||||
|
/// <remarks>
|
||||||
|
/// We don't use ent.Segment.Relocs, as that is expected to be empty.
|
||||||
|
/// </remarks>
|
||||||
private bool RelocJumpTable(SegmentMapEntry ent, byte[] data, int bufOffset,
|
private bool RelocJumpTable(SegmentMapEntry ent, byte[] data, int bufOffset,
|
||||||
ChangeSet cs) {
|
ChangeSet cs) {
|
||||||
const int ENTRY_LEN = 14;
|
const int ENTRY_LEN = 14;
|
||||||
|
|
||||||
|
if (ent.Segment.Relocs.Count != 0) {
|
||||||
|
Debug.WriteLine("WEIRD: jump table has reloc data?");
|
||||||
|
}
|
||||||
|
|
||||||
byte[] srcData = ent.Segment.GetConstData();
|
byte[] srcData = ent.Segment.GetConstData();
|
||||||
Array.Copy(srcData, 0, data, bufOffset, srcData.Length);
|
Array.Copy(srcData, 0, data, bufOffset, srcData.Length);
|
||||||
|
|
||||||
@ -458,7 +477,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
TypedRangeSet undoSet = 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);
|
||||||
|
|
||||||
if (fileNum == 0) {
|
if (fileNum == 0) {
|
||||||
@ -476,7 +495,7 @@ namespace SourceGen.Tools.Omf {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: segment ends right after FileNum, so don't try to read further
|
// Note: segment might end right after FileNum, so don't try to read further
|
||||||
// until we've confirmed that FileNum != 0.
|
// until we've confirmed that FileNum != 0.
|
||||||
|
|
||||||
int segNum = RawData.GetWord(data, bufOffset + i + 4, 2, false);
|
int segNum = RawData.GetWord(data, bufOffset + i + 4, 2, false);
|
||||||
|
@ -31,6 +31,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<system:String x:Key="str_FileOffsetLenFmt">File offset {0}, length {1} ({2})</system:String>
|
<system:String x:Key="str_FileOffsetLenFmt">File offset {0}, length {1} ({2})</system:String>
|
||||||
<system:String x:Key="str_RecordHeaderFmt">Records ({0}):</system:String>
|
<system:String x:Key="str_RecordHeaderFmt">Records ({0}):</system:String>
|
||||||
|
<system:String x:Key="str_RelocHeaderFmt">Relocation dictionary ({0}):</system:String>
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
|
|
||||||
<Grid Margin="8">
|
<Grid Margin="8">
|
||||||
@ -59,7 +60,7 @@ limitations under the License.
|
|||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
CanUserReorderColumns="False"
|
CanUserReorderColumns="False"
|
||||||
CanUserSortColumns="False"
|
CanUserSortColumns="False"
|
||||||
SelectionMode="Single">
|
SelectionMode="Extended">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<!-- make the no-focus color the same as the in-focus color -->
|
<!-- make the no-focus color the same as the in-focus color -->
|
||||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
||||||
@ -86,7 +87,7 @@ limitations under the License.
|
|||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
CanUserReorderColumns="False"
|
CanUserReorderColumns="False"
|
||||||
CanUserSortColumns="False"
|
CanUserSortColumns="False"
|
||||||
SelectionMode="Single">
|
SelectionMode="Extended">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<!-- make the no-focus color the same as the in-focus color -->
|
<!-- make the no-focus color the same as the in-focus color -->
|
||||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
||||||
@ -101,7 +102,7 @@ limitations under the License.
|
|||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
|
||||||
<TextBlock Grid.Row="5" Text="Relocation dictionary:" Margin="0,8,0,0"
|
<TextBlock Grid.Row="5" Text="{Binding RelocHeaderStr, FallbackValue=Relocation dictionary:}" Margin="0,8,0,0"
|
||||||
Visibility="{Binding HasRelocs, Converter={StaticResource BoolToVis}}"/>
|
Visibility="{Binding HasRelocs, Converter={StaticResource BoolToVis}}"/>
|
||||||
<DataGrid Name="relocList" Grid.Row="6" Height="145" Margin="0,8,0,0"
|
<DataGrid Name="relocList" Grid.Row="6" Height="145" Margin="0,8,0,0"
|
||||||
Visibility="{Binding HasRelocs, Converter={StaticResource BoolToVis}}"
|
Visibility="{Binding HasRelocs, Converter={StaticResource BoolToVis}}"
|
||||||
@ -115,7 +116,7 @@ limitations under the License.
|
|||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
CanUserReorderColumns="False"
|
CanUserReorderColumns="False"
|
||||||
CanUserSortColumns="False"
|
CanUserSortColumns="False"
|
||||||
SelectionMode="Single">
|
SelectionMode="Extended">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<!-- make the no-focus color the same as the in-focus color -->
|
<!-- make the no-focus color the same as the in-focus color -->
|
||||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
||||||
|
@ -48,6 +48,12 @@ namespace SourceGen.Tools.Omf.WpfGui {
|
|||||||
set { mRecordHeaderStr = value; OnPropertyChanged(); }
|
set { mRecordHeaderStr = value; OnPropertyChanged(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string mRelocHeaderStr;
|
||||||
|
public string RelocHeaderStr {
|
||||||
|
get { return mRelocHeaderStr; }
|
||||||
|
set { mRelocHeaderStr = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
|
||||||
public class HeaderItem {
|
public class HeaderItem {
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
public string Value { get; private set; }
|
public string Value { get; private set; }
|
||||||
@ -141,6 +147,8 @@ namespace SourceGen.Tools.Omf.WpfGui {
|
|||||||
|
|
||||||
fmt = (string)FindResource("str_RecordHeaderFmt");
|
fmt = (string)FindResource("str_RecordHeaderFmt");
|
||||||
RecordHeaderStr = string.Format(fmt, RecordItems.Count);
|
RecordHeaderStr = string.Format(fmt, RecordItems.Count);
|
||||||
|
fmt = (string)FindResource("str_RelocHeaderFmt");
|
||||||
|
RelocHeaderStr = string.Format(fmt, RelocItems.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateHeaderItems() {
|
private void GenerateHeaderItems() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user