src->rt; smol*.py -> src; add optional 16-bit hash version

This commit is contained in:
PoroCYon 2019-03-30 04:24:46 +01:00
parent 0186019f99
commit fa674f5239
14 changed files with 62 additions and 26 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
/bin
/obj
/__pycache__
__pycache__

View File

@ -1,6 +1,7 @@
OBJDIR := obj
BINDIR := bin
SRCDIR := src
SRCDIR := rt
PYDIR := src
LDDIR := ld
TESTDIR:= test
@ -40,7 +41,7 @@ CXXFLAGS += -m$(BITS) $(shell pkg-config --cflags sdl2)
LIBS=-lc
SMOLFLAGS +=
SMOLFLAGS += -s
ASFLAGS += -DUSE_INTERP -DUSE_DNLOAD_LOADER -DNO_START_ARG -DUNSAFE_DYNAMIC #-DALIGN_STACK
#-DUSE_DNLOAD_LOADER #-DUSE_DT_DEBUG #-DUSE_DL_FINI #-DNO_START_ARG #-DUNSAFE_DYNAMIC
@ -73,7 +74,7 @@ $(OBJDIR)/%.start.o: $(OBJDIR)/%.lto.o $(OBJDIR)/crt1.lto.o
$(CC) $(LDFLAGS) -r -o "$@" $^
$(OBJDIR)/symbols.%.asm: $(OBJDIR)/%.o
$(PYTHON3) ./smol.py $(SMOLFLAGS) $(LIBS) "$<" "$@"
$(PYTHON3) $(PYDIR)/smol.py $(SMOLFLAGS) $(LIBS) "$<" "$@"
$(OBJDIR)/stub.%.o: $(OBJDIR)/symbols.%.asm $(SRCDIR)/header32.asm \
$(SRCDIR)/loader32.asm

View File

@ -11,7 +11,7 @@
_smol_start:
;.loopme: jmp short .loopme
%ifdef USE_DL_FINI
push edx ; _dl_fini
%endif
@ -81,28 +81,46 @@ _smol_start:
add esi, ebx
push ecx
%ifndef USE_HASH16
push ebx
push 33
push 5381
pop eax
pop ebx
%else
xor eax, eax
%endif
xor ecx, ecx
.nexthashiter:
xchg eax, ecx
lodsb
or al, al
xchg eax, ecx
jz short .breakhash
;
xchg eax, ecx
lodsb
or al, al
xchg eax, ecx
jz short .breakhash
push edx
mul ebx
pop edx
add eax, ecx
jmp short .nexthashiter
%ifndef USE_HASH16
push edx
mul ebx
pop edx
; add eax, ecx
%else
ror ax, 2
; add ax, cx
%endif
add eax, ecx
jmp short .nexthashiter
.breakhash:
%ifndef USE_HASH16
pop ebx
%endif
pop ecx
;%ifndef USE_HASH16
; cmp ecx, eax
;%else
; cmp cx, ax
;%endif
cmp ecx, eax
je short .hasheq
@ -244,7 +262,7 @@ link.done:
%ifdef USE_DL_FINI
pop edx ; _dl_fini
%endif
; move esp into eax, *then* increase the stack by 4, as main()
; move esp into eax, *then* increase the stack by 4, as main()
; expects a return address to be inserted by a call instruction
; (which we don't have, so we're doing a 1-byte fixup instead of a
; 5-byte call)

View File

@ -30,6 +30,9 @@ def main():
parser.add_argument('--readelf', default=shutil.which('readelf'), \
help="which readelf binary to use")
parser.add_argument('-s', '--hash16', default=False, action='store_true', \
help="Use 16-bit (BSD) hashes instead of 32-bit djb2 hashes. "\
+"Conflicts with -DUSE_DNLOAD_LOADER")
# 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', \
@ -69,7 +72,7 @@ def main():
symbols.setdefault(library, [])
symbols[library].append((symbol, reloc))
output(arch, symbols, args.nx, args.output)
output(arch, symbols, args.nx, args.hash16, args.output)
if __name__ == '__main__':
main()

View File

@ -3,11 +3,11 @@ import sys
from smolshared import *
def output_x86(libraries, nx, outf):
def output_x86(libraries, nx, h16, outf):
outf.write('; vim: set ft=nasm:\n') # be friendly
if nx:
outf.write('%define USE_NX 1\n')
if nx: outf.write('%define USE_NX 1\n')
if h16: outf.write('%define USE_HASH16 1\n')
usedrelocs = set({})
for library, symrels in libraries.items():
@ -56,7 +56,7 @@ dynamic.end:
eprintf('Relocation type ' + reloc + ' of symbol ' + sym + ' unsupported!')
sys.exit(1)
hash = hash_djb2(sym)
hash = hash_bsd2(sym) if h16 else hash_djb2(sym)
if nx:
outf.write("\t\t_symbols.{lib}.{name}: dd 0x{hash:x}"\
.format(lib=shorts[library],name=sym,hash=hash).lstrip('\n'))
@ -87,7 +87,14 @@ global {name}
# end output_x86
def output_amd64(libraries, outf):
def output_amd64(libraries, nx, h16, outf):
if h16:
eprintf("--hash16 not supported yet for x86_64 outputs.")
exit(1)
if nx: outf.write('%define USE_NX 1\n')
# if h16: outf.write('%define USE_HASH16 1\n')
outf.write('; vim: set ft=nasm:\n')
outf.write('bits 64\n')
@ -129,7 +136,7 @@ global {name}
{name}:
""".format(name=sym).lstrip('\n'))
hash = hash_djb2(sym)
hash = hash_bsd2(sym) if h16 else hash_djb2(sym)
outf.write('\t\t_symbols.{lib}.{name}: dq 0x{hash:x}\n'\
.format(lib=shorts[library],name=sym,hash=hash))
@ -152,9 +159,9 @@ global {name}
# end output_amd64
def output(arch, libraries, nx, outf):
if arch == 'i386': output_x86(libraries, nx, outf)
elif arch == 'x86_64': output_amd64(libraries, outf)
def output(arch, libraries, nx, h16, outf):
if arch == 'i386': output_x86(libraries, nx, h16, outf)
elif arch == 'x86_64': output_amd64(libraries, nx, h16, outf)
else:
eprintf("E: cannot emit for arch '" + str(arch) + "'")
sys.exit(1)

View File

@ -3,9 +3,16 @@ import sys
archmagic = {
'i386': 3, 3: 'i386' ,
# arm: 40
'x86_64': 62, 62: 'x86_64',
}
def hash_bsd2(s):
h = 0
for c in s:
h = ((h >> 2) + ((h & 3) << 14) + ord(c)) & 0xFFFF
return h
def hash_djb2(s):
h = 5381
for c in s: