


'----------
elf_Header:
'----------

'data "7f `ELF` 01 01 01 00 hl0 hl0"  ' 0000 e_ident      (16 bytes)
'data "hw0000"        ' 0010 e_type 0     none 1 relocatable 2 executable 3 shared object 4 core ff00 processor-specific ffff processor specific
'data "hw0000"        ' 0012 e_machine    2 sparc 3 intel386 4 motorola68000
'data "hl00000000"    ' 0014 e_version    0 none 1 current
'data "hl00000000"    ' 0018 e_entry      virtual address entry point for code
'data "hl00000000"    ' 001c e_phoff      program header table offset (bytes) or null
'data "hl00000000"    ' 0020 e_shoff      section header table offset (bytes) or null
'data "hl00000000"    ' 0024 e_flags      processor specific flags
'data "hw0000"        ' 0028 e_ehsize     elf header size in bytes
'data "hw0000"        ' 002a e_phentsize  size of each program header entry
'data "hw0000"        ' 002c e_phnum      number of entries in program header
'data "hw0000"        ' 002e e_shentsize  section header entry size in bytes
'data "hw0000"        ' 0030 e_shnum      number of entries in the section header
'data "hw0000"        ' 0032 e_shstrndx   section header table index for section name string table

'34h


data "!end!"


'
'  ########    #########
'  ##     ##   ##
'  ##     ##   ##
'  ##     ##   ##
'  ########    ########
'  ##          ##
'  ##          ##
'  ##          ##
'  ##          #########
'



'==================
elf_section_header:
'==================

data "hl00000000"    'sh_name       index to section header string table section
data "hl00000000"    'sh_type       categorize section contents 1 progbits? 3 string table 6 dynamic linking
data "hl00000000"    'sh_flags      bit attributes 1 write 2 shf_alloc 4 executable
data "hl00000000"    'sh_addr       base address where section should be
data "hl00000000"    'sh_offset     position in the file
data "hl00000000"    'sh_size       section size in bytes
data "hl00000000"    'sh_link       various:
data "hl00000000"    'sh_info       various
data "hl00000000"    'sh_addralign  alignment of section 1 2 4 bytes etc
data "hl00000000"    'sh_entsize    fixed size for entries - otherwise 0

data "!end!"

'Special Sections:
' .bss         unitialised data
' .comment
' .data        initialised data
' .data1       initialised data
' .debug
' .dynamic     dynamic linking
' .dynstr      strings for dynamic linking
' .dynsym      symbols for dynamic linking
' .fini
' .got
' .hash
' .init
' .interp
' .line
' .note
' .plt
' .rel (name)
' .rela (name)
' .rodata
' .rodata1
' .shstrtab
' .strtab        string table
' .symtab        symbol table
' .text          executable instructions
'

'string table: 00 `string` 00 .... 00

'symbol table
'elf_symbol_table_entry:
'hl0 ' st_name    index into string table
'hl0 ' st_value   could be an address depending on context
'hl0 ' st_size    asociated size
'00  ' st_info    symbol type and binding attributes
'00  ' st_other   undefined
'hw00'st_shndx    relevant section header table index




'=========
dos_header:
'=========

data "`MZ`  90 00"     ' 0000
data "03 00 00 00"     ' 0004
data "04 00 00 00"     ' 0008
data "FF FF 00 00"     ' 000c
data "B8 00 00 00"     ' 0010
data "00 00 00 00"     ' 0014   
data "40 00 00 00"     ' 0018 e_lfanew
data "$20"             '      32 nulls
data "hle8"            ' 003c 'e8 (cofo) was hl80
  '
data "0E 1F BA 0E"     ' 0040
data "00 B4 09 CD"     ' 0044
data "21 B8 01 4C"     ' 0048
data "CD 21"

data "`This program cannot be run in DOS mode.` 0d 0a 00"

data "/e8" 'e8 : adds &h68 to all offsets (cofo) (was 80)

data "!end!"


 
'=========
pe_header:
'=========

'----------------------------
'IMAGE FILE HEADER (24 bytes)
'============================

data "`PE` 00 00"     ' 0000  Signature: 00004550 'PE
data "hw014c"         ' 0004  Machine:
                      '       IMAGE_FILE_MACHINE_I386  014c
                      '       IMAGE_FILE_MACHINE_AMD64 8664
data "hwSECT"         ' 0006  no of sections:
data "hlDATETIME"     ' 0008  DateTimeStamp: eg 489E0DEE
                      '       Date & Time: 09/August/2008  22:36:46
data "hl0"            ' 000C  Pointer to symbol table:
data "hl0"            ' 0010  Number of symbols:
data "hw00e0"         ' 0014  Size of Optional header: hw00e0 32bit hw00f0 64bit
data "hwLIBX"         ' 0016  Characteristics: was 30e
                      '       IMAGE_FILE_LINE_NUMS_STRIPPED
                      '       IMAGE_FILE_LOCAL_SYMS_STRIPPED
                      '       not IMAGE_FILE_32BIT_MACHINE
                      '       IMAGE_FILE_DEBUG_STRIPPED
                      '       IMAGE_FILE_DLL &h2000
                      '       'DLL=2102 EXE=0102


'WITH NOTES FOR PE32 / PE32+

'---------------------------------------
'`OPTIONAL` FILE HEADER (96 / 112 bytes)
'=======================================

'
'0X10B for PE32 / 0X20B for PE32+
'
data "hw0*0b 'MAGIC"   ' 0018  magic: h010b for PE32, hw020b for PE32+
data "02"              ' 001A  major linker version: 08 was 02 08
data "38"              ' 001B  minor linker version: 00 was 38 00
data "hl0"             ' 001C  Size of Code: to fill in
data "hl0"             ' 0020  Size of Initialised Data: to fill in
data "hlUNINITIA"      ' 0024  Size of Uninitialised Data: to fill in

data "ga _main_"       ' 0028  Address of Entry Point:
data "ga _code_"       ' 002C  Base of Code:
'
'
'OMIT IN PE32+
'
data "^ga base_of_data" ' 0030  Base of Data:
'
'
'DWORD IN PE32, QWORD IN PE32+
'
data "hgIMAGEBAS" ' 0034  0030  Image Base: 10000000 for dll 00400000 for EXE
'
'
data "hl1000"     ' 0038  Section Alignment:
data "hl200"      ' 003C  File Alignment Alignment:
data "hw4"        ' 0040  Major Operating System Version: was 4
data "hw0"        ' 0042  Minor Operating System Version: was 0
data "hw1"        ' 0044  Major Image Version: was 1
data "hw0"        ' 0046  Minor Image Version: was 0
data "hw4"        ' 0048  Major Subsystem Version: WAS 5 4
data "hw0"        ' 004A  Minor Subsystem Version: WAS 2 0
data "hl0"        ' 004C  Reserved: (wIN32)
data "hl5000"     ' 0050  Size of Image to fill in
data "hl400"      ' 0054  Size of headers to fill in
data "hl0"        ' 0058  Checksum 'unused
data "hw*"        ' 005C  Subsystem:
                  '       #define IMAGE_SUBSYSTEM_UNKNOWN 0
                  '       #define IMAGE_SUBSYSTEM_NATIVE 1
                  '       #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
                  '       #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
