X-Git-Url: https://git.alrj.org/?p=bold.git;a=blobdiff_plain;f=runtime%2Fbold_ibh-x86_64.asm;h=f309ce7666b85e66972409485f4d4aa6d054362e;hp=69d4610d693046ffeed0a3cfffa75f29facd6d02;hb=HEAD;hpb=11e867f1fbccaa1d55e0406ba6c970492f22e56a diff --git a/runtime/bold_ibh-x86_64.asm b/runtime/bold_ibh-x86_64.asm index 69d4610..f309ce7 100644 --- a/runtime/bold_ibh-x86_64.asm +++ b/runtime/bold_ibh-x86_64.asm @@ -19,8 +19,7 @@ ; learn everything about import by hash on Linux. ; Compile with -; yasm -f elf64 -o bold_ibh-x86_64.o bold_ibh-x86_64.asm -; (or replace yasm by nasm) +; nasm -f elf64 -o bold_ibh-x86_64.o bold_ibh-x86_64.asm BITS 64 @@ -42,56 +41,79 @@ segment .text _bold__ibh_start: ; {{{ Do the RTLD - mov rbx, [_dt_debug] ; rbx points to r_debug - mov rbx, [rbx + 8] ; rbx points to link_map - mov rbx, [rbx + 24] ; skip the first two link_map entries - mov rbx, [rbx + 24] + mov r14, [rel _dt_debug] ; r14 points to r_debug + mov r14, [r14 + 8] ; r14 points to link_map + mov r14, [r14 + 24] ; skip the first two link_map entries + mov r14, [r14 + 24] mov esi, _bold__functions_hash ; Implicitly zero-extended mov edi, _bold__functions_pointers ; ditto - mov ecx, _bold__functions_count + push byte _bold__functions_count ; Warning: Max 127 external symbols. + pop rcx ; Linker should enforce this. ; Load all the symbols .symbol_loop: - lodsd ; Load symbol hash in eax + lodsd ; Load symbol hash + xchg ebx, eax ; into ebx push rsi push rcx ; {{{ For each hash - mov r15d, eax ; Save function hash - mov r13, rbx ; copy link_map's pseudo-head ; Iterate over libraries found in link_map .libloop: - mov rdx, [r13 + 16] ; link_map->l_ld + mov rdx, [r14 + 16] ; link_map->l_ld ; Find the interesting entries in the DYNAMIC table. - .dynamic_loop: - xor eax, eax ; enough because hash was 32 bits - - mov al, DT_HASH ; DT_HASH == 4 - cmp [rdx], rax - cmove r9, [rdx+8] ; r9 : pointer to the hash table - - inc al ; DT_STRTAB == 5 - cmp [rdx], rax - cmove r10, [rdx+8] ; r10 : pointer to strtab - inc al ; DT_SYMTAB == 6 - cmp [rdx], rax - cmove r11, [rdx+8] ; r11 : pointer to symtab + .dynamic_loop: + mov rsi, [rdx+8] + + cmp [rdx], dword 4 ; DT_HASH == 4 + jne .no_hash ; Why the heck does it segfault when + mov ecx, [rsi+4] ; I use cmove ecx, [rsi+4] instead + .no_hash: ; of this jne construction ???? + + cmp [rdx], dword 5 ; DT_STRTAB == 5 + cmove r10, rsi ; r10 : pointer to strtab + + cmp [rdx], dword 6 ; DT_SYMTAB == 6 + cmove r11, rsi ; r11 : pointer to symtab + + cmp [rdx], dword 0x6ffffef5 ; DT_GNU_HASH + jne .not_gnu_hash + mov ecx, [rsi] ; ecx is nbuckets + mov r9d, [rsi + 8] ; maskwords (64 bits entries) + lea r9, [rsi + 16 + r9 * 8] ; rdx points to the first bucket + + xor eax, eax + .walk_buckets: ; Find the last chain + cmp eax, [r9] + cmovl eax, [r9] + add r9, 4 ; next bucket + loop .walk_buckets ; eax is offset to the last chain + ; Now, rdx points to the beginning of the first chain + + mov ecx, [rsi+4] ; symndx + xchg eax, ecx + shl rax, 2 ; symndx * 4 + sub r9, rax ; hash values - symndx * 4 + .walk_chain: + bt dword [r9 + rcx*4], 0 ; + inc ecx ; Increment ecx for each entry found + jc .walk_chain ; in the chain. + dec ecx ; fixup. + .not_gnu_hash: ; Next dynamic entry add rdx, 16 - xor al, al - cmp [rdx], rax - jnz .dynamic_loop + cmp [rdx], dword 0 + jnz short .dynamic_loop ; All DYNAMIC entries have been read. - mov ecx, [r9 + 4] ; nchain, number of exported symbols ; Iterate over the symbols in the library (symtab entries). - .symbolloop: + .symtabloop: ; Find the symbol name in strtab mov esi, [r11] ; st_name, offset in strtab add rsi, r10 ; pointer to symbol name @@ -107,30 +129,36 @@ _bold__ibh_start: jnz short .hash_loop .hash_end: - cmp edx, r15d ; Compare with stored hash - je .found - add r11, 24 ; Next symtab entry - loop .symbolloop + cmp edx, ebx ; Compare with stored hash + je short .found + lea r11, [r11 + 24] ; Next symtab entry + loop .symtabloop ; Symbol was not found in this library - mov r13, [r13 + 24] ; Next link_map entry - jmp short .libloop + mov r14, [r14 + 24] ; Next link_map entry + jmp .libloop .found: mov rax, [r11 + 8] ; st_value, offset of the symbol - add rax, [r13] ; add link_map->l_addr + add rax, [r14] ; add link_map->l_addr + stosq ; Store function pointer ; }}} pop rcx pop rsi - stosq ; Store function pointer - loop .symbol_loop + ;loop .symbol_loop + dec ecx + jnz .symbol_loop ; }}} ; When all is resolved, call main() call main - mov edi, eax exit: ; Exit cleanly - mov eax, SYS_exit + xchg edi, eax + push byte SYS_exit + pop rax syscall + +%assign code_size $ - _bold__ibh_start +%warning Code size is: code_size