newlib sdk: libc loader for fasm applications, fasm libc header and "hello" demo

git-svn-id: svn://kolibrios.org@3915 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-09-20 14:02:22 +00:00
parent ede166e8ab
commit 993637ca7b
13 changed files with 1611 additions and 16 deletions

View File

@ -0,0 +1 @@
s|[^ ][A-Za-z0-9_]*|_&,'&',\\|

View File

@ -0,0 +1 @@
s|\<DATA\>||

View File

@ -38,6 +38,8 @@ void __main (){};
void* get_entry_point(void *raw); void* get_entry_point(void *raw);
void _pei386_runtime_relocator (void){};
void __attribute__((noreturn)) void __attribute__((noreturn))
__crt_startup (void) __crt_startup (void)
{ {
@ -45,11 +47,12 @@ __crt_startup (void)
void *img; void *img;
void __attribute__((noreturn)) (*entry)(void *img); void __attribute__((noreturn)) (*entry)(void *img);
// _pei386_runtime_relocator();
img = load_libc(); img = load_libc();
if(img == NULL) if(img == NULL)
{ {
asm("int3");
asm ("int $0x40" ::"a"(-1)); asm ("int $0x40" ::"a"(-1));
}; };

View File

@ -22,7 +22,7 @@ struct app_hdr
int reserved; int reserved;
void *__idata_start; void *__idata_start;
void *__idata_end; void *__idata_end;
void (*main)(int argc, char **argv, char **envp); int (*main)(int argc, char **argv, char **envp);
}; };
int _argc; int _argc;
@ -117,9 +117,9 @@ libc_crt_startup (void *libc_base)
_argv = arg; _argv = arg;
header->main(_argc, _argv, NULL); retval = header->main(_argc, _argv, NULL);
done: done:
_exit (retval); exit (retval);
} }

View File

