From 17a597978e7c7aa4311fe1b8fb186a6232ccfe4d Mon Sep 17 00:00:00 2001 From: Amand Tihon Date: Sat, 30 Jul 2011 20:38:45 +0200 Subject: [PATCH] First support for .gnu.hash/DT_GNU_HASH. * Not optimized yet. * Strange bug when using cmove that I'll have to investigate. * Thanks go to kernel_error and flure for the motivation :) --- runtime/bold_ibh-x86_64.asm | 68 ++++++++++++++++++++++++------------ runtime/bold_ibh-x86_64.o | Bin 1504 -> 1776 bytes 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/runtime/bold_ibh-x86_64.asm b/runtime/bold_ibh-x86_64.asm index a9a3732..f309ce7 100644 --- a/runtime/bold_ibh-x86_64.asm +++ b/runtime/bold_ibh-x86_64.asm @@ -65,33 +65,55 @@ _bold__ibh_start: mov rdx, [r14 + 16] ; link_map->l_ld ; Find the interesting entries in the DYNAMIC table. - .dynamic_loop: - - push byte DT_HASH ; DT_HASH == 4 - pop rax - cmp [rdx], eax - cmove r9, [rdx+8] ; r9 : pointer to the hash table - - inc eax ; DT_STRTAB == 5 - cmp [rdx], eax - cmove r10, [rdx+8] ; r10 : pointer to strtab - inc eax ; DT_SYMTAB == 6 - cmp [rdx], eax - 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 - lea rdx, [rdx + 16] ; add rdx, 16 - xor eax, eax - cmp [rdx], eax - ;cmp [rdx], dword 0 ; Gut feeling: would harm compression + add rdx, 16 + 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 @@ -110,11 +132,11 @@ _bold__ibh_start: cmp edx, ebx ; Compare with stored hash je short .found lea r11, [r11 + 24] ; Next symtab entry - loop .symbolloop + loop .symtabloop ; Symbol was not found in this library mov r14, [r14 + 24] ; Next link_map entry - jmp short .libloop + jmp .libloop .found: mov rax, [r11 + 8] ; st_value, offset of the symbol add rax, [r14] ; add link_map->l_addr @@ -123,7 +145,9 @@ _bold__ibh_start: pop rcx pop rsi - loop .symbol_loop + ;loop .symbol_loop + dec ecx + jnz .symbol_loop ; }}} ; When all is resolved, call main() diff --git a/runtime/bold_ibh-x86_64.o b/runtime/bold_ibh-x86_64.o index b72a08bb7c6cbca470093a90230f6a1a6a230ec0..786f97b7a3c79659f48e8ad4550379aeee04d924 100644 GIT binary patch delta 607 zcmaFB{egGF0>+aQ7n(Cpn0V7(^Z*kB82n&_&@4cTZ?Z0)H2cI-~%R4&4Z5oyHq+E{vRy*_Wz_u^C5v|D~8e~j@`ySjMoe= z86L>Kq-c0(P0NAOZ-|H3(Xk=Cf>9cZD3*mgBgqvngvL4P1a@9=2QSNfxvchBBMD|0_)^i zjDBfZED@GWKKw3T9RCl189^{c6o*G|kbogjwDgu^wyS6 xV2j{mV1{Z1`J8KVEt|L`H&g^fNkZ9NK$>UrS~hWBUZ@C&YMETfCe8s9004UDMZf?6 -- 2.39.5