added fasm2 as well
This commit is contained in:
403
toolchain/fasm2/include/format/coff.inc
Normal file
403
toolchain/fasm2/include/format/coff.inc
Normal file
@ -0,0 +1,403 @@
|
||||
|
||||
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
|
||||
align.assume sym, SECTION_ALIGN
|
||||
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
|
||||
|
||||
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 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
|
||||
|
||||
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
|
684
toolchain/fasm2/include/format/coffms.inc
Normal file
684
toolchain/fasm2/include/format/coffms.inc
Normal file
@ -0,0 +1,684 @@
|
||||
|
||||
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
|
||||
align.assume sym, SECTION_ALIGN
|
||||
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 + IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE
|
||||
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
|
||||
|
||||
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+
|
||||
|
||||
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
|
||||
|
||||
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
|
573
toolchain/fasm2/include/format/elf32.inc
Normal file
573
toolchain/fasm2/include/format/elf32.inc
Normal file
@ -0,0 +1,573 @@
|
||||
|
||||
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
|
||||
align.assume sym, SECTION_ALIGN
|
||||
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
|
||||
|
||||
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 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
|
||||
|
||||
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
|
611
toolchain/fasm2/include/format/elf64.inc
Normal file
611
toolchain/fasm2/include/format/elf64.inc
Normal file
@ -0,0 +1,611 @@
|
||||
|
||||
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
|
||||
R_GOT32 = R_X86_64_GOT32
|
||||
R_GOTPCREL = R_X86_64_GOTPCREL
|
||||
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
|
||||
align.assume sym, SECTION_ALIGN
|
||||
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
|
||||
|
||||
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,gsym,psym
|
||||
element sym : relocatable * (-1) + SYMBOL_INDEX
|
||||
element gsym : GOT + SYMBOL_INDEX
|
||||
element psym : PLT + SYMBOL_INDEX
|
||||
match str =as? name:size, declaration
|
||||
label name:size at sym
|
||||
label GOT.name at gsym
|
||||
label PLT.name at psym
|
||||
SYMBOL_NAME = string str
|
||||
SYMBOL_SIZE = size
|
||||
else match name:size, declaration
|
||||
label name:size at sym
|
||||
label GOT.name at gsym
|
||||
label PLT.name at psym
|
||||
SYMBOL_NAME = `name
|
||||
SYMBOL_SIZE = size
|
||||
else match str =as? name, declaration
|
||||
label name at sym
|
||||
label GOT.name at gsym
|
||||
label PLT.name at psym
|
||||
SYMBOL_NAME = string str
|
||||
SYMBOL_SIZE = 0
|
||||
else
|
||||
label declaration at sym
|
||||
label GOT.declaration at gsym
|
||||
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 GOT?
|
||||
element PLT?
|
||||
|
||||
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 relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto GOT
|
||||
jyes r_got32
|
||||
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
|
||||
check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto GOT
|
||||
jyes r_gotpcrel
|
||||
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,value + ELF.SECTION_BASE + offset - 1 elementof value
|
||||
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, value + ELF.SECTION_BASE + offset - 1 elementof value
|
||||
compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 32
|
||||
jump add_relocation
|
||||
r_gotpcrel:
|
||||
compute offset, $%
|
||||
emit 4
|
||||
check $% > offset
|
||||
jno done
|
||||
compute offset, offset - ELF.SECTION_OFFSET
|
||||
compute addend, value + ELF.SECTION_BASE + offset - 1 elementof value
|
||||
compute info, ELF.R_GOTPCREL + (0 scaleof (1 metadataof value)) shl 32
|
||||
jump add_relocation
|
||||
r_got32:
|
||||
compute offset, $%
|
||||
emit 4
|
||||
check $% > offset
|
||||
jno done
|
||||
compute offset, offset - ELF.SECTION_OFFSET
|
||||
compute addend, 0 scaleof value
|
||||
compute info, ELF.R_GOT32 + (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
|
||||
|
||||
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
|
321
toolchain/fasm2/include/format/elfexe.inc
Normal file
321
toolchain/fasm2/include/format/elfexe.inc
Normal file
@ -0,0 +1,321 @@
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
align.assume DYNAMIC, 1000h
|
||||
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
|
1128
toolchain/fasm2/include/format/macho.inc
Normal file
1128
toolchain/fasm2/include/format/macho.inc
Normal file
File diff suppressed because it is too large
Load Diff
146
toolchain/fasm2/include/format/mz.inc
Normal file
146
toolchain/fasm2/include/format/mz.inc
Normal file
@ -0,0 +1,146 @@
|
||||
|
||||
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
|
||||
|
||||
iterate word, word,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
|
||||
|
||||
end iterate
|
||||
|
||||
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
|
999
toolchain/fasm2/include/format/pe.inc
Normal file
999
toolchain/fasm2/include/format/pe.inc
Normal file
@ -0,0 +1,999 @@
|
||||
|
||||
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_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
|
||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040
|
||||
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080
|
||||
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100
|
||||
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200
|
||||
IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400
|
||||
IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800
|
||||
IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000
|
||||
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000
|
||||
IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000
|
||||
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||
|
||||
IMAGE_SUBSYSTEM_UNKNOWN = 0
|
||||
IMAGE_SUBSYSTEM_NATIVE = 1
|
||||
IMAGE_SUBSYSTEM_WINDOWS_GUI = 2
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI = 3
|
||||
IMAGE_SUBSYSTEM_POSIX_CUI = 7
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
|
||||
IMAGE_SUBSYSTEM_EFI_APPLICATION = 10
|
||||
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11
|
||||
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12
|
||||
IMAGE_SUBSYSTEM_EFI_ROM = 13
|
||||
IMAGE_SUBSYSTEM_XBOX = 14
|
||||
|
||||
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_BASED_ABSOLUTE = 0
|
||||
IMAGE_REL_BASED_HIGH = 1
|
||||
IMAGE_REL_BASED_LOW = 2
|
||||
IMAGE_REL_BASED_HIGHLOW = 3
|
||||
IMAGE_REL_BASED_HIGHADJ = 4
|
||||
IMAGE_REL_BASED_DIR64 = 10
|
||||
|
||||
PE::
|
||||
|
||||
namespace PE
|
||||
|
||||
if defined Settings.Magic
|
||||
MAGIC = Settings.Magic
|
||||
else
|
||||
MAGIC = 0x10B
|
||||
end if
|
||||
|
||||
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_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE
|
||||
end if
|
||||
|
||||
if defined Settings.DllCharacteristics
|
||||
DLL_CHARACTERISTICS = Settings.DllCharacteristics
|
||||
else
|
||||
DLL_CHARACTERISTICS = 0
|
||||
end if
|
||||
|
||||
if defined Settings.Subsystem
|
||||
SUBSYSTEM = Settings.Subsystem
|
||||
else
|
||||
SUBSYSTEM = IMAGE_SUBSYSTEM_WINDOWS_CUI
|
||||
end if
|
||||
|
||||
if defined Settings.MajorSubsystemVersion
|
||||
MAJOR_SUBSYSTEM_VERSION = Settings.MajorSubsystemVersion
|
||||
else
|
||||
MAJOR_SUBSYSTEM_VERSION = 3
|
||||
end if
|
||||
|
||||
if defined Settings.MinorSubsystemVersion
|
||||
MINOR_SUBSYSTEM_VERSION = Settings.MinorSubsystemVersion
|
||||
else
|
||||
MINOR_SUBSYSTEM_VERSION = 10
|
||||
end if
|
||||
|
||||
if defined Settings.SectionAlignment
|
||||
SECTION_ALIGNMENT := Settings.SectionAlignment
|
||||
else
|
||||
SECTION_ALIGNMENT := 1000h
|
||||
end if
|
||||
|
||||
if defined Settings.FileAlignment
|
||||
FILE_ALIGNMENT := Settings.FileAlignment
|
||||
else
|
||||
FILE_ALIGNMENT := 512
|
||||
end if
|
||||
|
||||
if defined Fixups
|
||||
element RELOCATION
|
||||
DLL_CHARACTERISTICS = DLL_CHARACTERISTICS or IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||
align.assume RELOCATION, PE.SECTION_ALIGNMENT
|
||||
else
|
||||
RELOCATION := 0
|
||||
CHARACTERISTICS = CHARACTERISTICS or IMAGE_FILE_RELOCS_STRIPPED
|
||||
end if
|
||||
|
||||
if defined Settings.ImageBase
|
||||
IMAGE_BASE := RELOCATION + Settings.ImageBase
|
||||
else
|
||||
IMAGE_BASE := RELOCATION + 400000h
|
||||
end if
|
||||
|
||||
if defined Settings.LegacyHeaders
|
||||
LEGACY_HEADERS := Settings.LegacyHeaders
|
||||
else
|
||||
LEGACY_HEADERS := 1
|
||||
end if
|
||||
|
||||
NUMBER_OF_DIRECTORIES := 16
|
||||
|
||||
if defined Settings.Stub
|
||||
|
||||
virtual at 0
|
||||
file Settings.Stub
|
||||
if $ >= 1Ch
|
||||
load SIGNATURE : word from 0
|
||||
if SIGNATURE = "MZ" | SIGNATURE = "ZM"
|
||||
StubTemplate::
|
||||
end if
|
||||
end if
|
||||
end virtual
|
||||
|
||||
if defined StubTemplate
|
||||
|
||||
load .BYTES_IN_LAST_PAGE : word from StubTemplate:2
|
||||
load .NUMBER_OF_PAGES : word from StubTemplate:4
|
||||
.TEMPLATE_LENGTH = .NUMBER_OF_PAGES shl 9 - (-.BYTES_IN_LAST_PAGE) and 1FFh
|
||||
|
||||
load .RELOCATIONS_OFFSET : word from StubTemplate:18h
|
||||
if .RELOCATIONS_OFFSET >= 40h
|
||||
file Settings.Stub,.TEMPLATE_LENGTH
|
||||
else
|
||||
load .NUMBER_OF_RELOCATIONS : word from StubTemplate:6
|
||||
.RELOCATIONS_LENGTH = .NUMBER_OF_RELOCATIONS shl 2
|
||||
load .NUMBER_OF_HEADER_PARAGRAPHS : word from StubTemplate:8
|
||||
.TEMPLATE_HEADER_LENGTH = .NUMBER_OF_HEADER_PARAGRAPHS shl 4
|
||||
|
||||
file Settings.Stub,1Ch
|
||||
rb 40h - $
|
||||
file Settings.Stub:.RELOCATIONS_OFFSET,.RELOCATIONS_LENGTH
|
||||
align 16
|
||||
.HEADER_LENGTH = $
|
||||
file Settings.Stub:.TEMPLATE_HEADER_LENGTH,.TEMPLATE_LENGTH-.TEMPLATE_HEADER_LENGTH
|
||||
.LENGTH = $
|
||||
|
||||
store 40h : word at 18h
|
||||
store .HEADER_LENGTH shr 4 : word at 8
|
||||
store .LENGTH and 1FFh : word at 2
|
||||
store (.LENGTH-1) shr 9 + 1 : word at 4
|
||||
end if
|
||||
|
||||
store Header : dword at 3Ch
|
||||
|
||||
else
|
||||
|
||||
Stub:
|
||||
.signature dw "MZ"
|
||||
.bytes_in_last_page dw .LENGTH and 1FFh
|
||||
.number_of_pages dw (.LENGTH-1) shr 9 + 1
|
||||
.number_of_relocations dw 0
|
||||
.number_of_header_paragraphs dw .HEADER_LENGTH shr 4
|
||||
.minimum_heap dw (10000h - (.LENGTH-.HEADER_LENGTH)) shr 4
|
||||
.maximum_heap dw 0FFFFh
|
||||
.initial_ss dw (-100h) shr 4
|
||||
.initial_sp dw 0FFFEh
|
||||
.checksum dw 0
|
||||
.initial_ip dw 100h
|
||||
.initial_cs dw (-100h) shr 4
|
||||
.relocations_offset dw 40h
|
||||
.overlay_number dw 0
|
||||
rb 3Ch - $
|
||||
.new_header_offset dd Header
|
||||
|
||||
.HEADER_LENGTH = $
|
||||
|
||||
file Settings.Stub
|
||||
|
||||
.LENGTH = $
|
||||
|
||||
end if
|
||||
|
||||
else
|
||||
|
||||
Stub:
|
||||
.signature dw "MZ"
|
||||
.bytes_in_last_page dw .LENGTH and 1FFh
|
||||
.number_of_pages dw (.LENGTH-1) shr 9 + 1
|
||||
.number_of_relocations dw 0
|
||||
.number_of_header_paragraphs dw .HEADER_LENGTH shr 4
|
||||
.minimum_heap dw .STACK_LENGTH shr 4
|
||||
.maximum_heap dw 0FFFFh
|
||||
.initial_ss dw 0
|
||||
.initial_sp dw .LENGTH - .HEADER_LENGTH + .STACK_LENGTH
|
||||
.checksum dw 0
|
||||
.initial_ip dw 0
|
||||
.initial_cs dw 0
|
||||
.relocations_offset dw 40h
|
||||
.overlay_number dw 0
|
||||
rb 3Ch - $
|
||||
.new_header_offset dd Header
|
||||
|
||||
.HEADER_LENGTH = $
|
||||
.STACK_LENGTH = 100h
|
||||
|
||||
namespace Stub
|
||||
|
||||
use16
|
||||
|
||||
start:
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov dx,message - start
|
||||
mov ah,9
|
||||
int 21h
|
||||
mov ax,4C01h
|
||||
int 21h
|
||||
|
||||
message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h
|
||||
|
||||
end namespace
|
||||
|
||||
align 16
|
||||
|
||||
.LENGTH = $
|
||||
|
||||
end if
|
||||
|
||||
if defined Settings.Stamp
|
||||
TIMESTAMP := Settings.Stamp
|
||||
else
|
||||
TIMESTAMP := __TIME__
|
||||
end if
|
||||
|
||||
align 8
|
||||
|
||||
Header:
|
||||
.Signature dw "PE",0
|
||||
.Machine dw MACHINE
|
||||
.NumberOfSections dw NUMBER_OF_SECTIONS
|
||||
.TimeDateStamp dd TIMESTAMP
|
||||
.PointerToSymbolTable dd 0
|
||||
.NumberOfSymbols dd 0
|
||||
.SizeOfOptionalHeader dw SectionTable - OptionalHeader
|
||||
.Characteristics dw CHARACTERISTICS
|
||||
|
||||
OptionalHeader:
|
||||
.Magic dw MAGIC
|
||||
.MajorLinkerVersion db 2
|
||||
.MinorLinkerVersion db 0
|
||||
.SizeOfCode dd 0
|
||||
.SizeOfInitializedData dd 0
|
||||
.SizeOfUninitializedData dd 0
|
||||
.AddressOfEntryPoint dd 0
|
||||
.BaseOfCode dd 0
|
||||
if MAGIC <> 0x20B
|
||||
.BaseOfData dd 0
|
||||
.ImageBase dd IMAGE_BASE - RELOCATION
|
||||
else
|
||||
.ImageBase dq IMAGE_BASE - RELOCATION
|
||||
end if
|
||||
.SectionAlignment dd SECTION_ALIGNMENT
|
||||
.FileAlignment dd FILE_ALIGNMENT
|
||||
.MajorOperatingSystemVersion dw 1
|
||||
.MinorOperatingSystemVersion dw 0
|
||||
.MajorImageVersion dw 0
|
||||
.MinorImageVersion dw 0
|
||||
.MajorSubsystemVersion dw MAJOR_SUBSYSTEM_VERSION
|
||||
.MinorSubsystemVersion dw MINOR_SUBSYSTEM_VERSION
|
||||
.Win32VersionValue dd 0
|
||||
.SizeOfImage dd SIZE_OF_IMAGE
|
||||
.SizeOfHeaders dd SIZE_OF_HEADERS
|
||||
.CheckSum dd 0
|
||||
.Subsystem dw SUBSYSTEM
|
||||
.DllCharacteristics dw DLL_CHARACTERISTICS
|
||||
if MAGIC <> 0x20B
|
||||
.SizeOfStackReserve dd 1000h
|
||||
.SizeOfStackCommit dd 1000h
|
||||
.SizeOfHeapReserve dd 10000h
|
||||
.SizeOfHeapCommit dd 0
|
||||
else
|
||||
.SizeOfStackReserve dq 1000h
|
||||
.SizeOfStackCommit dq 1000h
|
||||
.SizeOfHeapReserve dq 10000h
|
||||
.SizeOfHeapCommit dq 0
|
||||
end if
|
||||
.LoaderFlags dd 0
|
||||
.NumberOfRvaAndSizes dd NUMBER_OF_DIRECTORIES
|
||||
RvaAndSizes:
|
||||
.Rva dd 0
|
||||
.Size dd 0
|
||||
.ENTRY_LENGTH = $ - RvaAndSizes
|
||||
db (NUMBER_OF_DIRECTORIES-1)*RvaAndSizes.ENTRY_LENGTH dup 0
|
||||
SectionTable:
|
||||
.Name dq '.flat'
|
||||
.VirtualSize dd 0
|
||||
.VirtualAddress dd 0
|
||||
.SizeOfRawData dd 0
|
||||
.PointerToRawData dd 0
|
||||
.PointerToRelocations dd 0
|
||||
.PointerToLineNumbers dd 0
|
||||
.NumberOfRelocations dw 0
|
||||
.NumberOfLineNumbers dw 0
|
||||
.Characteristics dd IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE
|
||||
.ENTRY_LENGTH = $ - SectionTable
|
||||
db (NUMBER_OF_SECTIONS-1)*SectionTable.ENTRY_LENGTH dup 0
|
||||
|
||||
HeadersEnd:
|
||||
define CheckSumBlocks PE,HeadersEnd
|
||||
|
||||
SECTION_INDEX = 0
|
||||
RELOCATION_INDEX = 0
|
||||
DEFINED_SECTION = 0
|
||||
SECTION_DIRECTORIES = 0
|
||||
align SECTION_ALIGNMENT
|
||||
FIRST_SECTION_RVA:
|
||||
section $%%
|
||||
align FILE_ALIGNMENT,0
|
||||
SIZE_OF_HEADERS = $%
|
||||
FILE_OFFSET = $%
|
||||
SECTION_BASE = IMAGE_BASE + FIRST_SECTION_RVA
|
||||
org SECTION_BASE
|
||||
|
||||
store SECTION_BASE-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint
|
||||
store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress
|
||||
store FILE_OFFSET at PE:SectionTable.PointerToRawData
|
||||
|
||||
virtual at 0
|
||||
relocated_addresses:: rd NUMBER_OF_RELOCATIONS
|
||||
end virtual
|
||||
|
||||
virtual at 0
|
||||
relocation_types:: rw NUMBER_OF_RELOCATIONS
|
||||
end virtual
|
||||
|
||||
end namespace
|
||||
|
||||
RVA? equ -PE.IMAGE_BASE +
|
||||
|
||||
macro entry? address*
|
||||
namespace PE
|
||||
store address-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro stack? reserve*,commit:1000h
|
||||
namespace PE
|
||||
store reserve at PE:OptionalHeader.SizeOfStackReserve
|
||||
store commit at PE:OptionalHeader.SizeOfStackCommit
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro heap? reserve*,commit:0
|
||||
namespace PE
|
||||
store reserve at PE:OptionalHeader.SizeOfHeapReserve
|
||||
store commit at PE:OptionalHeader.SizeOfHeapCommit
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro section?
|
||||
namespace PE
|
||||
|
||||
repeat SECTION_DIRECTORIES
|
||||
end data
|
||||
end repeat
|
||||
|
||||
local AREA,DATA_LENGTH
|
||||
AREA::
|
||||
DATA_LENGTH = $-$$-($%-$%%)
|
||||
CheckSumBlocks reequ CheckSumBlocks,AREA,DATA_LENGTH
|
||||
|
||||
SECTION_SIZE = $ - SECTION_BASE
|
||||
store SECTION_SIZE at PE:SectionTable.VirtualSize+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
align SECTION_ALIGNMENT
|
||||
SECTION_BASE = $
|
||||
section $%%
|
||||
align FILE_ALIGNMENT,0
|
||||
RAW_DATA_SIZE = $% - FILE_OFFSET
|
||||
store RAW_DATA_SIZE at PE:SectionTable.SizeOfRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
FILE_OFFSET = $%
|
||||
org SECTION_BASE
|
||||
|
||||
load SECTION_CHARACTERISTICS from PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
if SECTION_SIZE > 0 & RAW_DATA_SIZE = 0
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
||||
store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
end if
|
||||
|
||||
if LEGACY_HEADERS
|
||||
if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_CODE & RAW_DATA_SIZE > 0
|
||||
load CODE_SIZE from PE:OptionalHeader.SizeOfCode
|
||||
if CODE_SIZE = 0
|
||||
load CODE_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
store CODE_BASE at PE:OptionalHeader.BaseOfCode
|
||||
end if
|
||||
CODE_SIZE = CODE_SIZE + RAW_DATA_SIZE
|
||||
store CODE_SIZE at PE:OptionalHeader.SizeOfCode
|
||||
end if
|
||||
if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_INITIALIZED_DATA & RAW_DATA_SIZE > 0
|
||||
load DATA_SIZE from PE:OptionalHeader.SizeOfInitializedData
|
||||
if DATA_SIZE = 0 & MAGIC <> 0x20B
|
||||
load DATA_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
store DATA_BASE at PE:OptionalHeader.BaseOfData
|
||||
end if
|
||||
DATA_SIZE = DATA_SIZE + RAW_DATA_SIZE
|
||||
store DATA_SIZE at PE:OptionalHeader.SizeOfInitializedData
|
||||
end if
|
||||
if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
||||
load BSS_SIZE from PE:OptionalHeader.SizeOfUninitializedData
|
||||
BSS_SIZE = BSS_SIZE + SECTION_SIZE
|
||||
store BSS_SIZE at PE:OptionalHeader.SizeOfUninitializedData
|
||||
end if
|
||||
end if
|
||||
|
||||
if DEFINED_SECTION | SECTION_SIZE > 0
|
||||
SECTION_INDEX = SECTION_INDEX + 1
|
||||
end if
|
||||
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro section? declaration*
|
||||
namespace PE
|
||||
|
||||
section
|
||||
|
||||
DEFINED_SECTION = 1
|
||||
|
||||
store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
store FILE_OFFSET at PE:SectionTable.PointerToRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
|
||||
SECTION_DIRECTORIES = 0
|
||||
|
||||
match name attributes, declaration
|
||||
|
||||
store name:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
|
||||
SECTION_CHARACTERISTICS = 0
|
||||
|
||||
local seq
|
||||
define seq attributes:
|
||||
while 1
|
||||
match :, seq
|
||||
break
|
||||
else match =readable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_READ
|
||||
else match =writeable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE
|
||||
else match =writable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE
|
||||
else match =executable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_EXECUTE
|
||||
else match =discardable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_DISCARDABLE
|
||||
else match =shareable? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_SHARED
|
||||
else match =import? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
|
||||
data import
|
||||
else match =export? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
|
||||
data export
|
||||
else match =resource? =from? path tail, seq
|
||||
redefine seq tail
|
||||
SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
|
||||
data resource from path
|
||||
else match =resource? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
|
||||
data resource
|
||||
else match =fixups? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1
|
||||
data fixups
|
||||
else match =code? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_CODE
|
||||
else match =data? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_INITIALIZED_DATA
|
||||
else match =udata? tail, seq
|
||||
redefine seq tail
|
||||
SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
||||
else match attribute tail, seq
|
||||
err 'unknown attribute "',`attribute,'"'
|
||||
redefine seq :
|
||||
end match
|
||||
end while
|
||||
|
||||
store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
else
|
||||
|
||||
store declaration:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH
|
||||
|
||||
end match
|
||||
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro data? type*
|
||||
namespace PE
|
||||
local number,content
|
||||
define content
|
||||
match =export?, type
|
||||
number = 0
|
||||
else match =import?, type
|
||||
number = 1
|
||||
else match =resource? =from? path, type
|
||||
number = 2
|
||||
define content resource_from path
|
||||
else match =resource?, type
|
||||
number = 2
|
||||
else match =fixups?, type
|
||||
number = 5
|
||||
define content fixups
|
||||
else
|
||||
number = type
|
||||
end match
|
||||
define DATA_DIRECTORY number
|
||||
load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
|
||||
if DATA_BASE = 0
|
||||
store $-IMAGE_BASE:dword at PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
|
||||
match instruction, content
|
||||
instruction
|
||||
end match
|
||||
else
|
||||
err 'data already defined'
|
||||
end if
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro end?.data?
|
||||
namespace PE
|
||||
load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
|
||||
store $-IMAGE_BASE-DATA_BASE:dword at PE:RvaAndSizes.Size+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH
|
||||
restore DATA_DIRECTORY
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro PE.resource_directory?
|
||||
namespace PE
|
||||
Resource: rb RESOURCE_HEADERS_LENGTH
|
||||
Resource.counter = 0
|
||||
define RESOURCE_DIRECTORIES_LIST Resource_root
|
||||
Resource_root.counter = 0
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro PE.resource_data? type*,id*,lang*,codepage:0
|
||||
namespace PE
|
||||
local _type,_id,_lang
|
||||
_type = type
|
||||
_id = id
|
||||
_lang = lang
|
||||
if ~ type eqtype 0
|
||||
_type = _type shl 32
|
||||
end if
|
||||
if ~ id eqtype 0
|
||||
_id = id shl 32
|
||||
end if
|
||||
if ~ lang eqtype 0
|
||||
_lang = lang shl 32
|
||||
end if
|
||||
repeat 1, %type:_type, %id:_id, %lang:_lang
|
||||
if ~ defined Resource_#%type#_#%id.counter
|
||||
if ~ defined Resource_#%type.counter
|
||||
repeat 1, i:Resource_root.counter
|
||||
Resource_root.entry#i = type
|
||||
Resource_root.offset#i = (Resource_#%type - Resource) or 80000000h
|
||||
end repeat
|
||||
Resource_root.counter = Resource_root.counter + 1
|
||||
match list, RESOURCE_DIRECTORIES_LIST
|
||||
define RESOURCE_DIRECTORIES_LIST list,Resource_#%type
|
||||
end match
|
||||
Resource_#%type.counter = 0
|
||||
end if
|
||||
repeat 1, i:Resource_#%type.counter
|
||||
Resource_#%type.entry#i = id
|
||||
Resource_#%type.offset#i = (Resource_#%type#_#%id - Resource) or 80000000h
|
||||
end repeat
|
||||
Resource_#%type.counter = Resource_#%type.counter + 1
|
||||
|
||||
match list, RESOURCE_DIRECTORIES_LIST
|
||||
define RESOURCE_DIRECTORIES_LIST list,Resource_#%type#_#%id
|
||||
end match
|
||||
Resource_#%type#_#%id.counter = 0
|
||||
end if
|
||||
repeat 1, i:Resource_#%type#_#%id.counter
|
||||
Resource_#%type#_#%id.entry#i = lang
|
||||
Resource_#%type#_#%id.offset#i = Resource_#%type#_#%id#_#%lang - Resource
|
||||
end repeat
|
||||
Resource_#%type#_#%id.counter = Resource_#%type#_#%id.counter + 1
|
||||
repeat 1, i:Resource.counter
|
||||
Resource_#%type#_#%id#_#%lang := Resource.entry#i
|
||||
Resource.cp#i := codepage
|
||||
Resource.data#i:
|
||||
end repeat
|
||||
end repeat
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro PE.end_resource_data?
|
||||
namespace PE
|
||||
repeat 1, i:Resource.counter
|
||||
Resource.size#i := $ - Resource.data#i
|
||||
end repeat
|
||||
Resource.counter = Resource.counter + 1
|
||||
align 4
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro PE.end_resource_directory?
|
||||
namespace PE
|
||||
RESOURCE_HEADERS_POINTER = 0
|
||||
|
||||
match list, RESOURCE_DIRECTORIES_LIST
|
||||
iterate dir, list
|
||||
dir := Resource + RESOURCE_HEADERS_POINTER
|
||||
RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16 + dir.counter * 8
|
||||
local x,y,z,a,b
|
||||
x = dir.counter shr 1
|
||||
while x > 0
|
||||
y = x
|
||||
while y < dir.counter
|
||||
z = y
|
||||
while z-x >= 0
|
||||
repeat 1, i:z, j:z-x
|
||||
if dir.entry#i eqtype 0
|
||||
if ~ dir.entry#j eqtype 0 | dir.entry#i >= dir.entry#j
|
||||
z = 0
|
||||
end if
|
||||
else if ~ dir.entry#j eqtype 0
|
||||
a = dir.entry#i bswap lengthof dir.entry#i
|
||||
b = dir.entry#j bswap lengthof dir.entry#j
|
||||
if ( lengthof a >= lengthof b & a shr ((lengthof a - lengthof b)*8) >= b ) | ( lengthof a < lengthof b & a > b shr ((lengthof b - lengthof a)*8) )
|
||||
z = 0
|
||||
end if
|
||||
end if
|
||||
if z > 0
|
||||
a = dir.entry#i
|
||||
b = dir.offset#i
|
||||
dir.entry#i = dir.entry#j
|
||||
dir.offset#i = dir.offset#j
|
||||
dir.entry#j = a
|
||||
dir.offset#j = b
|
||||
z = z - x
|
||||
end if
|
||||
end repeat
|
||||
end while
|
||||
y = y + 1
|
||||
end while
|
||||
x = x shr 1
|
||||
end while
|
||||
end iterate
|
||||
iterate dir, list
|
||||
store __TIME__ : 4 at dir + 4
|
||||
dir.names_counter = 0
|
||||
repeat dir.counter, i:0
|
||||
if dir.entry#i eqtype 0
|
||||
store dir.entry#i : 4 at dir + 16 + i * 8
|
||||
else
|
||||
dir.names_counter = dir.names_counter + 1
|
||||
repeat 1, %id:dir.entry#i
|
||||
if ~ defined Resource_string#%id
|
||||
restore Resource_string#%id
|
||||
Resource_string#%id = Resource + RESOURCE_HEADERS_POINTER
|
||||
if lengthof dir.entry#i and 1
|
||||
err 'a word-aligned string is expected as a name'
|
||||
end if
|
||||
RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + lengthof dir.entry#i + 2
|
||||
store (lengthof dir.entry#i)/2 : 2 at Resource_string#%id
|
||||
store dir.entry#i : lengthof dir.entry#i at Resource_string#%id + 2
|
||||
end if
|
||||
store (Resource_string#%id - Resource) or 80000000h : 4 at dir + 16 + i * 8
|
||||
end repeat
|
||||
end if
|
||||
store dir.offset#i : 4 at dir + 16 + i * 8 + 4
|
||||
end repeat
|
||||
store dir.names_counter : 2 at dir + 12
|
||||
store dir.counter - dir.names_counter : 2 at dir + 14
|
||||
end iterate
|
||||
end match
|
||||
|
||||
if RESOURCE_HEADERS_POINTER and 11b
|
||||
RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 4 - RESOURCE_HEADERS_POINTER and 11b
|
||||
end if
|
||||
|
||||
repeat Resource.counter, i:0
|
||||
Resource.entry#i := Resource + RESOURCE_HEADERS_POINTER
|
||||
RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16
|
||||
store RVA(Resource.data#i) : 4 at Resource.entry#i
|
||||
store Resource.size#i : 4 at Resource.entry#i + 4
|
||||
store Resource.cp#i : 4 at Resource.entry#i + 8
|
||||
end repeat
|
||||
|
||||
RESOURCE_HEADERS_LENGTH = RESOURCE_HEADERS_POINTER
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
macro PE.resource_from path*
|
||||
|
||||
local res_file,res_size,res_header_size,res_data_size,res_data
|
||||
local offset,char,type,id,lang
|
||||
|
||||
virtual at 0
|
||||
res_file:: file path
|
||||
res_size := $
|
||||
end virtual
|
||||
|
||||
PE.resource_directory
|
||||
|
||||
offset = 0
|
||||
while offset < res_size
|
||||
load res_header_size : 4 from res_file : offset + 4
|
||||
load res_data_size : 4 from res_file : offset + 0
|
||||
|
||||
if res_data_size > 0
|
||||
|
||||
offset =: offset + 8
|
||||
load char : 2 from res_file : offset
|
||||
if char = 0FFFFh
|
||||
load char : 2 from res_file : offset + 2
|
||||
type = +char
|
||||
offset = offset + 4
|
||||
else
|
||||
while 1
|
||||
if char = 0
|
||||
load type : (%-1)*2 from res_file : offset
|
||||
offset = offset + (% + % and 1)*2
|
||||
break
|
||||
end if
|
||||
load char : 2 from res_file : offset + %*2
|
||||
end while
|
||||
end if
|
||||
load char : 2 from res_file : offset
|
||||
if char = 0FFFFh
|
||||
load char : 2 from res_file : offset + 2
|
||||
id = +char
|
||||
offset = offset + 4
|
||||
else
|
||||
while 1
|
||||
if char = 0
|
||||
load id : (%-1)*2 from res_file : offset
|
||||
offset = offset + (% + % and 1)*2
|
||||
break
|
||||
end if
|
||||
load char : 2 from res_file : offset + %*2
|
||||
end while
|
||||
end if
|
||||
load char : 2 from res_file : offset + 6
|
||||
lang = +char
|
||||
|
||||
restore offset
|
||||
|
||||
PE.resource_data type,id,lang
|
||||
load res_data : res_data_size from res_file : offset + res_header_size
|
||||
db res_data
|
||||
PE.end_resource_data
|
||||
|
||||
end if
|
||||
|
||||
offset = offset + res_header_size + res_data_size
|
||||
if offset and 11b
|
||||
offset = offset + 4 - offset and 11b
|
||||
end if
|
||||
end while
|
||||
|
||||
PE.end_resource_directory
|
||||
|
||||
end macro
|
||||
|
||||
macro PE.fixups
|
||||
namespace PE
|
||||
Fixups:
|
||||
calminstruction BuildFixups
|
||||
local PAGE_RVA, BLOCK_HEADER, BLOCK_SIZE
|
||||
local INDEX, ADDRESS, TYPE, FIXUP
|
||||
check NUMBER_OF_RELOCATIONS = 0
|
||||
jyes dummy
|
||||
compute PAGE_RVA, -1
|
||||
compute BLOCK_HEADER, 0
|
||||
compute BLOCK_SIZE, 0
|
||||
compute INDEX,0
|
||||
process:
|
||||
check INDEX = NUMBER_OF_RELOCATIONS
|
||||
jyes close_block
|
||||
load ADDRESS, relocated_addresses:INDEX shl 2, 4
|
||||
check PAGE_RVA >= 0 & ADDRESS and not 0FFFh = PAGE_RVA
|
||||
jyes append_to_block
|
||||
close_block:
|
||||
check BLOCK_HEADER
|
||||
jno start_new_block
|
||||
check BLOCK_SIZE and 11b
|
||||
jno finish_block
|
||||
emit 2, 0
|
||||
compute BLOCK_SIZE, BLOCK_SIZE + 2
|
||||
finish_block:
|
||||
store BLOCK_HEADER+4, 4, BLOCK_SIZE
|
||||
start_new_block:
|
||||
check INDEX = NUMBER_OF_RELOCATIONS
|
||||
jyes done
|
||||
compute PAGE_RVA, ADDRESS and not 0FFFh
|
||||
compute BLOCK_HEADER, $%
|
||||
emit 4, PAGE_RVA
|
||||
emit 4, 0
|
||||
compute BLOCK_SIZE, 8
|
||||
append_to_block:
|
||||
load TYPE, relocation_types:INDEX shl 1, 2
|
||||
compute FIXUP, (ADDRESS and 0FFFh) or (TYPE shl 12)
|
||||
emit 2, FIXUP
|
||||
compute BLOCK_SIZE, BLOCK_SIZE + 2
|
||||
compute INDEX, INDEX + 1
|
||||
jump process
|
||||
dummy:
|
||||
emit 4, 0
|
||||
emit 4, 8
|
||||
done:
|
||||
end calminstruction
|
||||
BuildFixups
|
||||
end namespace
|
||||
end macro
|
||||
|
||||
if defined PE.Fixups
|
||||
|
||||
calminstruction dword? value*
|
||||
compute value, value
|
||||
check value relativeto 0 | ~ value relativeto PE.RELOCATION
|
||||
jyes plain
|
||||
local offset
|
||||
compute offset, $%
|
||||
emit 4, value - PE.RELOCATION
|
||||
check $% > offset
|
||||
jno done
|
||||
store PE.relocated_addresses:PE.RELOCATION_INDEX shl 2, 4, $-4-PE.IMAGE_BASE
|
||||
store PE.relocation_types:PE.RELOCATION_INDEX shl 1, 2, IMAGE_REL_BASED_HIGHLOW
|
||||
compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1
|
||||
done:
|
||||
exit
|
||||
plain:
|
||||
emit 4, value
|
||||
end calminstruction
|
||||
|
||||
calminstruction qword? value*
|
||||
compute value, value
|
||||
check value relativeto 0 | ~ value relativeto PE.RELOCATION
|
||||
jyes plain
|
||||
local offset
|
||||
compute offset, $%
|
||||
emit 8, value - PE.RELOCATION
|
||||
check $% > offset
|
||||
jno done
|
||||
store PE.relocated_addresses:PE.RELOCATION_INDEX shl 2, 4, $-8-PE.IMAGE_BASE
|
||||
store PE.relocation_types:PE.RELOCATION_INDEX shl 1, 2, IMAGE_REL_BASED_DIR64
|
||||
compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1
|
||||
done:
|
||||
exit
|
||||
plain:
|
||||
emit 8, value
|
||||
end calminstruction
|
||||
|
||||
end if
|
||||
|
||||
postpone
|
||||
purge section?
|
||||
section
|
||||
namespace PE
|
||||
SIZE_OF_IMAGE := SECTION_BASE - IMAGE_BASE
|
||||
NUMBER_OF_SECTIONS := SECTION_INDEX
|
||||
NUMBER_OF_RELOCATIONS := RELOCATION_INDEX
|
||||
end namespace
|
||||
end postpone
|
||||
|
||||
postpone ?
|
||||
namespace PE
|
||||
CHECKSUM = 0
|
||||
|
||||
calminstruction CheckSum
|
||||
local AREA, DATA_LENGTH, POS, H
|
||||
get_block:
|
||||
match AREA=,DATA_LENGTH=,CheckSumBlocks, CheckSumBlocks
|
||||
jyes block_ready
|
||||
match AREA=,DATA_LENGTH, CheckSumBlocks
|
||||
jyes last_block
|
||||
exit
|
||||
last_block:
|
||||
arrange CheckSumBlocks,
|
||||
block_ready:
|
||||
compute POS, 0
|
||||
process_block:
|
||||
check POS + 2 <= DATA_LENGTH
|
||||
jno finish_block
|
||||
load H, AREA:POS, 2
|
||||
compute CHECKSUM, CHECKSUM + H
|
||||
compute POS, POS + 2
|
||||
jump process_block
|
||||
finish_block:
|
||||
check POS + 1 = DATA_LENGTH
|
||||
jno reduce_checksum
|
||||
load H, AREA:POS, 1
|
||||
compute CHECKSUM, CHECKSUM + H
|
||||
reduce_checksum:
|
||||
check CHECKSUM shr 16
|
||||
jno get_block
|
||||
compute CHECKSUM, CHECKSUM shr 16 + CHECKSUM and 0FFFFh
|
||||
jump reduce_checksum
|
||||
done:
|
||||
end calminstruction
|
||||
|
||||
CheckSum
|
||||
CHECKSUM = CHECKSUM + $%
|
||||
store CHECKSUM at PE:OptionalHeader.CheckSum
|
||||
end namespace
|
||||
end postpone
|
Reference in New Issue
Block a user