diff --git a/SabreTools.Serialization/Wrappers/NewExecutable.cs b/SabreTools.Serialization/Wrappers/NewExecutable.cs
index 34ac1b1b..e4e05f50 100644
--- a/SabreTools.Serialization/Wrappers/NewExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/NewExecutable.cs
@@ -36,7 +36,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayAddressLock)
{
// Use the cached data if possible
if (_overlayAddress != null)
@@ -51,52 +51,59 @@ namespace SabreTools.Serialization.Wrappers
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
return -1;
- // Search through the segments table to find the furthest
- long endOfSectionData = -1;
- foreach (var entry in SegmentTable)
+ lock (_sourceDataLock)
{
- // Get end of segment data
- long offset = (entry.Offset * (1 << Header.SegmentAlignmentShiftCount)) + entry.Length;
+ // Search through the segments table to find the furthest
+ long endOfSectionData = -1;
+ foreach (var entry in SegmentTable)
+ {
+ // Get end of segment data
+ long offset = (entry.Offset * (1 << Header.SegmentAlignmentShiftCount)) + entry.Length;
- // Read and find the end of the relocation data
+ // Read and find the end of the relocation data
#if NET20 || NET35
if ((entry.FlagWord & SegmentTableEntryFlag.RELOCINFO) != 0)
#else
- if (entry.FlagWord.HasFlag(SegmentTableEntryFlag.RELOCINFO))
+ if (entry.FlagWord.HasFlag(SegmentTableEntryFlag.RELOCINFO))
#endif
- {
- _dataSource.Seek(offset, SeekOrigin.Begin);
- var relocationData = Deserializers.NewExecutable.ParsePerSegmentData(_dataSource);
+ {
+ _dataSource.Seek(offset, SeekOrigin.Begin);
+ var relocationData = Deserializers.NewExecutable.ParsePerSegmentData(_dataSource);
- offset = _dataSource.Position;
- }
+ offset = _dataSource.Position;
+ }
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
-
- // Search through the resources table to find the furthest
- foreach (var entry in ResourceTable.ResourceTypes)
- {
- // Skip invalid entries
- if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
- continue;
-
- foreach (var resource in entry.Resources)
- {
- int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
if (offset > endOfSectionData)
endOfSectionData = offset;
}
+
+ // Search through the resources table to find the furthest
+ foreach (var entry in ResourceTable.ResourceTypes)
+ {
+ // Skip invalid entries
+ if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
+ continue;
+
+ foreach (var resource in entry.Resources)
+ {
+ int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
+ if (offset > endOfSectionData)
+ endOfSectionData = offset;
+ }
+ }
+
+ // If we didn't find the end of section data
+ if (endOfSectionData <= 0)
+ endOfSectionData = -1;
+
+ // Adjust the position of the data by 705 bytes
+ // TODO: Investigate what the byte data is
+ endOfSectionData += 705;
+
+ // Cache and return the position
+ _overlayAddress = endOfSectionData;
+ return _overlayAddress.Value;
}
-
- // If we didn't find the end of section data
- if (endOfSectionData <= 0)
- endOfSectionData = -1;
-
- // Cache and return the position
- _overlayAddress = endOfSectionData;
- return _overlayAddress.Value;
}
}
}
@@ -109,7 +116,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayDataLock)
{
// Use the cached data if possible
if (_overlayData != null)
@@ -124,44 +131,8 @@ namespace SabreTools.Serialization.Wrappers
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
return null;
- // Search through the segments table to find the furthest
- long endOfSectionData = -1;
- foreach (var entry in SegmentTable)
- {
- // Get end of segment data
- long offset = (entry.Offset * (1 << Header.SegmentAlignmentShiftCount)) + entry.Length;
-
- // Read and find the end of the relocation data
-#if NET20 || NET35
- if ((entry.FlagWord & SegmentTableEntryFlag.RELOCINFO) != 0)
-#else
- if (entry.FlagWord.HasFlag(SegmentTableEntryFlag.RELOCINFO))
-#endif
- {
- _dataSource.Seek(offset, SeekOrigin.Begin);
- var relocationData = Deserializers.NewExecutable.ParsePerSegmentData(_dataSource);
-
- offset = _dataSource.Position;
- }
-
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
-
- // Search through the resources table to find the furthest
- foreach (var entry in ResourceTable.ResourceTypes)
- {
- // Skip invalid entries
- if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
- continue;
-
- foreach (var resource in entry.Resources)
- {
- int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
- }
+ // Get the overlay address if possible
+ long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
@@ -175,9 +146,12 @@ namespace SabreTools.Serialization.Wrappers
}
// Otherwise, cache and return the data
- long overlayLength = dataLength - endOfSectionData;
- _overlayData = _dataSource.ReadFrom((int)endOfSectionData, (int)overlayLength, retainPosition: true);
- return _overlayData;
+ lock (_sourceDataLock)
+ {
+ long overlayLength = dataLength - endOfSectionData;
+ _overlayData = _dataSource.ReadFrom((int)endOfSectionData, (int)overlayLength, retainPosition: true);
+ return _overlayData;
+ }
}
}
}
@@ -189,7 +163,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayStringsLock)
{
// Use the cached data if possible
if (_overlayStrings != null)
@@ -204,52 +178,30 @@ namespace SabreTools.Serialization.Wrappers
if (Header == null || SegmentTable == null || ResourceTable?.ResourceTypes == null)
return null;
- // Search through the segments table to find the furthest
- int endOfSectionData = -1;
- foreach (var entry in SegmentTable)
- {
- int offset = (entry.Offset << Header.SegmentAlignmentShiftCount) + entry.Length;
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
-
- // Search through the resources table to find the furthest
- foreach (var entry in ResourceTable.ResourceTypes)
- {
- // Skip invalid entries
- if (entry.ResourceCount == 0 || entry.Resources == null || entry.Resources.Length == 0)
- continue;
-
- foreach (var resource in entry.Resources)
- {
- int offset = (resource.Offset << ResourceTable.AlignmentShiftCount) + resource.Length;
- if (offset > endOfSectionData)
- endOfSectionData = offset;
- }
- }
+ // Get the overlay address if possible
+ long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
return null;
- // Adjust the position of the data by 705 bytes
- // TODO: Investigate what the byte data is
- endOfSectionData += 705;
-
- // If we're at the end of the file, cache an empty list
+ // If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlayStrings = [];
return _overlayStrings;
}
- // TODO: Revisit the 16 MiB limit
- // Cap the check for overlay strings to 16 MiB (arbitrary)
- long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
+ lock (_sourceDataLock)
+ {
+ // TODO: Revisit the 16 MiB limit
+ // Cap the check for overlay strings to 16 MiB (arbitrary)
+ long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
- // Otherwise, cache and return the strings
- _overlayStrings = _dataSource.ReadStringsFrom(endOfSectionData, (int)overlayLength, charLimit: 3);
- return _overlayStrings;
+ // Otherwise, cache and return the strings
+ _overlayStrings = _dataSource.ReadStringsFrom((int)endOfSectionData, (int)overlayLength, charLimit: 3);
+ return _overlayStrings;
+ }
}
}
}
@@ -273,7 +225,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_stubExecutableDataLock)
{
// If we already have cached data, just use that immediately
if (_stubExecutableData != null)
@@ -282,13 +234,16 @@ namespace SabreTools.Serialization.Wrappers
if (Stub?.Header?.NewExeHeaderAddr == null)
return null;
- // Populate the raw stub executable data based on the source
- int endOfStubHeader = 0x40;
- int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
- _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
+ lock (_sourceDataLock)
+ {
+ // Populate the raw stub executable data based on the source
+ int endOfStubHeader = 0x40;
+ int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
+ _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
- // Cache and return the stub executable data, even if null
- return _stubExecutableData;
+ // Cache and return the stub executable data, even if null
+ return _stubExecutableData;
+ }
}
}
}
@@ -302,21 +257,41 @@ namespace SabreTools.Serialization.Wrappers
///
private long? _overlayAddress = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _overlayAddressLock = new();
+
///
/// Overlay data, if it exists
///
private byte[]? _overlayData = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _overlayDataLock = new();
+
///
/// Overlay strings, if they exist
///
private List? _overlayStrings = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _overlayStringsLock = new();
+
///
/// Stub executable data, if it exists
///
private byte[]? _stubExecutableData = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _stubExecutableDataLock = new();
+
///
/// Lock object for reading from the source
///
diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
index cbded142..6ce94e9c 100644
--- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs
@@ -31,7 +31,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_debugDataLock)
{
// Use the cached data if possible
if (_debugData != null && _debugData.Count != 0)
@@ -42,8 +42,11 @@ namespace SabreTools.Serialization.Wrappers
return null;
// Otherwise, build and return the cached dictionary
- ParseDebugTable();
- return _debugData;
+ lock (_sourceDataLock)
+ {
+ ParseDebugTable();
+ return _debugData;
+ }
}
}
}
@@ -59,8 +62,12 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_entryPointDataLock)
{
+ // If we already have cached data, just use that immediately
+ if (_entryPointData != null)
+ return _entryPointData;
+
// If the section table is missing
if (SectionTable == null)
return null;
@@ -77,17 +84,17 @@ namespace SabreTools.Serialization.Wrappers
// If the entry point matches with the start of a section, use that
int entryPointSection = FindEntryPointSectionIndex();
if (entryPointSection >= 0 && OptionalHeader.AddressOfEntryPoint == SectionTable[entryPointSection]?.VirtualAddress)
- return GetSectionData(entryPointSection);
-
- // If we already have cached data, just use that immediately
- if (_entryPointData != null)
+ {
+ _entryPointData = GetSectionData(entryPointSection);
return _entryPointData;
+ }
// Read the first 128 bytes of the entry point
- _entryPointData = _dataSource.ReadFrom(entryPointAddress, length: 128, retainPosition: true);
-
- // Cache and return the entry point padding data, even if null
- return _entryPointData;
+ lock (_sourceDataLock)
+ {
+ _entryPointData = _dataSource.ReadFrom(entryPointAddress, length: 128, retainPosition: true);
+ return _entryPointData;
+ }
}
}
}
@@ -102,7 +109,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_headerPaddingDataLock)
{
// If we already have cached data, just use that immediately
if (_headerPaddingData != null)
@@ -133,12 +140,16 @@ namespace SabreTools.Serialization.Wrappers
// Check if the header length is more than 0 before reading data
int headerLength = (int)(firstSectionAddress - headerStartAddress);
if (headerLength <= 0)
+ {
_headerPaddingData = [];
- else
- _headerPaddingData = _dataSource.ReadFrom((int)headerStartAddress, headerLength, retainPosition: true);
+ return _headerPaddingData;
+ }
- // Cache and return the header padding data, even if null
- return _headerPaddingData;
+ lock (_sourceDataLock)
+ {
+ _headerPaddingData = _dataSource.ReadFrom((int)headerStartAddress, headerLength, retainPosition: true);
+ return _headerPaddingData;
+ }
}
}
}
@@ -150,7 +161,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_headerPaddingStringsLock)
{
// If we already have cached data, just use that immediately
if (_headerPaddingStrings != null)
@@ -181,12 +192,16 @@ namespace SabreTools.Serialization.Wrappers
// Check if the header length is more than 0 before reading strings
int headerLength = (int)(firstSectionAddress - headerStartAddress);
if (headerLength <= 0)
+ {
_headerPaddingStrings = [];
- else
- _headerPaddingStrings = _dataSource.ReadStringsFrom((int)headerStartAddress, headerLength, charLimit: 3);
+ return _headerPaddingStrings;
+ }
- // Cache and return the header padding data, even if null
- return _headerPaddingStrings;
+ lock (_sourceDataLock)
+ {
+ _headerPaddingStrings = _dataSource.ReadStringsFrom((int)headerStartAddress, headerLength, charLimit: 3);
+ return _headerPaddingStrings;
+ }
}
}
}
@@ -205,7 +220,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayAddressLock)
{
// Use the cached data if possible
if (_overlayAddress != null)
@@ -257,6 +272,10 @@ namespace SabreTools.Serialization.Wrappers
if (endOfSectionData <= 0)
endOfSectionData = -1;
+ // If the section data is followed by the end of the data
+ if (endOfSectionData >= dataLength)
+ endOfSectionData = -1;
+
// Cache and return the position
_overlayAddress = endOfSectionData;
return _overlayAddress.Value;
@@ -272,7 +291,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayDataLock)
{
// Use the cached data if possible
if (_overlayData != null)
@@ -287,38 +306,8 @@ namespace SabreTools.Serialization.Wrappers
if (SectionTable == null)
return null;
- // If we have certificate data, use that as the end
- if (OptionalHeader?.CertificateTable != null)
- {
- int certificateTableAddress = (int)OptionalHeader.CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable);
- if (certificateTableAddress != 0 && certificateTableAddress < dataLength)
- dataLength = certificateTableAddress;
- }
-
- // Search through all sections and find the furthest a section goes
- int endOfSectionData = -1;
- foreach (var section in SectionTable)
- {
- // If we have an invalid section
- if (section == null)
- continue;
-
- // If we have an invalid section address
- int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(SectionTable);
- if (sectionAddress == 0)
- continue;
-
- // If we have an invalid section size
- if (section.SizeOfRawData == 0 && section.VirtualSize == 0)
- continue;
-
- // Get the real section size
- int sectionSize = (int)section.SizeOfRawData;
-
- // Compare and set the end of section data
- if (sectionAddress + sectionSize > endOfSectionData)
- endOfSectionData = sectionAddress + sectionSize;
- }
+ // Get the overlay address if possible
+ long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
@@ -332,9 +321,12 @@ namespace SabreTools.Serialization.Wrappers
}
// Otherwise, cache and return the data
- long overlayLength = dataLength - endOfSectionData;
- _overlayData = _dataSource.ReadFrom(endOfSectionData, (int)overlayLength, retainPosition: true);
- return _overlayData;
+ lock (_sourceDataLock)
+ {
+ long overlayLength = dataLength - endOfSectionData;
+ _overlayData = _dataSource.ReadFrom(endOfSectionData, (int)overlayLength, retainPosition: true);
+ return _overlayData;
+ }
}
}
}
@@ -346,7 +338,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_overlayStringsLock)
{
// Use the cached data if possible
if (_overlayStrings != null)
@@ -361,61 +353,30 @@ namespace SabreTools.Serialization.Wrappers
if (SectionTable == null)
return null;
- // If we have certificate data, use that as the end
- if (OptionalHeader?.CertificateTable != null)
- {
- int certificateTableAddress = (int)OptionalHeader.CertificateTable.VirtualAddress.ConvertVirtualAddress(SectionTable);
- if (certificateTableAddress != 0 && certificateTableAddress < dataLength)
- dataLength = certificateTableAddress;
- }
-
- // Search through all sections and find the furthest a section goes
- int endOfSectionData = -1;
- foreach (var section in SectionTable)
- {
- // If we have an invalid section
- if (section == null)
- continue;
-
- // If we have an invalid section address
- int sectionAddress = (int)section.VirtualAddress.ConvertVirtualAddress(SectionTable);
- if (sectionAddress == 0)
- continue;
-
- // If we have an invalid section size
- if (section.SizeOfRawData == 0 && section.VirtualSize == 0)
- continue;
-
- // Get the real section size
- int sectionSize;
- if (section.SizeOfRawData < section.VirtualSize)
- sectionSize = (int)section.VirtualSize;
- else
- sectionSize = (int)section.SizeOfRawData;
-
- // Compare and set the end of section data
- if (sectionAddress + sectionSize > endOfSectionData)
- endOfSectionData = sectionAddress + sectionSize;
- }
+ // Get the overlay address if possible
+ long endOfSectionData = OverlayAddress;
// If we didn't find the end of section data
if (endOfSectionData <= 0)
return null;
- // If we're at the end of the file, cache an empty list
+ // If we're at the end of the file, cache an empty byte array
if (endOfSectionData >= dataLength)
{
_overlayStrings = [];
return _overlayStrings;
}
- // TODO: Revisit the 16 MiB limit
- // Cap the check for overlay strings to 16 MiB (arbitrary)
- long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
+ lock (_sourceDataLock)
+ {
+ // TODO: Revisit the 16 MiB limit
+ // Cap the check for overlay strings to 16 MiB (arbitrary)
+ long overlayLength = Math.Min(dataLength - endOfSectionData, 16 * 1024 * 1024);
- // Otherwise, cache and return the strings
- _overlayStrings = _dataSource.ReadStringsFrom(endOfSectionData, (int)overlayLength, charLimit: 3);
- return _overlayStrings;
+ // Otherwise, cache and return the strings
+ _overlayStrings = _dataSource.ReadStringsFrom((int)endOfSectionData, (int)overlayLength, charLimit: 3);
+ return _overlayStrings;
+ }
}
}
}
@@ -430,7 +391,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_sectionNamesLock)
{
// Use the cached data if possible
if (_sectionNames != null)
@@ -475,7 +436,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_stubExecutableDataLock)
{
// If we already have cached data, just use that immediately
if (_stubExecutableData != null)
@@ -484,13 +445,16 @@ namespace SabreTools.Serialization.Wrappers
if (Stub?.Header?.NewExeHeaderAddr == null)
return null;
- // Populate the raw stub executable data based on the source
- int endOfStubHeader = 0x40;
- int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
- _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
+ lock (_sourceDataLock)
+ {
+ // Populate the raw stub executable data based on the source
+ int endOfStubHeader = 0x40;
+ int lengthOfStubExecutableData = (int)Stub.Header.NewExeHeaderAddr - endOfStubHeader;
+ _stubExecutableData = _dataSource.ReadFrom(endOfStubHeader, lengthOfStubExecutableData, retainPosition: true);
- // Cache and return the stub executable data, even if null
- return _stubExecutableData;
+ // Cache and return the stub executable data, even if null
+ return _stubExecutableData;
+ }
}
}
}
@@ -502,7 +466,7 @@ namespace SabreTools.Serialization.Wrappers
{
get
{
- lock (_sourceDataLock)
+ lock (_resourceDataLock)
{
// Use the cached data if possible
if (_resourceData != null && _resourceData.Count != 0)
@@ -692,45 +656,95 @@ namespace SabreTools.Serialization.Wrappers
#region Instance Variables
///
- /// Header padding data, if it exists
+ /// Cached debug data
///
- private byte[]? _headerPaddingData = null;
+ private readonly Dictionary _debugData = [];
///
- /// Header padding strings, if they exist
+ /// Lock object for
///
- private List? _headerPaddingStrings = null;
+ private readonly object _debugDataLock = new();
///
/// Entry point data, if it exists and isn't aligned to a section
///
private byte[]? _entryPointData = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _entryPointDataLock = new();
+
+ ///
+ /// Header padding data, if it exists
+ ///
+ private byte[]? _headerPaddingData = null;
+
+ ///
+ /// Lock object for
+ ///
+ private readonly object _headerPaddingDataLock = new();
+
+ ///
+ /// Header padding strings, if they exist
+ ///
+ private List? _headerPaddingStrings = null;
+
+ ///
+ /// Lock object for
+ ///
+ private readonly object _headerPaddingStringsLock = new();
+
///
/// Address of the overlay, if it exists
///
private int? _overlayAddress = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _overlayAddressLock = new();
+
///
/// Overlay data, if it exists
///
private byte[]? _overlayData = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _overlayDataLock = new();
+
///
/// Overlay strings, if they exist
///
private List? _overlayStrings = null;
///
- /// Stub executable data, if it exists
+ /// Lock object for
///
- private byte[]? _stubExecutableData = null;
+ private readonly object _overlayStringsLock = new();
+
+ ///
+ /// Cached resource data
+ ///
+ private readonly Dictionary _resourceData = [];
+
+ ///
+ /// Lock object for
+ ///
+ private readonly object _resourceDataLock = new();
///
/// Sanitized section names
///
private string[]? _sectionNames = null;
+ ///
+ /// Lock object for
+ ///
+ private readonly object _sectionNamesLock = new();
+
///
/// Cached raw section data
///
@@ -741,6 +755,16 @@ namespace SabreTools.Serialization.Wrappers
///
private List[]? _sectionStringData = null;
+ ///
+ /// Stub executable data, if it exists
+ ///
+ private byte[]? _stubExecutableData = null;
+
+ ///
+ /// Lock object for
+ ///
+ private readonly object _stubExecutableDataLock = new();
+
///
/// Cached raw table data
///
@@ -751,16 +775,6 @@ namespace SabreTools.Serialization.Wrappers
///
private List[]? _tableStringData = null;
- ///
- /// Cached debug data
- ///
- private readonly Dictionary _debugData = [];
-
- ///
- /// Cached resource data
- ///
- private readonly Dictionary _resourceData = [];
-
///
/// Cached version info data
///