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