Commit 3eea42e2 authored by PoroCYon's avatar PoroCYon Committed by PoroCYon
Browse files

32-bit version working (not yet the dnload version)

parent 8c7ce9c9
......@@ -41,8 +41,8 @@ CXXFLAGS += -m$(BITS) $(shell pkg-config --cflags sdl2)
LIBS=-lc
SMOLFLAGS += -s
ASFLAGS += -DUSE_INTERP -DUSE_DNLOAD_LOADER -DNO_START_ARG -DUNSAFE_DYNAMIC #-DALIGN_STACK
SMOLFLAGS +=
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
NASM ?= nasm
......
......@@ -35,7 +35,7 @@
%define DT_DEBUG (21)
%define ST_NAME_OFF ( 0)
; ,---- not 16?
; ,---- not 16? ; what's this comment??!
; v
%if __BITS__ == 32
%define D_UN_PTR_OFF ( 4)
......
......@@ -2,6 +2,9 @@
%include "rtld.inc"
; TODO
%define R10_BIAS (0)
%ifdef ELF_TYPE
[section .text.startup.smol]
%else
......@@ -9,9 +12,14 @@
[section .text]
%endif
%ifndef USE_DNLOAD_LOADER
_smol_linkmap:
dd 0
_smol_linkoff:
dd 0
%endif
_smol_start:
;.loopme: jmp short .loopme
%ifdef USE_DL_FINI
push edx ; _dl_fini
%endif
......@@ -28,9 +36,14 @@ _smol_start:
; mov eax, [eax + LM_NEXT_OFFSET] ; skip the vdso
%endif
%ifdef USE_JMP_BYTES
push _symbols+1
%else
push _symbols
push eax
%endif
%ifdef USE_DNLOAD_LOADER
; TODO: borked!
pop ebp
pop edi
......@@ -152,6 +165,10 @@ _smol_start:
; if USE_DNLOAD_LOADER
%else
;.loopme: jmp short .loopme
mov [_smol_linkmap], eax
mov ebx, eax
mov edi, eax
push -1
......@@ -160,103 +177,79 @@ _smol_start:
repne scasd
sub edi, ebx
sub edi, LM_ENTRY_OFFSET_BASE+4
mov [_smol_linkoff], edi
pop edi ; _symbols
; edi: _symbols
; ebp: link_map* root
push ecx
.next_hash:
pop ecx
mov ecx, [edi]
mov ebp, [_smol_linkmap]
; ecx: hash (assumed nonzero)
; ebp: link_map* chain
push ecx
.next_link:
pop ecx
mov ebp, [ebp + L_NEXT_OFF]
mov esi, ebp
add esi, [_smol_linkoff]
; 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
; ebx: bucket
mov ebx, [esi + LF_GNU_BUCKETS_OFF]
mov ebx, [ebx + edx * 4]
.next_chain:
; edx: luhash
mov edx, [esi + LF_GNU_CHAIN_ZERO_OFF]
mov edx, [edx + ebx * 4]
; ecx: hash
mov al, dl
shr edx, 1
cmp edx, ecx
je short .chain_break
and al, 1
jnz short .next_link
inc ebx
jmp short .next_chain
.chain_break:
mov eax, [ebp + L_INFO_DT_SYMTAB_OFF]
mov eax, [eax + D_UN_PTR_OFF]
lea eax, [eax + ebx * 8]
mov eax, [eax + ebx * 8 + ST_VALUE_OFF]
%ifdef SKIP_ZERO_VALUE
or eax, eax
jz short .next_link
%endif
add eax, [ebp + L_ADDR_OFF]
stosd
%ifdef USE_JMP_BYTES
inc edi
%endif
cmp word [edi], 0
jne short .next_hash
xchg ebp, ebx
xchg ebx, edi;esi
mov esi, _symbols
link: ; (struct link_map *root, char *symtable)
.do_library: ; null library name means end of symbol table, we're done
cmp byte [esi], 0
jz .done
.find_map_entry: ; compare basename(entry->l_name) to lib name, if so we got a match
push esi
mov esi, [ebp + LM_NAME_OFFSET]
.basename: ; (const char *s (esi))
mov edi, esi
.basename.cmp:
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 esi
push edi
.strcmp.cmp:
lodsb
or al, al
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:
jz short .process_map_entry
; no match, next entry it is!
mov ebp, [ebp + LM_NEXT_OFFSET]
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!
lodsb
test al, al
jz short .do_library
push ebx
xchg ebx, edi
link_symbol: ; (struct link_map *entry, uint32_t *h)
mov ecx, esi
; eax = *h % entry->l_nbuckets
mov eax, [ecx]
xor edx, edx
mov ebx, [ebp + edi + LM_NBUCKETS_OFFSET]
div ebx
; eax = entry->l_gnu_buckets[edx]
mov eax, [ebp + edi + LM_GNU_BUCKETS_OFFSET]
mov eax, [eax + edx * 4]
; *h |= 1
or word [ecx], 1
.check_bucket: ; edx = entry->l_gnu_chain_zero[eax] | 1
mov edx, [ebp + edi + LM_GNU_CHAIN_ZERO_OFFSET]
mov edx, [edx + eax * 4]
or edx, 1
; check if this is our symbol
cmp edx, [ecx]
je short .found
inc eax
jmp short .check_bucket
.found: ; it is! edx = entry->l_info[DT_SYMTAB]->d_un.d_ptr
mov edx, [ebp + LM_INFO_OFFSET + DT_SYMTAB * 4]
mov edx, [edx + DYN_PTR_OFFSET]
; edx = edx[eax].dt_value + entry->l_addr
shl eax, DT_SYMSIZE_SHIFT
mov edx, [edx + eax + DT_VALUE_OFFSET]
add edx, [ebp + LM_ADDR_OFFSET]
sub edx, ecx
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 ...
%endif
......
......@@ -166,7 +166,7 @@ repne scasd ; technically, scasq should be used, but meh. this is 1 byte smaller
push r14
pop rbx
; 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
.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]
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 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
.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 edx, dword [rdx + rcx * 4]
......
......@@ -6,7 +6,7 @@
%define L_LD_OFF ( 8)
%define L_NEXT_OFF (0x0C)
%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_NBUCKETS_OFF (0x178)
......
......@@ -32,7 +32,7 @@ def main():
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")
+"Must be used 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', \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment