core/debug/pe
debug_pe
Types
24COFF_Symbol
COFF_Symbol :: struct {
name: [8]u8,
value: u32le,
section_number: i16le,
type: IMAGE_SYM_TYPE,
storage_class: IMAGE_SYM_CLASS,
number_of_aux_symbols: u8,
}SourceCOFF_Symbol_Aux_Format5
COFF_Symbol_Aux_Format5 :: struct {
size: u32le,
num_relocs: u16le,
num_line_numbers: u16le,
checksum: u32le,
sec_num: u16le,
selection: IMAGE_COMDAT_SELECT,
_: [3]u8,
}SourceCOFF_Symbol_Aux_Format5 describes the expected form of an aux symbol attached to a section definition symbol. The PE format defines a number of different aux symbol formats: format 1 for function definitions, format 2 for .be and .ef symbols, and so on. Format 5 holds extra info associated with a section definition, including number of relocations + line numbers, as well as COMDAT info. See https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-5-section-definitions for more on what's going on here.
Data_Directory
Data_Directory :: struct #packed {
virtual_address: u32le,
size: u32le,
}SourceDebug_Directory_Entry
Debug_Directory_Entry :: struct {
characteristics: u32le,
time_date_stamp: u32le,
major_version: u16le,
minor_version: u16le,
type: IMAGE_DEBUG_TYPE,
size_of_data: u32le,
address_of_raw_data: u32le,
pointer_to_raw_data: u32le,
}Source.debug section
File_Header
File_Header :: struct #packed {
machine: IMAGE_FILE_MACHINE,
number_of_sections: u16le,
time_date_stamp: u32le,
pointer_to_symbol_table: u32le,
number_of_symbols: u32le,
size_of_optional_header: u16le,
characteristics: IMAGE_FILE_CHARACTERISTICS,
}SourceIMAGE_COMDAT_SELECT
IMAGE_COMDAT_SELECT :: enum u8 {
NODUPLICATES = 1,
ANY = 2,
SAME_SIZE = 3,
EXACT_MATCH = 4,
ASSOCIATIVE = 5,
LARGEST = 6,
}SourceIMAGE_DEBUG_TYPE
IMAGE_DEBUG_TYPE :: enum u32le {
UNKNOWN = 0, // An unknown value that is ignored by all tools.
COFF = 1, // The COFF debug information (line numbers, symbol table, and string table). This type of debug information is also pointed to by fields in the file headers.
CODEVIEW = 2, // The Visual C++ debug information.
FPO = 3, // The frame pointer omission (FPO) information. This information tells the debugger how to interpret nonstandard stack frames, which use the EBP register for a purpose other than as a frame pointer.
MISC = 4, // The location of DBG file.
EXCEPTION = 5, // A copy of .pdata section.
FIXUP = 6, // Reserved.
OMAP_TO_SRC = 7, // The mapping from an RVA in image to an RVA in source image.
OMAP_FROM_SRC = 8, // The mapping from an RVA in source image to an RVA in image.
BORLAND = 9, // Reserved for Borland.
RESERVED10 = 10, // Reserved.
CLSID = 11, // Reserved.
REPRO = 16, // PE determinism or reproducibility.
EX_DLLCHARACTERISTICS = 20, // Extended DLL characteristics bits.
}SourceIMAGE_DIRECTORY_ENTRY
IMAGE_DIRECTORY_ENTRY :: enum u8 {
EXPORT = 0,
IMPORT = 1,
RESOURCE = 2,
EXCEPTION = 3,
SECURITY = 4,
BASERELOC = 5,
DEBUG = 6,
ARCHITECTURE = 7, // reserved
GLOBALPTR = 8,
TLS = 9,
LOAD_CONFIG = 10,
BOUND_IMPORT = 11,
IAT = 12,
DELAY_IMPORT = 13,
COM_DESCRIPTOR = 14, // DLR Runtime headers
_RESERVED = 15,
}SourceIMAGE_DIRECTORY_ENTRY constants
IMAGE_DLLCHARACTERISTIC
IMAGE_DLLCHARACTERISTIC :: enum u16le {
HIGH_ENTROPY_VA = 5,
DYNAMIC_BASE = 6,
FORCE_INTEGRITY = 7,
NX_COMPAT = 8,
NO_ISOLATION = 9,
NO_SEH = 10,
NO_BIND = 11,
APPCONTAINER = 12,
WDM_DRIVER = 13,
GUARD_CF = 14,
TERMINAL_SERVER_AWARE = 15,
}SourceIMAGE_DLLCHARACTERISTICS
IMAGE_DLLCHARACTERISTICS :: bit_set[IMAGE_DLLCHARACTERISTIC; u16le]SourceIMAGE_FILE_CHARACTERISTIC
IMAGE_FILE_CHARACTERISTIC :: enum u16le {
RELOCS_STRIPPED = 0,
EXECUTABLE_IMAGE = 1,
LINE_NUMS_STRIPPED = 2,
LOCAL_SYMS_STRIPPED = 3,
AGGRESIVE_WS_TRIM = 4,
LARGE_ADDRESS_AWARE = 5,
BYTES_REVERSED_LO = 7,
MACHINE_32BIT = 8, // IMAGE_FILE_32BIT_MACHINE originally
DEBUG_STRIPPED = 9,
REMOVABLE_RUN_FROM_SWAP = 10,
NET_RUN_FROM_SWAP = 11,
SYSTEM = 12,
DLL = 13,
UP_SYSTEM_ONLY = 14,
BYTES_REVERSED_HI = 15,
}SourceIMAGE_FILE_CHARACTERISTICS
IMAGE_FILE_CHARACTERISTICS :: bit_set[IMAGE_FILE_CHARACTERISTIC; u16le]SourceIMAGE_FILE_MACHINE
IMAGE_FILE_MACHINE :: enum u16le {
UNKNOWN = 0,
AM33 = 467,
AMD64 = 34404,
ARM = 448,
ARMNT = 452,
ARM64 = 43620,
EBC = 3772,
I386 = 332,
IA64 = 512,
LOONGARCH32 = 25138,
LOONGARCH64 = 25188,
M32R = 36929,
MIPS16 = 614,
MIPSFPU = 870,
MIPSFPU16 = 1126,
POWERPC = 496,
POWERPCFP = 497,
R4000 = 358,
SH3 = 418,
SH3DSP = 419,
SH4 = 422,
SH5 = 424,
THUMB = 450,
WCEMIPSV2 = 361,
}SourceIMAGE_REL
IMAGE_REL :: enum u16le {
I386_ABSOLUTE = 0,
I386_DIR16 = 1,
I386_REL16 = 2,
I386_DIR32 = 6,
I386_DIR32NB = 7,
I386_SEG12 = 9,
I386_SECTION = 10,
I386_SECREL = 11,
I386_TOKEN = 12,
I386_SECREL7 = 13,
I386_REL32 = 20,
AMD64_ABSOLUTE = 0,
AMD64_ADDR64 = 1,
AMD64_ADDR32 = 2,
AMD64_ADDR32NB = 3,
AMD64_REL32 = 4,
AMD64_REL32_1 = 5,
AMD64_REL32_2 = 6,
AMD64_REL32_3 = 7,
AMD64_REL32_4 = 8,
AMD64_REL32_5 = 9,
AMD64_SECTION = 10,
AMD64_SECREL = 11,
AMD64_SECREL7 = 12,
AMD64_TOKEN = 13,
AMD64_SREL32 = 14,
AMD64_PAIR = 15,
AMD64_SSPAN32 = 16,
ARM_ABSOLUTE = 0,
ARM_ADDR32 = 1,
ARM_ADDR32NB = 2,
ARM_BRANCH24 = 3,
ARM_BRANCH11 = 4,
ARM_SECTION = 14,
ARM_SECREL = 15,
ARM_MOV32 = 16,
THUMB_MOV32 = 17,
THUMB_BRANCH20 = 18,
THUMB_BRANCH24 = 20,
THUMB_BLX23 = 21,
ARM_PAIR = 22,
ARM64_ABSOLUTE = 0,
ARM64_ADDR32 = 1,
ARM64_ADDR32NB = 2,
ARM64_BRANCH26 = 3,
ARM64_PAGEBASE_REL21 = 4,
ARM64_REL21 = 5,
ARM64_PAGEOFFSET_12A = 6,
ARM64_PAGEOFFSET_12L = 7,
ARM64_SECREL = 8,
ARM64_SECREL_LOW12A = 9,
ARM64_SECREL_HIGH12A = 10,
ARM64_SECREL_LOW12L = 11,
ARM64_TOKEN = 12,
ARM64_SECTION = 13,
ARM64_ADDR64 = 14,
ARM64_BRANCH19 = 15,
ARM64_BRANCH14 = 16,
ARM64_REL32 = 17,
}SourceIMAGE_SCN_CHARACTERISTICS
IMAGE_SCN_CHARACTERISTICS :: enum u32le {
TYPE_NO_PAD = 8, // The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. = 0x00000010, // Reserved for future use.
CNT_CODE = 32, // The section contains executable code.
CNT_INITIALIZED_DATA = 64, // The section contains initialized data.
CNT_UNINITIALIZED_DATA = 128, // The section contains uninitialized data.
LNK_OTHER = 256, // Reserved for future use.
LNK_INFO = 512, // The section contains comments or other information. The .drectve section has this type. This is valid for object files only. = 0x00000400, // Reserved for future use.
LNK_REMOVE = 2048, // The section will not become part of the image. This is valid only for object files.
LNK_COMDAT = 4096, // The section contains COMDAT data. For more information, see COMDAT Sections (Object Only). This is valid only for object files.
GPREL = 32768, // The section contains data referenced through the global pointer (GP).
MEM_PURGEABLE = 131072, // Reserved for future use.
MEM_16BIT = 131072, // Reserved for future use.
MEM_LOCKED = 262144, // Reserved for future use.
MEM_PRELOAD = 524288, // Reserved for future use.
ALIGN_1BYTES = 1048576, // Align data on a 1-byte boundary. Valid only for object files.
ALIGN_2BYTES = 2097152, // Align data on a 2-byte boundary. Valid only for object files.
ALIGN_4BYTES = 3145728, // Align data on a 4-byte boundary. Valid only for object files.
ALIGN_8BYTES = 4194304, // Align data on an 8-byte boundary. Valid only for object files.
ALIGN_16BYTES = 5242880, // Align data on a 16-byte boundary. Valid only for object files.
ALIGN_32BYTES = 6291456, // Align data on a 32-byte boundary. Valid only for object files.
ALIGN_64BYTES = 7340032, // Align data on a 64-byte boundary. Valid only for object files.
ALIGN_128BYTES = 8388608, // Align data on a 128-byte boundary. Valid only for object files.
ALIGN_256BYTES = 9437184, // Align data on a 256-byte boundary. Valid only for object files.
ALIGN_512BYTES = 10485760, // Align data on a 512-byte boundary. Valid only for object files.
ALIGN_1024BYTES = 11534336, // Align data on a 1024-byte boundary. Valid only for object files.
ALIGN_2048BYTES = 12582912, // Align data on a 2048-byte boundary. Valid only for object files.
ALIGN_4096BYTES = 13631488, // Align data on a 4096-byte boundary. Valid only for object files.
ALIGN_8192BYTES = 14680064, // Align data on an 8192-byte boundary. Valid only for object files.
LNK_NRELOC_OVFL = 16777216, // The section contains extended relocations.
MEM_DISCARDABLE = 33554432, // The section can be discarded as needed.
MEM_NOT_CACHED = 67108864, // The section cannot be cached.
MEM_NOT_PAGED = 134217728, // The section is not pageable.
MEM_SHARED = 268435456, // The section can be shared in memory.
MEM_EXECUTE = 536870912, // The section can be executed as code.
MEM_READ = 1073741824, // The section can be read.
MEM_WRITE = 2147483648, // The section can be written to.
}SourceIMAGE_SUBSYSTEM
IMAGE_SUBSYSTEM :: enum u16le {
UNKNOWN = 0,
NATIVE = 1,
WINDOWS_GUI = 2,
WINDOWS_CUI = 3,
OS2_CUI = 5,
POSIX_CUI = 7,
NATIVE_WINDOWS = 8,
WINDOWS_CE_GUI = 9,
EFI_APPLICATION = 10,
EFI_BOOT_SERVICE_DRIVER = 11,
EFI_RUNTIME_DRIVER = 12,
EFI_ROM = 13,
XBOX = 14,
WINDOWS_BOOT_APPLICATION = 16,
}SourceIMAGE_SYM_CLASS
IMAGE_SYM_CLASS :: enum u8 {
NULL = 0,
AUTOMATIC = 1,
EXTERNAL = 2,
STATIC = 3,
REGISTER = 4,
EXTERNAL_DEF = 5,
LABEL = 6,
UNDEFINED_LABEL = 7,
MEMBER_OF_STRUCT = 8,
ARGUMENT = 9,
STRUCT_TAG = 10,
MEMBER_OF_UNION = 11,
UNION_TAG = 12,
TYPE_DEFINITION = 13,
UNDEFINED_STATIC = 14,
ENUM_TAG = 15,
MEMBER_OF_ENUM = 16,
REGISTER_PARAM = 17,
BIT_FIELD = 18,
FAR_EXTERNAL = 68, // Not in PECOFF v8 spec
BLOCK = 100,
FUNCTION = 101,
END_OF_STRUCT = 102,
FILE = 103,
SECTION = 104,
WEAK_EXTERNAL = 105,
CLR_TOKEN = 107,
END_OF_FUNCTION = 255,
}SourceIMAGE_SYM_TYPE
IMAGE_SYM_TYPE :: enum u16le {
NULL = 0,
VOID = 1,
CHAR = 2,
SHORT = 3,
INT = 4,
LONG = 5,
FLOAT = 6,
DOUBLE = 7,
STRUCT = 8,
UNION = 9,
ENUM = 10,
MOE = 11,
BYTE = 12,
WORD = 13,
UINT = 14,
DWORD = 15,
PCODE = 32768,
DTYPE_NULL = 0,
DTYPE_POINTER = 16,
DTYPE_FUNCTION = 32,
DTYPE_ARRAY = 48,
}SourceOPTIONAL_HEADER_MAGIC
OPTIONAL_HEADER_MAGIC :: enum u16le {
PE32 = 267,
PE32_PLUS = 523,
}SourceOptional_Header32
Optional_Header32 :: struct #packed {
base: Optional_Header_Base,
base_of_data: u32le,
image_base: u32le,
section_alignment: u32le,
file_alignment: u32le,
major_operating_system_version: u16le,
minor_operating_system_version: u16le,
major_image_version: u16le,
minor_image_version: u16le,
major_subsystem_version: u16le,
minor_subsystem_version: u16le,
win32_version_value: u32le,
size_of_image: u32le,
size_of_headers: u32le,
check_sum: u32le,
subsystem: IMAGE_SUBSYSTEM,
dll_characteristics: IMAGE_DLLCHARACTERISTICS,
size_of_stack_reserve: u32le,
size_of_stack_commit: u32le,
size_of_heap_reserve: u32le,
size_of_heap_commit: u32le,
loader_flags: u32le,
number_of_rva_and_sizes: u32le,
data_directory: [16]Data_Directory,
}SourceOptional_Header64
Optional_Header64 :: struct #packed {
base: Optional_Header_Base,
image_base: u64le,
section_alignment: u32le,
file_alignment: u32le,
major_operating_system_version: u16le,
minor_operating_system_version: u16le,
major_image_version: u16le,
minor_image_version: u16le,
major_subsystem_version: u16le,
minor_subsystem_version: u16le,
win32_version_value: u32le,
size_of_image: u32le,
size_of_headers: u32le,
check_sum: u32le,
subsystem: IMAGE_SUBSYSTEM,
dll_characteristics: IMAGE_DLLCHARACTERISTICS,
size_of_stack_reserve: u64le,
size_of_stack_commit: u64le,
size_of_heap_reserve: u64le,
size_of_heap_commit: u64le,
loader_flags: u32le,
number_of_rva_and_sizes: u32le,
data_directory: [16]Data_Directory,
}SourceOptional_Header_Base
Optional_Header_Base :: struct #packed {
magic: OPTIONAL_HEADER_MAGIC,
major_linker_version: u8,
minor_linker_version: u8,
size_of_code: u32le,
size_of_initialized_data: u32le,
size_of_uninitialized_data: u32le,
address_of_entry_point: u32le,
base_of_code: u32le,
}SourceReloc
Reloc :: struct {
virtual_address: u32le,
symbol_table_index: u32le,
type: IMAGE_REL,
}SourceSection_Header32
Section_Header32 :: struct {
name: [8]u8,
virtual_size: u32le,
virtual_address: u32le,
size_of_raw_data: u32le,
pointer_to_raw_data: u32le,
pointer_to_relocations: u32le,
pointer_to_line_numbers: u32le,
number_of_relocations: u16le,
number_of_line_numbers: u16le,
characteristics: IMAGE_SCN_CHARACTERISTICS,
}SourceConstants
8COFF_SYMBOL_SIZE
COFF_SYMBOL_SIZE :: 18SourceIMAGE_SYM_ABSOLUTE
IMAGE_SYM_ABSOLUTE :: -1SourceThe symbol has an absolute (non-relocatable) value and is not an address.
IMAGE_SYM_DEBUG
IMAGE_SYM_DEBUG :: -2SourceThe symbol provides general type or debugging information but does not correspond to a section. Microsoft tools use this setting along with .file records (storage class FILE).
IMAGE_SYM_UNDEFINED
IMAGE_SYM_UNDEFINED :: 0SourceThe symbol record is not yet assigned a section. A value of zero indicates that a reference to an external symbol is defined elsewhere. A value of non-zero is a common symbol with a size that is specified by the value.
PE_CODE_VIEW_SIGNATURE_RSDS
PE_CODE_VIEW_SIGNATURE_RSDS :: u32le = u32le(0x5344_5352)SourcePE_SIGNATURE
PE_SIGNATURE :: u32le = u32le(0x0000_4550)Source"PE\x00\x00"
PE_SIGNATURE_OFFSET_INDEX_POS
PE_SIGNATURE_OFFSET_INDEX_POS :: 0x3cSourcePE_SIGNATURE_STRING
PE_SIGNATURE_STRING :: "PE\x00\x00"Source