summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/boot/boot_info.h76
-rw-r--r--include/boot/efi.h365
-rw-r--r--include/elf/elf.h331
3 files changed, 772 insertions, 0 deletions
diff --git a/include/boot/boot_info.h b/include/boot/boot_info.h
new file mode 100644
index 0000000..cc02ae8
--- /dev/null
+++ b/include/boot/boot_info.h
@@ -0,0 +1,76 @@
+#pragma once
+// ============================================================================
+// boot_info.h - Boot handoff struct
+// Shared between the UEFI loader and the kernel.
+// The loader fills it, the kernel consumes it. Simple.
+// In future i will expand this struct
+// ============================================================================
+
+#include <stdint.h>
+
+// ── Boot Magic Number───────────────────────────────────────────────────────
+inline constexpr uint64_t BOOT_INFO_MAGIC = 0xDEADDEADDEADDEADULL;
+
+// ── Framebuffer (GOP) ───────────────────────────────────────────────────────
+// TODO: remove Framebuffer to driver
+enum class PixelFormat : uint32_t {
+ RGB = 0, // PixelRedGreenBlueReserved8BitPerColor
+ BGR = 1, // PixelBlueGreenRedReserved8BitPerColor
+ Mask = 2, // PixelBitMask — need to check masks
+};
+
+struct FramebufferInfo {
+ uint64_t base; // Physical address of framebuffer
+ uint32_t width; // Horizontal resolution in pixels
+ uint32_t height; // Vertical resolution in pixels
+ uint32_t pitch; // Bytes per scanline (>= width * 4)
+ PixelFormat format;
+};
+
+// ── Memory map ─────────────────────────────────────────────────────────────
+//TODO: remove FrameBuffer
+enum class MemoryRegionType : uint32_t {
+ Usable = 0, // Free RAM - kernel can use
+ Reserved = 1, // Firmware/hardware reserved
+ AcpiReclaimable = 2, // ACPI tables - free after parsing
+ AcpiNvs = 3, // ACPI non-volatile storage
+ BootloaderReclaimable = 4, // Loader code/data - free after kernel init
+ KernelAndModules = 5, // Kernel image + any loaded modules
+ Framebuffer = 6, // Framebuffer memory - do not use as RAM
+};
+
+struct MemoryRegion {
+ uint64_t base;
+ uint64_t length;
+ MemoryRegionType type;
+ uint32_t _reserved; // Padding to 24 bytes
+};
+
+// ── Boot info structure ────────────────────────────────────────────────────
+
+struct BootInfo {
+ uint64_t magic; // Must be BOOT_INFO_MAGIC
+
+ // Framebuffer
+ // Todo: remove
+ FramebufferInfo framebuffer;
+
+ // Memory map (array of MemoryRegion)
+ MemoryRegion* memory_map;
+ uint64_t memory_map_count;
+
+ // Platform-specific firmware tables (both always present to keep layout uniform)
+ uint64_t rsdp_address; // ACPI RSDP (x86_64), 0 if absent
+ uint64_t fdt_address; // Flattened Device Tree (aarch64), 0 if absent
+
+ // Kernel load info
+ uint64_t kernel_phys_base; // Where the kernel was loaded physically
+ uint64_t kernel_virt_base; // Kernel's virtual base (from ELF)
+ uint64_t kernel_size; // Total size of kernel in memory
+
+ // Kernel entry point (virtual address from ELF e_entry)
+ uint64_t kernel_entry_point;
+
+ // Higher-half direct map base (if set up by loader)
+ uint64_t hhdm_base; // e.g., 0xFFFF800000000000
+};
diff --git a/include/boot/efi.h b/include/boot/efi.h
new file mode 100644
index 0000000..bcb8854
--- /dev/null
+++ b/include/boot/efi.h
@@ -0,0 +1,365 @@
+#pragma once
+// ============================================================================
+// efi.h - Minimal UEFI type and protocol definitions
+//
+// Only what we need for our boot loader. No external dependencies (like gnu-efi).
+// Reference: UEFI Specification 2.10, https://uefi.org/specs/UEFI/2.10/
+// I generate it with Cloude, because i don't want to manually rewrite whole spec
+// ============================================================================
+
+#include <stdint.h>
+#include <stddef.h>
+
+// ── Base types ─────────────────────────────────────────────────────────────
+
+typedef uint64_t UINTN;
+typedef int64_t INTN;
+typedef uint64_t EFI_STATUS;
+typedef void* EFI_HANDLE;
+typedef void* EFI_EVENT;
+typedef uint64_t EFI_PHYSICAL_ADDRESS;
+typedef uint64_t EFI_VIRTUAL_ADDRESS;
+typedef wchar_t CHAR16; // With -fshort-wchar, wchar_t is 16-bit
+typedef uint8_t BOOLEAN;
+
+#define TRUE 1
+#define FALSE 0
+#define IN
+#define OUT
+#define OPTIONAL
+#define EFIAPI
+
+// ── Status codes ───────────────────────────────────────────────────────────
+
+#define EFI_SUCCESS 0ULL
+#define EFI_ERROR_BIT (1ULL << 63)
+#define EFI_LOAD_ERROR (EFI_ERROR_BIT | 1)
+#define EFI_INVALID_PARAMETER (EFI_ERROR_BIT | 2)
+#define EFI_UNSUPPORTED (EFI_ERROR_BIT | 3)
+#define EFI_BAD_BUFFER_SIZE (EFI_ERROR_BIT | 4)
+#define EFI_BUFFER_TOO_SMALL (EFI_ERROR_BIT | 5)
+#define EFI_NOT_FOUND (EFI_ERROR_BIT | 14)
+
+#define EFI_ERROR(status) ((status) & EFI_ERROR_BIT)
+
+// ── GUIDs ──────────────────────────────────────────────────────────────────
+
+struct EFI_GUID {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[8];
+};
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { 0x9042A9DE, 0x23DC, 0x4A38, { 0x96, 0xFB, 0x7A, 0xDE, 0xD0, 0x80, 0x51, 0x6A } }
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { 0x964E5B22, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } }
+
+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
+ { 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } }
+
+#define EFI_FILE_INFO_ID \
+ { 0x09576E92, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } }
+
+#define EFI_ACPI_20_TABLE_GUID \
+ { 0x8868E871, 0xE4F1, 0x11D3, { 0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 } }
+
+#define EFI_DTB_TABLE_GUID \
+ { 0xB1B621D5, 0xF19C, 0x41A5, { 0x83, 0x0B, 0xD9, 0x15, 0x2C, 0x69, 0xAA, 0xE0 } }
+
+// ── Memory types ───────────────────────────────────────────────────────────
+
+typedef uint32_t EFI_MEMORY_TYPE;
+#define EfiReservedMemoryType 0
+#define EfiLoaderCode 1
+#define EfiLoaderData 2
+#define EfiBootServicesCode 3
+#define EfiBootServicesData 4
+#define EfiRuntimeServicesCode 5
+#define EfiRuntimeServicesData 6
+#define EfiConventionalMemory 7
+#define EfiUnusableMemory 8
+#define EfiACPIReclaimMemory 9
+#define EfiACPIMemoryNVS 10
+#define EfiMemoryMappedIO 11
+#define EfiMemoryMappedIOPortSpace 12
+#define EfiPalCode 13
+#define EfiPersistentMemory 14
+#define EfiMaxMemoryType 15
+
+typedef uint32_t EFI_ALLOCATE_TYPE;
+#define AllocateAnyPages 0
+#define AllocateMaxAddress 1
+#define AllocateAddress 2
+
+struct EFI_MEMORY_DESCRIPTOR {
+ uint32_t Type;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ EFI_VIRTUAL_ADDRESS VirtualStart;
+ uint64_t NumberOfPages;
+ uint64_t Attribute;
+};
+
+// ── Simple Text Output Protocol ────────────────────────────────────────────
+
+struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+ void* Reset;
+ EFI_STATUS (EFIAPI *OutputString)(
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* This,
+ CHAR16* String
+ );
+ void* TestString;
+ void* QueryMode;
+ void* SetMode;
+ void* SetAttribute;
+ EFI_STATUS (EFIAPI *ClearScreen)(
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* This
+ );
+ void* SetCursorPosition;
+ void* EnableCursor;
+ void* Mode;
+};
+
+// ── Graphics Output Protocol ───────────────────────────────────────────────
+
+typedef uint32_t EFI_GRAPHICS_PIXEL_FORMAT;
+#define PixelRedGreenBlueReserved8BitPerColor 0
+#define PixelBlueGreenRedReserved8BitPerColor 1
+#define PixelBitMask 2
+#define PixelBltOnly 3
+
+struct EFI_PIXEL_BITMASK {
+ uint32_t RedMask;
+ uint32_t GreenMask;
+ uint32_t BlueMask;
+ uint32_t ReservedMask;
+};
+
+struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION {
+ uint32_t Version;
+ uint32_t HorizontalResolution;
+ uint32_t VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ uint32_t PixelsPerScanLine;
+};
+
+struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE {
+ uint32_t MaxMode;
+ uint32_t Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+};
+
+struct EFI_GRAPHICS_OUTPUT_PROTOCOL {
+ void* QueryMode;
+ void* SetMode;
+ void* Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode;
+};
+
+// ── File Protocol ──────────────────────────────────────────────────────────
+
+#define EFI_FILE_MODE_READ 0x0000000000000001ULL
+#define EFI_FILE_READ_ONLY 0x0000000000000001ULL
+
+struct EFI_FILE_PROTOCOL {
+ uint64_t Revision;
+ EFI_STATUS (EFIAPI *Open)(
+ EFI_FILE_PROTOCOL* This,
+ EFI_FILE_PROTOCOL** NewHandle,
+ CHAR16* FileName,
+ uint64_t OpenMode,
+ uint64_t Attributes
+ );
+ EFI_STATUS (EFIAPI *Close)(
+ EFI_FILE_PROTOCOL* This
+ );
+ void* Delete;
+ EFI_STATUS (EFIAPI *Read)(
+ EFI_FILE_PROTOCOL* This,
+ UINTN* BufferSize,
+ void* Buffer
+ );
+ void* Write;
+ void* GetPosition;
+ void* SetPosition;
+ EFI_STATUS (EFIAPI *GetInfo)(
+ EFI_FILE_PROTOCOL* This,
+ EFI_GUID* InformationType,
+ UINTN* BufferSize,
+ void* Buffer
+ );
+};
+
+struct EFI_FILE_INFO {
+ uint64_t Size;
+ uint64_t FileSize;
+ uint64_t PhysicalSize;
+ uint8_t _time_padding[48]; // Skip EFI_TIME fields
+ uint64_t Attribute;
+ CHAR16 FileName[1]; // Variable length
+};
+
+// ── Simple File System Protocol ────────────────────────────────────────────
+
+struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
+ uint64_t Revision;
+ EFI_STATUS (EFIAPI *OpenVolume)(
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* This,
+ EFI_FILE_PROTOCOL** Root
+ );
+};
+
+// ── Loaded Image Protocol ──────────────────────────────────────────────────
+
+struct EFI_LOADED_IMAGE_PROTOCOL {
+ uint32_t Revision;
+ EFI_HANDLE ParentHandle;
+ void* SystemTable;
+ EFI_HANDLE DeviceHandle;
+ void* FilePath;
+ void* Reserved;
+ uint32_t LoadOptionsSize;
+ void* LoadOptions;
+ void* ImageBase;
+ uint64_t ImageSize;
+ EFI_MEMORY_TYPE ImageCodeType;
+ EFI_MEMORY_TYPE ImageDataType;
+ void* Unload;
+};
+
+// ── Boot Services ──────────────────────────────────────────────────────────
+
+struct EFI_BOOT_SERVICES {
+ char _hdr[24];
+
+ // Task Priority (2)
+ void* RaiseTPL;
+ void* RestoreTPL;
+
+ // Memory Services
+ EFI_STATUS (EFIAPI *AllocatePages)(
+ EFI_ALLOCATE_TYPE Type,
+ EFI_MEMORY_TYPE MemoryType,
+ UINTN Pages,
+ EFI_PHYSICAL_ADDRESS* Memory
+ );
+ EFI_STATUS (EFIAPI *FreePages)(
+ EFI_PHYSICAL_ADDRESS Memory,
+ UINTN Pages
+ );
+ EFI_STATUS (EFIAPI *GetMemoryMap)(
+ UINTN* MemoryMapSize,
+ EFI_MEMORY_DESCRIPTOR* MemoryMap,
+ UINTN* MapKey,
+ UINTN* DescriptorSize,
+ uint32_t* DescriptorVersion
+ );
+ EFI_STATUS (EFIAPI *AllocatePool)(
+ EFI_MEMORY_TYPE PoolType,
+ UINTN Size,
+ void** Buffer
+ );
+ EFI_STATUS (EFIAPI *FreePool)(
+ void* Buffer
+ );
+
+ // Event & Timer (6)
+ void* CreateEvent;
+ void* SetTimer;
+ void* WaitForEvent;
+ void* SignalEvent;
+ void* CloseEvent;
+ void* CheckEvent;
+
+ // Protocol Handler (6 + 3)
+ void* InstallProtocolInterface;
+ void* ReinstallProtocolInterface;
+ void* UninstallProtocolInterface;
+ EFI_STATUS (EFIAPI *HandleProtocol)(
+ EFI_HANDLE Handle,
+ EFI_GUID* Protocol,
+ void** Interface
+ );
+ void* Reserved;
+ void* RegisterProtocolNotify;
+ void* LocateHandle;
+ void* LocateDevicePath;
+ void* InstallConfigurationTable;
+
+ // Image Services (5)
+ void* LoadImage;
+ void* StartImage;
+ void* Exit;
+ void* UnloadImage;
+ EFI_STATUS (EFIAPI *ExitBootServices)(
+ EFI_HANDLE ImageHandle,
+ UINTN MapKey
+ );
+
+ // Misc (3)
+ void* GetNextMonotonicCount;
+ void* Stall;
+ void* SetWatchdogTimer;
+
+ // DriverSupport (2)
+ void* ConnectController;
+ void* DisconnectController;
+
+ // Open/Close Protocol (3)
+ void* OpenProtocol;
+ void* CloseProtocol;
+ void* OpenProtocolInformation;
+
+ // Library (3)
+ void* ProtocolsPerHandle;
+ void* LocateHandleBuffer;
+ EFI_STATUS (EFIAPI *LocateProtocol)(
+ EFI_GUID* Protocol,
+ void* Registration,
+ void** Interface
+ );
+};
+
+// ── Configuration Table ────────────────────────────────────────────────────
+
+struct EFI_CONFIGURATION_TABLE {
+ EFI_GUID VendorGuid;
+ void* VendorTable;
+};
+
+// ── System Table ───────────────────────────────────────────────────────────
+
+struct EFI_SYSTEM_TABLE {
+ char _hdr[24];
+
+ CHAR16* FirmwareVendor;
+ uint32_t FirmwareRevision;
+ uint32_t _pad;
+
+ EFI_HANDLE ConsoleInHandle;
+ void* ConIn;
+ EFI_HANDLE ConsoleOutHandle;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* ConOut;
+ EFI_HANDLE StandardErrorHandle;
+ void* StdErr;
+ void* RuntimeServices;
+ EFI_BOOT_SERVICES* BootServices;
+ UINTN NumberOfTableEntries;
+ EFI_CONFIGURATION_TABLE* ConfigurationTable;
+};
+
+// ── Utility ────────────────────────────────────────────────────────────────
+
+inline bool guid_equal(const EFI_GUID& a, const EFI_GUID& b) {
+ return a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 &&
+ a.Data4[0] == b.Data4[0] && a.Data4[1] == b.Data4[1] &&
+ a.Data4[2] == b.Data4[2] && a.Data4[3] == b.Data4[3] &&
+ a.Data4[4] == b.Data4[4] && a.Data4[5] == b.Data4[5] &&
+ a.Data4[6] == b.Data4[6] && a.Data4[7] == b.Data4[7];
+}
diff --git a/include/elf/elf.h b/include/elf/elf.h
new file mode 100644
index 0000000..512ba14
--- /dev/null
+++ b/include/elf/elf.h
@@ -0,0 +1,331 @@
+#pragma once
+
+// ============================================================================
+// elf.h - ELF format definitions
+// https://refspecs.linuxbase.org/elf/elf.pdf
+// https://gist.github.com/x0nu11byt3/bcb35c3de461e5fb66173071a2379779
+// https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblh/index.html
+// ============================================================================
+
+#include <stdint.h>
+
+/* ELF Types */
+#pragma message("TODO: describe ELF types from specification")
+
+// ============================================================================
+// =================================== ELF Header =============================
+// ============================================================================
+#define EI_NIDENT (16)
+
+/* e_ident offset (https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#ELF_header) */
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_ABIVERSION 8
+#define EI_PAD 9
+
+/* ELF Magic value */
+#define ELF_MAGIC 0x464C457F // "\x7FELF" little-endian
+
+/* ELF Class */
+#define ELFCLASS32 0x1
+#define ELFCLASS64 0x2
+
+/* Data format: or LSB(Least Significant Bit, little-endian) or MSB(Most Significant Bit, big-endian) */
+#define ELFDATA2LSB 0x1
+#define ELFDATA2MSB 0x2
+
+/* ELF version */
+#define ELFVERSION 0x1
+
+/* Target ABI */
+#define ELFABISYSTEMV 0x00
+#define ELFABIHPUX 0x01
+#define ELFABINETBSD 0x02
+#define ELFABILINUX 0x03
+#define ELFABIGNUHURD 0x04
+#define ELFABISOLARIS 0x06
+#define ELFABIAIX 0x07
+#define ELFABIIRIX 0x08
+#define ELFABIFREEBSD 0x09
+#define ELFABITRU64 0x0A
+#define ELFABINM 0x0B
+#define ELFABIOPENBSD 0x0C
+#define ELFABIOPENVMS 0x0D
+#define ELFABINSKERNEL 0x0E
+#define ELFABIAROS 0x0F
+#define ELFABIFENIXOS 0x10
+#define ELFABICLOUDABI 0x11
+#define ELFABISTOPENVOS 0x12
+
+/* ABI version */
+#pragma message("TODO: do something with ABI version")
+/* Currently i don't use ABI version */
+
+/* Object File Types, e_type field */
+#define ET_NONE 0x0 /* Unknown */
+#define ET_REL 0x1 /* Relocatable. (output of gcc -c). Contains sections + symbol tables + relocations. No program header */
+#define ET_EXEC 0x2 /* Executable. Statically-linked executable with fixed virtual addresses. Has program headers. */
+#define ET_DYN 0x3 /* Shared object. Shared library or PIE executable. Postitoin-independent, relocated at load time. */
+#define ET_CORE 0x4 /* Core dump. Process memory image for post-mortem debugging */
+#define ET_LOOS 0xFE00 /* Reserved inclusive range. Operating system specific */
+#define ET_HIOS 0xFEFF /* Reserved inclusive range. Operating system specific */
+#define ET_LOPROC 0xFF00 /* Reserved inclusive range. Processor specific */
+#define ET_HIPROC 0xFFFF /* Reserved inclusive range. Processor specific */
+
+/* Arch types, e_machine field */
+#pragma message("TODO: add other architecture defines, copy from github")
+#define EM_X86 0x03
+#define EM_X86_64 0x3E
+#define EM_ARM 0x28 /* up to Armv7/AArch32 */
+#define EM_AARCH64 0xB7 /* Armv8/AArch64 */
+
+/* Version value, e_version field */
+#define EV_NONE 0x00
+#define EV_CURRENT 0x01
+#define EV_NUM 0x02
+
+/* Other header fields:
+ e_entry: Memory address of the entry point.
+ e_phoff: Pointer to the start of the program header table.
+ e_shoff: Pointer to the start of section header table.
+ e_flags: Interpretation of this field depends on the target arch.
+ e_ehsize: Contains the size of header (normally 64 bytes for 64-bit and 52 Bytes for 32-bit)
+ e_phentsize: Contains the size of program header table entry. Or 0x20 (for 32-bit) or 0x38 (for 64-bit).
+ e_phnum: Contains the number of entries in the program header table.
+ e_shentsize: Contains the size of a section header table entry. Or 0x28 (for 32-bit) or 0x40 (for 64-bit)
+ e_shnum: Contains the number of entries in the section header table.
+ e_shstrndx: Contains index of the section header table entry, that contains the section names.
+*/
+
+/* ELF header (atm only for 64 bit) */
+#pragma message("TODO: add elf header for 32 bit")
+struct Elf64_Ehdr {
+ uint8_t e_ident[EI_NIDENT];
+ uint16_t e_type;
+ uint16_t e_machine;
+ uint32_t e_version;
+ uint64_t e_entry;
+ uint64_t e_phoff;
+ uint64_t e_shoff;
+ uint32_t e_flags;
+ uint16_t e_ehsize;
+ uint16_t e_phentsize;
+ uint16_t e_phnum;
+ uint16_t e_shentsize;
+ uint16_t e_shnum;
+ uint16_t e_shstrndx;
+};
+
+// ============================================================================
+// =================================== Program Header =========================
+// ============================================================================
+
+/* Type, p_type field */
+#define PT_NULL 0x00000000 /* Program header table entry unused */
+#define PT_LOAD 0x00000001 /* Loadable segment */
+#define PT_DYNAMIC 0x00000002 /* Dynamic linking information */
+#define PT_INTERP 0x00000003 /* Interpreter information */
+#define PT_NOTE 0x00000004 /* Auxiliary information */
+#define PT_SHLIB 0x00000005 /* Reserved */
+#define PT_PHDR 0x00000006 /* Segment containing program header table itself */
+#define PT_TLS 0x00000007 /* Thread-Local Storage template */
+#define PT_NUM 0x00000008 /* Number of defined types */
+#define PT_LOOS 0x60000000 /* Reserved inclusive range. Operating system specific: */
+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6FFFFFFF /* Reserved inclusive range. Operating system specific end*/
+#define PT_LOPROC 0x70000000 /* Reserved inclusive range. Processor specific */
+#define PT_HIPROC 0x7FFFFFFF /* Reserved inclusive range. Processor specific */
+
+/* Flags, p_flags 64-bit field */
+#define PF_X 0x1 /* Executable segment */
+#define PF_W 0x2 /* Writeable segment */
+#define PF_R 0x4 /* Readable segment */
+#define PF_MASKOS 0x0FF00000 /* OS-specific */
+#define PF_MASKPROC 0xF0000000 /* Processor-specific */
+
+/* Other Program Header fields:
+ p_offset: Offset of the segment in the file image.
+ p_vaddr: Virtual address of the segment in memory.
+ p_paddr: On systems where physical address is relevant, reserved for segment's physical address.
+ p_filesz: Size in bytes of the segment in the file image. May be 0.
+ p_memsz: Size in bytes of the segment in memory. May be 0.
+ p_flags: 32-bit flags (don't exist on 64 bit header)
+ p_align: 0 and 1 specify no alignment. Otherwise should be a positive, integral power of 2, with p_vaddr equating p_offset modules p_align
+*/
+
+/* Elf64 Program Header */
+struct Elf64_Phdr {
+ uint32_t p_type;
+ uint32_t p_flags;
+ uint64_t p_offset;
+ uint64_t p_vaddr;
+ uint64_t p_paddr;
+ uint64_t p_filesz;
+ uint64_t p_memsz;
+ uint64_t p_align;
+};
+
+// ============================================================================
+// =================================== Section Header =============================
+// ============================================================================
+
+/* Section Header Type, sh_type field */
+#define SHT_NULL 0x0 /* Section header table entry unused. First entry in the section table must be SHT_NULL according the stanard */
+#define SHT_PROGBITS 0x1 /* Program data */
+#define SHT_SYMTAB 0x2 /* Symbol table */
+#define SHT_STRTAB 0x3 /* String table */
+#define SHT_RELA 0x4 /* Relocation entries with addends */
+#define SHT_HASH 0x5 /* Symbol hash table */
+#define SHT_DYNAMIC 0x6 /* Dynamic linking information */
+#define SHT_NOTE 0x7 /* Notes */
+#define SHT_NOBITS 0x8 /* Program space with no data (bss) */
+#define SHT_REL 0x9 /* Relocation entries, no addends */
+#define SHT_SHLIB 0x0A /* Reserved */
+#define SHT_DYNSYM 0x0B /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 0x0E /* Array of constructors */
+#define SHT_FINI_ARRAY 0x0F /* Array of destructors */
+#define SHT_PREINIT_ARRAY 0x10 /* Array of pre-constructors */
+#define SHT_GROUP 0x11 /* Section group */
+#define SHT_SYMTAB_SHNDX 0x12 /* Extended section indices */
+#define SHT_NUM 0x13 /* Number of defined types */
+#define SHT_LOOS 0x60000000 /* Start OS-specific */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
+
+/* Section Header flags, sh_flags field */
+#define SHF_WRITE 0x1 /*Writable*/
+#define SHF_ALLOC 0x2 /*Occupies memory during execution*/
+#define SHF_EXECINSTR 0x4 /*Executable*/
+#define SHF_MERGE 0x10 /*Might be merged*/
+#define SHF_STRINGS 0x20 /*Contains null-terminated strings*/
+#define SHF_INFO_LINK 0x40 /*'sh_info' contains SHT index*/
+#define SHF_LINK_ORDER 0x80 /*Preserve order after combining*/
+#define SHF_OS_NONCONFORMING 0x100 /*Non-standard OS specific handling required*/
+#define SHF_GROUP 0x200 /*Section is member of a group*/
+#define SHF_TLS 0x400 /*Section hold thread-local data*/
+#define SHF_COMPRESSED 0x800 /*Section with compressed data*/
+#define SHF_MASKOS 0x0FF00000 /*OS-specific*/
+#define SHF_MASKPROC 0xF0000000 /*Processor-specific*/
+#define SHF_ORDERED 0x4000000 /*Special ordering requirement (Solaris)*/
+#define SHF_EXCLUDE 0x8000000 /*Section is excluded unless referenced or allocated (Solaris)*/
+
+/* Other Section Header fields:
+ sh_name: An offset to a string in the .shstrab section that represents the name of this section. Zero means no name.
+ sh_addr: Virtual address of the section in memory, for sections that are loaded.
+ sh_offset: Offset of the section in the file image.
+ sh_size: Size in bytes of the section. May be 0.
+ sh_link: Contains the section index of an associated section. This field is used for several purposes, depending on the type of section.
+ sh_info: Contains extra information about the section. This field is used for several purposes, depending on the type of section.
+ sh_addralign: Contains the required alignment of the section. This field must be a power of two.
+ sh_entsize: Contains the size, in bytes, of each entry, for sections that contain fixed-size entries. Otherwise, this field contains zero.
+*/
+/*
+ The most common ELF sections:
+ .text - contains executable code. Packed with Read and Execute flags. Load only one times. Can't be changed.
+ .data - initalized data. Read and Write flags.
+ .rodata - initalized read only data. Read flag.
+ .bss - unititlized data. Read and Write flags.
+ other sections you can see here: https://gist.github.com/x0nu11byt3/bcb35c3de461e5fb66173071a2379779#sections
+
+ Also, there is something like "group of sections" (readelf -g), but it's very rare.
+*/
+
+/* Elf64 Section Header */
+struct Elf64_Shdr {
+ uint32_t sh_name;
+ uint32_t sh_type;
+ uint64_t sh_flags;
+ uint64_t sh_addr;
+ uint64_t sh_offset;
+ uint64_t sh_size;
+ uint32_t sh_link;
+ uint32_t sh_info;
+ uint64_t sh_addralign;
+ uint64_t sh_entsize;
+};
+
+// ============================================================================
+// =================================== Symbols ================================
+// ============================================================================
+// https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-79797/index.html
+#pragma message("TODO: do")
+
+/* Symbol fields:
+ st_name: Symbol name
+ st_info: Symbol type and binding. It is calculated using macros
+ st_other: Symbol visibility.
+ st_shndx: Section index.
+ st_value: Symbol value.
+ st_size: Symbol size;
+*/
+
+/* Symbol struct */
+struct Elf64_Sym {
+ uint32_t st_name;
+ uint8_t st_info;
+ uint8_t st_other;
+ uint16_t st_shndx;
+ uint64_t st_value;
+ uint64_t st_size;
+};
+
+
+// ============================================================================
+// =================================== ELF Page size ==========================
+// ============================================================================
+#define ELF_PAGE_SIZE 0x1000
+#define ELF_PAGE_MASK (ELF_PAGE_SIZE - 1)
+
+// ============================================================================
+// =================================== ELF Load Result ========================
+// ============================================================================
+// ATM it uses in efi_elf_parser.cpp
+
+/* Error codes for ElfLoadResult.error */
+#define ELF_ERR_NONE 0 /* success */
+#define ELF_ERR_FILE_TOO_SMALL 1 /* file smaller than ELF header */
+#define ELF_ERR_INVALID_MAGIC 2 /* bad magic */
+#define ELF_ERR_INVALID_CLASS 3 /* bad class */
+#define ELF_ERR_INVALID_IDENT 4 /* bad ident */
+#define ELF_ERR_INVALID_ARCH 5 /* bad machine */
+#define ELF_ERR_INVALID_TYPE 6 /* bad type */
+#define ELF_ERR_NO_LOAD_SEGS 7 /* no PT_LOAD segments found */
+#define ELF_ERR_ALLOC_FAILED 8 /* AllocatePages failed (check efi_alloc_status) */
+
+/* Elf Load Result object */
+struct ElfLoadResult {
+ uint64_t entry_point;
+ uint64_t phys_base;
+ uint64_t virt_base;
+ uint64_t total_size;
+ uint64_t efi_alloc_status; /* EFI_STATUS from AllocatePages, valid when error == ELF_ERR_ALLOC_FAILED */
+ uint8_t error; /* ELF_ERR_* code above */
+ bool success;
+};