data "hw0"        ' 005E  DLL Characteristics: 140: nxAware, can be relocated at load time (was 0)

'
'THESE ARE DWORD IN PE32 AND QUAD IN PE32+
'
data "hg00100000" ' 0060  0060  Size of Stack Reserve:
data "hg00100000" ' 0064  0068  Size of Stack Commit:
data "hg00100000" ' 0068  0070  Size of Heap Reserve:
data "hg00001000" ' 006C  0078  Size of Heap Commit:


data "hl0"        ' 0070  0080  Loader Flags:
data "hl10"       ' 0074  0084  Number of RVA and sizes
  

'
'RVA 96 / 112    (0078 PE32 OR 0088 FOR PE32+)
'
  
'
'Optional Header Data Directories
'================================
' 
'
'giving offset and length: (2 DWORDS)
'
'    DESCRIPTION                 FILE ADDR:
'    MODE                        32    64
'==========================================
' 01 export table                0078  0088
' 02 import tables               0080  0090
' 03 resource table              0088  0098
' 04 exception table             0090  00A0
' 05 certificate table           0098  00A8
' 06 base relocation table       00A0  00B0
' 07 debug                       00A8  00B8
' 08 architecture                00B0  00C0
' 09 global ptr                  00B8  00C8
' 10 thread local storage        00C0  00D0
' 11 load configuration          00C8  00D8
' 12 bound import                00D0  00E0
' 13 import address table        00D8  00E8
' 14 delay import descriptor     00E0  00F0
' 15 CLR common language runtime 00E8  00F8
' 16 reserved                    00F0  0100
'
' RVA 00F8/0108 (16 entries * 8 bytes)
'
' Table Entries                  00F8  0108 ...
'==============================================
' each header table 40 bytes.. 
'  
' CODE HEADER:
'---------------
' 00 NAME                        00F8  0108
' 08 VIRTUAL SIZE                0100  0110
' 12 VIRTUAL ADDRESS             0104  0114
' 16 SIZE OF RAW DATA            0108  0118
' 20 POINTER TO RAW DATA         010C  011C
' 24 ( POINTER TO RELOCATIONS )  0110  0120
' 28 ( POINTER TO LINE NUMBERS ) 0114  0124
' 32 ( NUMBER OF RELOCATIONS )   0118  0128
' 34 ( NUMBER OF LINE NUMBERS )  011C  012C
' 36 CHARACTERISTICS             0120  0130
' 40 


'SECTION HEADER FLAGS
'====================
' HL0001 reserved
' HL0002 reserved
' HL0008 IMAGE_SCN_TYPE_NO_PAD obsolete
' HL0010 reserved
' HL0020 IMAGE_SCN_CNT_COD contains executable code
' HL0040 IMAGE_SCN_CNT_INITIALIZED_DATA
' HL0080 IMAGE_SCN_CNT_UNINITIALIZED_ DATA
' HL0100 IMAGE_SCN_LNK_OTHER reserved
' HL0200 IMAGE_SCN_LNK_INFO contains comments (obj files only)
' HL0400 reserved
' HL0800 IMAGE_SCN_LNK_REMOVE not part of image (obj files only)
' HL1000 IMAGE_SCN_LNK_COMDAT
' HL8000 IMAGE_SCN_GPRE contains date reference by global ptr

' HL10000000 IMAGE_SCN_MEM_SHARED can be shared
' HL20000000 IMAGE_SCN_MEM_EXECUTE can be executed as code
' HL40000000 IMAGE_SCN_MEM_READ can be read
' HL80000000 IMAGE_SCN_MEM_WRITE can be written to



data "!end!"


'----------
pe_imports:
'==========


data ".imports"
data "ga name_list1 hl0 hl0 ga module_name1 ga address_list1"
'data "ga name_list2 hl0 hl0 ga module_name2 ga address_list2"
data "ga name_list3 hl0 hl0 ga module_name3 ga address_list3"

data "hl0 hl0 hl0 hl0 hl0 ' termination"

data ".module_name1 `KERNEL32.DLL` 00"
'data ".module_name2 `OLEAUT32.DLL` 00"
data ".module_name3 `USER32.DLL` 00"


'IN PE32+ MODE THESE TABLES HAVE 64BIT ADDRESSES INSTEAD OF 32BIT ADDRESSES
'null termination


data ".name_list1    gg _LoadLibrary gg _GetProcAddress gg _FreeLibrary"
data "gg _GetModuleHandle gg _GetCommandLine gg _GetExitCodeProcess gg _ExitProcess"
data "gg _CreateFile gg _ReadFile gg _CloseHandle hg0"
'data ".name_list2    gg _SysAllocStringByteLen gg _SysFreeString hg0"
data ".name_list3    gg _MessageBoxA gg _MessageBoxW hg0"


'-------------------------------
data "/+8 .import_address_table"
'===============================

data ".address_list1    gg _LoadLibrary gg _GetProcAddress gg _FreeLibrary"
data "gg _GetModuleHandle gg _GetCommandLine gg _GetExitCodeProcess gg _ExitProcess"
data "gg _CreateFile gg _ReadFile gg _CloseHandle hg0"
'data ".address_list2    gg _SysAllocStringByteLen gg _SysFreeString hg0"
data ".address_list3    gg _MessageBoxA gg _MessageBoxW hg0"



data "/+4 ._LoadLibrary        hw0 `LoadLibraryA` 00"          '00  00
data "/+4 ._GetProcAddress     hw0 `GetProcAddress` 00"        '04  08
data "/+4 ._FreeLibrary        hw0 `FreeLibrary` 00"           '08  16
data "/+4 ._GetModuleHandle    hw0 `GetModuleHandleA` 00"      '12  24
data "/+4 ._GetCommandLine     hw0  `GetCommandLineA` 00"      '16  32
data "/+4 ._GetExitCodeProcess hw0 `GetExitCodeProcess` 00"    '20  40
data "/+4 ._ExitProcess        hw0 `ExitProcess` 00"           '24  48
data "/+4 ._CreateFile         hw0 `CreateFileA` 00"           '28  56
data "/+4 ._ReadFile           hw0 `ReadFile` 00"              '32  64
data "/+4 ._CloseHandle        hw0 `CloseHandle` 00"           '36  72
                                                               '40  80 gap
data "/+4 ._MessageBoxA hw0 `MessageBoxA` 00"                  '44  88
data "/+4 ._MessageBoxW hw0 `MessageBoxW` 00"                  '48  96

