#ifdef __WATCOMC__
#define __attribute__(attr)
#endif

typedef unsigned char   BYTE;
typedef unsigned char	UCHAR;
typedef unsigned short	WORD;
typedef unsigned short	USHORT;
typedef unsigned int	UINT;
typedef unsigned long	DWORD;
typedef unsigned long	ULONG;

struct exec_info {
    DWORD   text_vaddr;
    DWORD   text_size;
    DWORD   text_fileptr;
    DWORD   data_vaddr;
    DWORD   data_size;
    DWORD   data_fileptr;
    DWORD   bss_vaddr;
    DWORD   bss_size;
    DWORD   sym_size;
    DWORD   sym_entries;
    DWORD   sym_fileptr;
    DWORD   str_size;
    DWORD   str_fileptr;
    DWORD   tr_size;
    DWORD   tr_fileptr;
    DWORD   dr_size;
    DWORD   dr_fileptr;
    DWORD   entry;
};

struct exec
{
    DWORD a_info;
    DWORD a_text;
    DWORD a_data;
    DWORD a_bss;
    DWORD a_syms;
    DWORD a_entry;
    DWORD a_trsize;
    DWORD a_drsize;
};

#define N_TXTOFF(x)	1024
#define N_DATOFF(x)	(N_TXTOFF(x) + (x).a_text)
#define N_TRELOFF(x)	(N_DATOFF(x) + (x).a_data)
#define N_DRELOFF(x)	(N_TRELOFF(x) + (x).a_trsize)
#define N_SYMOFF(x)	(N_DRELOFF(x) + (x).a_drsize)
#define N_STROFF(x)	(N_SYMOFF(x) + (x).a_syms)

#define SEGMENT_SIZE	0x10000
#define N_TXTADDR(x)	SEGMENT_SIZE
#define N_DATADDR(x)	(SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1)))
#define N_BSSADDR(x)	(N_DATADDR(x) + (x).a_data)
#define N_BSSADDR2(x)	((N_DATADDR(x) + (x).a_data + SEGMENT_SIZE -1) & ~(SEGMENT_SIZE-1))

typedef struct filehdr {
    WORD    f_magic;
    WORD    f_nscns;
    DWORD   f_timdat;
    DWORD   f_symptr;
    DWORD   f_nsyms;
    WORD    f_opthdr;
    WORD    f_flags;
} FILEHDR;

typedef struct {
    DWORD info;
    DWORD tsize;	/* text size in bytes, padded to FW bdry*/
    DWORD dsize;	/* initialized data "  "                */
    DWORD bsize;	/* uninitialized data "   "             */
    DWORD entry;	/* entry pt.				*/
    DWORD text_start;	/* base of text used for this file	*/
    DWORD data_start;	/* base of data used for this file	*/
} AOUTHDR;

typedef struct scnhdr {
    char    s_name[8];
    DWORD   s_paddr;
    DWORD   s_vaddr;
    DWORD   s_size;
    DWORD   s_scnptr;
    DWORD   s_relptr;
    DWORD   s_lnnoptr;
    WORD    s_nreloc;
    WORD    s_nlnno;
    DWORD   s_flags;
} SCNHDR;

struct exe_hdr {
    WORD signatur;
    WORD low;
    WORD high;
    WORD reloc;
    WORD hdr_para;
};

struct emx_hdr {
    char    sig[18];
    char    next_hdr[4];
};

struct nlist {
    union {
	char *n_name;
	struct nlist *n_next;
	long n_strx;
    } n_un;
    unsigned char n_type;
    char n_other;
    short n_desc;
    unsigned long n_value;
};

typedef struct reloc_info
{
    DWORD r_address;
    DWORD r_symbolnum:24;
    DWORD r_pcrel:1;
    DWORD r_length:2;
    DWORD r_extern:1;
    DWORD r_pad:4;
} RELOC;


/* coff */

#define E_SYMNMLEN      8       /* # characters in a symbol name        */

