//
//  pe.txt
//
//  www.catch22.net
//
//  Copyright (C) 2012 James Brown
//  Please refer to the file LICENCE.TXT for copying permission
//

include "basetypes.txt";

/* oof */
struct Smeg
{
  int a;
};

/* smeg */
enum IMAGE_DIRECTORY
{
	IMAGE_DIRECTORY_ENTRY_EXPORT          = 0,   // Export Directory
	IMAGE_DIRECTORY_ENTRY_IMPORT          = 1,   // Import Directory
	IMAGE_DIRECTORY_ENTRY_RESOURCE        = 2,   // Resource Directory
	IMAGE_DIRECTORY_ENTRY_EXCEPTION       = 3,   // Exception Directory
	IMAGE_DIRECTORY_ENTRY_SECURITY        = 4,   // Security Directory
	IMAGE_DIRECTORY_ENTRY_BASERELOC       = 5,   // Base Relocation Table
	IMAGE_DIRECTORY_ENTRY_DEBUG           = 6,   // Debug Directory
	IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    = 7,   // Architecture Specific Data
	IMAGE_DIRECTORY_ENTRY_GLOBALPTR       = 8,   // RVA of GP
	IMAGE_DIRECTORY_ENTRY_TLS             = 9,   // TLS Directory
	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    = 10,   // Load Configuration Directory
	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   = 11,   // Bound Import Directory in headers
	IMAGE_DIRECTORY_ENTRY_IAT            = 12,   // Import Address Table
	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   = 13,   // Delay Load Import Descriptors
	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14,   // COM Runtime descriptor
};



struct FOO
{
  union {
	int x;	// union member x 
	int y;  // union member y 
  };
};

[export]
struct BAR 
{
   struct 
   {
	char a;		// blah blah
	int b;
	int c, d;	// hello world
	
   };
   struct FOO f;
} bar, car;


typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    short e_magic;                     // Magic number
    word   e_cblp;                      // bytes on last page of file
    word   e_cp;                        // Pages in file
    word   e_crlc;                      // Relocations
    word   e_cparhdr;                   // Size of header in paragraphs
    word   e_minalloc;                  // Minimum extra paragraphs needed
    short e_maxalloc;                  // Maximum extra paragraphs needed
    word   e_ss;                        // Initial (relative) SS value
    word   e_sp;                        // Initial SP value
    word   e_csum;                      // Checksum

/* hello */
    word   e_ip;                        // Initial IP value
    word   e_cs;                        // Initial (relative) CS value
    word   e_lfarlc;                    // File address of relocation table
    word   e_ovno;                      // Overlay number
    word   e_res[4];                    // Reserved words
    word   e_oemid;                     // OEM identifier (for e_oeminfo)
    word   e_oeminfo;                   // OEM information; e_oemid specific
    word   e_res2[10];                  // Reserved words
    dword   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef enum _IMAGE_FILE_MACHINE
{
	IMAGE_FILE_MACHINE_UNKNOWN       = 0,
	IMAGE_FILE_MACHINE_I386          = 0x014c,  // Intel 386.
	IMAGE_FILE_MACHINE_R3000         = 0x0162,  // MIPS little-endian, 0x160 big-endian
	IMAGE_FILE_MACHINE_R4000         = 0x0166,  // MIPS little-endian
	IMAGE_FILE_MACHINE_R10000        = 0x0168,  // MIPS little-endian
	IMAGE_FILE_MACHINE_WCEMIPSV2     = 0x0169,  // MIPS little-endian WCE v2
	IMAGE_FILE_MACHINE_ALPHA         = 0x0184,  // Alpha_AXP
	IMAGE_FILE_MACHINE_SH3           = 0x01a2,  // SH3 little-endian
	IMAGE_FILE_MACHINE_SH3DSP        = 0x01a3,
	IMAGE_FILE_MACHINE_SH3E          = 0x01a4,  // SH3E little-endian
	IMAGE_FILE_MACHINE_SH4           = 0x01a6,  // SH4 little-endian
	IMAGE_FILE_MACHINE_SH5           = 0x01a8,  // SH5
	IMAGE_FILE_MACHINE_ARM           = 0x01c0,  // ARM Little-Endian
	IMAGE_FILE_MACHINE_THUMB         = 0x01c2,
	IMAGE_FILE_MACHINE_AM33          = 0x01d3,
	IMAGE_FILE_MACHINE_POWERPC       = 0x01F0,  // IBM PowerPC Little-Endian
	IMAGE_FILE_MACHINE_POWERPCFP     = 0x01f1,
	IMAGE_FILE_MACHINE_IA64          = 0x0200,  // Intel 64
	IMAGE_FILE_MACHINE_MIPS16        = 0x0266,  // MIPS
	IMAGE_FILE_MACHINE_ALPHA64       = 0x0284,  // ALPHA64
	IMAGE_FILE_MACHINE_MIPSFPU       = 0x0366,  // MIPS
	IMAGE_FILE_MACHINE_MIPSFPU16     = 0x0466,  // MIPS
	IMAGE_FILE_MACHINE_AXP64         = IMAGE_FILE_MACHINE_ALPHA64,
	IMAGE_FILE_MACHINE_TRICORE       = 0x0520,  // Infineon
	IMAGE_FILE_MACHINE_CEF           = 0x0CEF,
	IMAGE_FILE_MACHINE_EBC           = 0x0EBC,  // EFI Byte Code
	IMAGE_FILE_MACHINE_AMD64         = 0x8664,  // AMD64 (K8)
	IMAGE_FILE_MACHINE_M32R          = 0x9041,  // M32R little-endian
	IMAGE_FILE_MACHINE_CEE           = 0xC0EE,

} IMAGE_FILE_MACHINE;