'OLDER VERSION
'data "/+4 ._SysAllocStringByteLen hw0 `SysAllocStringByteLen` 00" '32  64  88 
'data "/+4 ._SysFreeString hw0 `SysFreeString` 00"                 '36  72  96
'                                                                  '40  80  104 gap


data "01 `end_of_imports` 01"

data "/+1000"
data "!end!"


''------------
'pe_resources:
''============


'LEVELS:
' TYPE
'   ID
'     LANG
'

' RT_CURSOR       = 1
' RT_BITMAP       = 2
' RT_ICON         = 3
' RT_MENU         = 4
' RT_DIALOG       = 5
' RT_STRING       = 6
' RT_FONTDIR      = 7
' RT_FONT         = 8
' RT_ACCELERATOR  = 9
' RT_RCDATA       = 10
' RT_MESSAGETABLE = 11
' RT_GROUP_CURSOR = 12
' RT_GROUP_ICON   = 14
' RT_VERSION      = 16
' RT_DLGINCLUDE   = 17
' RT_PLUGPLAY     = 19
' RT_VXD          = 20
' RT_ANICURSOR    = 21
' RT_ANIICON      = 22
' RT_HTML         = 23
' RT_MANIFEST     = 24




'data ".resources"
' Characteristics
' Time/Data stamp
' Major Version  : Minor Version
' Number of Name Entries
' Number of ID Entries

' EACH ENTRY:
'    ID or Name string pointer
'    LEAF: (bit31=0) 31 bit data entry address OR SUBDIRECTORY (bit31=1) 31 bit address
' 

' RESOURCE DIRECTORY STRING: 2BYTE_LENGTH : WCHARS
'data "hw0 hw0"

'data "/+10" 'align for source data entries


' RESOURCE DATA ENTRY
'    ADDRESS OF RESOURCE DATA
'    SIZE OF RESOURCE DATA
'    CODEPAGE 1252 ENGLISH (LOCALE UK 2057) 68000 UTF7 UNICODE   68001 UTF8 UNICODE
'    RESERVED


'  RAW RESOURCE DATA ... /+10 ...

'data "01 `end_of_resources` 01"
'data "/+1000"
'data "!end!"




'==========================
'PORTABLE EXECUTABLE FORMAT
'==========================


'-----------------------------------------------
function exportdata(byref eord as sys) as string
'===============================================
  '
  dim as long e,i,j,ei
  dim as long   pf,po,pn,ps
  dim as string wf,wo,wn,ws,w1,w2
  '
  'ordinal counter eord
  '
  'create ordinal index
  '--------------------
  '
  e=eord-1 : ei=e-1
  for i=0 to e
    expi(i)=i
  next
  '
  'simple sort into ascending order
  '--------------------------------
  '
  for i=0 to ei
    for j=i+1 to e
      if expal(expi(i))>expal(expi(j)) then swap expi(i),expi(j)
    next
  next
  '
  'build export data blocks
  '------------------------
  '
  'OXYGEN SCRIPT TO INSERT AFTER MAIN CODE
  '
  pf=1 : po=1 : pn=1 : ps=1
  for i=0 to e
    w2=str(i)
    w1="ga "+expwn(expi(i))+cr    'FUNCTION ADDRESSES TABLE `EAT`
    ape(wf,pf,w1)
    w1="nw "+w2+cr            'ORDINALS TABLE           `EOT`
    ape(wo,po,w1)
    w1="ga #en#"+w2+cr        'NAMES TABLE              `ENT`
    ape(wn,pn,w1)
    w1="/+4 .#en#"+w2+" "+chr(96)+expal(expi(i))+chr(96)+ " 00"+cr 'NAMES
    ape(ws,ps,w1)
  next
  '
  'combine to make export data
  '---------------------------
  '
  function="/+4 .export_funcs"+cr+left(wf,pf-1)+_
           "/+4 .export_ordls"+cr+left(wo,po-1)+_
           "/+4 .export_names"+cr+left(wn,pn-1)+_
           left(ws,ps-1)
  '


  'w1=str(eord) : eord+=1    'ORDINAL COUNTER
  'wva(11)+="ga "+wn+cr      'FUNCTION ADDRESSES TABLE `EAT`
  'wva(12)+="nw "+w1+cr      'ORDINALS TABLE           `EOT`
  'wva(13)+="ga #en#"+w1+cr  'NAMES TABLE              `ENT`
  '
  'wva(14)+="/+4 .#en#"+w1+" "+chr(96)+ali+chr(96)+ " 00"+cr 'NAMES
end function


'-----------------------------------------------------
function cvlm(byref s as string,byval i as sys) as sys
'=====================================================
  function=cvl(mid(s,i+1,4))
end function


'--------------------------------------------------------
sub ptch(byref s as string,byval p as sys,byval v as sys)
'========================================================
  mk4(s,p+1,v)
end sub


'--------------------------------------------------------------------------------
function sect(byref mage as string, byval p as long, byval lfc as long) as string
'================================================================================
  function=mid(mage,p+1,lfc)
end function
 

'-------------------------
function sizebss() as sys
'=========================
  dim as sys a,b
  a=aoff+depsp 'aoff+static space for run-time compiling
  b=(a+&hfff)and &h7ffff000 'round up to nearest 4k
  return b
end function


'-------------------------------------------
function padhex(v as sys,l as sys) as string
'===========================================
  dim as string w=hex(cast(integer,v))
  function=right("00000000"+w,l)
end function


'---------------------------------------------------
function DateTimeEncode(byref s as string) as string
'===================================================
  dim as sys tss,tmi,thh,tmm,tde,tyy
  if s="" then s=time+"  "+date
  thh=wval(mid(s,1,2))
  tmi=wval(mid(s,4,2))
  tss=wval(mid(s,7,2))
  tmm=wval(mid(s,11,2))
  tde=wval(mid(s,14,2)) 'rebase 0
  tyy=wval(mid(s,17,4))
  if tmm>1 then tde+=31
  if tmm>2 then tde+=28 :if (tyy mod 4) = 0 then tde+=1
  if tmm>3 then tde+=31
  if tmm>4 then tde+=30
  if tmm>5 then tde+=31
  if tmm>6 then tde+=30
  if tmm>7 then tde+=31
  if tmm>8 then tde+=31
  if tmm>9 then tde+=30
  if tmm>10 then tde+=31
  if tmm>11 then tde+=30
  tyy-=1970
  tde=tde+tyy*365'-1 
  'leaps
  tde=tde+tyy\4  ' base 1968. 0 . add days for previous leaps
  tss+=(tmi*60)+(thh*3600)
  tss+=tde*86400 ' total seconds
  tss-=3600 ' fudge
  function=padhex(tss,8)
end function