struct external_syment 
{
  union {
    char e_name[E_SYMNMLEN];
    struct {
      unsigned long e_zeroes __attribute__((packed));
      unsigned long e_offset __attribute__((packed));
    } e;
  } e;
  unsigned long e_value __attribute__((packed));
  short e_scnum;
  unsigned short e_type;
  unsigned char e_sclass;
  unsigned char e_numaux;
};

#define SYMENT  struct external_syment
#define	SYMESZ	sizeof(SYMENT)

/* nt headers */

#define DIR_EXPORT	   0
#define DIR_IMPORT	   1
#define DIR_RESOURCE	   2
#define DIR_EXCEPTION	   3
#define DIR_SECURITY	   4
#define DIR_BASERELOC	   5
#define DIR_DEBUG	   6
#define DIR_COPYRIGHT	   7
#define DIR_GLOBALPTR	   8
#define DIR_TLS 	   9
#define DIR_LOAD_CONFIG   10

typedef struct {
    ULONG   VirtualAddress;
    ULONG   Size;
} IMAGE_DATA_DIRECTORY;

typedef struct {
    USHORT  Magic;
    UCHAR   MajorLinkerVersion;
    UCHAR   MinorLinkerVersion;
    ULONG   SizeOfCode;
    ULONG   SizeOfInitializedData;
    ULONG   SizeOfUninitializedData;
    ULONG   AddressOfEntryPoint;
    ULONG   BaseOfCode;
    ULONG   BaseOfData;
    ULONG   ImageBase;
    ULONG   SectionAlignment;
    ULONG   FileAlignment;
    USHORT  MajorOperatingSystemVersion;
    USHORT  MinorOperatingSystemVersion;
    USHORT  MajorImageVersion;
    USHORT  MinorImageVersion;
    USHORT  MajorSubsystemVersion;
    USHORT  MinorSubsystemVersion;
    ULONG   Reserved1;
    ULONG   SizeOfImage;
    ULONG   SizeOfHeaders;
    ULONG   CheckSum;
    USHORT  Subsystem;
    USHORT  DllCharacteristics;
    ULONG   SizeOfStackReserve;
    ULONG   SizeOfStackCommit;
    ULONG   SizeOfHeapReserve;
    ULONG   SizeOfHeapCommit;
    ULONG   LoaderFlags;
    ULONG   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[16];
} NTOPTHDR;

typedef struct {
    union {
	char *	Function;
	long	Ordinal;
    } u1;
} THUNK_DATA;

typedef struct import_desc {
    DWORD	Characteristics;
    DWORD	TimeDateStamp;
    DWORD	ForwarderChain;
    DWORD	Name;
    DWORD	FirstThunk;
} IMP_DESC;

typedef struct export_desc {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   **AddressOfFunctions;
    DWORD   **AddressOfNames;
    WORD    **AddressOfNameOrdinals;
} EXP_DESC;

typedef struct linenumber {
    union {
	unsigned long l_symndx;
	unsigned long l_paddr;
    } l_addr;
    unsigned short l_lnno;
}
LINENUMBER;

typedef struct debug_desc {
    DWORD	Characteristics;
    DWORD	TimeDateStamp;
    WORD	MajorVersion;
    WORD	MinorVersion;
    DWORD	Type;
    DWORD	SizeOfData;
    DWORD	AddressOfRawData;
    DWORD	PointerOfRawData;
} DEBUG_DESC;

typedef struct coffsyms_desc {
    DWORD	NumberOfSymbols;
    DWORD	LvaToFirstSymbol;
    DWORD	NumberOfLineNumbers;
    DWORD	LvaToFirstLineNumber;
    DWORD	RvaToFirstByteOfCode;
    DWORD	RvaToLastByteOfCode;
    DWORD	RvaToFirstByteOfData;
    DWORD	RvaToLastByteOfData;
} COFFSYMS_DESC;
