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