mirror of https://github.com/Shizmob/smol
32-bit version working (not yet the dnload version)
This commit is contained in:
parent
8c7ce9c930
commit
3eea42e29c
4
Makefile
4
Makefile
|
@ -41,8 +41,8 @@ CXXFLAGS += -m$(BITS) $(shell pkg-config --cflags sdl2)
|
||||||
|
|
||||||
LIBS=-lc
|
LIBS=-lc
|
||||||
|
|
||||||
SMOLFLAGS += -s
|
SMOLFLAGS +=
|
||||||
ASFLAGS += -DUSE_INTERP -DUSE_DNLOAD_LOADER -DNO_START_ARG -DUNSAFE_DYNAMIC #-DALIGN_STACK
|
ASFLAGS += -DUSE_INTERP -DNO_START_ARG -DUNSAFE_DYNAMIC -DUSE_DNLOAD_LOADER #-DALIGN_STACK
|
||||||
#-DUSE_DNLOAD_LOADER #-DUSE_DT_DEBUG #-DUSE_DL_FINI #-DNO_START_ARG #-DUNSAFE_DYNAMIC
|
#-DUSE_DNLOAD_LOADER #-DUSE_DT_DEBUG #-DUSE_DL_FINI #-DNO_START_ARG #-DUNSAFE_DYNAMIC
|
||||||
|
|
||||||
NASM ?= nasm
|
NASM ?= nasm
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
%define DT_DEBUG (21)
|
%define DT_DEBUG (21)
|
||||||
|
|
||||||
%define ST_NAME_OFF ( 0)
|
%define ST_NAME_OFF ( 0)
|
||||||
; ,---- not 16?
|
; ,---- not 16? ; what's this comment??!
|
||||||
; v
|
; v
|
||||||
%if __BITS__ == 32
|
%if __BITS__ == 32
|
||||||
%define D_UN_PTR_OFF ( 4)
|
%define D_UN_PTR_OFF ( 4)
|
||||||
|
|
171
rt/loader32.asm
171
rt/loader32.asm
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
%include "rtld.inc"
|
%include "rtld.inc"
|
||||||
|
|
||||||
|
; TODO
|
||||||
|
%define R10_BIAS (0)
|
||||||
|
|
||||||
%ifdef ELF_TYPE
|
%ifdef ELF_TYPE
|
||||||
[section .text.startup.smol]
|
[section .text.startup.smol]
|
||||||
%else
|
%else
|
||||||
|
@ -9,9 +12,14 @@
|
||||||
[section .text]
|
[section .text]
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%ifndef USE_DNLOAD_LOADER
|
||||||
|
_smol_linkmap:
|
||||||
|
dd 0
|
||||||
|
_smol_linkoff:
|
||||||
|
dd 0
|
||||||
|
%endif
|
||||||
|
|
||||||
_smol_start:
|
_smol_start:
|
||||||
;.loopme: jmp short .loopme
|
|
||||||
%ifdef USE_DL_FINI
|
%ifdef USE_DL_FINI
|
||||||
push edx ; _dl_fini
|
push edx ; _dl_fini
|
||||||
%endif
|
%endif
|
||||||
|
@ -28,9 +36,14 @@ _smol_start:
|
||||||
; mov eax, [eax + LM_NEXT_OFFSET] ; skip the vdso
|
; mov eax, [eax + LM_NEXT_OFFSET] ; skip the vdso
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%ifdef USE_JMP_BYTES
|
||||||
|
push _symbols+1
|
||||||
|
%else
|
||||||
push _symbols
|
push _symbols
|
||||||
push eax
|
%endif
|
||||||
|
|
||||||
%ifdef USE_DNLOAD_LOADER
|
%ifdef USE_DNLOAD_LOADER
|
||||||
|
; TODO: borked!
|
||||||
pop ebp
|
pop ebp
|
||||||
pop edi
|
pop edi
|
||||||
|
|
||||||
|
@ -152,6 +165,10 @@ _smol_start:
|
||||||
|
|
||||||
; if USE_DNLOAD_LOADER
|
; if USE_DNLOAD_LOADER
|
||||||
%else
|
%else
|
||||||
|
;.loopme: jmp short .loopme
|
||||||
|
|
||||||
|
mov [_smol_linkmap], eax
|
||||||
|
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
push -1
|
push -1
|
||||||
|
@ -160,103 +177,79 @@ _smol_start:
|
||||||
repne scasd
|
repne scasd
|
||||||
sub edi, ebx
|
sub edi, ebx
|
||||||
sub edi, LM_ENTRY_OFFSET_BASE+4
|
sub edi, LM_ENTRY_OFFSET_BASE+4
|
||||||
|
mov [_smol_linkoff], edi
|
||||||
|
|
||||||
xchg ebp, ebx
|
pop edi ; _symbols
|
||||||
xchg ebx, edi;esi
|
|
||||||
mov esi, _symbols
|
|
||||||
|
|
||||||
link: ; (struct link_map *root, char *symtable)
|
; edi: _symbols
|
||||||
.do_library: ; null library name means end of symbol table, we're done
|
; ebp: link_map* root
|
||||||
cmp byte [esi], 0
|
push ecx
|
||||||
jz .done
|
.next_hash:
|
||||||
.find_map_entry: ; compare basename(entry->l_name) to lib name, if so we got a match
|
pop ecx
|
||||||
push esi
|
mov ecx, [edi]
|
||||||
mov esi, [ebp + LM_NAME_OFFSET]
|
|
||||||
|
|
||||||
.basename: ; (const char *s (esi))
|
mov ebp, [_smol_linkmap]
|
||||||
mov edi, esi
|
; ecx: hash (assumed nonzero)
|
||||||
.basename.cmp:
|
; ebp: link_map* chain
|
||||||
lodsb
|
|
||||||
cmp al, '/'
|
|
||||||
cmove edi, esi
|
|
||||||
or al, al
|
|
||||||
jnz short .basename.cmp
|
|
||||||
.basename.done:
|
|
||||||
pop esi
|
|
||||||
.basename.end:
|
|
||||||
|
|
||||||
.strcmp: ; (const char *s1 (esi), const char *s2 (edi))
|
push ecx
|
||||||
push esi
|
.next_link:
|
||||||
push edi
|
pop ecx
|
||||||
.strcmp.cmp:
|
mov ebp, [ebp + L_NEXT_OFF]
|
||||||
lodsb
|
mov esi, ebp
|
||||||
or al, al
|
add esi, [_smol_linkoff]
|
||||||
jz short .strcmp.done
|
|
||||||
sub al, [edi]
|
|
||||||
jnz short .strcmp.done
|
|
||||||
inc edi
|
|
||||||
jmp short .strcmp.cmp
|
|
||||||
.strcmp.done:
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
.strcmp.end:
|
|
||||||
|
|
||||||
|
; edx: btk_ind
|
||||||
|
push ecx
|
||||||
|
push ecx
|
||||||
|
push ecx
|
||||||
|
pop eax
|
||||||
|
mov ecx, [esi + LF_NBUCKETS_OFF]
|
||||||
|
xor edx, edx
|
||||||
|
div ecx
|
||||||
|
pop ecx
|
||||||
|
shr ecx, 1
|
||||||
|
|
||||||
jz short .process_map_entry
|
; ebx: bucket
|
||||||
; no match, next entry it is!
|
mov ebx, [esi + LF_GNU_BUCKETS_OFF]
|
||||||
mov ebp, [ebp + LM_NEXT_OFFSET]
|
mov ebx, [ebx + edx * 4]
|
||||||
jmp short .find_map_entry
|
|
||||||
.process_map_entry: ; skip past the name in the symbol table now to get to the symbols
|
|
||||||
lodsb
|
|
||||||
or al, al
|
|
||||||
jnz short .process_map_entry
|
|
||||||
|
|
||||||
.do_symbols: ; null byte means end of symbols for this library!
|
.next_chain:
|
||||||
lodsb
|
; edx: luhash
|
||||||
test al, al
|
mov edx, [esi + LF_GNU_CHAIN_ZERO_OFF]
|
||||||
jz short .do_library
|
mov edx, [edx + ebx * 4]
|
||||||
push ebx
|
|
||||||
xchg ebx, edi
|
|
||||||
|
|
||||||
link_symbol: ; (struct link_map *entry, uint32_t *h)
|
; ecx: hash
|
||||||
mov ecx, esi
|
mov al, dl
|
||||||
|
|
||||||
; eax = *h % entry->l_nbuckets
|
shr edx, 1
|
||||||
mov eax, [ecx]
|
cmp edx, ecx
|
||||||
xor edx, edx
|
je short .chain_break
|
||||||
mov ebx, [ebp + edi + LM_NBUCKETS_OFFSET]
|
|
||||||
div ebx
|
and al, 1
|
||||||
; eax = entry->l_gnu_buckets[edx]
|
jnz short .next_link
|
||||||
mov eax, [ebp + edi + LM_GNU_BUCKETS_OFFSET]
|
|
||||||
mov eax, [eax + edx * 4]
|
inc ebx
|
||||||
; *h |= 1
|
jmp short .next_chain
|
||||||
or word [ecx], 1
|
|
||||||
.check_bucket: ; edx = entry->l_gnu_chain_zero[eax] | 1
|
.chain_break:
|
||||||
mov edx, [ebp + edi + LM_GNU_CHAIN_ZERO_OFFSET]
|
mov eax, [ebp + L_INFO_DT_SYMTAB_OFF]
|
||||||
mov edx, [edx + eax * 4]
|
mov eax, [eax + D_UN_PTR_OFF]
|
||||||
or edx, 1
|
lea eax, [eax + ebx * 8]
|
||||||
; check if this is our symbol
|
mov eax, [eax + ebx * 8 + ST_VALUE_OFF]
|
||||||
cmp edx, [ecx]
|
%ifdef SKIP_ZERO_VALUE
|
||||||
je short .found
|
or eax, eax
|
||||||
inc eax
|
jz short .next_link
|
||||||
jmp short .check_bucket
|
%endif
|
||||||
.found: ; it is! edx = entry->l_info[DT_SYMTAB]->d_un.d_ptr
|
|
||||||
mov edx, [ebp + LM_INFO_OFFSET + DT_SYMTAB * 4]
|
add eax, [ebp + L_ADDR_OFF]
|
||||||
mov edx, [edx + DYN_PTR_OFFSET]
|
stosd
|
||||||
; edx = edx[eax].dt_value + entry->l_addr
|
%ifdef USE_JMP_BYTES
|
||||||
shl eax, DT_SYMSIZE_SHIFT
|
inc edi
|
||||||
mov edx, [edx + eax + DT_VALUE_OFFSET]
|
%endif
|
||||||
add edx, [ebp + LM_ADDR_OFFSET]
|
cmp word [edi], 0
|
||||||
sub edx, ecx
|
jne short .next_hash
|
||||||
sub edx, 4
|
|
||||||
; finally, write it back!
|
|
||||||
mov [ecx], edx
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
add esi, 4
|
|
||||||
jmp short link.do_symbols
|
|
||||||
inc esi
|
|
||||||
link.done:
|
|
||||||
; if USE_DNLOAD_LOADER ... else ...
|
; if USE_DNLOAD_LOADER ... else ...
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ repne scasd ; technically, scasq should be used, but meh. this is 1 byte smaller
|
||||||
push r14
|
push r14
|
||||||
pop rbx
|
pop rbx
|
||||||
; pop r12
|
; pop r12
|
||||||
; shift left because we don't want to compare the lowest bit
|
; shift right because we don't want to compare the lowest bit
|
||||||
shr ebx, 1
|
shr ebx, 1
|
||||||
|
|
||||||
.next_link:
|
.next_link:
|
||||||
|
@ -180,7 +180,7 @@ repne scasd ; technically, scasq should be used, but meh. this is 1 byte smaller
|
||||||
mov ecx, dword [r10 + LF_NBUCKETS_OFF - R10_BIAS]
|
mov ecx, dword [r10 + LF_NBUCKETS_OFF - R10_BIAS]
|
||||||
div ecx
|
div ecx
|
||||||
|
|
||||||
; uint32_t bucket(edx) = entry->l_gnu_buckets[bkt_ind]
|
; uint32_t bucket(ecx) = entry->l_gnu_buckets[bkt_ind]
|
||||||
mov r8 , [r10 + LF_GNU_BUCKETS_OFF - R10_BIAS]
|
mov r8 , [r10 + LF_GNU_BUCKETS_OFF - R10_BIAS]
|
||||||
mov ecx, dword [r8 + rdx * 4]
|
mov ecx, dword [r8 + rdx * 4]
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ repne scasd ; technically, scasq should be used, but meh. this is 1 byte smaller
|
||||||
; jecxz .next_link
|
; jecxz .next_link
|
||||||
|
|
||||||
.next_chain:
|
.next_chain:
|
||||||
; uint32_t luhash(ecx) = entry->l_gnu_chain_zero[bucket] >> 1
|
; uint32_t luhash(edx) = entry->l_gnu_chain_zero[bucket] >> 1
|
||||||
mov rdx, [r10 + LF_GNU_CHAIN_ZERO_OFF - R10_BIAS]
|
mov rdx, [r10 + LF_GNU_CHAIN_ZERO_OFF - R10_BIAS]
|
||||||
mov edx, dword [rdx + rcx * 4]
|
mov edx, dword [rdx + rcx * 4]
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
%define L_LD_OFF ( 8)
|
%define L_LD_OFF ( 8)
|
||||||
%define L_NEXT_OFF (0x0C)
|
%define L_NEXT_OFF (0x0C)
|
||||||
%define L_INFO_OFF (0x20)
|
%define L_INFO_OFF (0x20)
|
||||||
;%define L_INFO_DT_SYMTAB_OFF ()
|
%define L_INFO_DT_SYMTAB_OFF (0x38)
|
||||||
|
|
||||||
%define LF_ENTRY_OFF ( 340)
|
%define LF_ENTRY_OFF ( 340)
|
||||||
%define LF_NBUCKETS_OFF (0x178)
|
%define LF_NBUCKETS_OFF (0x178)
|
||||||
|
|
|
@ -32,7 +32,7 @@ def main():
|
||||||
|
|
||||||
parser.add_argument('-s', '--hash16', default=False, action='store_true', \
|
parser.add_argument('-s', '--hash16', default=False, action='store_true', \
|
||||||
help="Use 16-bit (BSD) hashes instead of 32-bit djb2 hashes. "\
|
help="Use 16-bit (BSD) hashes instead of 32-bit djb2 hashes. "\
|
||||||
+"Conflicts with -DUSE_DNLOAD_LOADER")
|
+"Must be used with -DUSE_DNLOAD_LOADER")
|
||||||
# parser.add_argument('-d', '--dnload', default=False, action='store_true', \
|
# parser.add_argument('-d', '--dnload', default=False, action='store_true', \
|
||||||
# help="Use dnload's mechanism of importing functions. Slightly larger, but usually better compressable.")
|
# help="Use dnload's mechanism of importing functions. Slightly larger, but usually better compressable.")
|
||||||
# parser.add_argument('--libsep', default=False, action='store_true', \
|
# parser.add_argument('--libsep', default=False, action='store_true', \
|
||||||
|
|
Loading…
Reference in New Issue