vaseboot/include/VasEBoot/efi/pe32.h

355 lines
12 KiB
C

/*
* VAS_EBOOT -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
*
* VAS_EBOOT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VAS_EBOOT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VAS_EBOOT_EFI_PE32_HEADER
#define VAS_EBOOT_EFI_PE32_HEADER 1
#include <VasEBoot/types.h>
#include <VasEBoot/efi/memory.h>
/* The MSDOS compatibility stub. This was copied from the output of
objcopy, and it is not necessary to care about what this means. */
#define VAS_EBOOT_PE32_MSDOS_STUB \
{ \
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
}
#define VAS_EBOOT_PE32_MSDOS_STUB_SIZE 0x80
#define VAS_EBOOT_PE32_MAGIC 0x5a4d
struct VasEBoot_msdos_image_header
{
/* This is always 'MZ'. (VAS_EBOOT_PE32_MAGIC) */
VasEBoot_uint16_t msdos_magic;
VasEBoot_uint16_t reserved[29];
/* The file offset of the PE image header. */
VasEBoot_uint32_t pe_image_header_offset;
};
/* According to the spec, the minimal alignment is 512 bytes...
But some examples (such as EFI drivers in the Intel
Sample Implementation) use 32 bytes (0x20) instead, and it seems
to be working.
However, there is firmware showing up in the field now with
page alignment constraints to guarantee that page protection
bits take effect. Because currently existing VAS_EBOOT code can not
properly distinguish between in-memory and in-file layout, let's
bump all alignment to VAS_EBOOT_EFI_PAGE_SIZE. */
#define VAS_EBOOT_PE32_SECTION_ALIGNMENT VAS_EBOOT_EFI_PAGE_SIZE
#define VAS_EBOOT_PE32_FILE_ALIGNMENT VAS_EBOOT_PE32_SECTION_ALIGNMENT
struct VasEBoot_pe32_coff_header
{
VasEBoot_uint16_t machine;
VasEBoot_uint16_t num_sections;
VasEBoot_uint32_t time;
VasEBoot_uint32_t symtab_offset;
VasEBoot_uint32_t num_symbols;
VasEBoot_uint16_t optional_header_size;
VasEBoot_uint16_t characteristics;
};
#define VAS_EBOOT_PE32_MACHINE_I386 0x14c
#define VAS_EBOOT_PE32_MACHINE_IA64 0x200
#define VAS_EBOOT_PE32_MACHINE_X86_64 0x8664
#define VAS_EBOOT_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2
#define VAS_EBOOT_PE32_MACHINE_ARM64 0xAA64
#define VAS_EBOOT_PE32_MACHINE_LOONGARCH32 0x6232
#define VAS_EBOOT_PE32_MACHINE_LOONGARCH64 0x6264
#define VAS_EBOOT_PE32_MACHINE_RISCV32 0x5032
#define VAS_EBOOT_PE32_MACHINE_RISCV64 0x5064
#define VAS_EBOOT_PE32_RELOCS_STRIPPED 0x0001
#define VAS_EBOOT_PE32_EXECUTABLE_IMAGE 0x0002
#define VAS_EBOOT_PE32_LINE_NUMS_STRIPPED 0x0004
#define VAS_EBOOT_PE32_LOCAL_SYMS_STRIPPED 0x0008
#define VAS_EBOOT_PE32_AGGRESSIVE_WS_TRIM 0x0010
#define VAS_EBOOT_PE32_LARGE_ADDRESS_AWARE 0x0020
#define VAS_EBOOT_PE32_16BIT_MACHINE 0x0040
#define VAS_EBOOT_PE32_BYTES_REVERSED_LO 0x0080
#define VAS_EBOOT_PE32_32BIT_MACHINE 0x0100
#define VAS_EBOOT_PE32_DEBUG_STRIPPED 0x0200
#define VAS_EBOOT_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400
#define VAS_EBOOT_PE32_SYSTEM 0x1000
#define VAS_EBOOT_PE32_DLL 0x2000
#define VAS_EBOOT_PE32_UP_SYSTEM_ONLY 0x4000
#define VAS_EBOOT_PE32_BYTES_REVERSED_HI 0x8000
struct VasEBoot_pe32_data_directory
{
VasEBoot_uint32_t rva;
VasEBoot_uint32_t size;
};
struct VasEBoot_pe32_optional_header
{
VasEBoot_uint16_t magic;
VasEBoot_uint8_t major_linker_version;
VasEBoot_uint8_t minor_linker_version;
VasEBoot_uint32_t code_size;
VasEBoot_uint32_t data_size;
VasEBoot_uint32_t bss_size;
VasEBoot_uint32_t entry_addr;
VasEBoot_uint32_t code_base;
VasEBoot_uint32_t data_base;
VasEBoot_uint32_t image_base;
VasEBoot_uint32_t section_alignment;
VasEBoot_uint32_t file_alignment;
VasEBoot_uint16_t major_os_version;
VasEBoot_uint16_t minor_os_version;
VasEBoot_uint16_t major_image_version;
VasEBoot_uint16_t minor_image_version;
VasEBoot_uint16_t major_subsystem_version;
VasEBoot_uint16_t minor_subsystem_version;
VasEBoot_uint32_t reserved;
VasEBoot_uint32_t image_size;
VasEBoot_uint32_t header_size;
VasEBoot_uint32_t checksum;
VasEBoot_uint16_t subsystem;
VasEBoot_uint16_t dll_characteristics;
VasEBoot_uint32_t stack_reserve_size;
VasEBoot_uint32_t stack_commit_size;
VasEBoot_uint32_t heap_reserve_size;
VasEBoot_uint32_t heap_commit_size;
VasEBoot_uint32_t loader_flags;
VasEBoot_uint32_t num_data_directories;
/* Data directories. */
struct VasEBoot_pe32_data_directory export_table;
struct VasEBoot_pe32_data_directory import_table;
struct VasEBoot_pe32_data_directory resource_table;
struct VasEBoot_pe32_data_directory exception_table;
struct VasEBoot_pe32_data_directory certificate_table;
struct VasEBoot_pe32_data_directory base_relocation_table;
struct VasEBoot_pe32_data_directory debug;
struct VasEBoot_pe32_data_directory architecture;
struct VasEBoot_pe32_data_directory global_ptr;
struct VasEBoot_pe32_data_directory tls_table;
struct VasEBoot_pe32_data_directory load_config_table;
struct VasEBoot_pe32_data_directory bound_import;
struct VasEBoot_pe32_data_directory iat;
struct VasEBoot_pe32_data_directory delay_import_descriptor;
struct VasEBoot_pe32_data_directory com_runtime_header;
struct VasEBoot_pe32_data_directory reserved_entry;
};
struct VasEBoot_pe64_optional_header
{
VasEBoot_uint16_t magic;
VasEBoot_uint8_t major_linker_version;
VasEBoot_uint8_t minor_linker_version;
VasEBoot_uint32_t code_size;
VasEBoot_uint32_t data_size;
VasEBoot_uint32_t bss_size;
VasEBoot_uint32_t entry_addr;
VasEBoot_uint32_t code_base;
VasEBoot_uint64_t image_base;
VasEBoot_uint32_t section_alignment;
VasEBoot_uint32_t file_alignment;
VasEBoot_uint16_t major_os_version;
VasEBoot_uint16_t minor_os_version;
VasEBoot_uint16_t major_image_version;
VasEBoot_uint16_t minor_image_version;
VasEBoot_uint16_t major_subsystem_version;
VasEBoot_uint16_t minor_subsystem_version;
VasEBoot_uint32_t reserved;
VasEBoot_uint32_t image_size;
VasEBoot_uint32_t header_size;
VasEBoot_uint32_t checksum;
VasEBoot_uint16_t subsystem;
VasEBoot_uint16_t dll_characteristics;
VasEBoot_uint64_t stack_reserve_size;
VasEBoot_uint64_t stack_commit_size;
VasEBoot_uint64_t heap_reserve_size;
VasEBoot_uint64_t heap_commit_size;
VasEBoot_uint32_t loader_flags;
VasEBoot_uint32_t num_data_directories;
/* Data directories. */
struct VasEBoot_pe32_data_directory export_table;
struct VasEBoot_pe32_data_directory import_table;
struct VasEBoot_pe32_data_directory resource_table;
struct VasEBoot_pe32_data_directory exception_table;
struct VasEBoot_pe32_data_directory certificate_table;
struct VasEBoot_pe32_data_directory base_relocation_table;
struct VasEBoot_pe32_data_directory debug;
struct VasEBoot_pe32_data_directory architecture;
struct VasEBoot_pe32_data_directory global_ptr;
struct VasEBoot_pe32_data_directory tls_table;
struct VasEBoot_pe32_data_directory load_config_table;
struct VasEBoot_pe32_data_directory bound_import;
struct VasEBoot_pe32_data_directory iat;
struct VasEBoot_pe32_data_directory delay_import_descriptor;
struct VasEBoot_pe32_data_directory com_runtime_header;
struct VasEBoot_pe32_data_directory reserved_entry;
};
#define VAS_EBOOT_PE32_PE32_MAGIC 0x10b
#define VAS_EBOOT_PE32_PE64_MAGIC 0x20b
#define VAS_EBOOT_PE32_SUBSYSTEM_EFI_APPLICATION 10
#define VAS_EBOOT_PE32_NX_COMPAT 0x0100
#define VAS_EBOOT_PE32_NUM_DATA_DIRECTORIES 16
struct VasEBoot_pe32_section_table
{
char name[8];
VasEBoot_uint32_t virtual_size;
VasEBoot_uint32_t virtual_address;
VasEBoot_uint32_t raw_data_size;
VasEBoot_uint32_t raw_data_offset;
VasEBoot_uint32_t relocations_offset;
VasEBoot_uint32_t line_numbers_offset;
VasEBoot_uint16_t num_relocations;
VasEBoot_uint16_t num_line_numbers;
VasEBoot_uint32_t characteristics;
};
#define VAS_EBOOT_PE32_SCN_CNT_CODE 0x00000020
#define VAS_EBOOT_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040
#define VAS_EBOOT_PE32_SCN_MEM_DISCARDABLE 0x02000000
#define VAS_EBOOT_PE32_SCN_MEM_EXECUTE 0x20000000
#define VAS_EBOOT_PE32_SCN_MEM_READ 0x40000000
#define VAS_EBOOT_PE32_SCN_MEM_WRITE 0x80000000
#define VAS_EBOOT_PE32_SCN_ALIGN_1BYTES 0x00100000
#define VAS_EBOOT_PE32_SCN_ALIGN_2BYTES 0x00200000
#define VAS_EBOOT_PE32_SCN_ALIGN_4BYTES 0x00300000
#define VAS_EBOOT_PE32_SCN_ALIGN_8BYTES 0x00400000
#define VAS_EBOOT_PE32_SCN_ALIGN_16BYTES 0x00500000
#define VAS_EBOOT_PE32_SCN_ALIGN_32BYTES 0x00600000
#define VAS_EBOOT_PE32_SCN_ALIGN_64BYTES 0x00700000
#define VAS_EBOOT_PE32_SCN_ALIGN_SHIFT 20
#define VAS_EBOOT_PE32_SCN_ALIGN_MASK 7
#define VAS_EBOOT_PE32_SIGNATURE_SIZE 4
#if VAS_EBOOT_TARGET_SIZEOF_VOID_P == 8
#define VAS_EBOOT_PE32_NATIVE_MAGIC VAS_EBOOT_PE32_PE64_MAGIC
#else
#define VAS_EBOOT_PE32_NATIVE_MAGIC VAS_EBOOT_PE32_PE32_MAGIC
#endif
struct VasEBoot_pe_image_header
{
/* This is always PE\0\0. */
char signature[VAS_EBOOT_PE32_SIGNATURE_SIZE];
/* The COFF file header. */
struct VasEBoot_pe32_coff_header coff_header;
#if VAS_EBOOT_TARGET_SIZEOF_VOID_P == 8
/* The Optional header. */
struct VasEBoot_pe64_optional_header optional_header;
#else
/* The Optional header. */
struct VasEBoot_pe32_optional_header optional_header;
#endif
};
struct VasEBoot_pe32_fixup_block
{
VasEBoot_uint32_t page_rva;
VasEBoot_uint32_t block_size;
VasEBoot_uint16_t entries[0];
};
#define VAS_EBOOT_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset))
#define VAS_EBOOT_PE32_REL_BASED_ABSOLUTE 0
#define VAS_EBOOT_PE32_REL_BASED_HIGH 1
#define VAS_EBOOT_PE32_REL_BASED_LOW 2
#define VAS_EBOOT_PE32_REL_BASED_HIGHLOW 3
#define VAS_EBOOT_PE32_REL_BASED_HIGHADJ 4
#define VAS_EBOOT_PE32_REL_BASED_MIPS_JMPADDR 5
#define VAS_EBOOT_PE32_REL_BASED_ARM_MOV32A 5
#define VAS_EBOOT_PE32_REL_BASED_RISCV_HI20 5
#define VAS_EBOOT_PE32_REL_BASED_SECTION 6
#define VAS_EBOOT_PE32_REL_BASED_REL 7
#define VAS_EBOOT_PE32_REL_BASED_ARM_MOV32T 7
#define VAS_EBOOT_PE32_REL_BASED_RISCV_LOW12I 7
#define VAS_EBOOT_PE32_REL_BASED_RISCV_LOW12S 8
#define VAS_EBOOT_PE32_REL_BASED_LOONGARCH32_MARK_LA 8
#define VAS_EBOOT_PE32_REL_BASED_LOONGARCH64_MARK_LA 8
#define VAS_EBOOT_PE32_REL_BASED_IA64_IMM64 9
#define VAS_EBOOT_PE32_REL_BASED_DIR64 10
#define VAS_EBOOT_PE32_REL_BASED_HIGH3ADJ 11
struct VasEBoot_pe32_symbol
{
union
{
char short_name[8];
VasEBoot_uint32_t long_name[2];
};
VasEBoot_uint32_t value;
VasEBoot_uint16_t section;
VasEBoot_uint16_t type;
VasEBoot_uint8_t storage_class;
VasEBoot_uint8_t num_aux;
} VAS_EBOOT_PACKED;
#define VAS_EBOOT_PE32_SYM_CLASS_EXTERNAL 2
#define VAS_EBOOT_PE32_SYM_CLASS_STATIC 3
#define VAS_EBOOT_PE32_SYM_CLASS_FILE 0x67
#define VAS_EBOOT_PE32_DT_FUNCTION 0x20
struct VasEBoot_pe32_reloc
{
VasEBoot_uint32_t offset;
VasEBoot_uint32_t symtab_index;
VasEBoot_uint16_t type;
} VAS_EBOOT_PACKED;
#define VAS_EBOOT_PE32_REL_I386_DIR32 0x6
#define VAS_EBOOT_PE32_REL_I386_REL32 0x14
#endif /* ! VAS_EBOOT_EFI_PE32_HEADER */