2019-03-28 15:37:05 +00:00
|
|
|
; vim: set ft=nasm et:
|
2019-01-28 03:18:22 +00:00
|
|
|
|
|
|
|
%include "rtld.inc"
|
|
|
|
|
2020-08-24 03:21:00 +00:00
|
|
|
%ifndef HASH_END_TYP
|
|
|
|
%warning "W: HASH_END_TYP not defined, falling back to 16-bit!"
|
|
|
|
%define HASH_END_TYP word
|
|
|
|
%endif
|
|
|
|
|
2019-04-29 23:39:48 +00:00
|
|
|
%define R10_BIAS (0x178)
|
2019-04-29 23:05:41 +00:00
|
|
|
|
2019-02-02 17:14:28 +00:00
|
|
|
%ifdef ELF_TYPE
|
2019-01-28 03:18:22 +00:00
|
|
|
[section .text.startup.smol]
|
2019-02-02 17:14:28 +00:00
|
|
|
%else
|
|
|
|
; not defined -> debugging!
|
|
|
|
[section .text]
|
|
|
|
%endif
|
2019-01-28 03:18:22 +00:00
|
|
|
|
2019-04-29 23:05:41 +00:00
|
|
|
%ifndef USE_DNLOAD_LOADER
|
2020-03-09 15:23:10 +00:00
|
|
|
global _smol_priv_data
|
|
|
|
_smol_priv_data:
|
2019-04-29 23:05:41 +00:00
|
|
|
_smol_linkmap:
|
|
|
|
dd 0
|
|
|
|
_smol_linkoff:
|
|
|
|
dd 0
|
|
|
|
%endif
|
2019-01-28 03:18:22 +00:00
|
|
|
|
2020-03-09 15:23:10 +00:00
|
|
|
global _smol_start
|
2019-01-28 03:18:22 +00:00
|
|
|
_smol_start:
|
2019-08-12 22:56:29 +00:00
|
|
|
mov eax, [esp - 32] ; ???
|
|
|
|
|
2019-02-02 17:14:28 +00:00
|
|
|
%ifdef USE_DL_FINI
|
2019-03-28 15:37:05 +00:00
|
|
|
push edx ; _dl_fini
|
2019-02-02 17:14:28 +00:00
|
|
|
%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
; try to get the 'version-agnostic' pffset of the stuff we're
|
|
|
|
; interested in
|
2019-02-06 20:48:27 +00:00
|
|
|
|
|
|
|
%ifdef USE_DT_DEBUG
|
2019-03-28 15:37:05 +00:00
|
|
|
mov eax, [rel _DEBUG]
|
|
|
|
mov eax, [eax + 4]
|
2019-02-06 20:48:27 +00:00
|
|
|
%endif
|
|
|
|
|
|
|
|
%ifdef SKIP_ENTRIES
|
2019-03-28 15:37:05 +00:00
|
|
|
mov eax, [eax + LM_NEXT_OFFSET] ; skip this binary
|
|
|
|
; mov eax, [eax + LM_NEXT_OFFSET] ; skip the vdso
|
2019-02-06 20:48:27 +00:00
|
|
|
%endif
|
|
|
|
|
2019-04-29 23:05:41 +00:00
|
|
|
%ifdef USE_JMP_BYTES
|
|
|
|
push _symbols+1
|
|
|
|
%else
|
2019-03-28 15:37:05 +00:00
|
|
|
push _symbols
|
2019-04-29 23:05:41 +00:00
|
|
|
%endif
|
|
|
|
|
2020-08-24 02:36:53 +00:00
|
|
|
;.loopme: jmp short .loopme
|
2019-03-28 15:37:05 +00:00
|
|
|
%ifdef USE_DNLOAD_LOADER
|
2019-04-29 23:39:48 +00:00
|
|
|
push eax
|
2019-03-28 15:37:05 +00:00
|
|
|
pop ebp
|
|
|
|
pop edi
|
|
|
|
|
|
|
|
.next_hash:
|
|
|
|
mov ecx, [edi]
|
|
|
|
; assume it's nonzero
|
|
|
|
push ebp
|
|
|
|
pop edx
|
|
|
|
; edx: hash
|
|
|
|
; ebx: link_map* chain
|
|
|
|
|
|
|
|
.next_link:
|
|
|
|
; pop edx
|
|
|
|
mov edx, [edx + L_NEXT_OFF]
|
|
|
|
; ElfW(Dyn)* dyn(esi) = ebx->l_ld
|
|
|
|
mov esi, [edx + L_LD_OFF]
|
|
|
|
|
|
|
|
push edx
|
|
|
|
; get strtab off
|
|
|
|
.next_dyn:
|
|
|
|
lodsd
|
|
|
|
cmp al, DT_STRTAB
|
|
|
|
lodsd
|
|
|
|
jne short .next_dyn
|
|
|
|
|
|
|
|
; void* addr(edx) = ebx->l_addr
|
|
|
|
; const char* strtab(ebx)=lookup(esi,DT_STRTAB);
|
|
|
|
mov edx, [edx + L_ADDR_OFF]
|
|
|
|
cmp eax, edx
|
|
|
|
jae short .noreldynaddr
|
|
|
|
add eax, edx
|
|
|
|
.noreldynaddr:
|
|
|
|
push eax
|
|
|
|
pop ebx
|
|
|
|
|
|
|
|
; const ElfW(Sym)* symtab(edx) = lookup(esi, DT_SYMTAB);
|
|
|
|
lodsd ; SYMTAB d_tag
|
|
|
|
lodsd ; SYMTAB d_un
|
|
|
|
cmp eax, edx
|
|
|
|
jae short .norelsymaddr
|
|
|
|
add eax, edx
|
|
|
|
.norelsymaddr:
|
|
|
|
push eax
|
|
|
|
pop edx
|
|
|
|
|
|
|
|
.next_sym:
|
|
|
|
mov esi, [edx + ST_NAME_OFF]
|
|
|
|
add esi, ebx
|
|
|
|
|
|
|
|
push ecx
|
2020-08-07 22:07:52 +00:00
|
|
|
|
|
|
|
; source in eax, result in eax
|
|
|
|
%ifdef USE_CRC32C_HASH
|
|
|
|
push -1
|
|
|
|
pop eax
|
|
|
|
%else
|
|
|
|
%ifndef USE_HASH16
|
2019-03-28 15:37:05 +00:00
|
|
|
push ebx
|
|
|
|
push 33
|
|
|
|
push 5381
|
|
|
|
pop eax
|
|
|
|
pop ebx
|
2020-08-07 22:07:52 +00:00
|
|
|
%else
|
2019-03-30 03:24:46 +00:00
|
|
|
xor eax, eax
|
2020-08-07 22:07:52 +00:00
|
|
|
%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
xor ecx, ecx
|
2020-08-07 22:07:52 +00:00
|
|
|
%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
.nexthashiter:
|
2019-03-30 03:24:46 +00:00
|
|
|
xchg eax, ecx
|
|
|
|
lodsb
|
|
|
|
or al, al
|
|
|
|
xchg eax, ecx
|
|
|
|
jz short .breakhash
|
|
|
|
|
2020-08-07 22:07:52 +00:00
|
|
|
%ifdef USE_CRC32C_HASH
|
|
|
|
crc32 eax, cl
|
|
|
|
%else
|
|
|
|
%ifndef USE_HASH16
|
2019-03-30 03:24:46 +00:00
|
|
|
push edx
|
|
|
|
mul ebx
|
|
|
|
pop edx
|
|
|
|
; add eax, ecx
|
2020-08-07 22:07:52 +00:00
|
|
|
%else
|
2019-03-30 03:24:46 +00:00
|
|
|
ror ax, 2
|
|
|
|
; add ax, cx
|
2020-08-07 22:07:52 +00:00
|
|
|
%endif
|
2019-03-30 03:24:46 +00:00
|
|
|
add eax, ecx
|
2020-08-07 22:07:52 +00:00
|
|
|
%endif
|
2019-03-30 03:24:46 +00:00
|
|
|
jmp short .nexthashiter
|
2019-03-28 15:37:05 +00:00
|
|
|
|
|
|
|
.breakhash:
|
2019-03-30 03:24:46 +00:00
|
|
|
%ifndef USE_HASH16
|
2019-03-28 15:37:05 +00:00
|
|
|
pop ebx
|
2019-03-30 03:24:46 +00:00
|
|
|
%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
pop ecx
|
2019-03-30 03:24:46 +00:00
|
|
|
;%ifndef USE_HASH16
|
|
|
|
; cmp ecx, eax
|
|
|
|
;%else
|
|
|
|
; cmp cx, ax
|
|
|
|
;%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
cmp ecx, eax
|
|
|
|
je short .hasheq
|
|
|
|
|
|
|
|
add edx, SYMTAB_SIZE
|
|
|
|
cmp edx, ebx
|
|
|
|
jb short .next_sym
|
|
|
|
pop edx
|
|
|
|
jmp short .next_link
|
|
|
|
|
|
|
|
.hasheq:
|
|
|
|
mov eax, [edx + ST_VALUE_OFF]
|
2020-08-24 02:36:53 +00:00
|
|
|
mov cl , [edx + ST_INFO_OFF ]
|
2019-03-28 15:37:05 +00:00
|
|
|
pop edx
|
2019-04-02 14:58:36 +00:00
|
|
|
%ifdef SKIP_ZERO_VALUE
|
|
|
|
or eax, eax
|
|
|
|
jz short .next_link
|
|
|
|
%endif
|
2020-08-24 02:36:53 +00:00
|
|
|
;mov esi, [edx + L_ADDR_OFF]
|
2019-03-28 15:37:05 +00:00
|
|
|
;cmp eax, esi
|
|
|
|
; jb short .hasheqnorel
|
2020-08-24 02:36:53 +00:00
|
|
|
;add eax, esi
|
|
|
|
add eax, [edx + L_ADDR_OFF] ; TODO: CONDITIONAL!
|
2019-03-28 15:37:05 +00:00
|
|
|
.hasheqnorel:
|
2020-08-24 02:36:53 +00:00
|
|
|
%ifdef IFUNC_SUPPORT
|
|
|
|
xchg ecx, eax
|
|
|
|
and al, ST_INFO__STT_MASK
|
|
|
|
cmp al, STT_GNU_IFUNC
|
|
|
|
jne short .no_ifunc
|
|
|
|
;int3
|
2020-08-07 22:07:52 +00:00
|
|
|
%ifdef IFUNC_CORRECT_CCONV
|
2020-08-24 02:57:09 +00:00
|
|
|
; call destroys stuff, but we only need to preserve edi
|
|
|
|
; for our purposes anyway. we do need one push to align the
|
|
|
|
; stack to 16 bytes
|
|
|
|
push edi
|
2020-08-24 02:36:53 +00:00
|
|
|
call ecx
|
2020-08-24 02:57:09 +00:00
|
|
|
pop edi
|
2020-08-07 22:07:52 +00:00
|
|
|
%else
|
2020-08-24 02:57:09 +00:00
|
|
|
call ecx
|
2020-08-07 22:07:52 +00:00
|
|
|
%endif
|
2020-08-24 02:36:53 +00:00
|
|
|
db 0x3c ; cmp al, <next byte == xchg ecx,eax> --> jump over next insn
|
|
|
|
.no_ifunc:
|
|
|
|
xchg ecx, eax
|
|
|
|
%endif
|
2019-03-28 15:37:05 +00:00
|
|
|
stosd
|
|
|
|
%ifdef USE_JMP_BYTES
|
|
|
|
inc edi ; skip 0xE9 (jmp) offset
|
|
|
|
%endif
|
2020-08-24 03:21:00 +00:00
|
|
|
cmp HASH_END_TYP [edi], 0
|
2019-03-28 15:37:05 +00:00
|
|
|
jne short .next_hash
|
|
|
|
|
|
|
|
; if USE_DNLOAD_LOADER
|
|
|
|
%else
|
2019-04-29 23:05:41 +00:00
|
|
|
mov [_smol_linkmap], eax
|
|
|
|
|
2019-01-28 03:18:22 +00:00
|
|
|
mov ebx, eax
|
2019-02-27 13:34:29 +00:00
|
|
|
mov edi, eax
|
|
|
|
push -1
|
|
|
|
pop ecx
|
|
|
|
mov eax, _smol_start
|
|
|
|
repne scasd
|
|
|
|
sub edi, ebx
|
2019-04-29 23:39:48 +00:00
|
|
|
;sub edi, LM_ENTRY_OFFSET_BASE+4-R10_BIAS
|
|
|
|
add edi, R10_BIAS-LM_ENTRY_OFFSET_BASE-4
|
2019-04-29 23:05:41 +00:00
|
|
|
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
|
2019-04-29 23:39:48 +00:00
|
|
|
mov ecx, [esi + LF_NBUCKETS_OFF - R10_BIAS]
|
2019-04-29 23:05:41 +00:00
|
|
|
xor edx, edx
|
|
|
|
div ecx
|
|
|
|
pop ecx
|
|
|
|
shr ecx, 1
|
|
|
|
|
|
|
|
; ebx: bucket
|
2019-04-29 23:39:48 +00:00
|
|
|
mov ebx, [esi + LF_GNU_BUCKETS_OFF - R10_BIAS]
|
2019-04-29 23:05:41 +00:00
|
|
|
mov ebx, [ebx + edx * 4]
|
|
|
|
|
|
|
|
.next_chain:
|
|
|
|
; edx: luhash
|
2019-04-29 23:39:48 +00:00
|
|
|
mov edx, [esi + LF_GNU_CHAIN_ZERO_OFF - R10_BIAS]
|
2019-04-29 23:05:41 +00:00
|
|
|
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]
|
2020-08-24 02:36:53 +00:00
|
|
|
%ifdef IFUNC_SUPPORT
|
|
|
|
mov cl , [eax + ebx * 8 + ST_INFO_OFF ]
|
|
|
|
%endif
|
2019-04-29 23:05:41 +00:00
|
|
|
mov eax, [eax + ebx * 8 + ST_VALUE_OFF]
|
|
|
|
%ifdef SKIP_ZERO_VALUE
|
|
|
|
or eax, eax
|
|
|
|
jz short .next_link
|
|
|
|
%endif
|
|
|
|
|
2020-08-24 02:36:53 +00:00
|
|
|
;mov esi, [edx + L_ADDR_OFF]
|
|
|
|
;cmp eax, esi
|
|
|
|
; jb short .hasheqnorel
|
|
|
|
;add eax, esi
|
2019-04-29 23:05:41 +00:00
|
|
|
add eax, [ebp + L_ADDR_OFF]
|
2020-08-24 02:36:53 +00:00
|
|
|
.hasheqnorel:
|
|
|
|
%ifdef IFUNC_SUPPORT
|
|
|
|
xchg ecx, eax
|
|
|
|
and al, ST_INFO__STT_MASK
|
|
|
|
cmp al, STT_GNU_IFUNC
|
|
|
|
jne short .no_ifunc
|
|
|
|
;int3
|
2020-08-07 22:07:52 +00:00
|
|
|
%ifdef IFUNC_CORRECT_CCONV
|
2020-08-24 02:57:09 +00:00
|
|
|
; call destroys stuff, but we only need to preserve edi
|
|
|
|
; for our purposes anyway. we do need one push to align the
|
|
|
|
; stack to 16 bytes
|
|
|
|
push edi
|
2020-08-24 02:36:53 +00:00
|
|
|
call ecx
|
2020-08-24 02:57:09 +00:00
|
|
|
pop edi
|
2020-08-07 22:07:52 +00:00
|
|
|
%else
|
2020-08-24 02:57:09 +00:00
|
|
|
call ecx
|
|
|
|
%endif
|
2020-08-24 02:36:53 +00:00
|
|
|
db 0x3c ; cmp al, <next byte == xchg ecx,eax> --> jump over next insn
|
|
|
|
.no_ifunc:
|
|
|
|
xchg ecx, eax
|
|
|
|
%endif
|
2019-04-29 23:05:41 +00:00
|
|
|
stosd
|
|
|
|
%ifdef USE_JMP_BYTES
|
|
|
|
inc edi
|
|
|
|
%endif
|
2020-08-24 03:21:00 +00:00
|
|
|
cmp HASH_END_TYP [edi], 0
|
2019-04-29 23:05:41 +00:00
|
|
|
jne short .next_hash
|
2019-01-28 03:18:22 +00:00
|
|
|
|
2019-04-29 23:39:48 +00:00
|
|
|
pop eax ; get rid of leftover ecx on stack
|
|
|
|
|
2019-03-28 15:37:05 +00:00
|
|
|
; if USE_DNLOAD_LOADER ... else ...
|
|
|
|
%endif
|
2019-01-28 03:18:22 +00:00
|
|
|
|
|
|
|
;xor ebp, ebp ; let's put that burden on the user code, so they can leave
|
|
|
|
; it out if they want to
|
|
|
|
|
2019-02-02 17:14:28 +00:00
|
|
|
%ifdef USE_DL_FINI
|
2019-01-30 23:14:36 +00:00
|
|
|
pop edx ; _dl_fini
|
2019-02-02 17:14:28 +00:00
|
|
|
%endif
|
2019-03-30 03:24:46 +00:00
|
|
|
; move esp into eax, *then* increase the stack by 4, as main()
|
2019-03-28 15:37:05 +00:00
|
|
|
; 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)
|
|
|
|
push esp
|
|
|
|
pop eax
|
|
|
|
push eax
|
|
|
|
push eax
|
2019-01-28 03:18:22 +00:00
|
|
|
|
|
|
|
;jmp short _start
|
|
|
|
; by abusing the linker script, _start ends up right here :)
|
2020-03-09 15:23:10 +00:00
|
|
|
%ifdef ELF_TYPE
|
|
|
|
global _smol_rt_end:
|
|
|
|
_smol_rt_end:
|
|
|
|
%endif
|
2019-01-28 03:18:22 +00:00
|
|
|
|