/*
 * COFFLoader.h -- COFF structure definitions
 * Step 02: The binary format structures that map directly to the COFF spec.
 *
 * These typedefs mirror the PE/COFF specification from Microsoft.
 * Every field offset and size is exact -- we cast raw file bytes to
 * these structs for zero-copy parsing.
 */

#ifndef COFFLOADER_H_
#define COFFLOADER_H_

#include <stdint.h>

/* ================================================================
 * Machine types -- identifies the target architecture
 * ================================================================ */
#define MACHINE_AMD64  0x8664   /* x64 (64-bit) */
#define MACHINE_I386   0x014C   /* x86 (32-bit) */

/* ================================================================
 * Section characteristic flags (bitmask)
 * ================================================================ */
#define IMAGE_SCN_CNT_CODE               0x00000020
#define IMAGE_SCN_CNT_INITIALIZED_DATA   0x00000040
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
#define IMAGE_SCN_MEM_EXECUTE            0x20000000
#define IMAGE_SCN_MEM_READ               0x40000000
#define IMAGE_SCN_MEM_WRITE              0x80000000
#define IMAGE_SCN_MEM_DISCARDABLE        0x02000000
#define IMAGE_SCN_ALIGN_16BYTES          0x00500000

/* ================================================================
 * Symbol storage class constants
 * ================================================================ */
#define IMAGE_SYM_CLASS_EXTERNAL         2
#define IMAGE_SYM_CLASS_STATIC           3
#define IMAGE_SYM_CLASS_LABEL            6
#define IMAGE_SYM_CLASS_FUNCTION         101

/* ================================================================
 * AMD64 relocation types
 * ================================================================ */
#define IMAGE_REL_AMD64_ADDR64    0x0001
#define IMAGE_REL_AMD64_ADDR32NB  0x0003
#define IMAGE_REL_AMD64_REL32     0x0004
#define IMAGE_REL_AMD64_REL32_1   0x0005
#define IMAGE_REL_AMD64_REL32_2   0x0006
#define IMAGE_REL_AMD64_REL32_3   0x0007
#define IMAGE_REL_AMD64_REL32_4   0x0008
#define IMAGE_REL_AMD64_REL32_5   0x0009

/* ================================================================
 * i386 relocation types
 * ================================================================ */
#define IMAGE_REL_I386_DIR32      0x0006
#define IMAGE_REL_I386_REL32      0x0014

/* ================================================================
 * COFF File Header (20 bytes, always at offset 0)
 * ================================================================ */
#pragma pack(push, 1)
typedef struct coff_file_header {
    uint16_t Machine;              /* Target architecture            */
    uint16_t NumberOfSections;     /* Count of section headers       */
    uint32_t TimeDateStamp;        /* Compilation timestamp          */
    uint32_t PointerToSymbolTable; /* File offset to symbol table    */
    uint32_t NumberOfSymbols;      /* Total symbol table entries     */
    uint16_t SizeOfOptionalHeader; /* Always 0 for object files      */
    uint16_t Characteristics;      /* File flags                     */
} coff_file_header_t;

/* ================================================================
 * Section Header (40 bytes each, immediately after file header)
 * ================================================================ */
typedef struct coff_sect {
    char     Name[8];              /* Section name (null-padded)     */
    uint32_t VirtualSize;          /* 0 for object files             */
    uint32_t VirtualAddress;       /* 0 for object files             */
    uint32_t SizeOfRawData;        /* Size of section data in file   */
    uint32_t PointerToRawData;     /* File offset to raw data        */
    uint32_t PointerToRelocations; /* File offset to relocations     */
    uint32_t PointerToLineNumbers; /* File offset to line numbers    */
    uint16_t NumberOfRelocations;  /* Count of relocation entries    */
    uint16_t NumberOfLinenumbers;  /* Count of line number entries   */
    uint32_t Characteristics;      /* Section flags (bitmask)        */
} coff_sect_t;

/* ================================================================
 * Symbol Table Entry (18 bytes each)
 * ================================================================ */
typedef struct coff_sym {
    union {
        char     Name[8];          /* Short name (if <= 8 chars)     */
        uint32_t value[2];         /* value[0]==0: value[1] is
                                      offset into string table       */
    } first;
    uint32_t Value;                /* Offset within section          */
    uint16_t SectionNumber;        /* 1-based section index, or 0    */
    uint16_t Type;                 /* 0x20 = function                */
    uint8_t  StorageClass;         /* EXTERNAL=2, STATIC=3, etc.     */
    uint8_t  NumberOfAuxSymbols;   /* Aux entries that follow        */
} coff_sym_t;

/* ================================================================
 * Relocation Entry (10 bytes each, per-section)
 * ================================================================ */
typedef struct coff_reloc {
    uint32_t VirtualAddress;       /* Offset in section to patch     */
    uint32_t SymbolTableIndex;     /* Index into symbol table        */
    uint16_t Type;                 /* Relocation type                */
} coff_reloc_t;
#pragma pack(pop)

#endif /* COFFLOADER_H_ */