typedef struct _IMAGE_FILE_HEADER {

    [enum(IMAGE_FILE_MACHINE)]
    word    Machine;

    [bitflag(IMAGE_FILE_MACHINE)]
    word    NumberOfSections;
    dword   TimeDateStamp;
    dword   PointerToSymbolTable;
    dword   NumberOfSymbols;
    word    SizeOfOptionalHeader;
    word    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
    dword   VirtualAddress;
    dword   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    word    Magic;
    byte    MajorLinkerVersion;
    byte    MinorLinkerVersion;
    dword   SizeOfCode;
    dword   SizeOfInitializedData;
    dword   SizeOfUninitializedData;
    dword   AddressOfEntryPoint;
    dword   BaseOfCode;
    dword   BaseOfData;

    //
    // NT additional fields.
    //

    dword   ImageBase;
    dword   SectionAlignment;
    dword   FileAlignment;
    word    MajorOperatingSystemVersion;
    word    MinorOperatingSystemVersion;
    word    MajorImageVersion;
    word    MinorImageVersion;
    word    MajorSubsystemVersion;
    word    MinorSubsystemVersion;
    dword   Win32VersionValue;
    dword   SizeOfImage;
    dword   SizeOfHeaders;
    dword   CheckSum;
    word    Subsystem;
    word    DllCharacteristics;
    dword   SizeOfStackReserve;
    dword   SizeOfStackCommit;
    dword   SizeOfHeapReserve;
    dword   SizeOfHeapCommit;
    dword   LoaderFlags;
    dword   NumberOfRvaAndSizes;

    [name(IMAGE_DIRECTORY)]
    IMAGE_DATA_DIRECTORY DataDirectory[16];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_OPTIONAL_HEADER64 {
    WORD        Magic;
    BYTE        MajorLinkerVersion;
    BYTE        MinorLinkerVersion;
    DWORD       SizeOfCode;
    DWORD       SizeOfInitializedData;
    DWORD       SizeOfUninitializedData;
    DWORD       AddressOfEntryPoint;
    DWORD       BaseOfCode;
    ULONG64   ImageBase;
    DWORD       SectionAlignment;
    DWORD       FileAlignment;
    WORD        MajorOperatingSystemVersion;
    WORD        MinorOperatingSystemVersion;
    WORD        MajorImageVersion;
    WORD        MinorImageVersion;
    WORD        MajorSubsystemVersion;
    WORD        MinorSubsystemVersion;
    DWORD       Win32VersionValue;
    DWORD       SizeOfImage;
    DWORD       SizeOfHeaders;
    DWORD       CheckSum;
    WORD        Subsystem;
    WORD        DllCharacteristics;
    ULONG64   SizeOfStackReserve;
    ULONG64   SizeOfStackCommit;
    ULONG64   SizeOfHeapReserve;
    ULONG64   SizeOfHeapCommit;
    DWORD       LoaderFlags;
    DWORD       NumberOfRvaAndSizes;

    [name(IMAGE_DIRECTORY)]
    IMAGE_DATA_DIRECTORY DataDirectory[16];//IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

typedef struct _IMAGE_NT_HEADERS64 {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

typedef struct _IMAGE_NT_HEADERS {
    dword Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_SECTION_HEADER 
{
    char    Name[8];//IMAGE_SIZEOF_SHORT_NAME];
//    union {
            dword   PhysicalAddress;
    //        dword   VirtualSize;
  //  } Misc;
    dword   VirtualAddress;
    dword   SizeOfRawData;
    dword   PointerToRawData;
    dword   PointerToRelocations;
    dword   PointerToLinenumbers;
    word    NumberOfRelocations;
    word    NumberOfLinenumbers;
    dword   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;


[
   export, 
   assoc(".exe", ".sys", ".dll")
]
typedef struct _PE
{
  IMAGE_DOS_HEADER dosHeader;

  [offset(dosHeader.e_lfanew), switch_is(ntHeaders32.OptionalHeader.Magic)] 
  union 
  {
    [case(0)] IMAGE_NT_HEADERS32 ntHeaders32;
    [case(1)] IMAGE_NT_HEADERS64 ntHeaders64;
  };

  //[offset(ntHeaders32.FileHeader.SizeOfOptionalHeader)]
  IMAGE_SECTION_HEADER sectionHeader[4];

} PE;




PE pe;