add flat assembler toolchain

This commit is contained in:
2024-11-24 23:13:28 -05:00
parent 99e8e4072b
commit dbfd94ea40
302 changed files with 145599 additions and 0 deletions

View File

@ -0,0 +1,470 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct SCNHDR
s_name db 8 dup ?
s_paddr dd ?
s_vaddr dd ?
s_size dd ?
s_scnptr dd ?
s_relptr dd ?
s_lnnoptr dd ?
s_nreloc dw ?
s_nlnno dw ?
s_flags dd ?
end struct
SCNHSZ = sizeof SCNHDR
struct RELOC
r_vaddr dd ?
r_symndx dd ?
r_type dw ?
end struct
RELSZ = sizeof RELOC
struct SYMENT
e_name db 8 dup ?
virtual at e_name
e_zeroes dd ?
e_offset dd ?
end virtual
e_value dd ?
e_scnum dw ?
e_type dw ?
e_sclass db ?
e_numaux db ?
end struct
SYMESZ = sizeof SYMENT
I386MAGIC = 0x14c
F_RELFLG = 0x0001
F_EXEC = 0x0002
F_LNNO = 0x0004
F_LSYMS = 0x0008
F_AR32WR = 0x0100
STYP_TEXT = 0x0020
STYP_DATA = 0x0040
STYP_BSS = 0x0080
N_UNDEF = 0
N_ABS = -1
N_DEBUG = -2
T_NULL = 0000b
T_VOID = 0001b
T_CHAR = 0010b
T_SHORT = 0011b
T_INT = 0100b
T_LONG = 0101b
T_FLOAT = 0110b
T_DOUBLE = 0111b
T_STRUCT = 1000b
T_UNION = 1001b
T_ENUM = 1010b
T_MOE = 1011b
T_UCHAR = 1100b
T_USHORT = 1101b
T_UINT = 1110b
T_ULONG = 1111b
T_LNGDBL = 01_0000b
DT_NON = 00b
DT_PTR = 01b
DT_FCN = 10b
DT_ARY = 11b
C_NULL = 0
C_AUTO = 1
C_EXT = 2
C_STAT = 3
C_REG = 4
C_EXTDEF = 5
C_LABEL = 6
C_ULABEL = 7
C_MOS = 8
C_ARG = 9
C_STRTAG = 10
C_MOU = 11
C_UNTAG = 12
C_TPDEF = 13
C_USTATIC = 14
C_ENTAG = 15
C_MOE = 16
C_REGPARM = 17
C_FIELD = 18
C_AUTOARG = 19
C_LASTENT = 20
C_BLOCK = 100
C_FCN = 101
C_EOS = 102
C_FILE = 103
C_LINE = 104
C_ALIAS = 105
C_HIDDEN = 106
C_EFCN = 255
RELOC_ADDR32 = 6
RELOC_REL32 = 20
COFF::
namespace COFF
Header:
f_magic dw I386MAGIC
f_nscns dw NUMBER_OF_SECTIONS
f_timdat dd __TIME__
f_symptr dd SYMBOL_TABLE_OFFSET
f_nsyms dd NUMBER_OF_SYMBOLS
f_opthdr dw 0
f_flags dw F_AR32WR + F_LNNO
Sections: db NUMBER_OF_SECTIONS * SCNHSZ dup 0
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * SYMESZ
end virtual
virtual at 0
string_table:: dd STRING_TABLE_SIZE
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * RELSZ
end virtual
element relocatable?
macro section_start
local sym
element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX
SECTION_BASE = sym
org sym
if DEFINED_SECTION | defined DEFAULT_SECTION
store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
store C_STAT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum
SYMBOL_INDEX = SYMBOL_INDEX + 1
end if
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 0
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = STYP_TEXT + STYP_DATA
DEFINED_SECTION = 0
section_start
end namespace
macro section?
namespace COFF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
if ~ DEFINED_SECTION
DEFAULT_SECTION := 1
end if
if $%% = SECTION_OFFSET
SECTION_FLAGS = SECTION_FLAGS or STYP_BSS
SECTION_OFFSET = 0
section $
else
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_name
store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_scnptr
store SECTION_SIZE at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_size
store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_flags
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_nreloc
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * RELSZ at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_relptr
end if
SECTION_INDEX = SECTION_INDEX + 1
end if
end namespace
end macro
macro section? declaration*
namespace COFF
section
DEFINED_SECTION = 1
SECTION_FLAGS = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
define seq attributes
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =code?, attribute
SECTION_FLAGS = SECTION_FLAGS or STYP_TEXT
else match =data?, attribute
SECTION_FLAGS = SECTION_FLAGS or STYP_DATA
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_start
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check COFF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace COFF
match =static? value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = C_STAT
else match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = C_EXT
else match =static? value, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = `value
SYMBOL_CLASS = C_STAT
else
SYMBOL_VALUE = declaration
SYMBOL_NAME = `declaration
SYMBOL_CLASS = C_EXT
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = N_ABS
end if
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
end if
store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_value
store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum
store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace COFF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
SYMBOL_NAME = string str
else match name:size, declaration
label name:size at sym
SYMBOL_NAME = `name
else match str =as? name, declaration
label name at sym
SYMBOL_NAME = string str
else
label declaration at sym
SYMBOL_NAME = `declaration
end match
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name
end if
store C_EXT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr32
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
addr32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, RELOC_ADDR32
jump add_relocation
rel32:
compute value, value + COFF.SECTION_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, RELOC_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local reloc
compute reloc, COFF.RELOCATION_INDEX * RELSZ
asm store offset at COFF.relocations : reloc + RELOC.r_vaddr
asm store symndx at COFF.relocations : reloc + RELOC.r_symndx
asm store type at COFF.relocations : reloc + RELOC.r_type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
postpone
purge section?
section
namespace COFF
NUMBER_OF_SECTIONS := SECTION_INDEX
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * RELSZ from relocations:0
db byte_sequence
SYMBOL_TABLE_OFFSET = $%
load byte_sequence : NUMBER_OF_SYMBOLS * SYMESZ from symbol_table:0
db byte_sequence
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,754 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct IMAGE_SECTION_HEADER
Name db 8 dup ?
VirtualSize dd ?
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
end struct
struct IMAGE_RELOCATION
VirtualAddress dd ?
SymbolTableIndex dd ?
Type dw ?
end struct
struct IMAGE_SYMBOL
ShortName db 8 dup ?
virtual at ShortName
Zeroes dd ?
Offset dd ?
end virtual
Value dd ?
SectionNumber dw ?
Type dw ?
StorageClass db ?
NumberOfAuxSymbols db ?
end struct
IMAGE_FILE_MACHINE_UNKNOWN = 0x0
IMAGE_FILE_MACHINE_AM33 = 0x1D3
IMAGE_FILE_MACHINE_AMD64 = 0x8664
IMAGE_FILE_MACHINE_ARM = 0x1C0
IMAGE_FILE_MACHINE_ARMNT = 0x1C4
IMAGE_FILE_MACHINE_ARM64 = 0xAA64
IMAGE_FILE_MACHINE_EBC = 0xEBC
IMAGE_FILE_MACHINE_I386 = 0x14C
IMAGE_FILE_MACHINE_IA64 = 0x200
IMAGE_FILE_MACHINE_M32R = 0x9041
IMAGE_FILE_MACHINE_MIPS16 = 0x266
IMAGE_FILE_MACHINE_MIPSFPU = 0x366
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
IMAGE_FILE_MACHINE_POWERPC = 0x1F0
IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1
IMAGE_FILE_MACHINE_R4000 = 0x166
IMAGE_FILE_MACHINE_SH3 = 0x1A2
IMAGE_FILE_MACHINE_SH3DSP = 0x1A3
IMAGE_FILE_MACHINE_SH4 = 0x1A6
IMAGE_FILE_MACHINE_SH5 = 0x1A8
IMAGE_FILE_MACHINE_THUMB = 0x1C2
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
IMAGE_FILE_RELOCS_STRIPPED = 0x0001
IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002
IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004
IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008
IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010
IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020
IMAGE_FILE_BYTES_REVERSED_LO = 0x0080
IMAGE_FILE_32BIT_MACHINE = 0x0100
IMAGE_FILE_DEBUG_STRIPPED = 0x0200
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400
IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800
IMAGE_FILE_SYSTEM = 0x1000
IMAGE_FILE_DLL = 0x2000
IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
IMAGE_SCN_TYPE_NO_PAD = 0x00000008
IMAGE_SCN_CNT_CODE = 0x00000020
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040
IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080
IMAGE_SCN_LNK_OTHER = 0x00000100
IMAGE_SCN_LNK_INFO = 0x00000200
IMAGE_SCN_LNK_REMOVE = 0x00000800
IMAGE_SCN_LNK_COMDAT = 0x00001000
IMAGE_SCN_GPREL = 0x00008000
IMAGE_SCN_MEM_PURGEABLE = 0x00020000
IMAGE_SCN_MEM_16BIT = 0x00020000
IMAGE_SCN_MEM_LOCKED = 0x00040000
IMAGE_SCN_MEM_PRELOAD = 0x00080000
IMAGE_SCN_ALIGN_1BYTES = 0x00100000
IMAGE_SCN_ALIGN_2BYTES = 0x00200000
IMAGE_SCN_ALIGN_4BYTES = 0x00300000
IMAGE_SCN_ALIGN_8BYTES = 0x00400000
IMAGE_SCN_ALIGN_16BYTES = 0x00500000
IMAGE_SCN_ALIGN_32BYTES = 0x00600000
IMAGE_SCN_ALIGN_64BYTES = 0x00700000
IMAGE_SCN_ALIGN_128BYTES = 0x00800000
IMAGE_SCN_ALIGN_256BYTES = 0x00900000
IMAGE_SCN_ALIGN_512BYTES = 0x00A00000
IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000
IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000
IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000
IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000
IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000
IMAGE_SCN_MEM_DISCARDABLE = 0x02000000
IMAGE_SCN_MEM_NOT_CACHED = 0x04000000
IMAGE_SCN_MEM_NOT_PAGED = 0x08000000
IMAGE_SCN_MEM_SHARED = 0x10000000
IMAGE_SCN_MEM_EXECUTE = 0x20000000
IMAGE_SCN_MEM_READ = 0x40000000
IMAGE_SCN_MEM_WRITE = 0x80000000
IMAGE_REL_AMD64_ABSOLUTE = 0x0000
IMAGE_REL_AMD64_ADDR64 = 0x0001
IMAGE_REL_AMD64_ADDR32 = 0x0002
IMAGE_REL_AMD64_ADDR32NB = 0x0003
IMAGE_REL_AMD64_REL32 = 0x0004
IMAGE_REL_AMD64_REL32_1 = 0x0005
IMAGE_REL_AMD64_REL32_2 = 0x0006
IMAGE_REL_AMD64_REL32_3 = 0x0007
IMAGE_REL_AMD64_REL32_4 = 0x0008
IMAGE_REL_AMD64_REL32_5 = 0x0009
IMAGE_REL_AMD64_SECTION = 0x000A
IMAGE_REL_AMD64_SECREL = 0x000B
IMAGE_REL_AMD64_SECREL7 = 0x000C
IMAGE_REL_AMD64_TOKEN = 0x000D
IMAGE_REL_AMD64_SREL32 = 0x000E
IMAGE_REL_AMD64_PAIR = 0x000F
IMAGE_REL_AMD64_SSPAN32 = 0x0010
IMAGE_REL_I386_ABSOLUTE = 0x0000
IMAGE_REL_I386_DIR16 = 0x0001
IMAGE_REL_I386_REL16 = 0x0002
IMAGE_REL_I386_DIR32 = 0x0006
IMAGE_REL_I386_DIR32NB = 0x0007
IMAGE_REL_I386_SEG12 = 0x0009
IMAGE_REL_I386_SECTION = 0x000A
IMAGE_REL_I386_SECREL = 0x000B
IMAGE_REL_I386_TOKEN = 0x000C
IMAGE_REL_I386_SECREL7 = 0x000D
IMAGE_REL_I386_REL32 = 0x0014
IMAGE_SYM_UNDEFINED = 0
IMAGE_SYM_ABSOLUTE = -1
IMAGE_SYM_DEBUG = -2
IMAGE_SYM_TYPE_NULL = 0
IMAGE_SYM_TYPE_VOID = 1
IMAGE_SYM_TYPE_CHAR = 2
IMAGE_SYM_TYPE_SHORT = 3
IMAGE_SYM_TYPE_INT = 4
IMAGE_SYM_TYPE_LONG = 5
IMAGE_SYM_TYPE_FLOAT = 6
IMAGE_SYM_TYPE_DOUBLE = 7
IMAGE_SYM_TYPE_STRUCT = 8
IMAGE_SYM_TYPE_UNION = 9
IMAGE_SYM_TYPE_ENUM = 10
IMAGE_SYM_TYPE_MOE = 11
IMAGE_SYM_TYPE_BYTE = 12
IMAGE_SYM_TYPE_WORD = 13
IMAGE_SYM_TYPE_UINT = 14
IMAGE_SYM_TYPE_DWORD = 15
IMAGE_SYM_DTYPE_NULL = 0
IMAGE_SYM_DTYPE_POINTER = 1
IMAGE_SYM_DTYPE_FUNCTION = 2
IMAGE_SYM_DTYPE_ARRAY = 3
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1
IMAGE_SYM_CLASS_NULL = 0
IMAGE_SYM_CLASS_AUTOMATIC = 1
IMAGE_SYM_CLASS_EXTERNAL = 2
IMAGE_SYM_CLASS_STATIC = 3
IMAGE_SYM_CLASS_REGISTER = 4
IMAGE_SYM_CLASS_EXTERNAL_DEF = 5
IMAGE_SYM_CLASS_LABEL = 6
IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8
IMAGE_SYM_CLASS_ARGUMENT = 9
IMAGE_SYM_CLASS_STRUCT_TAG = 10
IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11
IMAGE_SYM_CLASS_UNION_TAG = 12
IMAGE_SYM_CLASS_TYPE_DEFINITION = 13
IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14
IMAGE_SYM_CLASS_ENUM_TAG = 15
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16
IMAGE_SYM_CLASS_REGISTER_PARAM = 17
IMAGE_SYM_CLASS_BIT_FIELD = 18
IMAGE_SYM_CLASS_BLOCK = 100
IMAGE_SYM_CLASS_FUNCTION = 101
IMAGE_SYM_CLASS_END_OF_STRUCT = 102
IMAGE_SYM_CLASS_FILE = 103
IMAGE_SYM_CLASS_SECTION = 104
IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105
IMAGE_SYM_CLASS_CLR_TOKEN = 107
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1
IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2
IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
COFF::
namespace COFF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := IMAGE_FILE_MACHINE_I386
end if
if defined Settings.Characteristics
CHARACTERISTICS = Settings.Characteristics
else
CHARACTERISTICS = IMAGE_FILE_32BIT_MACHINE
end if
Header:
Machine dw MACHINE
NumberOfSections dw NUMBER_OF_SECTIONS
TimeDateStamp dd __TIME__
PointerToSymbolTable dd SYMBOL_TABLE_OFFSET
NumberOfSymbols dd NUMBER_OF_SYMBOLS
SizeOfOptionalHeader dw 0
Characteristics dw CHARACTERISTICS
Sections: db NUMBER_OF_SECTIONS * sizeof IMAGE_SECTION_HEADER dup 0
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL
end virtual
virtual at 0
string_table:: dd STRING_TABLE_SIZE
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION
end virtual
element relocatable?
macro section_start
local sym
element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX
SECTION_BASE = sym
org sym
if DEFINED_SECTION | defined DEFAULT_SECTION
store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
store IMAGE_SYM_CLASS_STATIC at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber
SYMBOL_INDEX = SYMBOL_INDEX + 1
end if
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 0
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = IMAGE_SCN_CNT_CODE + IMAGE_SCN_CNT_INITIALIZED_DATA
DEFINED_SECTION = 0
section_start
end namespace
macro section?
namespace COFF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
if ~ DEFINED_SECTION
DEFAULT_SECTION := 1
end if
if $%% = SECTION_OFFSET
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
SECTION_OFFSET = 0
section $
else
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRelocations
if RELOCATION_INDEX - SECTION_RELOCATION_INDEX > 65535
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_NRELOC_OVFL
store 0FFFFh at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations
load RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION from relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION
store RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION at relocations : (SECTION_RELOCATION_INDEX+1) * sizeof IMAGE_RELOCATION
RELOCATION_INDEX = RELOCATION_INDEX + 1
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.VirtualAddress
store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.SymbolTableIndex
store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.Type
else
store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations
end if
end if
store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Name
store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRawData
store SECTION_SIZE at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.SizeOfRawData
store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Characteristics
SECTION_INDEX = SECTION_INDEX + 1
end if
end namespace
end macro
macro section? declaration*
namespace COFF
section
DEFINED_SECTION = 1
SECTION_FLAGS = 0
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =code?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_CODE
else match =data?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_INITIALIZED_DATA
else match =readable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_READ
else match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_EXECUTE
else match =shareable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_SHARED
else match =discardable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_DISCARDABLE
else match =notpageable?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_NOT_PAGED
else match =linkremove?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_REMOVE
else match =linkinfo?, attribute
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_INFO
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
repeat 1, i:SECTION_ALIGN
if defined IMAGE_SCN_ALIGN_#i#BYTES
SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_ALIGN_#i#BYTES
else
err 'invalid section alignment'
end if
end repeat
section_start
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check COFF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace COFF
match =static? value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC
else match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = string str
SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
else match =static? value, declaration
SYMBOL_VALUE = value
SYMBOL_NAME = `value
SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC
else
SYMBOL_VALUE = declaration
SYMBOL_NAME = `declaration
SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL
if 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = IMAGE_SYM_UNDEFINED
SYMBOL_VALUE = 0
SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL
SYMBOL_TAG = 0 scaleof (1 metadataof SYMBOL_VALUE)
end if
else
SYMBOL_SECTION_INDEX = IMAGE_SYM_ABSOLUTE
end if
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
end if
store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Value
store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber
store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
if SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL
store 1 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.NumberOfAuxSymbols
SYMBOL_INDEX = SYMBOL_INDEX + 1
store SYMBOL_TAG : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL
store IMAGE_WEAK_EXTERN_SEARCH_ALIAS : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + 4
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace COFF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
SYMBOL_NAME = string str
else match name:size, declaration
label name:size at sym
SYMBOL_NAME = `name
else match str =as? name, declaration
label name at sym
SYMBOL_NAME = string str
else
label declaration at sym
SYMBOL_NAME = `declaration
end match
if lengthof SYMBOL_NAME > 8
store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes
store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
else
store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName
end if
store IMAGE_SYM_CLASS_EXTERNAL at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element COFF.IMAGE_BASE
RVA? equ -COFF.IMAGE_BASE+
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
if COFF.MACHINE = IMAGE_FILE_MACHINE_I386
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes dir32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes dir32nb
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
dir32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32
jump add_relocation
dir32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32NB
jump add_relocation
rel32:
compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET)
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes dir32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes dir32nb
plain:
emit 8, value
exit
local offset, symndx, type
dir32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32
jump add_relocation
dir32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_I386_DIR32NB
jump add_relocation
add_relocation:
compute offset, $%
emit 8, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
else if COFF.MACHINE = IMAGE_FILE_MACHINE_AMD64
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr32
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes addr32nb
check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable
jyes rel32
plain:
emit 4, value
exit
local offset, symndx, type
addr32:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR32
jump add_relocation
addr32nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR32NB
jump add_relocation
rel32:
compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET)
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_REL32
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable
jyes addr64
check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable
jyes addr64nb
plain:
emit 8, value
exit
local offset, symndx, type
addr64:
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR64
jump add_relocation
addr64nb:
compute value, value + COFF.IMAGE_BASE
compute symndx, 0 scaleof (1 metadataof value)
compute type, IMAGE_REL_AMD64_ADDR64NB
jump add_relocation
add_relocation:
compute offset, $%
emit 8, 0 scaleof value
check $% > offset
jno done
compute offset, offset - COFF.SECTION_OFFSET
local relocation
compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION
asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress
asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex
asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type
compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1
done:
end calminstruction
end if
iterate <dd,dword>, dd,dword, dq,qword
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
end iterate
postpone
purge section?
section
namespace COFF
NUMBER_OF_SECTIONS := SECTION_INDEX
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION from relocations:0
db byte_sequence
SYMBOL_TABLE_OFFSET = $%
load byte_sequence : NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL from symbol_table:0
db byte_sequence
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,640 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct Elf32_Shdr
sh_name dd ?
sh_type dd ?
sh_flags dd ?
sh_addr dd ?
sh_offset dd ?
sh_size dd ?
sh_link dd ?
sh_info dd ?
sh_addralign dd ?
sh_entsize dd ?
end struct
struct Elf32_Sym
st_name dd ?
st_value dd ?
st_size dd ?
st_info db ?
st_other db ?
st_shndx dw ?
end struct
struct Elf32_Rel
r_offset dd ?
r_info dd ?
end struct
struct Elf32_Rela
r_offset dd ?
r_info dd ?
r_addend dd ?
end struct
struct Elf32_Phdr
p_type dd ?
p_offset dd ?
p_vaddr dd ?
p_paddr dd ?
p_filesz dd ?
p_memsz dd ?
p_flags dd ?
p_align dd ?
end struct
purge struct?
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_M32 = 1
EM_SPARC = 2
EM_386 = 3
EM_68K = 4
EM_88K = 5
EM_860 = 7
EM_MIPS = 8
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
SHN_UNDEF = 0
SHN_LORESERVE = 0xff00
SHN_LOPROC = 0xff00
SHN_HIPROC = 0xff1f
SHN_ABS = 0xfff1
SHN_COMMON = 0xfff2
SHN_HIRESERVE = 0xffff
SHT_NULL = 0
SHT_PROGBITS = 1
SHT_SYMTAB = 2
SHT_STRTAB = 3
SHT_RELA = 4
SHT_HASH = 5
SHT_DYNAMIC = 6
SHT_NOTE = 7
SHT_NOBITS = 8
SHT_REL = 9
SHT_SHLIB = 10
SHT_DYNSYM = 11
SHT_LOPROC = 0x70000000
SHT_HIPROC = 0x7fffffff
SHT_LOUSER = 0x80000000
SHT_HIUSER = 0xffffffff
SHF_WRITE = 0x1
SHF_ALLOC = 0x2
SHF_EXECINSTR = 0x4
SHF_MASKPROC = 0xf0000000
STT_NOTYPE = 0
STT_OBJECT = 1
STT_FUNC = 2
STT_SECTION = 3
STT_FILE = 4
STT_LOPROC = 13
STT_HIPROC = 15
STB_LOCAL = 0
STB_GLOBAL = 1
STB_WEAK = 2
STB_LOPROC = 13
STB_HIPROC = 15
R_386_NONE = 0
R_386_32 = 1
R_386_PC32 = 2
R_386_GOT32 = 3
R_386_PLT32 = 4
R_386_COPY = 5
R_386_GLOB_DAT = 6
R_386_JMP_SLOT = 7
R_386_RELATIVE = 8
R_386_GOTOFF = 9
R_386_GOTPC = 10
R_X86_64_NONE = 0
R_X86_64_64 = 1
R_X86_64_PC32 = 2
R_X86_64_GOT32 = 3
R_X86_64_PLT32 = 4
R_X86_64_COPY = 5
R_X86_64_GLOB_DAT = 6
R_X86_64_JUMP_SLOT = 7
R_X86_64_RELATIVE = 8
R_X86_64_GOTPCREL = 9
R_X86_64_32 = 10
R_X86_64_32S = 11
R_X86_64_16 = 12
R_X86_64_PC16 = 13
R_X86_64_8 = 14
R_X86_64_PC8 = 15
R_X86_64_DPTMOD64 = 16
R_X86_64_DTPOFF64 = 17
R_X86_64_TPOFF64 = 18
R_X86_64_TLSGD = 19
R_X86_64_TLSLD = 20
R_X86_64_DTPOFF32 = 21
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_PC64 = 24
R_X86_64_GOTOFF64 = 25
R_X86_64_GOTPC32 = 26
ELF::
namespace ELF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_386
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if MACHINE = EM_386
R_32 = R_386_32
R_PC32 = R_386_PC32
R_GOTOFF = R_386_GOTOFF
R_PLT32 = R_386_PLT32
else if MACHINE = EM_X86_64
R_32 = R_X86_64_32
R_PC32 = R_X86_64_PC32
R_PLT32 = R_X86_64_PLT32
end if
Header:
e_ident db 0x7F,'ELF',ELFCLASS32,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw ET_REL
e_machine dw MACHINE
e_version dd EV_CURRENT
e_entry dd 0
e_phoff dd 0
e_shoff dd SECTION_TABLE_OFFSET
e_flags dd 0
e_ehsize dw Content
e_phentsize dw 0
e_phnum dw 0
e_shentsize dw sizeof Elf32_Shdr
e_shnum dw NUMBER_OF_SECTIONS
e_shstrndx dw STRING_TABLE_SECTION_INDEX
Content:
virtual at 0
section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf32_Shdr
end virtual
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf32_Sym
end virtual
virtual at 0
string_table::
_null db 0
_symtab db '.symtab',0
_strtab db '.strtab',0
SECTION_NAME_POSITION = $
rb SECTION_NAME_TABLE_SIZE - $
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel
end virtual
element relocatable?
macro section_org
local sym
element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX
SECTION_BASE = sym
org sym
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 1
SECTION_SYMBOL_INDEX = SECTION_INDEX
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS
SECTION_OFFSET = $%
SECTION_ALIGN = 4
SECTION_NAME = '.flat'
SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR
DEFINED_SECTION = 0
section_org
end namespace
macro section?
namespace ELF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
store SECTION_OFFSET at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_ALIGN at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_FLAGS at section_table : Elf32_Shdr.sh_flags + SECTION_INDEX * sizeof Elf32_Shdr
if $%% = SECTION_OFFSET
store SHT_NOBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
section $
else
store SHT_PROGBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf32_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SHT_REL at section_table : Elf32_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_INDEX at section_table : Elf32_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store 4 at section_table : Elf32_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf32_Shdr
store SECTION_NAME_POSITION + 4 at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_NAME_POSITION + 4 at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store '.rel' + SECTION_NAME shl (4*8) : 4 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + 4 + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 2
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
else
store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store SECTION_NAME_POSITION at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym
store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 1
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
end if
end if
end namespace
end macro
macro section? declaration*
namespace ELF
section
DEFINED_SECTION = 1
SECTION_FLAGS = SHF_ALLOC
SECTION_OFFSET = $%
SECTION_ALIGN = 4
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_org
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check ELF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace ELF
match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_SIZE = sizeof value
SYMBOL_NAME = string str
else
SYMBOL_VALUE = declaration
SYMBOL_SIZE = sizeof declaration
SYMBOL_NAME = `declaration
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = SHN_ABS
end if
store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_VALUE at symbol_table : Elf32_Sym.st_value + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf32_Sym
if SYMBOL_SIZE
store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
else
store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace ELF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
element psym : PLT + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = size
else match name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = `name
SYMBOL_SIZE = size
else match str =as? name, declaration
label name at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = 0
else
label declaration at sym
label PLT.declaration at psym
SYMBOL_NAME = `declaration
SYMBOL_SIZE = 0
end match
store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym
store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element _GLOBAL_OFFSET_TABLE_
RVA? equ -_GLOBAL_OFFSET_TABLE_+
element PLT?
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_32
check ~ value relativeto 0 & (value + _GLOBAL_OFFSET_TABLE_) relativeto 1 elementof (value + _GLOBAL_OFFSET_TABLE_) & 1 elementof (1 metadataof (value + _GLOBAL_OFFSET_TABLE_)) relativeto ELF.relocatable
jyes r_gotoff
check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable
jyes r_pc32
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT
jyes r_plt32
plain:
emit 4, value
exit
local offset, info
r_32:
compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_gotoff:
compute value, value + _GLOBAL_OFFSET_TABLE_
compute info, ELF.R_GOTOFF + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_pc32:
compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET)
compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
r_plt32:
compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET)
compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 8
jump add_relocation
add_relocation:
compute offset, $%
emit 4, 0 scaleof value
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
local Rel
compute Rel, ELF.RELOCATION_INDEX * sizeof Elf32_Rel
asm store offset at ELF.relocations : Rel + Elf32_Rel.r_offset
asm store info at ELF.relocations : Rel + Elf32_Rel.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
postpone
purge section?
section
namespace ELF
SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf32_Sym
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
rb (-$%) and 11b
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel from relocations:0
db byte_sequence
store _symtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store SYMBOL_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store sizeof Elf32_Sym at section_table : Elf32_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf32_Shdr
store 4 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SHT_SYMTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
store STRING_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + SECTION_INDEX * sizeof Elf32_Shdr
store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf32_Shdr.sh_info + SECTION_INDEX * sizeof Elf32_Shdr
SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
store _strtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr
store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr
store STRING_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr
store 1 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr
store SHT_STRTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr
STRING_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
assert SECTION_INDEX <= SHN_LORESERVE
NUMBER_OF_SECTIONS := SECTION_INDEX
rb (-$%) and 11b
SECTION_TABLE_OFFSET := $%
load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf32_Shdr from section_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,652 @@
macro struct? name
macro end?.struct?!
end namespace
esc end struc
virtual at 0
name name
sizeof.name = $
end virtual
purge end?.struct?
end macro
esc struc name
label . : sizeof.name
namespace .
end macro
struct Elf64_Shdr
sh_name dd ?
sh_type dd ?
sh_flags dq ?
sh_addr dq ?
sh_offset dq ?
sh_size dq ?
sh_link dd ?
sh_info dd ?
sh_addralign dq ?
sh_entsize dq ?
end struct
struct Elf64_Sym
st_name dd ?
st_info db ?
st_other db ?
st_shndx dw ?
st_value dq ?
st_size dq ?
end struct
struct Elf64_Rel
r_offset dq ?
r_info dq ?
end struct
struct Elf64_Rela
r_offset dq ?
r_info dq ?
r_addend dq ?
end struct
struct Elf64_Phdr
p_type dd ?
p_flags dd ?
p_offset dq ?
p_vaddr dq ?
p_paddr dq ?
p_filesz dq ?
p_memsz dq ?
p_align dq ?
end struct
purge struct?
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_IA_64 = 50
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
SHN_UNDEF = 0
SHN_LORESERVE = 0xff00
SHN_LOPROC = 0xff00
SHN_HIPROC = 0xff1f
SHN_ABS = 0xfff1
SHN_COMMON = 0xfff2
SHN_HIRESERVE = 0xffff
SHT_NULL = 0
SHT_PROGBITS = 1
SHT_SYMTAB = 2
SHT_STRTAB = 3
SHT_RELA = 4
SHT_HASH = 5
SHT_DYNAMIC = 6
SHT_NOTE = 7
SHT_NOBITS = 8
SHT_REL = 9
SHT_SHLIB = 10
SHT_DYNSYM = 11
SHT_LOPROC = 0x70000000
SHT_HIPROC = 0x7fffffff
SHT_LOUSER = 0x80000000
SHT_HIUSER = 0xffffffff
SHF_WRITE = 0x1
SHF_ALLOC = 0x2
SHF_EXECINSTR = 0x4
SHF_MASKPROC = 0xf0000000
STT_NOTYPE = 0
STT_OBJECT = 1
STT_FUNC = 2
STT_SECTION = 3
STT_FILE = 4
STT_LOPROC = 13
STT_HIPROC = 15
STB_LOCAL = 0
STB_GLOBAL = 1
STB_WEAK = 2
STB_LOPROC = 13
STB_HIPROC = 15
R_X86_64_NONE = 0
R_X86_64_64 = 1
R_X86_64_PC32 = 2
R_X86_64_GOT32 = 3
R_X86_64_PLT32 = 4
R_X86_64_COPY = 5
R_X86_64_GLOB_DAT = 6
R_X86_64_JUMP_SLOT = 7
R_X86_64_RELATIVE = 8
R_X86_64_GOTPCREL = 9
R_X86_64_32 = 10
R_X86_64_32S = 11
R_X86_64_16 = 12
R_X86_64_PC16 = 13
R_X86_64_8 = 14
R_X86_64_PC8 = 15
R_X86_64_DPTMOD64 = 16
R_X86_64_DTPOFF64 = 17
R_X86_64_TPOFF64 = 18
R_X86_64_TLSGD = 19
R_X86_64_TLSLD = 20
R_X86_64_DTPOFF32 = 21
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_PC64 = 24
R_X86_64_GOTOFF64 = 25
R_X86_64_GOTPC32 = 26
ELF::
namespace ELF
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_X86_64
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if MACHINE = EM_X86_64
R_64 = R_X86_64_64
R_32 = R_X86_64_32S
R_PC32 = R_X86_64_PC32
R_PLT32 = R_X86_64_PLT32
end if
Header:
e_ident db 0x7F,'ELF',ELFCLASS64,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw ET_REL
e_machine dw MACHINE
e_version dd EV_CURRENT
e_entry dq 0
e_phoff dq 0
e_shoff dq SECTION_TABLE_OFFSET
e_flags dd 0
e_ehsize dw Content
e_phentsize dw 0
e_phnum dw 0
e_shentsize dw sizeof Elf64_Shdr
e_shnum dw NUMBER_OF_SECTIONS
e_shstrndx dw STRING_TABLE_SECTION_INDEX
Content:
virtual at 0
section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf64_Shdr
end virtual
virtual at 0
symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf64_Sym
end virtual
virtual at 0
string_table::
_null db 0
_symtab db '.symtab',0
_strtab db '.strtab',0
SECTION_NAME_POSITION = $
rb SECTION_NAME_TABLE_SIZE - $
STRING_POSITION = $
rb STRING_TABLE_SIZE - $
end virtual
virtual at 0
relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela
end virtual
element relocatable?
macro section_org
local sym
element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX
SECTION_BASE = sym
org sym
end macro
RELOCATION_INDEX = 0
SECTION_INDEX = 1
SECTION_SYMBOL_INDEX = SECTION_INDEX
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS
SECTION_OFFSET = $%
SECTION_ALIGN = 8
SECTION_NAME = '.flat'
SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR
DEFINED_SECTION = 0
section_org
end namespace
macro section?
namespace ELF
SECTION_SIZE = $% - SECTION_OFFSET
if DEFINED_SECTION | SECTION_SIZE > 0
store SECTION_OFFSET at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_ALIGN at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_FLAGS at section_table : Elf64_Shdr.sh_flags + SECTION_INDEX * sizeof Elf64_Shdr
if $%% = SECTION_OFFSET
store SHT_NOBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
section $
else
store SHT_PROGBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
UNINITIALIZED_LENGTH = $% - $%%
section $
db UNINITIALIZED_LENGTH dup 0
end if
store SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf64_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
if RELOCATION_INDEX > SECTION_RELOCATION_INDEX
store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SHT_RELA at section_table : Elf64_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_INDEX at section_table : Elf64_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store 8 at section_table : Elf64_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf64_Shdr
store SECTION_NAME_POSITION + 5 at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_NAME_POSITION + 5 at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store '.rela' + SECTION_NAME shl (5*8) : 5 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + 5 + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 2
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
else
store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store SECTION_NAME_POSITION at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym
store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION
SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1
SECTION_INDEX = SECTION_INDEX + 1
SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1
end if
end if
end namespace
end macro
macro section? declaration*
namespace ELF
section
DEFINED_SECTION = 1
SECTION_FLAGS = SHF_ALLOC
SECTION_OFFSET = $%
SECTION_ALIGN = 8
match name attributes, declaration
SECTION_NAME = name
local seq,list
match flags =align? boundary, attributes
SECTION_ALIGN = boundary
define seq flags
else match =align? boundary, attributes
SECTION_ALIGN = boundary
define seq
else
define seq attributes
end match
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =writeable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE
else match =executable?, attribute
SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
else
SECTION_NAME = declaration
end match
section_org
SECTION_RELOCATION_INDEX = RELOCATION_INDEX
end namespace
end macro
calminstruction align? boundary,value:?
check ELF.SECTION_ALIGN mod (boundary) = 0
jyes allowed
err 'section not aligned enough'
exit
allowed:
compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
macro public? declaration*
namespace ELF
match value =as? str, declaration
SYMBOL_VALUE = value
SYMBOL_SIZE = sizeof value
SYMBOL_NAME = string str
else
SYMBOL_VALUE = declaration
SYMBOL_SIZE = sizeof declaration
SYMBOL_NAME = `declaration
end match
if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0
SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE)
SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE
else
SYMBOL_SECTION_INDEX = SHN_ABS
end if
store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_VALUE at symbol_table : Elf64_Sym.st_value + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf64_Sym
if SYMBOL_SIZE
store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
else
store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
end if
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
macro extrn? declaration*
namespace ELF
local sym,psym
element sym : relocatable * (-1) + SYMBOL_INDEX
element psym : PLT + SYMBOL_INDEX
match str =as? name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = size
else match name:size, declaration
label name:size at sym
label PLT.name at psym
SYMBOL_NAME = `name
SYMBOL_SIZE = size
else match str =as? name, declaration
label name at sym
label PLT.name at psym
SYMBOL_NAME = string str
SYMBOL_SIZE = 0
else
label declaration at sym
label PLT.declaration at psym
SYMBOL_NAME = `declaration
SYMBOL_SIZE = 0
end match
store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym
store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION
STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1
store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym
store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym
SYMBOL_INDEX = SYMBOL_INDEX + 1
end namespace
end macro
element PLT?
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
calminstruction dword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_32
check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE)
jno plain
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable
jyes r_pc32
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT
jyes r_plt32
plain:
emit 4, value
exit
local offset, addend, info
r_32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof value
compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
r_pc32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)
compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
r_plt32:
compute offset, $%
emit 4
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset)
compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 32
jump add_relocation
add_relocation:
local Rela
compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela
asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset
asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend
asm store info at ELF.relocations : Rela + Elf64_Rela.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
calminstruction qword? value
compute value, value
check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable
jyes r_64
plain:
emit 8, value
exit
local offset, addend, info
r_64:
compute offset, $%
emit 8
check $% > offset
jno done
compute offset, offset - ELF.SECTION_OFFSET
compute addend, 0 scaleof value
compute info, ELF.R_64 + (0 scaleof (1 metadataof value)) shl 32
add_relocation:
local Rela
compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela
asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset
asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend
asm store info at ELF.relocations : Rela + Elf64_Rela.r_info
compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1
done:
end calminstruction
iterate <dd,dword>, dd,dword, dq,qword
calminstruction dd? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call dword, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit dword
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dd? definitions&
local cmd
arrange cmd, =label label : =dword
assemble cmd
arrange cmd, =dd definitions
assemble cmd
end calminstruction
end iterate
postpone
purge section?
section
namespace ELF
SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION
STRING_TABLE_SIZE := STRING_POSITION
NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX
NUMBER_OF_SYMBOLS := SYMBOL_INDEX
SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf64_Sym
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
rb (-$%) and 111b
RELOCATIONS_OFFSET = $%
load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela from relocations:0
db byte_sequence
store _symtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store SYMBOL_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store sizeof Elf64_Sym at section_table : Elf64_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf64_Shdr
store 8 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SHT_SYMTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
store STRING_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + SECTION_INDEX * sizeof Elf64_Shdr
store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf64_Shdr.sh_info + SECTION_INDEX * sizeof Elf64_Shdr
SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
store _strtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr
store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr
store STRING_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr
store 1 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr
store SHT_STRTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr
STRING_TABLE_SECTION_INDEX := SECTION_INDEX
load byte_sequence : STRING_TABLE_SIZE from string_table:0
db byte_sequence
SECTION_INDEX = SECTION_INDEX + 1
assert SECTION_INDEX <= SHN_LORESERVE
NUMBER_OF_SECTIONS := SECTION_INDEX
rb (-$%) and 111b
SECTION_TABLE_OFFSET := $%
load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf64_Shdr from section_table:0
db byte_sequence
end namespace
end postpone