@ -39,7 +39,7 @@ static inline int IsPowerOf2(uint32_t val)
return (val & (val - 1)) == 0; return (val & (val - 1)) == 0;
} }
int validate_pe(void *raw, size_t raw_size, int is_exec) int validate_pe(void *raw, size_t raw_size)
{ {
PIMAGE_DOS_HEADER dos; PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt; PIMAGE_NT_HEADERS32 nt;
@ -63,15 +63,9 @@ int validate_pe(void *raw, size_t raw_size, int is_exec)
if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
return 0; return 0;
if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
return 0;
if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return 0; return 0;
if( is_exec && nt->OptionalHeader.ImageBase != 0)
return 0;
if(nt->OptionalHeader.SectionAlignment < 4096) if(nt->OptionalHeader.SectionAlignment < 4096)
{ {
if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
@ -214,7 +208,7 @@ void* load_libc()
// printf("libc.dll raw %p, size %d\n", raw_img, raw_size); // printf("libc.dll raw %p, size %d\n", raw_img, raw_size);
if(validate_pe(raw_img, raw_size, 0) != 0) if(validate_pe(raw_img, raw_size) != 0)
{ {
// printf("invalide libc.dll\n"); // printf("invalide libc.dll\n");
img_base = create_image(raw_img); img_base = create_image(raw_img);

View File

@ -686,7 +686,7 @@ module_t* load_library(const char *name)
memcpy(path+dllpath->path_len, libname, len); memcpy(path+dllpath->path_len, libname, len);
path[len+dllpath->path_len]=0; path[len+dllpath->path_len]=0;
printf("%s\n", path); // printf("%s\n", path);
img_base = load_lib_internal(path); img_base = load_lib_internal(path);

View File

@ -106,12 +106,12 @@ typedef struct _IMAGE_NT_HEADERS
typedef struct _IMAGE_SECTION_HEADER typedef struct _IMAGE_SECTION_HEADER
{ {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union union
{ {
DWORD PhysicalAddress; DWORD PhysicalAddress;
DWORD VirtualSize; DWORD VirtualSize;
} Misc; } Misc;
DWORD VirtualAddress; DWORD VirtualAddress;
DWORD SizeOfRawData; DWORD SizeOfRawData;
DWORD PointerToRawData; DWORD PointerToRawData;

View File

@ -0,0 +1,283 @@
include 'import32.inc'
include 'proc32.inc'
use32
org 0x0
db 'MENUET02'
dd 0x01
dd __start
dd __iend
dd __bssend
dd __stack
dd __cmdline
dd __pgmname
dd 0x0
dd __idata_start
dd __idata_end
dd main
IMAGE_DOS_SIGNATURE equ 0x5A4D
IMAGE_NT_SIGNATURE equ 0x00004550
IMAGE_FILE_MACHINE_I386 equ 0x014c
IMAGE_NT_OPTIONAL_HDR32_MAGIC equ 0x10B
IMAGE_NT_HEADERS32_SIZE equ 0xF8
__start:
.e_lfanew equ 0x3C
.FileHeader.NumberOfSections equ 0x06
.OptionalHeader.ImageBase equ 0x34
.SectionAlignment equ 0x38
.FileAlignment equ 0x3C
.OptionalHeader.SizeOfImage equ 0x50
.OptionalHeader.SizeOfHeaders equ 0x54
.VirtualAddress equ 0x0C
.SizeOfRawData equ 0x10
.PointerToRawData equ 0x14
.OptionalHeader.RelocDataDirectory.VirtualAddress equ 0xA0
.OptionalHeader.RelocDataDirectory.Size equ 0xA4
.SizeOfBlock equ 0x04
mov eax, 68
mov ebx, 12
mov ecx, STACK_SIZE
add ecx, 4095
and ecx, -4096
int 0x40
test eax, eax
jz .exit
add ecx, eax
mov [fs:8], eax
mov [fs:12], ecx
mov esp, ecx
sub esp, 1024
mov eax, 9
mov ebx, esp
mov ecx, -1
int 0x40
mov eax, [ebx+30]
mov [fs:0], eax
add esp, 1024
mov eax, 68
mov ebx, 27
mov ecx, libc_path
int 0x40
test eax, eax
jz .exit
push edx
push eax
.validate_pe:
cmp edx, 0x3F
jbe .exit
cmp word [eax], IMAGE_DOS_SIGNATURE
jne .exit
mov edx, [eax+.e_lfanew]
test edx, edx
jz .exit
add edx, eax ;edx = nt header
jb .exit
cmp dword [edx], IMAGE_NT_SIGNATURE
jnz .exit
cmp word [edx+0x04], IMAGE_FILE_MACHINE_I386
jnz .exit
cmp word [edx+0x18], IMAGE_NT_OPTIONAL_HDR32_MAGIC
jnz .exit
mov ecx, [edx+.SectionAlignment]
cmp ecx, 4095
ja .l1
cmp ecx, [edx+.FileAlignment]
jne .exit
jmp @F
.l1:
cmp ecx, [edx+.FileAlignment]
jb .exit
@@:
test ecx, ecx
jz .exit
lea eax, [ecx-1]
test ecx, eax
jnz .exit
mov ecx, [edx+.FileAlignment]
test ecx, ecx
jz .exit
lea ebx, [ecx-1]
test ecx, ebx
jnz .exit
cmp word [edx+.FileHeader.NumberOfSections], 96
ja .exit
.create_image:
mov ecx, [edx+.OptionalHeader.SizeOfImage]
mov eax, 68
mov ebx, 12
int 0x40
mov ebp, eax
test eax, eax
jz .exit_2
mov ecx, [edx+.OptionalHeader.SizeOfHeaders]
mov esi, [esp]
mov edi, eax
shr ecx, 2 ;copy header
rep movsd
lea eax, [edx+IMAGE_NT_HEADERS32_SIZE] ;eax = MAGE_SECTION_HEADER
movzx ebx, word [edx+.FileHeader.NumberOfSections]
test ebx, ebx
jz @F
.copy_loop:
mov ecx, [eax+.SizeOfRawData]
test ecx, ecx
jz .next_section
mov esi, [eax+.PointerToRawData]
test esi, esi
jz .next_section
add esi, [esp]
mov edi, [eax+.VirtualAddress]
add edi, ebp
shr ecx, 2
rep movsd
;copy section
.next_section:
add eax, 0x28
dec ebx
jnz .copy_loop
@@:
push edx
mov esi, [edx+.OptionalHeader.RelocDataDirectory.Size]
test esi, esi
jz .call_libc
mov ebx, ebp
sub ebx, [edx+.OptionalHeader.ImageBase] ;delta
mov edx, [edx+.OptionalHeader.RelocDataDirectory.VirtualAddress]
lea ecx, [ebp+edx] ;IMAGE_BASE_RELOCATION
mov eax, [ecx+.SizeOfBlock]
test eax, eax
jz .unmap_relocs
mov esi, ebx
shr esi, 16
push esi
align 4
.loop_block:
sub eax, 8
lea edx, [ecx+8] ;entry
shr eax, 1
jz .next_block
lea edi, [ecx+eax*2+8] ;last entry
align 4
.loop_reloc:
mov si, [edx]
mov eax, esi
and eax, 0FFFh
add eax, [ecx] ;offset
shr si, 12 ;reloc type
dec si
jnz @F
.type_1:
mov esi, [esp]
add [eax+ebp], si
jmp .next_entry
@@:
dec si
jnz @F
.type_2:
add [eax+ebp], bx
jmp .next_entry
@@:
dec si
jnz .next_entry
.type_3:
add [eax+ebp], ebx
.next_entry:
add edx, 2
cmp edx, edi
jne .loop_reloc
.next_block:
add ecx, [ecx+.SizeOfBlock]
mov eax, [ecx+.SizeOfBlock]
test eax, eax
jnz .loop_block
add esp, 4
pop edx
mov esi, [edx+.OptionalHeader.RelocDataDirectory.Size]
mov edx, [edx+.OptionalHeader.RelocDataDirectory.VirtualAddress]
.unmap_relocs:
mov ebx, 26
mov eax, 68
mov ecx, ebp
int 0x40
.call_libc:
push ebp
mov edx, [ebp+0x3C]
add ebp, [ebp+edx+0x28]
call ebp
.exit_2:
.exit:
or eax, -1
int 0x40
libc_path db '/kolibrios/lib/libc.dll',0

View File

@ -0,0 +1,30 @@
STACK_SIZE equ 4096
include "app.inc"
align 8
main:
cinvoke _printf, msg_hello
ret
msg_hello db 'Hello world!',0x0D,0x0A,0
align 16
__idata_start:
library libc,'libc.dll'
include 'libc.inc'
__idata_end:
__iend:
__cmdline: rb 256
__pgmname: rb 1024
rb 16
__stack:
__bssend:

View File

@ -0,0 +1,68 @@
; Macroinstructions for making import section
macro library [name,string]
{ common
import.data:
forward
local _label
if defined name#.redundant
if ~ name#.redundant
dd name#.lookup,0,0, _label, name#.address
end if
end if
name#.referred = 1
common
dd 0,0,0,0,0
forward
if defined name#.redundant
if ~ name#.redundant
_label db string,0
rb $ and 1
end if
end if }
macro import name,[label,string]
{ common
rb (- $) and 3
if defined name#.referred
name#.lookup:
forward
if used label
if string eqtype ''
local _label
dd _label
else
dd 80000000h + string
end if
end if
common
if $ > name#.lookup
name#.redundant = 0
dd 0
else
name#.redundant = 1
end if
name#.address:
forward
if used label
if string eqtype ''
label dd _label
else
label dd 80000000h + string
end if
end if
common
if ~ name#.redundant
dd 0
end if
forward
if used label & string eqtype ''
_label dw 0
db string,0
rb $ and 1
end if
common
end if }
macro api [name] {}

View File

@ -0,0 +1,674 @@
import libc,\
__Balloc,'_Balloc',\
__Bfree,'_Bfree',\
__Exit,'_Exit',\
___ChkTTYIOMode,'__ChkTTYIOMode',\
___GetIOMode,'__GetIOMode',\
___SetIOMode,'__SetIOMode',\
___SetIOMode_nogrow,'__SetIOMode_nogrow',\
___allocPOSIXHandle,'__allocPOSIXHandle',\
___any_on,'__any_on',\
___ascii_mbtowc,'__ascii_mbtowc',\
___ascii_wctomb,'__ascii_wctomb',\
___assert_func,'__assert_func',\
___b2d,'__b2d',\
___call_exitprocs,'__call_exitprocs',\
___copybits,'__copybits',\
___cpu_features_init,'__cpu_features_init',\
___ctype_load_locale,'__ctype_load_locale',\
___ctype_ptr__,'__ctype_ptr__',\
___d2b,'__d2b',\
___dorand48,'__dorand48',\
___dtoa,'__dtoa',\
___emutls_get_address,'__emutls_get_address',\
___emutls_register_common,'__emutls_register_common',\
___errno,'__errno',\
___fp_lock_all,'__fp_lock_all',\
___fp_unlock_all,'__fp_unlock_all',\
___fpclassifyd,'__fpclassifyd',\
___fpclassifyf,'__fpclassifyf',\
___freePOSIXHandle,'__freePOSIXHandle',\
___getOSHandle,'__getOSHandle',\
___get_current_ctype_locale,'__get_current_ctype_locale',\
___gethex,'__gethex',\
___gettzinfo,'__gettzinfo',\
___growPOSIXHandles,'__growPOSIXHandles',\
___grow_iomode,'__grow_iomode',\
___gthread_once,'__gthread_once',\
___hexdig_init,'__hexdig_init',\
___hexnan,'__hexnan',\
___hi0bits,'__hi0bits',\
___i2b,'__i2b',\
___ieee754_acos,'__ieee754_acos',\
___ieee754_acosf,'__ieee754_acosf',\
___ieee754_acosh,'__ieee754_acosh',\
___ieee754_acoshf,'__ieee754_acoshf',\
___ieee754_asin,'__ieee754_asin',\
___ieee754_asinf,'__ieee754_asinf',\
___ieee754_atan2,'__ieee754_atan2',\
___ieee754_atan2f,'__ieee754_atan2f',\
___ieee754_atanh,'__ieee754_atanh',\
___ieee754_atanhf,'__ieee754_atanhf',\
___ieee754_cosh,'__ieee754_cosh',\
___ieee754_coshf,'__ieee754_coshf',\
___ieee754_exp,'__ieee754_exp',\
___ieee754_expf,'__ieee754_expf',\
___ieee754_fmod,'__ieee754_fmod',\
___ieee754_fmodf,'__ieee754_fmodf',\
___ieee754_gamma_r,'__ieee754_gamma_r',\
___ieee754_gammaf_r,'__ieee754_gammaf_r',\
___ieee754_hypot,'__ieee754_hypot',\
___ieee754_hypotf,'__ieee754_hypotf',\
___ieee754_j0,'__ieee754_j0',\
___ieee754_j0f,'__ieee754_j0f',\
___ieee754_j1,'__ieee754_j1',\
___ieee754_j1f,'__ieee754_j1f',\
___ieee754_jn,'__ieee754_jn',\
___ieee754_jnf,'__ieee754_jnf',\
___ieee754_lgamma_r,'__ieee754_lgamma_r',\
___ieee754_lgammaf_r,'__ieee754_lgammaf_r',\
___ieee754_log,'__ieee754_log',\
___ieee754_log10,'__ieee754_log10',\
___ieee754_log10f,'__ieee754_log10f',\
___ieee754_logf,'__ieee754_logf',\
___ieee754_pow,'__ieee754_pow',\
___ieee754_powf,'__ieee754_powf',\
___ieee754_rem_pio2,'__ieee754_rem_pio2',\
___ieee754_rem_pio2f,'__ieee754_rem_pio2f',\
___ieee754_remainder,'__ieee754_remainder',\
___ieee754_remainderf,'__ieee754_remainderf',\
___ieee754_scalb,'__ieee754_scalb',\
___ieee754_scalbf,'__ieee754_scalbf',\
___ieee754_sinh,'__ieee754_sinh',\
___ieee754_sinhf,'__ieee754_sinhf',\
___ieee754_sqrt,'__ieee754_sqrt',\
___ieee754_sqrtf,'__ieee754_sqrtf',\
___ieee754_y0,'__ieee754_y0',\
___ieee754_y0f,'__ieee754_y0f',\
___ieee754_y1,'__ieee754_y1',\
___ieee754_y1f,'__ieee754_y1f',\
___ieee754_yn,'__ieee754_yn',\
___ieee754_ynf,'__ieee754_ynf',\
___infinity,'__infinity',\
___infinityf,'__infinityf',\
___infinityld,'__infinityld',\
___init_mode,'__init_mode',\
___io_mode,'__io_mode',\
___isinfd,'__isinfd',\
___isinff,'__isinff',\
___isnand,'__isnand',\
___isnanf,'__isnanf',\
___kernel_cos,'__kernel_cos',\
___kernel_cosf,'__kernel_cosf',\
___kernel_rem_pio2,'__kernel_rem_pio2',\
___kernel_rem_pio2f,'__kernel_rem_pio2f',\
___kernel_sin,'__kernel_sin',\
___kernel_sinf,'__kernel_sinf',\
___kernel_standard,'__kernel_standard',\
___kernel_tan,'__kernel_tan',\
___kernel_tanf,'__kernel_tanf',\
___libc_getenv,'__libc_getenv',\
___lo0bits,'__lo0bits',\
___locale_charset,'__locale_charset',\
___locale_cjk_lang,'__locale_cjk_lang',\
___locale_mb_cur_max,'__locale_mb_cur_max',\
___locale_msgcharset,'__locale_msgcharset',\
___lshift,'__lshift',\
___malloc_lock,'__malloc_lock',\
___malloc_unlock,'__malloc_unlock',\
___mb_cur_max,'__mb_cur_max',\
___mbtowc,'__mbtowc',\
___mcmp,'__mcmp',\
___mdiff,'__mdiff',\
___mlocale_changed,'__mlocale_changed',\
___mprec_bigtens,'__mprec_bigtens',\
___mprec_tens,'__mprec_tens',\
___mprec_tinytens,'__mprec_tinytens',\
___multadd,'__multadd',\
___multiply,'__multiply',\
___mutex_lock,'__mutex_lock',\
___nlocale_changed,'__nlocale_changed',\
___pow5mult,'__pow5mult',\
___ratio,'__ratio',\
___register_exitproc,'__register_exitproc',\
___s2b,'__s2b',\
___sccl,'__sccl',\
___sclose,'__sclose',\
___seofread,'__seofread',\
___setOSHandle,'__setOSHandle',\
___set_handles,'__set_handles',\
___sflags,'__sflags',\
___sflush_r,'__sflush_r',\
___sfmoreglue,'__sfmoreglue',\
___sfp,'__sfp',\
___sfp_lock_acquire,'__sfp_lock_acquire',\
___sfp_lock_release,'__sfp_lock_release',\
___sfvwrite_r,'__sfvwrite_r',\
___shrink_iomode,'__shrink_iomode',\
___signbitd,'__signbitd',\
___signbitf,'__signbitf',\
___sigtramp,'__sigtramp',\
___sigtramp_r,'__sigtramp_r',\
___sinit,'__sinit',\
___sinit_lock_acquire,'__sinit_lock_acquire',\
___sinit_lock_release,'__sinit_lock_release',\
___smakebuf_r,'__smakebuf_r',\
___sprint_r,'__sprint_r',\
___sread,'__sread',\
___srefill_r,'__srefill_r',\
___srget,'__srget',\
___srget_r,'__srget_r',\
___sseek,'__sseek',\
___ssprint_r,'__ssprint_r',\
___ssrefill_r,'__ssrefill_r',\
___ssvfiscanf_r,'__ssvfiscanf_r',\
___ssvfscanf_r,'__ssvfscanf_r',\
___strtok_r,'__strtok_r',\
___submore,'__submore',\
___svfiscanf,'__svfiscanf',\
___svfiscanf_r,'__svfiscanf_r',\
___svfscanf,'__svfscanf',\
___svfscanf_r,'__svfscanf_r',\
___swbuf,'__swbuf',\
___swbuf_r,'__swbuf_r',\
___swrite,'__swrite',\
___swsetup_r,'__swsetup_r',\
___thread_startup,'__thread_startup',\
___tz_lock,'__tz_lock',\
___tz_unlock,'__tz_unlock',\
___tzcalc_limits,'__tzcalc_limits',\
___ulp,'__ulp',\
___wctomb,'__wctomb',\
__assert,'_assert',\
__atoi_r,'_atoi_r',\
__atol_r,'_atol_r',\
__buf_findstr,'_buf_findstr',\
__calloc_r,'_calloc_r',\
__cleanup,'_cleanup',\
__cleanup_r,'_cleanup_r',\
__close_r,'_close_r',\
__ctype_,'_ctype_',\
__daylight,'_daylight',\
__diprintf_r,'_diprintf_r',\
__dprintf_r,'_dprintf_r',\
__dtoa_r,'_dtoa_r',\
__exit,'_exit',\
__f_atan2,'_f_atan2',\
__f_atan2f,'_f_atan2f',\
__f_exp,'_f_exp',\
__f_expf,'_f_expf',\
__f_frexp,'_f_frexp',\
__f_frexpf,'_f_frexpf',\
__f_ldexp,'_f_ldexp',\
__f_ldexpf,'_f_ldexpf',\
__f_llrint,'_f_llrint',\
__f_llrintf,'_f_llrintf',\
__f_llrintl,'_f_llrintl',\
__f_log,'_f_log',\
__f_log10,'_f_log10',\
__f_log10f,'_f_log10f',\
__f_logf,'_f_logf',\
__f_lrint,'_f_lrint',\
__f_lrintf,'_f_lrintf',\
__f_lrintl,'_f_lrintl',\
__f_pow,'_f_pow',\
__f_powf,'_f_powf',\
__f_rint,'_f_rint',\
__f_rintf,'_f_rintf',\
__f_rintl,'_f_rintl',\
__f_tan,'_f_tan',\
__f_tanf,'_f_tanf',\
__fclose_r,'_fclose_r',\
__fdopen_r,'_fdopen_r',\
__fflush_r,'_fflush_r',\
__fgetc_r,'_fgetc_r',\
__fgets_r,'_fgets_r',\
__findenv,'_findenv',\
__fiprintf_r,'_fiprintf_r',\
__fiscanf_r,'_fiscanf_r',\
__fopen_r,'_fopen_r',\
__fprintf_r,'_fprintf_r',\
__fputc_r,'_fputc_r',\
__fputs_r,'_fputs_r',\
__fputwc_r,'_fputwc_r',\
__fread_r,'_fread_r',\
__free_r,'_free_r',\
__freopen_r,'_freopen_r',\
__fscanf_r,'_fscanf_r',\
__fseek_r,'_fseek_r',\
__fseeko_r,'_fseeko_r',\
__fstat_r,'_fstat_r',\
__ftell_r,'_ftell_r',\
__ftello_r,'_ftello_r',\
__fwalk,'_fwalk',\
__fwalk_reent,'_fwalk_reent',\
__fwrite_r,'_fwrite_r',\
__gettimeofday,'_gettimeofday',\
__gettimeofday_r,'_gettimeofday_r',\
__global_impure_ptr,'_global_impure_ptr',\
__grow_handles,'_grow_handles',\
__init_signal,'_init_signal',\
__init_signal_r,'_init_signal_r',\
__isatty,'_isatty',\
__isatty_r,'_isatty_r',\
__kill_r,'_kill_r',\
__localeconv_r,'_localeconv_r',\
__lseek_r,'_lseek_r',\
__malloc_r,'_malloc_r',\
__mbrtowc_r,'_mbrtowc_r',\
__mbtowc_r,'_mbtowc_r',\
__mktm_r,'_mktm_r',\
__mprec_log10,'_mprec_log10',\
__open_r,'_open_r',\
__printf_r,'_printf_r',\
__putc_r,'_putc_r',\
__putchar_r,'_putchar_r',\
__puts_r,'_puts_r',\
__raise_r,'_raise_r',\
__read,'_read',\
__read_r,'_read_r',\
__realloc_r,'_realloc_r',\
__remove_r,'_remove_r',\
__rename_r,'_rename_r',\
__seed48_r,'_seed48_r',\
__setlocale_r,'_setlocale_r',\
__sfread_r,'_sfread_r',\
__signal_r,'_signal_r',\
__siprintf_r,'_siprintf_r',\
__sniprintf_r,'_sniprintf_r',\
__snprintf_r,'_snprintf_r',\
__sprintf_r,'_sprintf_r',\
__srand48_r,'_srand48_r',\
__sscanf_r,'_sscanf_r',\
__strdup_r,'_strdup_r',\
__strerror_r,'_strerror_r',\
__strndup_r,'_strndup_r',\
__strtod_r,'_strtod_r',\
__strtol_r,'_strtol_r',\
__strtoll_r,'_strtoll_r',\
__strtoul_r,'_strtoul_r',\
__strtoull_r,'_strtoull_r',\
__sungetc_r,'_sungetc_r',\
__svfiprintf_r,'_svfiprintf_r',\
__svfprintf_r,'_svfprintf_r',\
__system_r,'_system_r',\
__tempnam_r,'_tempnam_r',\
__times_r,'_times_r',\
__timezone,'_timezone',\
__tls_map,'_tls_map',\
__tmpfile_r,'_tmpfile_r',\
__tmpnam_r,'_tmpnam_r',\
__towctrans_r,'_towctrans_r',\
__tzname,'_tzname',\
__ungetc_r,'_ungetc_r',\
__user_strerror,'_user_strerror',\
__vasniprintf_r,'_vasniprintf_r',\
__vasnprintf_r,'_vasnprintf_r',\
__vdiprintf_r,'_vdiprintf_r',\
__vdprintf_r,'_vdprintf_r',\
__vfiprintf_r,'_vfiprintf_r',\
__vfiscanf_r,'_vfiscanf_r',\
__vfprintf_r,'_vfprintf_r',\
__vfscanf_r,'_vfscanf_r',\
__vscanf_r,'_vscanf_r',\
__vsnprintf_r,'_vsnprintf_r',\
__vsprintf_r,'_vsprintf_r',\
__vsscanf_r,'_vsscanf_r',\
__wcrtomb_r,'_wcrtomb_r',\
__wctomb_r,'_wctomb_r',\
__wctrans_r,'_wctrans_r',\
__wctype_r,'_wctype_r',\
__write_r,'_write_r',\
_abort,'abort',\
_abs,'abs',\
_acos,'acos',\
_acosf,'acosf',\
_acosh,'acosh',\
_acoshf,'acoshf',\
_asctime,'asctime',\
_asctime_r,'asctime_r',\
_asin,'asin',\
_asinf,'asinf',\
_asinh,'asinh',\
_asinhf,'asinhf',\
_atan,'atan',\
_atan2,'atan2',\
_atan2f,'atan2f',\
_atanf,'atanf',\
_atanh,'atanh',\
_atanhf,'atanhf',\
_atof,'atof',\
_atoi,'atoi',\
_atol,'atol',\
_bsearch,'bsearch',\
_calloc,'calloc',\
_cbrt,'cbrt',\
_cbrtf,'cbrtf',\
_ceil,'ceil',\
_ceilf,'ceilf',\
_clearerr,'clearerr',\
_clock,'clock',\
_close,'close',\
_copysign,'copysign',\
_copysignf,'copysignf',\
_cos,'cos',\
_cosf,'cosf',\
_cosh,'cosh',\
_coshf,'coshf',\
_create_file,'create_file',\
_create_image,'create_image',\
_create_thread,'create_thread',\
_ctime,'ctime',\
_ctime_r,'ctime_r',\
_debugwrite,'debugwrite',\
_delete_file,'delete_file',\
_difftime,'difftime',\
_diprintf,'diprintf',\
_div,'div',\
_dprintf,'dprintf',\
_drem,'drem',\
_dremf,'dremf',\
_entry,'entry',\
_envz_get,'envz_get',\
_erf,'erf',\
_erfc,'erfc',\
_erfcf,'erfcf',\
_erff,'erff',\
_exit,'exit',\
_exp,'exp',\
_exp10,'exp10',\
_exp10f,'exp10f',\
_exp2,'exp2',\
_exp2f,'exp2f',\
_expf,'expf',\
_expm1,'expm1',\
_expm1f,'expm1f',\
_fabs,'fabs',\
_fabsf,'fabsf',\
_fclose,'fclose',\
_fdim,'fdim',\
_fdimf,'fdimf',\
_fdopen,'fdopen',\
_fflush,'fflush',\
_fgetc,'fgetc',\
_fgets,'fgets',\
_fileno,'fileno',\
_finite,'finite',\
_finitef,'finitef',\
_fiprintf,'fiprintf',\
_fiscanf,'fiscanf',\
_floor,'floor',\
_floorf,'floorf',\
_fma,'fma',\
_fmaf,'fmaf',\
_fmax,'fmax',\
_fmaxf,'fmaxf',\
_fmin,'fmin',\
_fminf,'fminf',\
_fmod,'fmod',\
_fmodf,'fmodf',\
_fopen,'fopen',\
_fprintf,'fprintf',\
_fputc,'fputc',\
_fputs,'fputs',\
_fputwc,'fputwc',\
_fread,'fread',\
_free,'free',\
_freopen,'freopen',\
_frexp,'frexp',\
_frexpf,'frexpf',\
_fscanf,'fscanf',\
_fseek,'fseek',\
_fseeko,'fseeko',\
_fstat,'fstat',\
_ftell,'ftell',\
_ftello,'ftello',\
_fwrite,'fwrite',\
_gamma,'gamma',\
_gamma_r,'gamma_r',\
_gammaf,'gammaf',\
_gammaf_r,'gammaf_r',\
_get_entry_point,'get_entry_point',\
_get_fileinfo,'get_fileinfo',\
_get_proc_address,'get_proc_address',\
_getenv,'getenv',\
_gettimeofday,'gettimeofday',\
_gmtime,'gmtime',\
_gmtime_r,'gmtime_r',\
_hypot,'hypot',\
_hypotf,'hypotf',\
_ilogb,'ilogb',\
_ilogbf,'ilogbf',\
_infinity,'infinity',\
_infinityf,'infinityf',\
_init_global_reent,'init_global_reent',\
_init_loader,'init_loader',\
_init_reent,'init_reent',\
_isalnum,'isalnum',\
_isalpha,'isalpha',\
_isascii,'isascii',\
_isblank,'isblank',\
_iscntrl,'iscntrl',\
_isdigit,'isdigit',\
_isgraph,'isgraph',\
_isinf,'isinf',\
_isinff,'isinff',\
_islower,'islower',\
_isnan,'isnan',\
_isnanf,'isnanf',\
_isprint,'isprint',\
_ispunct,'ispunct',\
_isspace,'isspace',\
_isupper,'isupper',\
_iswalnum,'iswalnum',\
_iswalpha,'iswalpha',\
_iswblank,'iswblank',\
_iswcntrl,'iswcntrl',\
_iswctype,'iswctype',\
_iswdigit,'iswdigit',\
_iswgraph,'iswgraph',\
_iswlower,'iswlower',\
_iswprint,'iswprint',\
_iswpunct,'iswpunct',\
_iswspace,'iswspace',\
_iswupper,'iswupper',\
_iswxdigit,'iswxdigit',\
_isxdigit,'isxdigit',\
_j0,'j0',\
_j0f,'j0f',\
_j1,'j1',\
_j1f,'j1f',\
_jn,'jn',\
_jnf,'jnf',\
_ldexp,'ldexp',\
_ldexpf,'ldexpf',\
_lgamma,'lgamma',\
_lgamma_r,'lgamma_r',\
_lgammaf,'lgammaf',\
_lgammaf_r,'lgammaf_r',\
_libc_crt_startup,'libc_crt_startup',\
_link_app,'link_app',\
_link_image,'link_image',\
_llrint,'llrint',\
_llrintf,'llrintf',\
_llrintl,'llrintl',\
_llround,'llround',\
_llroundf,'llroundf',\
_load_library,'load_library',\
_loader_env,'loader_env',\
_localeconv,'localeconv',\
_localtime,'localtime',\
_localtime_r,'localtime_r',\
_log,'log',\
_log10,'log10',\
_log10f,'log10f',\
_log1p,'log1p',\
_log1pf,'log1pf',\
_log2,'log2',\
_log2f,'log2f',\
_logb,'logb',\
_logbf,'logbf',\
_logf,'logf',\
_longjmp,'longjmp',\
_lrint,'lrint',\
_lrintf,'lrintf',\
_lrintl,'lrintl',\
_lround,'lround',\
_lroundf,'lroundf',\
_lseek,'lseek',\
_malloc,'malloc',\
_matherr,'matherr',\
_mbrtowc,'mbrtowc',\
_mbtowc,'mbtowc',\
_memalign,'memalign',\
_memchr,'memchr',\
_memcmp,'memcmp',\
_memcpy,'memcpy',\
_memmove,'memmove',\
_memset,'memset',\
_mktime,'mktime',\
_modf,'modf',\
_modff,'modff',\
_nan,'nan',\
_nanf,'nanf',\
_nearbyint,'nearbyint',\
_nearbyintf,'nearbyintf',\
_nextafter,'nextafter',\
_nextafterf,'nextafterf',\
_open,'open',\
_path_list,'path_list',\
_pow,'pow',\
_pow10,'pow10',\
_pow10f,'pow10f',\
_powf,'powf',\
_printf,'printf',\
_putc,'putc',\
_putchar,'putchar',\
_puts,'puts',\
_qsort,'qsort',\
_raise,'raise',\
_rand,'rand',\
_rand_r,'rand_r',\
_read,'read',\
_read_file,'read_file',\
_realloc,'realloc',\
_remainder,'remainder',\
_remainderf,'remainderf',\
_remove,'remove',\
_remquo,'remquo',\
_remquof,'remquof',\
_rename,'rename',\
_rint,'rint',\
_rintf,'rintf',\
_rintl,'rintl',\
_round,'round',\
_roundf,'roundf',\
_scalb,'scalb',\
_scalbf,'scalbf',\
_scalbln,'scalbln',\
_scalblnf,'scalblnf',\
_scalbn,'scalbn',\
_scalbnf,'scalbnf',\
_seed48,'seed48',\
_set_file_size,'set_file_size',\
_setjmp,'setjmp',\
_setlocale,'setlocale',\
_setvbuf,'setvbuf',\
_signal,'signal',\
_significand,'significand',\
_significandf,'significandf',\
_sin,'sin',\
_sincos,'sincos',\
_sincosf,'sincosf',\
_sinf,'sinf',\
_sinh,'sinh',\
_sinhf,'sinhf',\
_siprintf,'siprintf',\
_sniprintf,'sniprintf',\
_snprintf,'snprintf',\
_sprintf,'sprintf',\
_sqrt,'sqrt',\
_sqrtf,'sqrtf',\
_srand,'srand',\
_srand48,'srand48',\
_sscanf,'sscanf',\
_stpcpy,'stpcpy',\
_stpncpy,'stpncpy',\
_strcasecmp,'strcasecmp',\
_strcasestr,'strcasestr',\
_strcat,'strcat',\
_strchr,'strchr',\
_strcmp,'strcmp',\
_strcoll,'strcoll',\
_strcpy,'strcpy',\
_strcspn,'strcspn',\
_strdup,'strdup',\
_strerror,'strerror',\
_strftime,'strftime',\
_strlen,'strlen',\
_strncasecmp,'strncasecmp',\
_strncat,'strncat',\
_strncmp,'strncmp',\
_strncpy,'strncpy',\
_strndup,'strndup',\
_strnlen,'strnlen',\
_strpbrk,'strpbrk',\
_strrchr,'strrchr',\
_strsep,'strsep',\
_strspn,'strspn',\
_strstr,'strstr',\
_strtod,'strtod',\
_strtof,'strtof',\
_strtok,'strtok',\
_strtok_r,'strtok_r',\
_strtol,'strtol',\
_strtoll,'strtoll',\
_strtoul,'strtoul',\
_strtoull,'strtoull',\
_strupr,'strupr',\
_system,'system',\
_tan,'tan',\
_tanf,'tanf',\
_tanh,'tanh',\
_tanhf,'tanhf',\
_tempnam,'tempnam',\
_tgamma,'tgamma',\
_tgammaf,'tgammaf',\
_time,'time',\
_tls_alloc,'tls_alloc',\
_tmpfile,'tmpfile',\
_tmpnam,'tmpnam',\
_toascii,'toascii',\
_tolower,'tolower',\
_toupper,'toupper',\
_towctrans,'towctrans',\
_towlower,'towlower',\
_towupper,'towupper',\
_trunc,'trunc',\
_truncf,'truncf',\
_ungetc,'ungetc',\
_user_alloc,'user_alloc',\
_validate_pe,'validate_pe',\
_vasniprintf,'vasniprintf',\
_vasnprintf,'vasnprintf',\
_vdiprintf,'vdiprintf',\
_vdprintf,'vdprintf',\
_vfiprintf,'vfiprintf',\
_vfiscanf,'vfiscanf',\
_vfprintf,'vfprintf',\
_vfscanf,'vfscanf',\
_vscanf,'vscanf',\
_vsnprintf,'vsnprintf',\
_vsprintf,'vsprintf',\
_vsscanf,'vsscanf',\
_wcrtomb,'wcrtomb',\
_wctrans,'wctrans',\
_wctype,'wctype',\
_write,'write',\
_write_file,'write_file',\
_y0,'y0',\
_y0f,'y0f',\
_y1,'y1',\
_y1f,'y1f',\
_yn,'yn',\
_ynf,'ynf'

View File

@ -0,0 +1,301 @@
; Macroinstructions for defining and calling procedures
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ local loc
loc = (localbytes+3) and (not 3)
parmbase@proc equ ebp+8
localbase@proc equ ebp-loc
if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,loc
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
close@proc equ
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
virtual at parmbase@proc
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $-(parmbase@proc)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
macro locals
\{ virtual at localbase@proc+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(localbase@proc)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc
\{ localbytes = current
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if qqword eq type
dd ?,?,?,?,?,?,?,?
else if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val] { name def val }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match =label, def \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
struc label type { label . type }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count*2
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
rq count*4
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
rq count*2
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
rq count*4
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
dq ?,?,?,?
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
dq ?,?
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
dq ?,?,?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }

View File

@ -0,0 +1,240 @@
; Macroinstructions for defining data structures
macro struct name
{ virtual at 0
fields@struct equ name
match child parent, name \{ fields@struct equ child,fields@\#parent \}
sub@struct equ
struc db [val] \{ \common define field@struct .,db,<val>
fields@struct equ fields@struct,field@struct \}
struc dw [val] \{ \common define field@struct .,dw,<val>
fields@struct equ fields@struct,field@struct \}
struc du [val] \{ \common define field@struct .,du,<val>
fields@struct equ fields@struct,field@struct \}
struc dd [val] \{ \common define field@struct .,dd,<val>
fields@struct equ fields@struct,field@struct \}
struc dp [val] \{ \common define field@struct .,dp,<val>
fields@struct equ fields@struct,field@struct \}
struc dq [val] \{ \common define field@struct .,dq,<val>
fields@struct equ fields@struct,field@struct \}
struc dt [val] \{ \common define field@struct .,dt,<val>
fields@struct equ fields@struct,field@struct \}
struc rb count \{ define field@struct .,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rw count \{ define field@struct .,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rd count \{ define field@struct .,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rp count \{ define field@struct .,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rq count \{ define field@struct .,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rt count \{ define field@struct .,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro db [val] \{ \common \local anonymous
define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
macro dw [val] \{ \common \local anonymous
define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
macro du [val] \{ \common \local anonymous
define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
macro dd [val] \{ \common \local anonymous
define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
macro dp [val] \{ \common \local anonymous
define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
macro dq [val] \{ \common \local anonymous
define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
macro dt [val] \{ \common \local anonymous
define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
macro rb count \{ \local anonymous
define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rw count \{ \local anonymous
define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rd count \{ \local anonymous
define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rp count \{ \local anonymous
define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rq count \{ \local anonymous
define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rt count \{ \local anonymous
define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro union \{ fields@struct equ fields@struct,,union,<
sub@struct equ union \}
macro struct \{ fields@struct equ fields@struct,,substruct,<
sub@struct equ substruct \} }
macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
match any, sub@struct \{ fields@struct equ fields@struct> \}
restore sub@struct }
macro make@struct name,[field,type,def]
{ common
local define
define equ name
forward
local sub
match , field \{ make@substruct type,name,sub def
define equ define,.,sub, \}
match any, field \{ define equ define,.#field,type,<def> \}
common
match fields, define \{ define@struct fields \} }
macro define@struct name,[field,type,def]
{ common
virtual
db `name
load initial@struct byte from 0
if initial@struct = '.'
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
err
end if
end virtual
local list
list equ
forward
if ~ field eq .
name#field type def
sizeof.#name#field = $ - name#field
else
label name#.#type
rb sizeof.#type
end if
local value
match any, list \{ list equ list, \}
list equ list <value>
common
sizeof.#name = $
restruc name
match values, list \{
struc name value \\{ \\local \\..base
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
match , fields@struct \\\{ label \\..base
forward
match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match any, fields@struct \\\{ \\\local anonymous
fields@struct equ fields@struct,anonymous,name,<values> \\\}
match , fields@struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} }
macro enable@substruct
{ macro make@substruct substruct,parent,name,[field,type,def]
\{ \common
\local define
define equ parent,name
\forward
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\common
match fields, define \\{ define@\#substruct fields \\} \} }
enable@substruct
macro define@union parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
virtual at parent#.#name
parent#field type def
sizeof.#parent#field = $ - parent#field
end virtual
if sizeof.#parent#field > $ - parent#.#name
rb sizeof.#parent#field - ($ - parent#.#name)
end if
else
virtual at parent#.#name
label parent#.#type
type def
end virtual
label name#.#type at parent#.#name
if sizeof.#type > $ - parent#.#name
rb sizeof.#type - ($ - parent#.#name)
end if
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name [value] \{ \common
label .\#name
last@union equ
forward
match any, last@union \\{ virtual at .\#name
field type def
end virtual \\}
match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\}
last@union equ field
common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
macro define@substruct parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
parent#field type def
sizeof.#parent#field = $ - parent#field
else
label parent#.#type
rb sizeof.#type
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name value \{
label .\#name
forward
match , value \\{ field type def \\}
match any, value \\{ field type value
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
common \}
macro name value \{ \local ..anonymous
..anonymous name \} }