Skip to content

Commit

Permalink
automatically adapt end-of-hashes check width to the symbols used (cl…
Browse files Browse the repository at this point in the history
…oses #6)
  • Loading branch information
PoroCYon committed Aug 24, 2020
1 parent c1601fc commit b71b15b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
9 changes: 7 additions & 2 deletions rt/loader32.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

%include "rtld.inc"

%ifndef HASH_END_TYP
%warning "W: HASH_END_TYP not defined, falling back to 16-bit!"
%define HASH_END_TYP word
%endif

%define R10_BIAS (0x178)

%ifdef ELF_TYPE
Expand Down Expand Up @@ -186,7 +191,7 @@ _smol_start:
%ifdef USE_JMP_BYTES
inc edi ; skip 0xE9 (jmp) offset
%endif
cmp word [edi], 0
cmp HASH_END_TYP [edi], 0
jne short .next_hash

; if USE_DNLOAD_LOADER
Expand Down Expand Up @@ -300,7 +305,7 @@ repne scasd
%ifdef USE_JMP_BYTES
inc edi
%endif
cmp word [edi], 0
cmp HASH_END_TYP [edi], 0
jne short .next_hash

pop eax ; get rid of leftover ecx on stack
Expand Down
9 changes: 7 additions & 2 deletions rt/loader64.asm
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
; vim: set ft=nasm:

%ifndef HASH_END_TYP
%warning "W: HASH_END_TYP not defined, falling back to 16-bit!"
%define HASH_END_TYP word
%endif

;%define R10_BIAS (0x2B4)
%define R10_BIAS (0x2B4+0x40)

Expand Down Expand Up @@ -153,7 +158,7 @@ _smol_start:
%endif
%endif
stosq
cmp word [rdi], 0
cmp HASH_END_TYP [rdi], 0
%ifdef IFUNC_SUPPORT
%ifdef SKIP_ZERO_VALUE
jne .next_hash;short .next_hash
Expand Down Expand Up @@ -311,7 +316,7 @@ repne scasd ; technically, scasq should be used, but meh. this is 1 byte smaller
; IFUNC_SUPPORT
%endif
stosq ; *phash = finaladdr
cmp word [rdi], 0
cmp HASH_END_TYP [rdi], 0
jne short .next_hash
; } while (1)
; jmp short .next_hash
Expand Down
29 changes: 26 additions & 3 deletions smol/emit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

from .shared import *

fetch_width_from_bits = { 8: 'byte', 16: 'word', 32: 'dword', 64: 'qword' }

def get_min_check_width(libraries, hashfn):
minv = 8 # can't go lower
for k, v in libraries.items():
for sym in v:
hv = hashfn(sym[0]) # sym == (name, reloc)
if (hv & 0xffffffff) == 0:
# this should (hopefully) NEVER happen
error("Aiee, all-zero hash for sym '%s'!" % sym)
elif (hv & 0xFFFF) == 0:
minv = max(minv, 32) # need at least 32 bits
elif (hv & 0xFF) == 0:
minv = max(minv, 16) # need at least 16 bits

return minv

def sort_imports(libraries, hashfn):
#eprintf("in: " + str(libraries))

Expand All @@ -29,6 +46,9 @@ def output_x86(libraries, nx, h16, outf, det):
hashfn = hash_bsd2 if h16 else hash_djb2
if det: libraries = sort_imports(libraries, hashfn)

outf.write('%%define HASH_END_TYP %s\n' %
fetch_width_from_bits[get_min_check_width(libraries, hashfn)])

usedrelocs = set({})
for library, symrels in libraries.items():
for sym, reloc in symrels: usedrelocs.add(reloc)
Expand Down Expand Up @@ -74,7 +94,7 @@ def output_x86(libraries, nx, h16, outf, det):
for sym, reloc in symrels:
# meh
if reloc != 'R_386_PC32' and reloc != 'R_386_GOT32X':
eprintf('Relocation type ' + reloc + ' of symbol ' + sym + ' unsupported!')
eprintf('Relocation type %s of symbol %s unsupported!' % (reloc, sym))
sys.exit(1)

if nx:
Expand Down Expand Up @@ -118,6 +138,9 @@ def output_amd64(libraries, nx, h16, outf, det):
hashfn = hash_djb2 #hash_bsd2 if h16 else hash_djb2
if det: libraries = sort_imports(libraries, hashfn)

outf.write('%%define HASH_END_TYP %s\n' %
fetch_width_from_bits[get_min_check_width(libraries, hashfn)])

outf.write('; vim: set ft=nasm:\n')
outf.write('bits 64\n')

Expand Down Expand Up @@ -153,7 +176,7 @@ def output_amd64(libraries, nx, h16, outf, det):
for sym, reloc in symrels:
if reloc not in ['R_X86_64_PLT32', 'R_X86_64_GOTPCRELX', \
'R_X86_64_REX_GOTPCRELX', 'R_X86_64_GOTPCREL']:
error('Relocation type ' + reloc + ' of symbol ' + sym + ' unsupported!')
error('Relocation type %s of symbol %s unsupported!' % (reloc, sym))

if reloc in ['R_X86_64_GOTPCRELX', 'R_X86_64_REX_GOTPCRELX', \
'R_X86_64_GOTPCREL']:
Expand Down Expand Up @@ -189,5 +212,5 @@ def output(arch, libraries, nx, h16, outf, det):
if arch == 'i386': output_x86(libraries, nx, h16, outf, det)
elif arch == 'x86_64': output_amd64(libraries, nx, h16, outf, det)
else:
error("E: cannot emit for arch '" + str(arch) + "'")
error("E: cannot emit for arch '%s'" % str(arch))

0 comments on commit b71b15b

Please sign in to comment.