Files
zinnia/boot/efi/pe.h
T

165 lines
4.2 KiB
C++

// SPDX-License-Identifier: ISC
#pragma once
#include <stddef.h>
#include <stdint.h>
constexpr uint16_t PE_DOS_MAGIC = 0x5a4d;
constexpr uint32_t PE_SIGNATURE = 0x0000'4550;
constexpr uint16_t PE_OPTIONAL_MAGIC_PE32_PLUS = 0x020b;
constexpr uint16_t PE_SUBSYSTEM_EFI_APPLICATION = 10;
constexpr size_t PE_NUM_DATA_DIRECTORIES = 16;
constexpr size_t PE_DIRECTORY_BASE_RELOC = 5;
enum pe_file_characteristics : uint16_t {
PE_FILE_EXECUTABLE_IMAGE = 0x0002,
PE_FILE_LINE_NUMS_STRIPPED = 0x0004,
PE_FILE_DEBUG_STRIPPED = 0x0200,
};
enum pe_dll_characteristics : uint16_t {
PE_DLL_NX_COMPAT = 0x0100,
};
enum pe_section_characteristics : uint32_t {
PE_SCN_CNT_CODE = 0x0000'0020,
PE_SCN_CNT_INITIALIZED_DATA = 0x0000'0040,
PE_SCN_MEM_DISCARDABLE = 0x0200'0000,
PE_SCN_MEM_EXECUTE = 0x2000'0000,
PE_SCN_MEM_READ = 0x4000'0000,
PE_SCN_MEM_WRITE = 0x8000'0000,
};
struct pe_dos_header {
uint16_t e_magic;
uint16_t e_cblp;
uint16_t e_cp;
uint16_t e_crlc;
uint16_t e_cparhdr;
uint16_t e_minalloc;
uint16_t e_maxalloc;
uint16_t e_ss;
uint16_t e_sp;
uint16_t e_csum;
uint16_t e_ip;
uint16_t e_cs;
uint16_t e_lfarlc;
uint16_t e_ovno;
uint16_t e_res[4];
uint16_t e_oemid;
uint16_t e_oeminfo;
uint16_t e_res2[10];
uint32_t e_lfanew;
};
struct pe_coff_header {
uint16_t machine;
uint16_t number_of_sections;
uint32_t time_date_stamp;
uint32_t pointer_to_symbol_table;
uint32_t number_of_symbols;
uint16_t size_of_optional_header;
uint16_t characteristics;
};
struct pe_data_directory {
union {
struct {
uint32_t virtual_address;
uint32_t size;
};
uint64_t layout;
};
};
struct pe_optional_header64 {
union {
struct {
uint16_t magic;
uint8_t major_linker_version;
uint8_t minor_linker_version;
uint32_t size_of_code;
};
uint64_t magic_and_code_size;
};
union {
struct {
uint32_t size_of_initialized_data;
uint32_t size_of_uninitialized_data;
};
uint64_t data_sizes;
};
union {
struct {
uint32_t address_of_entry_point;
uint32_t base_of_code;
};
uint64_t entry_and_code_base;
};
uint64_t image_base;
uint32_t section_alignment;
uint32_t file_alignment;
uint16_t major_operating_system_version;
uint16_t minor_operating_system_version;
uint16_t major_image_version;
uint16_t minor_image_version;
uint16_t major_subsystem_version;
uint16_t minor_subsystem_version;
uint32_t win32_version_value;
union {
struct {
uint32_t size_of_image;
uint32_t size_of_headers;
};
uint64_t image_and_header_sizes;
};
uint32_t checksum;
uint16_t subsystem;
uint16_t dll_characteristics;
uint64_t size_of_stack_reserve;
uint64_t size_of_stack_commit;
uint64_t size_of_heap_reserve;
uint64_t size_of_heap_commit;
uint32_t loader_flags;
uint32_t number_of_rva_and_sizes;
struct pe_data_directory data_directories[PE_NUM_DATA_DIRECTORIES];
};
struct pe_section_header {
char name[8];
union {
struct {
uint32_t virtual_size;
uint32_t virtual_address;
};
uint64_t virtual_layout;
};
union {
struct {
uint32_t size_of_raw_data;
uint32_t pointer_to_raw_data;
};
uint64_t raw_layout;
};
uint32_t pointer_to_relocations;
uint32_t pointer_to_line_numbers;
uint16_t number_of_relocations;
uint16_t number_of_line_numbers;
uint32_t characteristics;
};
struct pe_base_reloc_block {
uint32_t page_rva;
uint32_t block_size;
uint16_t entries[2];
};
static_assert(sizeof(struct pe_dos_header) == 64);
static_assert(sizeof(struct pe_coff_header) == 20);
static_assert(sizeof(struct pe_optional_header64) == 240);
static_assert(offsetof(struct pe_optional_header64, size_of_image) == 56);
static_assert(offsetof(struct pe_optional_header64, data_directories) == 112);
static_assert(sizeof(struct pe_section_header) == 40);
static_assert(sizeof(struct pe_base_reloc_block) == 12);