sub setimagestat(byref s as string,byval em as string,byval offs as sys,byref pt as sys,byref lr as sys,byref lf as sys)
'================
  dim as string qt=chr(1)
  pt=cvlm(s,offs+12) 'get virtual offset
  lr=instr(pt+1,s,qt+"end_of_"+em+qt)-pt-1 'get length of data
  if lr<0 then
    lr=0
  else
    mid(s,pt+lr+1)=string(len(em)+9,chr(0)) 'blank end marker
  end if
  lf=(lr+&h1ff) and &hfffffe00 'round up legth to nearest 0x200 bytes
  ptch s,offs+08,lr  ' size of image data
  ptch s,offs+16,lf  ' size of file data (raw data length)
end sub


'---------------------------------------------------------------
function MakePE(byref fi as string, byref mage as string) as sys
'===============================================================
  '
  'CONVERTS MEMORY IMAGE INTO PE FILE (EXE OR DLL)
  '
  dim as sys a,b,i,p,q
  dim as sys sho,ocs,ods,oes,ois,ors,obs,pemo
  dim as sys prc,prd,pre,pri,prr,ptc,ptd,pte,pti,ptq,ptb
  dim as sys lrc,lrd,lre,lri,lrr,lfc,lfd,lfe,lfi,lfr,cofo
  dim as string w1,ssh,ssc,ssd,ssi,sse,ssr,dll

  if ert then exit function


  'including dos header 128 + pe header 24 + optional header 96 + section directory 128 ==> &h178 + stringbase 1 ==> &h179 (256+120+1)


  'MAP OUT ENTRY OFFSETS
  '=====================



  'TABLE ENTRIES ARE 40 BYTES EACH
  '===============================

  cofo=cvl(mid(mage,&h3d,4)) 'Coff header offset is size of DOS header (&he8)


  'CHECK MAGIC NUMBER FOR PE32=010b OR PE32+ (64BIT)=020b
  '
  if asc(mage,cofo+&h1a)=2 then pemo=16 'EXTRA 16 BYTES FOR PE32+ HEADER (64 BIT
  '
  if pemo then mid(mage,cofo+&h17)=chr(&h22) 'CAN HANDLE LARGE ADDRESSES
  '
  sho=cofo+&hf8+pemo  'SECTION HEADERS OFFSET
  '
  'OFFSETS OF TABLE ENTRIES
  '========================
  '
  'must be kept in sync with table in o2fini
  ' 
  rsrf=0 'resources flag
  expf=0 'exports flag
  a=sho  'section header offset
  do
    w1=mid(mage,a+1,8)
    if asc(w1)<>46 then
      exit do
    elseif instrword(w1,".text") then
      ocs=a 'code header offset
    elseif instrword(w1,".data") then
      ods=a 'initialised data header offset
    elseif instrword(w1,".bss") then
      obs=a 'uninitialised data header offset
    elseif instrword(w1,".edata") then
      oes=a : expf=1 'export header offset
    elseif instrword(w1,".idata") then
      ois=a 'import header offset
    elseif instrword(w1,".rsrc") then
      ors=a : rsrf=1 'resource header offset
    end if
    a+=40 'step next table entry
  loop


  'MAPPING OF EACH SECTION HEADER
  '==============================
  '
  ' 0  NAME
  ' 8  VIRTUAL SIZE
  ' 12 VIRTUAL ADDRESS
  ' 16 SIZE OF RAW DATA
  ' 20 POINTER TO RAW DATA
  ' 24 ( POINTER TO RELOCATIONS )
  ' 28 ( POINTER TO LINE NUMBERS )
  ' 32 ( NUMBER OF RELOCATIONS )
  ' 34 ( NUMBER OF LINE NUMBERS )
  ' 36 CHARACTERISTICS
  ' 40

  '
   
  'GET DATA OFFSETS AND RAW DATA LENGTHS
  '=====================================

  'returning offset, length, and file section length
  '
               setimagestat(mage,"code",     ocs,ptc,lrc,lfc)
               setimagestat(mage,"data",     ods,ptd,lrd,lfd)
  if expf then setimagestat(mage,"exports",  oes,pte,lre,lfe) 'use lfe
               setimagestat(mage,"imports",  ois,pti,lri,lfi)
  if rsrf then setimagestat(mage,"resources",ors,ptq,lrr,lfr) 'use lfr

  ptb=cvlm(mage,obs+12)

  
  'CALC FILE DATA OFFSETS 'aka: raw data
  '======================
  
               a=&h400         'PE FILE HEADER LENGTH IN FILE
               prc=a : a+=lfc  'CODE SECTION
               prd=a : a+=lfd  'DATA SECTION
  if expf then pre=a : a+=lfe  'EXPORT SECTION
               pri=a : a+=lfi  'IMPORT SECTION
  if rsrf then prr=a : a+=lfr  'RESOURCE SECTION


  'BUILD RAW DATA FOR FILE FROM MEMORY IMAGE
  '=========================================


               ssh=left(mage,&h400)   'HEADER   SECTION 
               ssc=sect(mage,ptc,lfc) 'CODE     SECTION
               ssd=sect(mage,ptd,lfd) 'DATA     SECTION
  if expf then sse=sect(mage,pte,lfe) 'EXPORT   SECTION
               ssi=sect(mage,pti,lfi) 'IMPORT   SECTION
  if rsrf then ssr=sect(mage,ptq,lfr) 'RESOURCE SECTION


  dll=ssh+ssc+ssd+sse+ssi+ssr


  'PATCH IN LENGTHS
  '----------------

  ptch dll,cofo+&h50,len(mage) 'INCLUDING BSS SPACE

  'giving section lengths in file lf? or in memory ls?

  ptch dll,cofo+&h1c,lfc             ' size of code section
  ptch dll,cofo+&h20,lfd+lfe+lfi+lfr ' size of initialised data section


  'PATCH DATA INTO THE SECTION HEADERS
  '-----------------------------------
  '
  'here the length of physical data (in memory image) = length of raw data
  '
  ptch dll,ocs+20,prc  ' offset of file data for code
  ptch dll,ods+20,prd  ' offset of file data for code
  ptch dll,ois+20,pri  ' offset of file data for imports

  if expf then
  '
  ptch dll,oes+20,pre  ' offset of file data for exports
  ptch dll,pre+4,q     ' timedate stamp for exports
  ptch dll,cofo+pemo+&h7c,lfe
  '
  end if

  if rsrf then
  '
  ptch dll,ors+20,prr  ' offset of file data for resources
  ptch dll,prr+4,q     ' timedate stamp
  ptch dll,cofo+pemo+&h8c,lfr
  '
  end if
  '
  '
  'CREATE AND STORE THE FILE
  '=========================
  '
  b=putfile(fi,dll)
  if b=0 then ert=err : ers=" Filing Error: "+fi
  function=1
end function



'--------------------------------------------------
sub resources(byref w5 as string,byref rsrf as sys)
'==================================================