View File

@ -0,0 +1,326 @@
ELFCLASSNONE = 0
ELFCLASS32 = 1
ELFCLASS64 = 2
ELFDATANONE = 0
ELFDATA2LSB = 1
ELFDATA2MSB = 2
ELFOSABI_NONE = 0
ELFOSABI_HPUX = 1
ELFOSABI_NETBSD = 2
ELFOSABI_GNU = 3
ELFOSABI_LINUX = 3
ELFOSABI_SOLARIS = 6
ELFOSABI_AIX = 7
ELFOSABI_IRIX = 8
ELFOSABI_FREEBSD = 9
ELFOSABI_TRU64 = 10
ELFOSABI_MODESTO = 11
ELFOSABI_OPENBSD = 12
ELFOSABI_OPENVMS = 13
ELFOSABI_NSK = 14
ELFOSABI_AROS = 15
ELFOSABI_FENIXOS = 16
ELFOSABI_CLOUDABI = 17
ELFOSABI_OPENVOS = 18
ET_NONE = 0
ET_REL = 1
ET_EXEC = 2
ET_DYN = 3
ET_CORE = 4
ET_LOPROC = 0xff00
ET_HIPROC = 0xffff
EM_NONE = 0
EM_M32 = 1
EM_SPARC = 2
EM_386 = 3
EM_68K = 4
EM_88K = 5
EM_860 = 7
EM_MIPS = 8
EM_X86_64 = 62
EV_NONE = 0
EV_CURRENT = 1
PT_NULL = 0
PT_LOAD = 1
PT_DYNAMIC = 2
PT_INTERP = 3
PT_NOTE = 4
PT_SHLIB = 5
PT_PHDR = 6
PT_GNU_EH_FRAME = 0x6474e550
PT_GNU_STACK = 0x6474e551
PT_GNU_RELRO = 0x6474e552
PT_LOPROC = 0x70000000
PT_HIPROC = 0x7fffffff
PF_X = 1
PF_W = 2
PF_R = 4
PF_MASKOS = 0x0ff00000
PF_MASKPROC = 0xf0000000
calminstruction align? boundary,value:?
compute boundary, (boundary-1)-($-ELF.DYNAMIC+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
ELF::
namespace ELF
if defined Settings.Class
CLASS := Settings.Class
else
CLASS := ELFCLASS32
end if
if defined Settings.Type
TYPE := Settings.Type
else
TYPE := ET_EXEC
end if
if defined Settings.Machine
MACHINE := Settings.Machine
else
MACHINE := EM_386
end if
if defined Settings.ABI
ABI := Settings.ABI
else
ABI := ELFOSABI_NONE
end if
if TYPE = ET_DYN
element DYNAMIC
else
DYNAMIC := 0
end if
if defined Settings.BaseAddress
BASE_ADDRESS := DYNAMIC + Settings.BaseAddress
else
BASE_ADDRESS := DYNAMIC + 8048000h
end if
if defined Settings.LoadHeaders
LOAD_HEADERS := Settings.LoadHeaders
else
LOAD_HEADERS := 1
end if
Header:
e_ident db 0x7F,'ELF',CLASS,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0
e_type dw TYPE
e_machine dw MACHINE
e_version dd EV_CURRENT
if CLASS <> ELFCLASS64
e_entry dd start - DYNAMIC
e_phoff dd ProgramHeader
e_shoff dd 0
e_flags dd 0
e_ehsize dw ProgramHeader
e_phentsize dw SEGMENT_HEADER_LENGTH
e_phnum dw NUMBER_OF_SEGMENTS
e_shentsize dw 28h
e_shnum dw 0
e_shstrndx dw 0
else
e_entry dq start - DYNAMIC
e_phoff dq ProgramHeader
e_shoff dq 0
e_flags dd 0
e_ehsize dw ProgramHeader
e_phentsize dw SEGMENT_HEADER_LENGTH
e_phnum dw NUMBER_OF_SEGMENTS
e_shentsize dw 40h
e_shnum dw 0
e_shstrndx dw 0
end if
ProgramHeader:
if CLASS <> ELFCLASS64
p_type dd PT_LOAD
p_offset dd 0
p_vaddr dd BASE_ADDRESS - DYNAMIC
p_paddr dd BASE_ADDRESS - DYNAMIC
p_filesz dd 0
p_memsz dd 0
p_flags dd PF_R+PF_W+PF_X
p_align dd 1000h
else
p_type dd PT_LOAD
p_flags dd PF_R+PF_W+PF_X
p_offset dq 0
p_vaddr dq BASE_ADDRESS - DYNAMIC
p_paddr dq BASE_ADDRESS - DYNAMIC
p_filesz dq 0
p_memsz dq 0
p_align dq 1000h
end if
SEGMENT_HEADER_LENGTH = $ - ProgramHeader
db (NUMBER_OF_SEGMENTS-1)*SEGMENT_HEADER_LENGTH dup 0
HEADERS_OFFSET = 0
HEADERS_BASE = BASE_ADDRESS
OVERLAY_HEADERS = LOAD_HEADERS
SEGMENT_INDEX = 0
DEFINED_SEGMENT = 0
SEGMENT_TYPE = PT_LOAD
FILE_OFFSET = $%
SEGMENT_BASE = BASE_ADDRESS + FILE_OFFSET and 0FFFh
org SEGMENT_BASE
start:
end namespace
RVA? equ -ELF.BASE_ADDRESS +
macro entry? address*
namespace ELF
store address-DYNAMIC at ELF:e_entry
end namespace
end macro
macro segment?
namespace ELF
DEFINED_SEGMENT_SIZE = $ - SEGMENT_BASE
if (DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0) & SEGMENT_TYPE = PT_LOAD & OVERLAY_HEADERS
FILE_OFFSET = HEADERS_OFFSET
SEGMENT_BASE = HEADERS_BASE
OVERLAY_HEADERS = 0
end if
store SEGMENT_BASE-DYNAMIC at ELF:p_vaddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_BASE-DYNAMIC at ELF:p_paddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store FILE_OFFSET at ELF:p_offset+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if SEGMENT_TYPE = PT_LOAD
RAW_DATA_SIZE = $%% - FILE_OFFSET
SEGMENT_SIZE = $ - SEGMENT_BASE
store RAW_DATA_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0
FILE_OFFSET = $%%
align 1000h
SEGMENT_BASE = $ + FILE_OFFSET and 0FFFh
end if
section SEGMENT_BASE
else
if OVERLAY_HEADERS = 0 & ( LOAD_HEADERS | SEGMENT_TYPE = PT_GNU_RELRO ) & ~ SEGMENT_TYPE = PT_GNU_STACK & ~ SEGMENT_TYPE = PT_NOTE
OVERLAY_HEADERS = 1
HEADERS_OFFSET = FILE_OFFSET
HEADERS_BASE = SEGMENT_BASE
end if
FILE_OFFSET = $%
SEGMENT_SIZE = $ - SEGMENT_BASE
store SEGMENT_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if OVERLAY_HEADERS = 0
SEGMENT_BASE = DYNAMIC + (SEGMENT_BASE-DYNAMIC) and not 0FFFh + FILE_OFFSET and 0FFFh
else
SEGMENT_BASE = $
end if
if $% > $%%
store 0:byte at $-1
end if
org SEGMENT_BASE
end if
if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0
SEGMENT_INDEX = SEGMENT_INDEX + 1
end if
end namespace
end macro
macro segment? attributes*
namespace ELF
segment
SEGMENT_TYPE = PT_LOAD
SEGMENT_FLAGS = 0
local seq,list
define seq attributes
while 1
match car cdr, seq
define list car
define seq cdr
else
match any, seq
define list any
end match
break
end match
end while
irpv attribute, list
match =readable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_R
else match =writeable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_W
else match =executable?, attribute
SEGMENT_FLAGS = SEGMENT_FLAGS or PF_X
else match =interpreter?, attribute
SEGMENT_TYPE = PT_INTERP
else match =dynamic?, attribute
SEGMENT_TYPE = PT_DYNAMIC
else match =note?, attribute
SEGMENT_TYPE = PT_NOTE
else match =gnustack?, attribute
SEGMENT_TYPE = PT_GNU_STACK
else match =gnuehframe?, attribute
SEGMENT_TYPE = PT_GNU_EH_FRAME
else match =gnurelro?, attribute
SEGMENT_TYPE = PT_GNU_RELRO
else
err 'unknown attribute "',`attribute,'"'
end match
end irpv
DEFINED_SEGMENT = 1
store SEGMENT_TYPE at ELF:p_type+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
store SEGMENT_FLAGS at ELF:p_flags+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
if SEGMENT_TYPE = PT_LOAD
store 1000h at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
else
store 1 at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH
end if
end namespace
end macro
postpone
purge segment?
segment
namespace ELF
NUMBER_OF_SEGMENTS := SEGMENT_INDEX
end namespace
end postpone

View File

@ -0,0 +1,328 @@
macro format?.MZ?
format binary as 'exe'
include 'format/mz.inc'
include 'p6.inc'
end macro
macro format?.PE? settings
PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED
PE.Settings.DllCharacteristics = 0
local seq
define seq settings:
while 1
match :, seq
break
else match =DLL? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL
redefine seq more
else match =large? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_LARGE_ADDRESS_AWARE
redefine seq more
else match =WDM? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
redefine seq more
else match =NX? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT
redefine seq more
else match =at? base =on? stub :, seq
PE.Settings.ImageBase = base
PE.Settings.Stub = stub
break
else match =at? base :, seq
PE.Settings.ImageBase = base
break
else match =on? stub :, seq
PE.Settings.Stub = stub
break
else
match =GUI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
redefine seq more
else match =console? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
redefine seq more
else match =native? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE
PE.Settings.SectionAlignment = 32
PE.Settings.FileAlignment = 32
redefine seq more
else match =EFI? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION
redefine seq more
else match =EFIboot? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
redefine seq more
else match =EFIruntime? more, seq
PE.Settings.Magic = 0x20B
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
redefine seq more
else
err 'invalid argument'
break
end match
match V.v more, seq
PE.Settings.MajorSubsystemVersion = V
PE.Settings.MinorSubsystemVersion = v
redefine seq more
end match
end match
end while
if PE.Settings.Characteristics and IMAGE_FILE_DLL
format binary as 'dll'
else
format binary as 'exe'
end if
include 'format/pe.inc'
include 'p6.inc'
use32
end macro
macro format?.PE64? settings
PE.Settings.Magic = 0x20B
PE.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_LARGE_ADDRESS_AWARE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED
PE.Settings.DllCharacteristics = 0
PE.Settings.MajorSubsystemVersion = 5
PE.Settings.MinorSubsystemVersion = 0
local seq
define seq settings:
while 1
match :, seq
break
else match =DLL? more, seq
PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL
redefine seq more
else match =WDM? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
redefine seq more
else match =NX? more, seq
PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT
redefine seq more
else match =at? base =on? stub :, seq
PE.Settings.ImageBase = base
PE.Settings.Stub = stub
break
else match =at? base :, seq
PE.Settings.ImageBase = base
break
else match =on? stub :, seq
PE.Settings.Stub = stub
break
else
match =GUI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
redefine seq more
else match =console? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
redefine seq more
else match =native? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE
PE.Settings.SectionAlignment = 32
PE.Settings.FileAlignment = 32
redefine seq more
else match =EFI? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION
redefine seq more
else match =EFIboot? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
redefine seq more
else match =EFIruntime? more, seq
PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
redefine seq more
else
err 'invalid argument'
break
end match
match V.v more, seq
PE.Settings.MajorSubsystemVersion = V
PE.Settings.MinorSubsystemVersion = v
redefine seq more
end match
end match
end while
if PE.Settings.Characteristics and IMAGE_FILE_DLL
format binary as 'dll'
else
format binary as 'exe'
end if
include 'format/pe.inc'
include 'x64.inc'
use64
end macro
macro format?.ELF? variant
match , variant
format binary as 'o'
include 'format/elf32.inc'
include 'p6.inc'
use32
else match =executable? settings, variant:
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'p6.inc'
use32
else match =dynamic? settings, variant:
ELF.Settings.Type = ET_DYN
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.ELF64? variant
match , variant
format binary as 'o'
include 'format/elf64.inc'
include 'x64.inc'
use64
else match =executable? settings, variant:
ELF.Settings.Class = ELFCLASS64
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else match =dynamic? settings, variant:
ELF.Settings.Class = ELFCLASS64
ELF.Settings.Type = ET_DYN
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.ELFx32? variant
match , variant
format binary as 'o'
ELF.Settings.Machine = EM_X86_64
include 'format/elf32.inc'
include 'x64.inc'
use64
else match =executable? settings, variant:
ELF.Settings.Class = ELFCLASS32
ELF.Settings.Machine = EM_X86_64
ELF.Settings.BaseAddress = 400000h
match brand =at? base:, settings
ELF.Settings.ABI = brand
ELF.Settings.BaseAddress = base
else match =at? base:, settings
ELF.Settings.BaseAddress = base
else match brand:, settings
ELF.Settings.ABI = brand
end match
include 'format/elfexe.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.COFF?
format binary as 'obj'
include 'format/coff.inc'
include 'p6.inc'
use32
end macro
macro format?.MS? variant
match =COFF?, variant
format binary as 'obj'
COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO
include 'format/coffms.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.MS64? variant
match =COFF?, variant
format binary as 'obj'
COFF.Settings.Machine = IMAGE_FILE_MACHINE_AMD64
COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO
include 'format/coffms.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro
macro format?.MachO? variant
match , variant
format binary as 'o'
MachO.Settings.FileType equ MH_OBJECT
include 'format/macho.inc'
include 'p6.inc'
use32
else match =executable?, variant
MachO.Settings.BaseAddress = 0x1000
include 'format/macho.inc'
include 'p6.inc'
use32
else
err 'invalid argument'
end match
end macro
macro format?.MachO64? variant
MachO.Settings.ProcessorType equ CPU_TYPE_X86_64
MachO.Settings.ProcessorSubtype equ CPU_SUBTYPE_X86_64_ALL
match , variant
format binary as 'o'
MachO.Settings.FileType equ MH_OBJECT
include 'format/macho.inc'
include 'x64.inc'
use64
else match =executable?, variant
MachO.Settings.BaseAddress = 0x100000000
include 'format/macho.inc'
include 'x64.inc'
use64
else
err 'invalid argument'
end match
end macro

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
MZ::
.signature dw "MZ"
.bytes_in_last_page dw .LENGTH and 1FFh
.number_of_pages dw (.LENGTH-1) shr 9 + 1
.number_of_relocations dw .NUMBER_OF_RELOCATIONS
.number_of_header_paragraphs dw .HEADER_LENGTH shr 4
.minimum_heap dw (.LENGTH+.RESERVED_LENGTH-1) shr 4 - (.LENGTH-1) shr 4
.maximum_heap dw 0FFFFh
.initial_ss dw 0
.initial_sp dw 0
.checksum dw 0
.initial_ip dw 0
.initial_cs dw 0
.relocations_offset dw .relocations
.overlay_number dw 0
.relocations dw .NUMBER_OF_RELOCATIONS dup (?,?)
rb 0Fh - ($%+0Fh) and 0Fh
.HEADER_LENGTH = $
.RELOCATION_INDEX = 0
.ENTRY_DEFINED = 0
.HEAP_DEFINED = 0
.STACK_DEFINED = 0
.STACK_LENGTH = 1000h
org 0
macro entry? definition
local v
if MZ.ENTRY_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_cs
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_ip
else
err 'value out of range'
end if
MZ.ENTRY_DEFINED = 1
else
err 'invalid argument'
end match
end macro
macro heap? definition
local v,min
if MZ.HEAP_DEFINED
err 'setting already specified'
else
v = definition
if v >= 0 & v < 10000h
load min : word from MZ : MZ.minimum_heap
v = v + min
if v > 0FFFFh
v = 0FFFFh
end if
store v : word at MZ : MZ.maximum_heap
else
err 'value out of range'
end if
MZ.HEAP_DEFINED = 1
end if
end macro
macro stack? definition
local v
if MZ.STACK_DEFINED
err 'setting already specified'
else match seg:offs, definition
v = seg
if v relativeto MZ.segment
store v - MZ.segment : word at MZ : MZ.initial_ss
else
err 'incorrect segment'
end if
v = offs
if v >= 0 & v < 10000h
store v : word at MZ : MZ.initial_sp
else
err 'value out of range'
end if
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = 0
else
MZ.STACK_DEFINED = 1
MZ.STACK_LENGTH = definition
end match
end macro
element MZ.segment
macro segment? definition
rb 0Fh - ($%+0Fh) and 0Fh
match name =use16?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use16
else match name =use32?, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
use32
else match name, definition
name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4
end match
org 0
end macro
calminstruction calminstruction?.initsym? var*, val&
publish var, val
end calminstruction
calminstruction calminstruction?.asm? line&
local name, i
initsym name, name.0
match name.i, name
compute i, i+1
arrange name, name.i
publish name, line
arrange line, =assemble name
assemble line
end calminstruction
iterate <dw,word>, dw,word, dd,dword
calminstruction word? value
compute value, value
check value relativeto MZ.segment
jno plain
local offset
compute offset, $%
emit word, value - MZ.segment
check $% > offset
jno done
compute offset, offset - MZ.HEADER_LENGTH
compute offset, offset and 0FFFFh + (offset and not 0FFFFh) shl 12
asm store offset:4 at MZ : MZ.relocations + MZ.RELOCATION_INDEX shl 2
compute MZ.RELOCATION_INDEX, MZ.RELOCATION_INDEX + 1
done:
exit
plain:
emit word, value
end calminstruction
calminstruction dw? definitions&
local value, n
start:
match value=,definitions, definitions, ()
jyes recognize
match value, definitions
arrange definitions,
recognize:
match n =dup? value, value, ()
jyes duplicate
match ?, value
jyes reserve
call word, value
next:
match , definitions
jno start
take , definitions
take definitions, definitions
jyes next
exit
reserve:
emit word
jump next
duplicate:
match (value), value
stack:
check n
jno next
take definitions, value
arrange value, definitions
compute n, n - 1
jump stack
end calminstruction
calminstruction (label) dw? definitions&
local cmd
arrange cmd, =label label : =word
assemble cmd
arrange cmd, =dw definitions
assemble cmd
end calminstruction
end iterate
calminstruction align? boundary,value:?
compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary
arrange value, =db boundary =dup value
assemble value
end calminstruction
postpone
if MZ.STACK_LENGTH
rb 0Fh - ($%+0Fh) and 0Fh
store ($%-MZ.HEADER_LENGTH) shr 4 : word at MZ : MZ.initial_ss
rb MZ.STACK_LENGTH
store MZ.STACK_LENGTH : word at MZ : MZ.initial_sp
end if
MZ.LENGTH = $%%
MZ.RESERVED_LENGTH = $%-$%%
MZ.NUMBER_OF_RELOCATIONS = MZ.RELOCATION_INDEX
end postpone

File diff suppressed because it is too large Load Diff