using System.Collections.Generic;
namespace SabreTools.Data.Models.PortableExecutable
{
///
/// The following list describes the Microsoft PE executable format, with the
/// base of the image header at the top. The section from the MS-DOS 2.0
/// Compatible EXE Header through to the unused section just before the PE header
/// is the MS-DOS 2.0 Section, and is used for MS-DOS compatibility only.
///
///
public sealed class Executable
{
///
/// MS-DOS executable stub
///
public MSDOS.Executable Stub { get; set; } = new();
///
/// After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte
/// signature that identifies the file as a PE format image file. This signature is "PE\0\0"
/// (the letters "P" and "E" followed by two null bytes).
///
public string Signature { get; set; } = string.Empty;
///
/// File header
///
public COFF.FileHeader FileHeader { get; set; } = new();
///
/// Microsoft extended optional header
///
public OptionalHeader OptionalHeader { get; set; } = new();
///
/// Section table
///
public COFF.SectionHeader[] SectionTable { get; set; } = [];
///
/// Symbol table
///
public COFF.SymbolTableEntries.BaseEntry[]? SymbolTable { get; set; }
///
/// String table
///
public COFF.StringTable? StringTable { get; set; }
#region Data Directories
///
/// The export data section, named .edata, contains information about symbols that other images
/// can access through dynamic linking. Exported symbols are generally found in DLLs, but DLLs
/// can also import symbols.
///
/// An overview of the general structure of the export section is described below. The tables
/// described are usually contiguous in the file in the order shown (though this is not
/// required). Only the export directory table and export address table are required to export
/// symbols as ordinals. (An ordinal is an export that is accessed directly by its export
/// address table index.) The name pointer table, ordinal table, and export name table all
/// exist to support use of export names.
///
///
#region Export Table (.edata)
///
/// A table with just one row (unlike the debug directory). This table indicates the
/// locations and sizes of the other export tables.
///
public Export.DirectoryTable? ExportDirectoryTable { get; set; }
///
/// An array of RVAs of exported symbols. These are the actual addresses of the exported
/// functions and data within the executable code and data sections. Other image files
/// can import a symbol by using an index to this table (an ordinal) or, optionally, by
/// using the public name that corresponds to the ordinal if a public name is defined.
///
public Export.AddressTableEntry[]? ExportAddressTable { get; set; }
///
/// An array of pointers to the public export names, sorted in ascending order.
///
public Export.NamePointerTable? NamePointerTable { get; set; }
///
/// An array of the ordinals that correspond to members of the name pointer table. The
/// correspondence is by position; therefore, the name pointer table and the ordinal table
/// must have the same number of members. Each ordinal is an index into the export address
/// table.
///
public Export.OrdinalTable? OrdinalTable { get; set; }
///
/// A series of null-terminated ASCII strings. Members of the name pointer table point into
/// this area. These names are the public names through which the symbols are imported and
/// exported; they are not necessarily the same as the private names that are used within
/// the image file.
///
public Export.NameTable? ExportNameTable { get; set; }
#endregion
///
/// All image files that import symbols, including virtually all executable (EXE) files,
/// have an .idata section. A typical file layout for the import information follows:
///
/// - Directory Table
/// Null Directory Entry
/// - DLL1 Import Lookup Table
/// Null
/// - DLL2 Import Lookup Table
/// Null
/// - DLL3 Import Lookup Table
/// Null
/// - Hint-Name Table
///
///
#region Import Table (.idata) and Import Address Table
///
/// The import information begins with the import directory table, which describes the
/// remainder of the import information.
///
public Import.DirectoryTableEntry[]? ImportDirectoryTable { get; set; }
///
/// An import lookup table is an array of 32-bit numbers for PE32 or an array of 64-bit
/// numbers for PE32+.
///
public Dictionary? ImportLookupTables { get; set; }
///
/// These addresses are the actual memory addresses of the symbols, although technically
/// they are still called "virtual addresses".
///
public Dictionary? ImportAddressTables { get; set; }
///
/// One hint/name table suffices for the entire import section.
///
public Import.HintNameTableEntry[]? HintNameTable { get; set; }
#endregion
#region Resource Table (.rsrc)
///
/// Resource directory table (.rsrc)
///
public Resource.DirectoryTable? ResourceDirectoryTable { get; set; }
#endregion
// TODO: Handle Exception Table
#region Certificate Table
///
/// Attribute certificate table
///
public AttributeCertificate.Entry[]? AttributeCertificateTable { get; set; }
#endregion
#region Base Relocation Table (.reloc)
///
/// Base relocation table
///
public BaseRelocation.Block[]? BaseRelocationTable { get; set; }
#endregion
#region Debug Data (.debug*)
///
/// Debug table
///
public DebugData.Table? DebugTable { get; set; }
#endregion
// TODO: Handle Architecture
// TODO: Handle Global Ptr
// TODO: Thread Local Storage (.tls)
// TODO: Load Configuration Table
// TODO: Bound Import Table
#region Delay Load Table
///
/// Delay-load directory table
///
public DelayLoad.DirectoryTable? DelayLoadDirectoryTable { get; set; }
#endregion
// TODO: CLR Runtime Header (.cormeta)
// TODO: Reserved
#endregion
#region Named Sections
// TODO: Support grouped sections in section reading and parsing
// https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#grouped-sections-object-only
// Grouped sections are ordered and mean that the data in the sections contributes
// to the "base" section (the one without the "$X" suffix). This may negatively impact
// the use of some of the different types of executables.
// .cormeta - CLR metadata is stored in this section. It is used to indicate that
// the object file contains managed code. The format of the metadata is not
// documented, but can be handed to the CLR interfaces for handling metadata.
// .drectve - A section is a directive section if it has the IMAGE_SCN_LNK_INFO
// flag set in the section header and has the .drectve section name. The linker
// removes a .drectve section after processing the information, so the section
// does not appear in the image file that is being linked.
//
// A .drectve section consists of a string of text that can be encoded as ANSI
// or UTF-8. If the UTF-8 byte order marker (BOM, a three-byte prefix that
// consists of 0xEF, 0xBB, and 0xBF) is not present, the directive string is
// interpreted as ANSI. The directive string is a series of linker options that
// are separated by spaces. Each option contains a hyphen, the option name, and
// any appropriate attribute. If an option contains spaces, the option must be
// enclosed in quotes. The .drectve section must not have relocations or line
// numbers.
//
// TODO: Can we implement reading/parsing the .drectve section?
// .pdata Section - Multiple formats per entry
// .sxdata - The valid exception handlers of an object are listed in the .sxdata
// section of that object. The section is marked IMAGE_SCN_LNK_INFO. It contains
// the COFF symbol index of each valid handler, using 4 bytes per index.
//
// Additionally, the compiler marks a COFF object as registered SEH by emitting
// the absolute symbol "@feat.00" with the LSB of the value field set to 1. A
// COFF object with no registered SEH handlers would have the "@feat.00" symbol,
// but no .sxdata section.
//
// TODO: Can we implement reading/parsing the .sxdata section?
#endregion
// TODO: Determine if "Archive (Library) File Format" is worth modelling
}
}