From 9dd50f7dfc612c28e82d72b53700b2afa1b42bb1 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 9 Aug 2023 00:29:01 -0700 Subject: [PATCH] Better document PE headers --- libc/nt/struct/imagefileheader.internal.h | 23 ++++++ libc/nt/struct/imageoptionalheader.internal.h | 78 +++++++++++++++---- libc/nt/struct/imagesectionheader.internal.h | 2 +- 3 files changed, 86 insertions(+), 17 deletions(-) diff --git a/libc/nt/struct/imagefileheader.internal.h b/libc/nt/struct/imagefileheader.internal.h index 0eaf97f72..0bfff84fc 100644 --- a/libc/nt/struct/imagefileheader.internal.h +++ b/libc/nt/struct/imagefileheader.internal.h @@ -3,12 +3,35 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) struct NtImageFileHeader { + + /* + * E.g. kNtImageFileMachineNexgen32e + */ uint16_t Machine; + + /* + * The number of sections. This indicates the size of the section + * table, which immediately follows the headers. + */ uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + + /* + * [File Size] The size of the optional header, which is required for + * executable files but not for object files. This value should be + * zero for an object file. For a description of the header format, + * see Optional Header (Image Only). + */ uint16_t SizeOfOptionalHeader; + + /* + * E.g. kNtPeFileExecutableImage | kNtImageFileLargeAddressAware + */ uint16_t Characteristics; }; diff --git a/libc/nt/struct/imageoptionalheader.internal.h b/libc/nt/struct/imageoptionalheader.internal.h index 29cf9a14f..421a6ce92 100644 --- a/libc/nt/struct/imageoptionalheader.internal.h +++ b/libc/nt/struct/imageoptionalheader.internal.h @@ -20,27 +20,49 @@ struct NtImageOptionalHeader { uint8_t MajorLinkerVersion; uint8_t MinorLinkerVersion; + + /* + * [informative] Sum SizeOfRawData for all code sections. Therefore + * must be a multiple of FileAlignment. + */ uint32_t SizeOfCode; + + /* + * [file size; informative] Sum of SizeOfRawData for all sections with + * kNtPeSectionCntInitializedData in Characteristics. Therefore will + * be a multiple of FileAlignment. + */ uint32_t SizeOfInitializedData; + + /* + * [virtual size; informative] Some kind of summation of sections with + * kNtPeSectionCntUninitializedData in the Characteristics. + */ uint32_t SizeOfUninitializedData; /* - * The address of the entry point relative to the image base when the - * executable file is loaded into memory. For program images, this is - * the starting address. For device drivers, this is the address of - * the initialization function. An entry point is optional for DLLs. - * When no entry point is present, this field must be zero. + * [Relative Virtual Address] The address of the entry point relative + * to the image base when the executable file is loaded into memory. + * For program images, this is the starting address. For device + * drivers, this is the address of the initialization function. An + * entry point is optional for DLLs. When no entry point is present, + * this field must be zero. */ uint32_t AddressOfEntryPoint; + /* + * [Relative Virtual Address] The address that is relative to the + * image base of the beginning-of-code section when it is loaded into + * memory. + */ uint32_t BaseOfCode; /* - * The preferred address of the first byte of image when loaded into - * memory; must be a multiple of 64 K. The default for DLLs is - * 0x10000000. The default for Windows CE EXEs is 0x00010000. The - * default for Windows NT, Windows 2000, Windows XP, Windows 95, - * Windows 98, and Windows Me is 0x00400000. + * [Virtual Address] The preferred address of the first byte + * of image when loaded into memory; must be a multiple of 64 K. The + * default for DLLs is 0x10000000. The default for Windows CE EXEs is + * 0x00010000. The default for Windows NT, Windows 2000, Windows XP, + * Windows 95, Windows 98, and Windows Me is 0x00400000. */ uint64_t ImageBase; @@ -53,8 +75,8 @@ struct NtImageOptionalHeader { /* * The alignment factor (in bytes) that is used to align the raw data - * of sections in the image file. The value should be a power of 2 - * between 512 and 64 K, inclusive. The default is 512. If the + * of sections in the image file. The value should be a power of two + * between 512 and 64K, inclusive. The default is 512. If the * SectionAlignment is less than the architecture's page size, then * FileAlignment must match SectionAlignment. */ @@ -69,23 +91,47 @@ struct NtImageOptionalHeader { uint32_t Win32VersionValue; /* - * The size (in bytes) of the image, including all headers, as the - * image is loaded in memory. It must be a multiple of + * [Virtual Size] The size (in bytes) of the image, including all + * headers, as the image is loaded in memory. It must be a multiple of * SectionAlignment. */ uint32_t SizeOfImage; /* - * The combined size of an MS-DOS stub, PE header, and section headers - * rounded up to a multiple of FileAlignment. + * [File Size] The combined size of an MS-DOS stub, PE header, and + * section headers rounded up to a multiple of FileAlignment. */ uint32_t SizeOfHeaders; uint32_t CheckSum; uint16_t Subsystem; uint16_t DllCharacteristics; + + /* + * The size of the stack to reserve. Only SizeOfStackCommit is + * committed; the rest is made available one page at a time until the + * reserve size is reached. + * + * At program startup, this number will contribute directly to an + * increase in the virtual size of the process. However it will only + * marginally increase the the number of private bytes (rss) owned by + * the process, by the amount of page table memory that was needed. + * + * While your program runs, reserve stack memory will trigger page + * faults so it can be allocated on an as-needed basis. + */ uint64_t SizeOfStackReserve; + + /* + * The size of the stack to commit. + * + * This value will directly contribute to an increase of both your + * program's virtual size and its private bytes (rss). It might be + * useful for micro-optimizing away page faults, if definite stack + * requirements are known ahead of time. + */ uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; uint64_t SizeOfHeapCommit; uint32_t LoaderFlags; diff --git a/libc/nt/struct/imagesectionheader.internal.h b/libc/nt/struct/imagesectionheader.internal.h index 7da391fac..632232e8e 100644 --- a/libc/nt/struct/imagesectionheader.internal.h +++ b/libc/nt/struct/imagesectionheader.internal.h @@ -4,7 +4,7 @@ struct NtImageSectionHeader { - uint8_t Name[8]; + char Name[8]; union {