#if 0
    '
    '---------
    'RESOURCES
    '=========
    '
    ' codepage 65001 unicode utf8
    ' codepage 437   ibm ascii 8bit
    '
    'RT_CURSOR	   = 1
    'RT_BITMAP	   = 2
    'RT_ICON	   = 3
    'RT_MENU	   = 4
    'RT_DIALOG	   = 5
    'RT_STRING	   = 6
    'RT_FONTDIR	   = 7
    'RT_FONT	   = 8
    'RT_ACCELERATOR= 9
    'RT_RCDATA	   = 10
    'RT_MESSAGETABLE  = 11
    'RT_GROUP_CURSOR  = 12
    'RT_GROUP_ICON = 14
    'RT_VERSION	   = 16
    'RT_DLGINCLUDE = 17
    'RT_PLUGPLAY   = 19
    'RT_VXD	   = 20
    'RT_ANICURSOR  = 21
    'RT_ANIICON	   = 22
    'RT_HTML	   = 23
    'RT_MANIFEST   = 24
    '
    'GROUP_ICONS (14)
    '
    'http://msdn.microsoft.com/en-us/library/ms997538.aspx
    '
    'IN ICO FILE:
    '
    'typedef struct
    '{
    'WORD           idReserved;   // Reserved (must be 0)
    'WORD           idType;       // Resource Type (1 for icons)
    'WORD           idCount;      // How many images?
    'ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
    '} ICONDIR, *LPICONDIR;
    '
    'IN RESOURCES: RT_GROUP_ICON = 14:
    '
    '#pragma pack(2)
    '
    'typedef struct 
    '{
    'WORD            idReserved;     // Reserved (must be 0)
    'WORD            idType;         // Resource type (1 for icons)
    'WORD            idCount;        // How many images?
    'GRPICONDIRENTRY   idEntries[1]; // The entries for each image
    '} GRPICONDIR, *LPGRPICONDIR;
    '
    'IN ICO FILE (16 BYTES)
    'typedef struct
    '{
    'BYTE   bWidth;          // Width, in pixels, of the image
    'BYTE   bHeight;         // Height, in pixels, of the image
    'BYTE   bColorCount;     // Number of colors in image (0 if >=8bpp)
    'BYTE   bReserved;       // Reserved ( must be 0)
    'WORD   wPlanes;         // Color Planes
    'WORD   wBitCount;       // Bits per pixel
    'DWORD  dwBytesInRes;    // How many bytes in this resource?
    'DWORD  dwImageOffset;   // Where in the file is this image?
    '} ICONDIRENTRY, *LPICONDIRENTRY;
    '
    'RESOURCE ENTRY (14 BYTES)
    '
    '#pragma pack( push )
    '#pragma pack( 2 )
    'typedef struct
    '{
    'BYTE   bWidth;          // Width, in pixels, of the image
    'BYTE   bHeight;         // Height, in pixels, of the image
    'BYTE   bColorCount;     // Number of colors in image (0 if >=8bpp)
    'BYTE   bReserved;       // Reserved
    'WORD   wPlanes;         // Color Planes
    'WORD   wBitCount;       // Bits per pixel
    'DWORD   dwBytesInRes;   // how many bytes in this resource?
    'DWORD   nID;            // the ID
    '} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
    '#pragma pack( pop )
#endif

    '
#if 1
    'TEST STUB FOR STRING
    '
    'ra=relative address from top resource dir
    '
    'dirmain-->type&ra-->dir-->id&ra-->dir-->lang&ra-->rva&length&codepage&reserved
    '    
    w5=".resources"+cr+_
      "hl0 hl0 hl1 hw0 hw1"+cr+_               '00 MAIN DIRECTORY  CHARACTERISTICS DATETIMESTAMP MAJORMINORVERSION NUMOFNAMES NUMOFIDS
      "hl6 hl80000018"+cr+_                    '10   ENTRY STRINGS
      "hl0 hl0 hl1 hw0 hw1"+cr+_               '18   STRINGS DIRECTORY
      "hl1 hl80000030"+cr+_                    '28     ID 1 STRINGS
      "hl0 hl0 hl1 hw0 hw1"+cr+_               '30     ID1 LANGUAGE DIRECTORY STRINGS
      "nl2057 hl48"+cr+_                       '40       ID1L STRING ENGLISH
      "ga data1 nl32 nl0 hl0"+cr+_             '48       DATA ENTRY: ADDRESS LENGTH CODEPAGE RESERVED
      ".data1 nw11 w`OxygenBasic` nw3 w`o2h` nw0 "+cr+_      '.data1   RAWDATA OF RESOURCE
      "/+200"+cr+"01 `end_of_resources` 01"+cr+"/+1000"+cr 'PADD TO NEAREST 512 BYTES
    
    rsrf=1
#endif


end sub 'resources


'----------------------------
function PrepExec() as string
'============================


dim as sys    a,b,c,d,k
dim as string w1,w2,w3,w4,wm,wd
dim as string prol,epil,asms,hdrs,udat,idat,imps,exps,ress


'       ################
'      #     #          #
'     #       #          #
'    #         #          #
'    #         #          #
'    #      #  #  #    #  #  #
'    #       #####      #####
'    #        ###        ###
'    #         #          #
'    #         #          #
'    #########            #
'    #                    #
'    #                    #
'     #                  #
'      #################
'            #
'           ###
'            # 
'
'  ########################

'  END OF PREPROCESSOR LOOP

'  ########################



'

'=====
finap:
'=====
'   
'   =========================
'   |  |      |   |   || | | |
'   |  | O2   |   |   || | | |
'   |H | O2H  |   |   || | |F|----------> ASSEMBLER
'   |  |      |   |   || | | |
'   |  |      |   |   || | | |
'   =========================
'

