add dnload import method to 64-bit version (unoptimized atm)

This commit is contained in:
PoroCYon 2019-03-11 01:14:38 +01:00 committed by PoroCYon
parent aed33c73a9
commit 5e19c2746e
6 changed files with 117 additions and 6 deletions

View File

@ -40,7 +40,8 @@ CXXFLAGS += -m$(BITS) $(shell pkg-config --cflags sdl2)
LIBS=-lc
ASFLAGS += -DUSE_INTERP -DALIGN_STACK -DNO_START_ARG #-DUSE_DT_DEBUG
SMOLFLAGS += -d
ASFLAGS += -DUSE_INTERP -DALIGN_STACK -DNO_START_ARG #-DUSE_DT_DEBUG
NASM ?= nasm
PYTHON3 ?= python3

View File

@ -30,6 +30,8 @@ def main():
parser.add_argument('--readelf', default=shutil.which('readelf'), \
help="which readelf binary to use")
parser.add_argument('-d', '--dnload', default=False, action='store_true', \
help="Use dnload's mechanism of importing functions. Slightly larger, but usually better compressable.")
# parser.add_argument('--libsep', default=False, action='store_true', \
# help="Separete import symbols per library, instead of looking at every library when resolving a symbol.")
@ -64,7 +66,7 @@ def main():
symbols.setdefault(library, [])
symbols[library].append((symbol, reloc))
output(arch, symbols, args.output)
output(arch, symbols, args.dnload, args.output)
if __name__ == '__main__':
main()

View File

@ -51,9 +51,11 @@ def output_x86(libraries, outf):
# end output_x86
def output_amd64(libraries, outf):
def output_amd64(libraries, dnload, outf):
outf.write('; vim: set ft=nasm:\n')
outf.write('bits 64\n')
if dnload:
outf.write('%define USE_DNLOAD_LOADER\n')
shorts = { l: l.split('.', 1)[0].lower().replace('-', '_') for l in libraries }
@ -108,9 +110,9 @@ global {name}
# end output_amd64
def output(arch, libraries, outf):
def output(arch, libraries, dnload, outf):
if arch == 'i386': output_x86(libraries, outf)
elif arch == 'x86_64': output_amd64(libraries, outf)
elif arch == 'x86_64': output_amd64(libraries, dnload, outf)
else:
eprintf("E: cannot emit for arch '" + str(arch) + "'")
sys.exit(1)

View File

@ -32,3 +32,9 @@
%define DT_SYMTAB ( 6)
%define DT_DEBUG (21)
%define ST_NAME_OFF ( 0)
; ,---- not 16?
; v
%define ST_VALUE_OFF ( 8)
%define SYMTAB_SIZE (24)

View File

@ -41,8 +41,100 @@ _smol_start:
mov r12, [r12 + L_NEXT_OFF] ; skip this binary
; mov r12, [r12 + L_NEXT_OFF] ; skip the vdso
; the second one isn't needed anymore, see code below (.next_link)
;%elifdef USE_DNLOAD_LOADER
; mov r12, [r12 + L_NEXT_OFF] ; skip this binary
%endif
%ifdef USE_DNLOAD_LOADER
push _symbols
push r12
pop r11
pop rdi
;.loopme: jmp short .loopme ; debugging
.next_hash:
;
mov r14d, dword [rdi]
; assume it's nonzero
push r11
pop r12
.next_link:
mov r12, [r12 + L_NEXT_OFF]
; ElfW(Dyn)* dyn(rsi) = r12->l_ld
mov rsi, [r12 + L_LD_OFF]
; get strtab off
.next_dyn:
lodsq
cmp al, DT_STRTAB
lodsq
jne short .next_dyn
; void* addr(rcx) = r12->l_addr
; const char* strtab(r9) = lookup(rsi,DT_STRTAB), *symtab_end(r8)=r9;
mov rcx, [r12 + L_ADDR_OFF]
cmp rax, rcx
jge short .noreldynaddr
add rax, rcx
.noreldynaddr:
push rax
push rax
pop r8
pop r9
; const ElfW(Sym)* symtab(rdx) = lookup(rsi, DT_SYMTAB);
lodsq ; SYMTAB d_tag
lodsq ; SYMTAB d_un.d_ptr
cmp rax, rcx
jge short .norelsymaddr
add rax, rcx
.norelsymaddr:
push rax
pop rdx
.next_sym:
mov esi, dword [rdx + ST_NAME_OFF]
add rsi, r9
push 33
push 5381
push 0
pop rcx
pop rax
pop rbx
.nexthashiter:
; TODO: optimize register usage so that lodsb can be used
mov cl, byte [rsi]
inc rsi
or cl, cl
jz short .breakhash
push rdx
mul ebx
pop rdx
add eax, ecx
jmp short .nexthashiter
.breakhash:
cmp r14d, eax
je short .eq
add rdx, SYMTAB_SIZE
cmp rdx, r8
jl short .next_sym
; int3
jmp short .next_link
.eq:
mov rax, [rdx + ST_VALUE_OFF]
add rax, [r12 + L_ADDR_OFF]
stosq
cmp word [rdi], 0
jne short .next_hash
; if USE_DNLOAD_LOADER
%else
push _smol_start
push r12
push -1
@ -134,6 +226,9 @@ repne scasd ; technically, scasq should be used, but ehhhh
; } while (1)
; jmp short .next_hash
; if USE_DNLOAD_LOADER ... else ...
%endif
.needed_end:
; int3 ; debugging
; xor rbp, rbp ; still 0 from _dl_start_user
@ -142,8 +237,11 @@ repne scasd ; technically, scasq should be used, but ehhhh
mov rdi, rsp
%endif
%ifdef ALIGN_STACK
%ifdef USE_DNLOAD_LOADER
push rax
%else
; apparently not needed?
; push rax
%endif
%endif
%ifdef USE_DL_FINI
xchg rsi, r13 ; _dl_fini

View File

@ -18,11 +18,13 @@
%define DT_SYMSIZE_SHIFT 4
%define DT_STRTAB 0x5
%define DT_SYMTAB 0x6
%else
%define L_ADDR_OFF ( 0)
%define L_NAME_OFF ( 8)
%define L_LD_OFF ( 16)
%define L_NEXT_OFF ( 24)
%define L_INFO_OFF ( 64)
%define L_INFO_DT_SYMTAB_OFF (112)