diff --git a/BurnOutSharp.Models/LinearExecutable/Enums.cs b/BurnOutSharp.Models/LinearExecutable/Enums.cs
index 56940955..0b9a4c4d 100644
--- a/BurnOutSharp.Models/LinearExecutable/Enums.cs
+++ b/BurnOutSharp.Models/LinearExecutable/Enums.cs
@@ -65,49 +65,263 @@ namespace BurnOutSharp.Models.LinearExecutable
}
[Flags]
- public enum InformationBlockFlag : uint
+ public enum ModuleFlags : uint
{
///
- /// Initialization (Only for DLL):
- /// 0 Global
- /// 1 Per-Process
+ /// Reserved for system use.
///
- Initialization = 1 << 2,
+ Reserved0 = 0x00000001,
///
- /// No internal fixup in exe image
+ /// Reserved for system use.
///
- NoInternalFixup = 1 << 4,
+ Reserved1 = 0x00000002,
///
- /// No internal fixup in exe image
+ /// Per-Process Library Initialization.
///
- NoExternalFixup = 1 << 5,
-
- // TODO: Figure out this block of flags
- // 8, 9, 10 all have the same note:
- // 0 Unknown
- // 1 Incompatible with PM windowing
- // 2 Compatible with PM windowing
- // 3 Uses PM windowing API
+ ///
+ /// The setting of this bit requires the EIP Object # and EIP fields
+ /// to have valid values. If the EIP Object # and EIP fields are
+ /// valid and this bit is NOT set, then Global Library Initialization
+ /// is assumed. Setting this bit for an EXE file is invalid.
+ ///
+ Initialization = 0x00000004,
///
- /// Module not loadable
+ /// Reserved for system use.
///
- ModuleNotLoadable = 1 << 13,
+ Reserved3 = 0x00000008,
///
- /// Module is DLL rather then program
+ /// Internal fixups for the module have been applied.
///
- IsDLL = 1 << 15,
+ ///
+ /// The setting of this bit in a Linear Executable Module indicates that
+ /// each object of the module has a preferred load address specified in
+ /// the Object Table Reloc Base Addr. If the module's objects can not be
+ /// loaded at these preferred addresses, then the relocation records that
+ /// have been retained in the file data will be applied.
+ ///
+ InternalFixupsApplied = 0x00000010,
- // Bits 16-31 are all reserved
+ ///
+ /// External fixups for the module have been applied.
+ ///
+ ExternalFixupsApplied = 0x00000020,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved6 = 0x00000040,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved7 = 0x00000080,
+
+ ///
+ /// Incompatible with PM windowing.
+ ///
+ IncompatibleWithPMWindowing = 0x00000100,
+
+ ///
+ /// Incompatible with PM windowing.
+ ///
+ CompatibleWithPMWindowing = 0x00000200,
+
+ ///
+ /// Uses PM windowing API.
+ ///
+ UsesPMWindowing = 0x00000300,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved10 = 0x00000400,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved11 = 0x00000800,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved12 = 0x00001000,
+
+ ///
+ /// Module is not loadable.
+ ///
+ ///
+ /// When the 'Module is not loadable' flag is set, it indicates that
+ /// either errors were detected at link time or that the module is
+ /// being incrementally linked and therefore can't be loaded.
+ ///
+ ModuleNotLoadable = 0x00002000,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved14 = 0x00004000,
+
+ ///
+ /// Module type mask.
+ ///
+ ModuleTypeMask = 0x00038000,
+
+ ///
+ /// Program module.
+ ///
+ ///
+ /// A module can not contain dynamic links to other modules that have
+ /// the 'program module' type.
+ ///
+ ProgramModule = 0x00000000,
+
+ ///
+ /// Library module.
+ ///
+ LibraryModule = 0x00008000,
+
+ ///
+ /// Protected Memory Library module.
+ ///
+ ProtectedMemoryLibraryModule = 0x00018000,
+
+ ///
+ /// Physical Device Driver module.
+ ///
+ PhysicalDeviceDriverModule = 0x00020000,
+
+ ///
+ /// Virtual Device Driver module.
+ ///
+ VirtualDeviceDriverModule = 0x00028000,
+
+ ///
+ /// Per-process Library Termination.
+ ///
+ ///
+ /// The setting of this bit requires the EIP Object # and EIP fields
+ /// to have valid values. If the EIP Object # and EIP fields are
+ /// valid and this bit is NOT set, then Global Library Termination
+ /// is assumed. Setting this bit for an EXE file is invalid.
+ ///
+ PerProcessLibraryTermination = 0x40000000,
+ }
+
+ [Flags]
+ public enum ObjectFlags : ushort
+ {
+ ///
+ /// Readable Object.
+ ///
+ ReadableObject = 0x0001,
+
+ ///
+ /// Writable Object.
+ ///
+ WritableObject = 0x0002,
+
+ ///
+ /// Executable Object.
+ ///
+ ExecutableObject = 0x0004,
+
+ // The readable, writable and executable flags provide support for all possible
+ // protections. In systems where all of these protections are not supported,
+ // the loader will be responsible for making the appropriate protection match
+ // for the system.
+
+ ///
+ /// Resource Object.
+ ///
+ ResourceObject = 0x0008,
+
+ ///
+ /// Discardable Object.
+ ///
+ DiscardableObject = 0x0010,
+
+ ///
+ /// Object is Shared.
+ ///
+ Shared = 0x0020,
+
+ ///
+ /// Object has Preload Pages.
+ ///
+ HasPreloadPages = 0x0040,
+
+ ///
+ /// Object has Invalid Pages.
+ ///
+ HasInvalidPages = 0x0080,
+
+ ///
+ /// Object has Zero Filled Pages.
+ ///
+ HasZeroFilledPages = 0x0100,
+
+ ///
+ /// Object is Resident (valid for VDDs, PDDs only).
+ ///
+ Resident = 0x0200,
+
+ ///
+ /// Object is Resident & Contiguous (VDDs, PDDs only).
+ ///
+ ResidentAndContiguous = 0x0300,
+
+ ///
+ /// Object is Resident & 'long-lockable' (VDDs, PDDs only).
+ ///
+ ResidentAndLongLockable = 0x0400,
+
+ ///
+ /// Reserved for system use.
+ ///
+ Reserved = 0x0800,
+
+ ///
+ /// 16:16 Alias Required (80x86 Specific).
+ ///
+ AliasRequired = 0x1000,
+
+ ///
+ /// Big/Default Bit Setting (80x86 Specific).
+ ///
+ BitSetting = 0x2000,
+
+ // The 'big/default' bit, for data segments, controls the setting of the
+ // Big bit in the segment descriptor. (The Big bit, or B-bit, determines
+ // whether ESP or SP is used as the stack pointer.) For code segments,
+ // this bit controls the setting of the Default bit in the segment
+ // descriptor. (The Default bit, or D-bit, determines whether the default
+ // word size is 32-bits or 16-bits. It also affects the interpretation of
+ // the instruction stream.)
+
+ ///
+ /// Object is conforming for code (80x86 Specific).
+ ///
+ Conforming = 0x4000,
+
+ ///
+ /// Object I/O privilege level (80x86 Specific). Only used for 16:16 Alias Objects.
+ ///
+ PrivilegeLevel = 0x8000,
}
public enum OperatingSystem : ushort
{
///
- /// OS/2
+ /// Unknown (any "new-format" OS)
+ ///
+ Unknown = 0x00,
+
+ ///
+ /// OS/2 (default)
///
OS2 = 0x01,
diff --git a/BurnOutSharp.Models/LinearExecutable/InformationBlock.cs b/BurnOutSharp.Models/LinearExecutable/InformationBlock.cs
index 88e41ebf..97266977 100644
--- a/BurnOutSharp.Models/LinearExecutable/InformationBlock.cs
+++ b/BurnOutSharp.Models/LinearExecutable/InformationBlock.cs
@@ -11,242 +11,416 @@ namespace BurnOutSharp.Models.LinearExecutable
/// the beginning of the block):
///
///
+ ///
[StructLayout(LayoutKind.Sequential)]
public class InformationBlock
{
///
- /// Specifies the signature word 'LE' (4Ch 45H)
+ /// Specifies the signature word
+ /// 'LE' (4Ch 45H)
+ /// 'LX' (4Ch 58H)
///
+ ///
+ /// The signature word is used by the loader to identify the EXE
+ /// file as a valid 32-bit Linear Executable Module Format.
+ ///
public char[] Signature;
///
- /// Byte order
+ /// Byte Ordering.
///
+ ///
+ /// This byte specifies the byte ordering for the linear EXE format.
+ ///
public ByteOrder ByteOrder;
///
- /// Word order
+ /// Word Ordering.
///
+ ///
+ /// This byte specifies the Word ordering for the linear EXE format.
+ ///
public WordOrder WordOrder;
///
- /// Executable format level
+ /// Linear EXE Format Level.
///
+ ///
+ /// The Linear EXE Format Level is set to 0 for the initial version of the
+ /// 32-bit linear EXE format. Each incompatible change to the linear EXE
+ /// format must increment this value. This allows the system to recognized
+ /// future EXE file versions so that an appropriate error message may be
+ /// displayed if an attempt is made to load them.
+ ///
public uint ExecutableFormatLevel;
///
- /// CPU type
+ /// Module CPU Type.
///
+ ///
+ /// This field specifies the type of CPU required by this module to run.
+ ///
public CPUType CPUType;
///
- /// Target operating system
+ /// Module OS Type.
///
- public OperatingSystem TargetOperatingSystem;
+ ///
+ /// This field specifies the type of Operating system required to run this module.
+ ///
+ public OperatingSystem ModuleOS;
///
/// Module version
///
+ ///
+ /// This is useful for differentiating between revisions of dynamic linked modules.
+ /// This value is specified at link time by the user.
+ ///
public uint ModuleVersion;
///
/// Module type flags
///
- public InformationBlockFlag ModuleTypeFlags;
+ public ModuleFlags ModuleTypeFlags;
///
- /// Number of memory pages
+ /// Number of pages in module.
///
- public uint MemoryPageCount;
+ ///
+ /// This field specifies the number of pages physically contained in this module.
+ /// In other words, pages containing either enumerated or iterated data, or
+ /// zero-fill pages that have relocations, not invalid or zero-fill pages implied
+ /// by the Virtual Size in the Object Table being larger than the number of pages
+ /// actually in the linear EXE file. These pages are contained in the 'preload
+ /// pages', 'demand load pages' and 'iterated data pages' sections of the linear
+ /// EXE module. This is used to determine the size of the page information tables
+ /// in the linear EXE module.
+ ///
+ public uint ModuleNumberPages;
///
- /// Initial object CS number
+ /// The Object number to which the Entry Address is relative.
///
+ ///
+ /// This specifies the object to which the Entry Address is relative. This must be
+ /// a nonzero value for a program module to be correctly loaded. A zero value for
+ /// a library module indicates that no library entry routine exists. If this value
+ /// is zero, then both the Per-process Library Initialization bit and the Per-process
+ /// Library Termination bit must be clear in the module flags, or else the loader
+ /// will fail to load the module. Further, if the Per-process Library Termination bit
+ /// is set, then the object to which this field refers must be a 32-bit object (i.e.,
+ /// the Big/Default bit must be set in the object flags; see below).
+ ///
public uint InitialObjectCS;
///
- /// Initial EIP
+ /// Entry Address of module.
///
+ ///
+ /// The Entry Address is the starting address for program modules and the library
+ /// initialization and Library termination address for library modules.
+ ///
public uint InitialEIP;
///
- /// Initial object SS number
+ /// The Object number to which the ESP is relative.
///
+ ///
+ /// This specifies the object to which the starting ESP is relative. This must be a
+ /// nonzero value for a program module to be correctly loaded. This field is ignored
+ /// for a library module.
+ ///
public uint InitialObjectSS;
///
- /// Initial ESP
+ /// Starting stack address of module.
///
+ ///
+ /// The ESP defines the starting stack pointer address for program modules. A zero
+ /// value in this field indicates that the stack pointer is to be initialized to the
+ /// highest address/offset in the object. This field is ignored for a library module.
+ ///
public uint InitialESP;
///
- /// Memory page size
+ /// The size of one page for this system.
///
+ ///
+ /// This field specifies the page size used by the linear EXE format and the system.
+ /// For the initial version of this linear EXE format the page size is 4Kbytes.
+ /// (The 4K page size is specified by a value of 4096 in this field.)
+ ///
public uint MemoryPageSize;
///
- /// Bytes on last page
+ /// The shift left bits for page offsets.
///
+ ///
+ /// This field gives the number of bit positions to shift left when interpreting
+ /// the Object Page Table entries' page offset field. This determines the alignment
+ /// of the page information in the file. For example, a value of 4 in this field
+ /// would align all pages in the Data Pages and Iterated Pages sections on 16 byte
+ /// (paragraph) boundaries. A Page Offset Shift of 9 would align all pages on a
+ /// 512 byte (disk sector) basis. The default value for this field is 12 (decimal),
+ /// which give a 4096 byte alignment. All other offsets are byte aligned.
+ ///
public uint BytesOnLastPage;
///
- /// Fix-up section size
+ /// Total size of the fixup information in bytes.
///
+ ///
+ /// This includes the following 4 tables:
+ /// - Fixup Page Table
+ /// - Fixup Record Table
+ /// - Import Module name Table
+ /// - Import Procedure Name Table
+ ///
public uint FixupSectionSize;
///
- /// Fix-up section checksum
+ /// Checksum for fixup information.
///
+ ///
+ /// This is a cryptographic checksum covering all of the fixup information. The
+ /// checksum for the fixup information is kept separate because the fixup data is
+ /// not always loaded into main memory with the 'loader section'. If the checksum
+ /// feature is not implemented, then the linker will set these fields to zero.
+ ///
public uint FixupSectionChecksum;
///
- /// Loader section size
+ /// Size of memory resident tables.
///
+ ///
+ /// This is the total size in bytes of the tables required to be memory resident
+ /// for the module, while the module is in use. This total size includes all
+ /// tables from the Object Table down to and including the Per-Page Checksum Table.
+ ///
public uint LoaderSectionSize;
///
- /// Loader section checksum
+ /// Checksum for loader section.
///
+ ///
+ /// This is a cryptographic checksum covering all of the loader section information.
+ /// If the checksum feature is not implemented, then the linker will set these fields
+ /// to zero.
+ ///
public uint LoaderSectionChecksum;
///
- /// Offset of object table
+ /// Object Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ObjectTableOffset;
///
- /// Object table entries
+ /// Object Table Count.
///
+ ///
+ /// This defines the number of entries in Object Table.
+ ///
public uint ObjectTableCount;
///
- /// Object page map offset
+ /// Object Page Table offset
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ObjectPageMapOffset;
///
- /// Object iterate data map offset
+ /// Object Iterated Pages offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ObjectIterateDataMapOffset;
///
- /// Resource table offset
+ /// Resource Table offset
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ResourceTableOffset;
///
- /// Resource table entries
+ /// Number of entries in Resource Table.
///
public uint ResourceTableCount;
///
- /// Resident names table offset
+ /// Resident Name Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ResidentNamesTableOffset;
///
- /// Entry table offset
+ /// Entry Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint EntryTableOffset;
///
- /// Module directives table offset
+ /// Module Format Directives Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ModuleDirectivesTableOffset;
///
- /// Module directives entries
+ /// Number of Module Format Directives in the Table.
///
+ ///
+ /// This field specifies the number of entries in the
+ /// Module Format Directives Table.
+ ///
public uint ModuleDirectivesCount;
///
- /// Fix-up page table offset
+ /// Fixup Page Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint FixupPageTableOffset;
///
- /// Fix-up record table offset
+ /// Fixup Record Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint FixupRecordTableOffset;
///
- /// Imported modules name table offset
+ /// Import Module Name Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint ImportedModulesNameTableOffset;
///
- /// Imported modules count
+ /// The number of entries in the Import Module Name Table.
///
public uint ImportedModulesCount;
///
- /// Imported procedure name table offset
+ /// Import Procedure Name Table offset.
///
- public uint ImportedProcedureNameTableOffset;
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
+ public uint ImportProcedureNameTableOffset;
///
- /// Per-page checksum table offset
+ /// Per-page Checksum Table offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint PerPageChecksumTableOffset;
///
- /// Data pages offset from top of file
+ /// Data Pages Offset.
///
+ ///
+ /// This offset is relative to the beginning of the EXE file.
+ ///
public uint DataPagesOffset;
///
- /// Preload page count
+ /// Number of Preload pages for this module.
///
+ ///
+ /// Note that OS/2 2.0 does not respect the preload of pages as specified
+ /// in the executable file for performance reasons.
+ ///
public uint PreloadPageCount;
///
- /// Non-resident names table offset from top of file
+ /// Non-Resident Name Table offset.
///
- public uint NonresidentNamesTableOffset;
+ ///
+ /// This offset is relative to the beginning of the EXE file.
+ ///
+ public uint NonResidentNamesTableOffset;
///
- /// Non-resident names table length
+ /// Number of bytes in the Non-resident name table.
///
- public uint NonresidentNamesTableLength;
+ public uint NonResidentNamesTableLength;
///
- /// Non-resident names table checksum
+ /// Non-Resident Name Table Checksum.
///
- public uint NonresidentNamesTableChecksum;
+ ///
+ /// This is a cryptographic checksum of the Non-Resident Name Table.
+ ///
+ public uint NonResidentNamesTableChecksum;
///
- /// Automatic data object
+ /// The Auto Data Segment Object number.
///
+ ///
+ /// This is the object number for the Auto Data Segment used by 16-bit modules.
+ /// This field is supported for 16-bit compatibility only and is not used by
+ /// 32-bit modules.
+ ///
public uint AutomaticDataObject;
///
- /// Debug information offset
+ /// Debug Information offset.
///
+ ///
+ /// This offset is relative to the beginning of the linear EXE header.
+ ///
public uint DebugInformationOffset;
///
- /// Debug information length
+ /// Debug Information length.
///
+ ///
+ /// The length of the debug information in bytes.
+ ///
public uint DebugInformationLength;
///
- /// Preload instance pages number
+ /// Instance pages in preload section.
///
+ ///
+ /// The number of instance data pages found in the preload section.
+ ///
public uint PreloadInstancePagesNumber;
///
- /// Demand instance pages number
+ /// Instance pages in demand section.
///
+ ///
+ /// The number of instance data pages found in the demand section.
+ ///
public uint DemandInstancePagesNumber;
///
- /// Extra heap allocation
+ /// Heap size added to the Auto DS Object.
///
+ ///
+ /// The heap size is the number of bytes added to the Auto Data Segment
+ /// by the loader. This field is supported for 16-bit compatibility only and
+ /// is not used by 32-bit modules.
+ ///
public uint ExtraHeapAllocation;
-
- ///
- /// ???
- ///
- public uint Reserved;
}
}
diff --git a/BurnOutSharp.Models/LinearExecutable/ObjectTableEntry.cs b/BurnOutSharp.Models/LinearExecutable/ObjectTableEntry.cs
index 68602efb..d67b1869 100644
--- a/BurnOutSharp.Models/LinearExecutable/ObjectTableEntry.cs
+++ b/BurnOutSharp.Models/LinearExecutable/ObjectTableEntry.cs
@@ -9,38 +9,73 @@ namespace BurnOutSharp.Models.LinearExecutable
/// values found in in the segment table (the locations are relative to
/// the beginning of each entry):
///
+ ///
+ /// Entries in the Object Table are numbered starting from one.
+ ///
///
+ ///
[StructLayout(LayoutKind.Sequential)]
public class ObjectTableEntry
{
///
- /// Virtual segment size in bytes
+ /// Virtual memory size.
///
+ ///
+ /// This is the size of the object that will be allocated when the object
+ /// is loaded. The object's virtual size (rounded up to the page size value)
+ /// must be greater than or equal to the total size of the pages in the EXE
+ /// file for the object. This memory size must also be large enough to
+ /// contain all of the iterated data and uninitialized data in the EXE file.
+ ///
public uint VirtualSegmentSize;
///
- /// Relocation base address
+ /// Relocation Base Address.
///
+ ///
+ /// The relocation base address the object is currently relocated to. If the
+ /// internal relocation fixups for the module have been removed, this is the
+ /// address the object will be allocated at by the loader.
+ ///
public uint RelocationBaseAddress;
///
- /// Object flags
+ /// Flag bits for the object.
///
- /// No flags are documented properly
- public uint ObjectFlags;
+ public ObjectFlags ObjectFlags;
///
- /// Page map index
+ /// Object Page Table Index.
///
- public uint PageMapIndex;
+ ///
+ /// This specifies the number of the first object page table entry for this object.
+ /// The object page table specifies where in the EXE file a page can be found for
+ /// a given object and specifies per-page attributes.
+ ///
+ /// The object table entries are ordered by logical page in the object table. In
+ /// other words the object table entries are sorted based on the object page table
+ /// index value.
+ ///
+ public uint PageTableIndex;
///
- /// Page map entries
+ /// # of object page table entries for this object.
///
- public uint PageMapEntries;
+ ///
+ /// Any logical pages at the end of an object that do not have an entry in the object
+ /// page table associated with them are handled as zero filled or invalid pages by
+ /// the loader.
+ ///
+ /// When the last logical pages of an object are not specified with an object page
+ /// table entry, they are treated as either zero filled pages or invalid pages based
+ /// on the last entry in the object page table for that object. If the last entry
+ /// was neither a zero filled or invalid page, then the additional pages are treated
+ /// as zero filled pages.
+ ///
+ public uint PageTableEntries;
///
- /// ???
+ /// Reserved for future use. Must be set to zero.
///
public uint Reserved;
}