'
'  SAVE REGISTERS
'  BOOTSTRAP
'  ALLOCATE STATIC MEMORY
'  FREE LIBRARIES
'  FREE MEMORY
'  RESTORE REGISTERS
'


  if ert=0 then if brc>0 then ers=str(brc)+" excess left brackets in source ((..) " : ert=10
  '
  '
  '=============
  'O2H CODE PREP
  '=============
  '
  'BSS DATASPACE ALLOCATION
  '------------------------
  '
  '
  '
  if dep then
    '
    prol=""
    udat="" 'SECONDARY (DYNAMIC) COMPILING TO MEMORY ONLY
    epil=cr+"._end_"+cr+"ret"+cr 'SHARE PARENTAL STATE
    '
  else 
    '
    'PROGRAM ENTRY FOR PRIMARY COMPILED CODE
    '=======================================
    '
    '---------------------------------------
    'CREATE BSS STATIC SPACE FOR GLOBALS ETC
    'THEN COPY RUNTIME LIBRARY INTO BSS
    '---------------------------------------
    '
    aoff+=15 : aoff and= &hfffffff0  'ROUND UP TO NEAREST 16
    '
    '
    'CODING FOR COMBINED RTFT AND SVT (only ebx is used, esi is free)
    '
    'copy 0-399 then 2048 to 4095 of the RTFT
    'the .bss section is assumed to be pre-initialised with nulls
    '
    udat=".bssdata"+cr+"$"+hex(cast(integer,sizebss()))+cr 'PRIMARY COMPILING
    '
    prol="mov edi,ebx : call get_bss : mov ebx,eax : mov esi,eax : mov ecx,100"+cr+_
    "(: mov eax,[edi] : mov [esi],eax : add edi,4 : add esi,4 : dec ecx : jg repeat :)"+cr+_
    "add edi,1644 : add esi, 1644 : mov ecx,512"+cr+_ '2048-400-4
    "(: mov eax,[edi] : mov [esi],eax : add edi,4 : add esi,4 : dec ecx : jg repeat :)"+cr
    '
    'NB: STATIC DATA IS PERSISTENT BETWEEN CALLS
    '
    epil=cr+"._end_"+cr+"ret"+cr
    '
  end if


  if (independent=0)and(dep=0) then
    '
    'PROGRAM ENTRY CODE, EXIT CODE
    '-----------------------------


    'PROVIDE PERSISTENT STORAGE FOR EBX AND ESI
    '------------------------------------------
    '
    'EBX contains base address of runtime procedure table


    '-----------------
    'MAIN BASIC PROLOG
    '=================
    
    prol="jmp fwd _main"+cr+_
    "._mem : call fwd here : .here : pop ebx : sub ebx,here : add ebx,bssdata : ret"+cr+_
    "._newbuf : push esi : push 0  : call [ebx+160]"+cr+_            'CREATE A SYSTEM BUFFER
    "  mov ecx,esi : mov edx,eax"+cr+_                               '
    "  ( : mov [edx],0 : add edx,4 : sub ecx,4 : jg repeat : )"+cr+_ '
    "  mov [edi],eax : add edi,8 : ret"+cr+_                         '
    "._main"+cr+_                                                    'START HERE
    "  push ebx : push esi : push edi : push ebp"+cr+_               'SAVE REGISTERS
    "  mov ebp,esp : push 0 : push 0 : push 0 : push 0"+cr+_         '
    prol+_                                                           'BUFFER POINTER ZONE
    "  push esi"+cr+_                                                'CREATE INTIALISED STATIC SPACE
    "  mov esi,512  : lea edi,[ebx+664] : call _newbuf"+cr+_         'BUFFER FOR GLOBAL STRINGS 664
    "  mov esi,4096 : lea edi,[ebx+680] : call _newbuf"+cr+_         'BUFFER FOR LIB HANDLES 680
    "  pop esi"+cr
    '
    '
    'VACANT BUFFER POINTERS
    '======================
    '
    '[ebx+648]
    '[ebx+656]
    '[ebx+640]
    '"  mov esi,4096 : lea edi,[ebx+640] : call _newbuf"+cr+_         'BUFFER FOR CONCATENATOR 640
    '
    '
    '-----------------
    'MAIN BASIC EPILOG
    '=================
    '
    'RESTORE REGISTERS AND RETURN
    '----------------------------
    '
    epil=cr+"._end_"+cr+_
    "  mov esp,ebp : pop ebp : pop edi : pop esi : pop ebx : ret"+cr+cr
    '
  end if  'primary dependent compiling
  '

  'FATAL ERRORS
  '============
  '
  if pef=1 then 'dll
    epil+="._error_"+cr+"push ecx : call [ebx+2048] : mov eax,0 : jmp _end_"+cr   'MBOX
  else
    epil+="._error_"+cr+"push ecx : call [ebx+2048] : jmp _end_"+cr   'MBOX
  end if
  if dep=0 then
    epil+=".get_bss : call fwd here : .here : pop eax : sub eax,here : add eax,bssdata : ret"+cr
  end if
  '


  if independent then 'INDEPENDENT MODE USING RTL
    prol=""
    epil=""
  end if
  '
  '
  asms=prol+t+epil
  replacecolonscrs(asms)


  'INITIALISED DATA
  '----------------
  '
  '
  if dep then
    'data embedded in code
  else 
    idat="._data"+cr+left(dats,dati)+cr+"00 01 `end_of_data` 01 /+1000"+cr
  end if
  '
  '
  '
  '==========
  'PE HEADERS
  '==========
  '
  if pef then
    '
    restore pe_header  : hdrs=readin()
    a=instr(hdrs,"^")
    c=instr(hdrs,"*") 'SUBSTITUTION WILL BE FOR MAGIC NUMBER
    if pem=64 then
      b=instr(hdrs,"hw014c")
      mid(hdrs,b)="hw8664" 'AMD64 CPU
      b=instr(hdrs,"hw00e0")
      mid(hdrs,b)="hw00f0" 'EXTRA 16 BYTES IN OPTIONAL HEADER
      w3="2" 'MAGIC NUMBER 020B
      lineblank(hdrs,a) 'OMIT
    else
      w3="1" 'MAGIC NUMBER 010B
      mid(hdrs,a)=" "
    end if
    mid(hdrs,c)=w3          'MAGIC NUMBER
    c=instr(c,hdrs,"*")     'LOCATE NEXT PATCH
    mid(hdrs,c)=chr(&h32+cnsl) 'SUBSYSTEM 2 OR 3 (3=EXISTING CONSOLE)
    '
    '
    restore dos_header : hdrs=readin()+hdrs
    '
    restore pe_imports : imps=readin
    '
    ' hdrs dos header+coff header+optional header
    ' imps imports section
    '
    ' -----------
    ' bss mapping
    ' ===========
    '
    ' [edi+600] IMPORT FUNCTIONS ADDRESS LIST (BOOTSTRAP LIBRARY)
    ' [edi+608] PROCESS HANDLE
    ' [edi+615] OXYGEN LIBRARY HANDLE
    '
    '
    '
    if independent then
      '
      w2="" : w3="" : wm="" 'OXYGEN NOT USED AT RUNTIME
      '
    else
      '
      'REQUIRES OXYGEN.DLL
      '
      w2="finit : call fwd get_oxygen : cmp eax,0 : jz fwd nend"+cr+_     'FIND OXYGEN DLL O2_LIB
      "call eax : mov ebx,eax"+cr                                         'CALL O2_LIB AND GET O2 RTL TABLE BASE IN EBX
      '
      w3="mov eax,[edi+616] : cmp eax,0 : jz fwd noxyfree : push eax : call [ebx+8]"+cr+_ 'FREE OXYGEN LIBRARY
      ".noxyfree"+cr
      ' 
    end if
    ' 
    if independent then goto nwrapped
    '


    '-----------------
    if pef=1 then 'DLL
    '=================

      wm="mov eax,[esp+8]"+cr+_
      ".cas : cmp eax,0 : jnz fwd cas : call fwd dll_finish : ret 12"+cr+_ 'process detach
      ".cas : cmp eax,1 : jnz fwd cas : call fwd dll_start  : ret 12"+cr+_ 'process attach success 1 fail 0 in eax
      ".cas : cmp eax,2 : jnz fwd cas : mov eax,1 : ret 12"+cr+_           'thread attach dummy
      ".cas : cmp eax,3 : jnz fwd cas : mov eax,1 : ret 12"+cr+_           'thread detach dummy
      ".cas : ret 12"+cr+_
      ".dll_start"+cr+_
      "  push ebx : push esi : push edi"+cr+_                              'MOUNT
      "  call get_bss : mov edi,eax"+cr+_                                  'RECORD BOOT INFO
      "  call fwd get_iat : mov ebx,eax : mov [edi+600],ebx"+cr+_          'FOR BOOTSTRAP LIBRARY
         w2+_                                                              'RETURN OXYGEN RTL BASE IN EBX
      "  call fwd _o2_"+cr+_                                               'MAIN PROGRAM
      ".nend : pop edi : pop esi : pop ebx : ret"+cr+_                     'DONE
      ".dll_finish : push eax : push ebx : push esi : push edi"+cr+_                  'DEMOUNT
      "  call fwd finish : "+cr+_                                          'USER TERMINATIONS
      "  call get_bss : mov edi,eax : mov ebx,[edi+600]"+cr+_              'BOOTSTRAP LIB TO DEMOUNT OXYGEN
         w3+_                                                              'RELEASE OXYGEN
      "pop edi : pop esi : pop ebx : pop eax : ret"+cr                     'EXIT
      '
    '----------
    else '2 EXE
    '==========
      '
      wm=cr+_ 'push ebx : push esi : push edi"+cr+_                       'MOUNT
      "call get_bss : mov edi,eax"+cr+_                                   'RECORD BOOT INFO
      "call get_iat : mov ebx,eax : mov [edi+600],ebx"+cr+_               'FOR BOOTSTRAP LIBRARY
      "push 0 : call [ebx+12] : mov [edi+608],eax"+cr+_                   'PROCESS MODULE HANDLE
      w2+_                                                                'RETURN OXYGEN RTL BASE IN EBX
      "call fwd _o2_"+cr+_                                                'MAIN PROGRAM
      "call get_bss : mov edi,eax : mov ebx,[edi+600]"+cr+_               'GET BOOTSTRAP TO DEMOUNT OXYGEN
      w3+_                                                                'RELEASE OXYGEN LIB HANDLE
      ".nend : push 0 : mov eax,esp : push eax : push [edi+608]"+cr+_     'PUSH MODULE HANDLE
      "call [ebx+20] : call [ebx+24]"+cr 'GetExitCodeProcess ExitProcess  'GET EXIT CODE : EXIT PROCESS
      '
    end if
    '
    w2=".get_iat : call fwd here : .here : pop eax : sub eax,here : add eax,import_address_table : ret"+cr+_
    ".get_bss : call fwd here : .here : pop eax : sub eax,here : add eax,bssdata : ret"+cr
    '
    '
    '
    '-------------------------
    'ACCESS TO RUNTIME LIBRARY
    '=========================
    '
    '
    '
    if hostdll="" then
      hostdll=".nconfig"+cr+"push 0x00006c6c : push 0x642e6e65 : push 0x6779786f : mov eax,esp"+cr+_ 'oxygen.dll'
      "push eax : call [ebx] : add esp,12 : cmp eax,0 : jnz fwd ndll"+cr+_
      "pushad : sub esp,32 : mov ecx,esp : mov [ecx],0x324f : mov [ecx+4],0x6779786f : mov [ecx+8],0x642e6e65"+cr+_
      "mov [ecx+12],0x003f6c6c : push 0 : push ecx : add ecx,4 : push ecx : push 0 : call [ebx+44] : add esp,32 : popad"+cr+_ 'message
      ""
    end if
    '
    '
    ' oxygen.ini or fixed path
    ' ------------------------
    '
    'oxygen.ini : oxyg en.c fg__'  in reverse : __gf c.ne gyxo :  0000676f 632e6e65 6779786f
    w3="push 0x00006766 : push 0x632e6e65 : push 0x6779786f : mov eax,esp"+cr+_
    "push 0 : push 128 : push 3 : push 0 : push 1 : push 0x80000000 : push eax : call [ebx+28]"+cr+_ 'Createfile
    "add esp,12 : cmp eax,0 : jz fwd nconfig : mov esi,eax"+cr+_
    "sub esp,2052 : mov edi,esp : mov [edi],0"+cr+_ 'CREATE buffer
    "push 0 : mov eax,esp : push 0 : push eax : push 2048 : push edi : push esi : call [ebx+32]"+cr+_ 'readfile
    "push esi : call [ebx+36]"+cr+_ 'close handle
    "mov ecx,edi : dec ecx : ( : inc ecx : mov al,[ecx] : cmp al,32 : ja repeat : ) : mov [ecx],0"+cr+_ 'place null terminator
    "push edi : call [ebx] : add esp,2056 : cmp eax,0 : jnz fwd ndll"+cr+_ 'attempt to load oxygen ' free config buffer
    hostdll
    '
    '
    wm+=w2+_
    ".get_oxygen"+cr+_
    "push edi"+cr+w3+"pop edi : ret"+cr+_ 'DEPENDING ON DLL AND PATH
    ".ndll"+cr+_
    "pop edi : mov [edi+616],eax"+cr+_ 'SAVE O2 LIB HANDLE 'get proc address 'o2_lib'
    "mov edx,eax : sub esp,16 : mov eax,esp : mov [eax],0x6c5f326f : mov [eax+4],0x00006269"+cr+_
    "push eax : push edx : call [ebx+04] : add esp,16 : ret"+cr+_ 'GetProcAddress of o2_lib
    cr
    '
    '
    '
    '--------
    nwrapped:
    '========
    '
     '
    '------------
    'EXPORT TABLE
    '============
    '
    'https://msdn.microsoft.com/en-us/library/ms809762.aspx
    '
    w2="" : w3=""
    '

    if eord then
      w3=" hl"+hex(cast(integer,eord))
      exps=cr+cr+_
      ".exports hl0 hl0 hl0 ga export_name"+cr+_
      "hl1"+w3+w3+" ga export_funcs ga export_names ga export_ordls hl0"+cr+_
      "/+4 .export_name `"+pexn+"` 00"+cr+_
      exportdata(eord)+_
      cr+"01 `end_of_exports` 01"+cr+"/+1000"+cr
      w3=""
      expf=1
    end if
    '
    rsrf=0
    '
    resources(ress,rsrf) 'RESOURCES SECTION
    '
    '-----------------
    'SECTION DIRECTORY
    '=================
    '
    'Optional Header Data Directory (cofo+0x78 or cofo+0x88 64bit )
    '
    a=128
    '
    'address followed by length
    '
    'EXPORT SECTION
    '--------------
    '
    if expf then w3="ga exports hl0" else w3="hl0 hl0" 'default length
    hdrs+=w3+cr : a-=8'EXPORT SECTION
    '
    'ALWAYS AN IMPORT SECTION
    '------------------------
    '
    hdrs+="ga imports hl200"+cr : a-=8
    '
    'EMBEDDED RESOURCES SECTION
    '--------------------------
    '
    if rsrf then w3="ga resources hl0" else w3="hl0 hl0" 'default length
    hdrs+=w3+cr : a-=8
    '
    'PAD OUT REST OF DIRECTORY WITH NULL ENTRIES
    '-------------------------------------------
    '
    hdrs+="$"+hex(cast(integer,a))+cr


    '-------------------------------------
    'SECTION TABLE/HEADERS (40 BYTES EACH)
    '=====================================
    '
    'following section directory of 16 entries = 80h bytes
    'BASE ADDRESS RVA 178 or 188 in PE32+
    '
    '
    'with default values
    '
    '--------------------------------------------------------------------------------------------'
    '                  name                virtsz      virtaddr      rdsz  rdpt.. characteristics'
    '============================================================================================'
    '                  0                   8           12           16      20... 36             '
    '--------------------------------------------------------------------------------------------'
               hdrs+= "`.text`    00 00 00 hl00000000  ga _code_    hl0000  $10   hl60000020"+cr ' code executable readable
               hdrs+= "`.data`    00 00 00 hl40000000  ga _data     hl0200  $10   hlc0000040"+cr ' initialised readable writable
               hdrs+= "`.bss`  00 00 00 00 hlUNINITIA  ga bssdata   hl0000  $10   hlc0000080"+cr ' uninitialised readable writable
    if expf then hdrs+= "`.edata`    00 00 hl02000000  ga exports   hl0200  $10   hlc0000040"+cr ' initialised readable writable
                 hdrs+= "`.idata`    00 00 hl02000000  ga imports   hl0200  $10   hlc0000040"+cr ' initialised readable writable
    if rsrf then hdrs+= "`.rsrc`  00 00 00 hl02000000  ga resources hl0200  $10   hl40000040"+cr ' initialised readable
    '--------------------------------------------------------------------------------------------'
    '
    'PATCH-INS
    '
    a=instr(hdrs,"hlDATETIME")
    mid(hdrs,a)="hl"+DateTimeEncode("")
    a=instr(hdrs,"hwSECT")
    mid(hdrs,a)="hw000"+chr(52+expf+rsrf) 'NUMBER OF SECTIONS 4..6
    a=instr(hdrs,"hwLIBX")
    if pef=1 then
      mid(hdrs,a)="hw2102"
    else
      mid(hdrs,a)="hw0102" 'FOR DLL OR EXE
    end if
    a=instr(hdrs,"hgIMAGEBAS")
    if pef=1 then
      mid(hdrs,a)="hg10000000"
    else
      mid(hdrs,a)="hg00400000" 'FOR DLL OR EXE
    end if
    wd=hex(cast(integer,sizebss())) 'MIN HEX 1000
    wd="hl"+right("0000"+wd,8)
    for b=1 to 2
      a=instr(hdrs,"hlUNINITIA")
      mid(hdrs,a)=wd 'UNINITIALISED DATA
    next
    
    
    '
    '
    'field descriptions
    '------------------
    '
    ' 00  name upto 8 bytes
    ' 08  virtual size (this is null padded if freater than the raw data size)
    ' 12  virtual address (offset in memory 4096 byte steps)
    ' 16  raw data size (rounded to 512 bytes)
    ' 20  raw data offset in file (512 byte steps)
    ' 24  pointer to relocations (null)
    ' 28  pointer to line numbers (null)
    ' 32  Number of relocations   (0)
    ' 34  Number of line numbers  (0)
    ' 36  Characteristics Bits:
    '      00 reserved
    '      01 reserved
    '      02 reserved
    '      04 reserved
    '      08 obsolete
    '      10 reserved
    '      20 contains executable code
    '      40 contains initialised data
    '      80 contains uninitialised data
    '     100 reserved     
    '     200 reserved contains comments (object files only)
    '     400 reserved
    '     800 will not become part of image (object files only)
    '    1000 contains COMDAT data
    '    8000 contains data referenced through global pointer
    '   10000 reserved
    '   20000 reserved
    '   40000 reserved
    '   80000 reserved
    '  100000 align on 1 byte boundary (object files only)
    '  200000 align on 2 byte boundary (object files only)
    '  300000 align on 4 byte boundary (object files only)
    '  400000 align on 8 byte boundary (object files only)
    '  500000 align on 16 byte boundary (object files only)
    '  600000 align on 32 byte boundary (object files only)
    '  700000 align on 64 byte boundary (object files only)
    '  800000 align on 128 byte boundary (object files only)
    '  900000 align on 256 byte boundary (object files only)
    '  A00000 align on 512 byte boundary (object files only)
    '  B00000 align on 1024 byte boundary (object files only)
    '  C00000 align on 2048 byte boundary (object files only)
    '  D00000 align on 4096 byte boundary (object files only)
    '  E00000 align on 8192 byte boundary (object files only)
    ' 1000000 contains extended relocations
    ' 2000000 can be discarded
    ' 4000000 cannot be cached
    ' 8000000 is not pageable
    '10000000 can be shared in memory
    '20000000 can be executed as code
    '40000000 can be read
    '80000000 can be written to


    'ENTRY POINT
    '
    'This jump will not appear in the PE file
    '
    if independent then
      hdrs+="/0ff0 c3"+cr+"/+1000" 'NO DIRECT EXEC
    else
      hdrs+="/0ff0 e9 gf _o2_ "+cr+"/+1000" 'JUMP TO MAIN CODE
    end if
    '
    replacecolonscrs(wm)
    '
    '---------------------------
    'BRING ALL SECTIONS TOGETHER
    '===========================
    '
    'also adding section for uninitialised data (.bss)
    '
    function="o2 ("+cr+hdrs+ep+"._code_ : ._main_"+cr+wm+"._o2_"+cr+_
    asms+cr+"o2 01 `end_of_code` 01 /+1000"+cr+"o2"+sp+".base_of_data"+cr+_
    idat+udat+exps+imps+ress+ep
    '
  else 'NOT PE FORMAT BUT DIRECTLY EXECUTABLE CODE STRING
    '
    if dep then
      function=asms 'SECONDARY COMPILED IN MEMORY
    else
      function="._code_ : ._main_"+cr+asms+cr+"o2"+sp+"/+1000 "+cr+_
      idat+udat+ep 'PRIMARY COMPILED IN MEMORY
    end if
    '
  end if
  '
  '
  'DIAGNOSTICS
  '-----------
  '
  'if vew=0 then open "t.txt" for output as 3 : print #3,"o2 ("+cr+hdrs+ep+_
  '"._code_ : ._main_"+cr+wm+"._o2_"+cr+asms+"o2 01 `end_of_code` 01 /+1000"+cr+_
  '"o2"+sp+".base_of_data"+cr+idat+udat+exps+imps+ress+ep : close 3
  'if len(ers) then if ert=0 then ert=1000
  '
  '


end function 'PrepExec

