1 ; kate: syntax Intel x86 (NASM);
3 ; Copyright (C) 2009 Amand "alrj" Tihon <amand.tihon@alrj.org>
5 ; Import by hash for linux/amd64 (elf64-x86-64)
6 ; This file is part of bold, the Byte Optimized Linker.
8 ; You can redistribute this file and/or modify it under the terms of the
9 ; GNU General Public License as published by the Free Software Foundation,
10 ; either version 3 of the License or (at your option) any later version.
12 ; Under Section 7 of GPL version 3, you are granted additional
13 ; permissions described in the Bold Runtime Library Exception, version
14 ; 1.0, as published by Amand Tihon.
16 ;------------------------------------------------------------------------------
17 ; alrj's x86_64 version of the import by hash method by parapete, las, leblane.
18 ; See the wonderful thread at http://www.pouet.net/topic.php?which=5392 to
19 ; learn everything about import by hash on Linux.
22 ; nasm -f elf64 -o bold_ibh-x86_64.o bold_ibh-x86_64.asm
28 global _bold__ibh_start
31 extern _dt_debug ; defined by bold linker
32 extern _bold__functions_hash ; in .data, generated by bold
33 extern _bold__functions_pointers ; in .bss, generated by bold
34 extern _bold__functions_count ; immediate 32 bits
35 extern main ; must be declared when using this
44 mov r14, [rel _dt_debug] ; r14 points to r_debug
45 mov r14, [r14 + 8] ; r14 points to link_map
46 mov r14, [r14 + 24] ; skip the first two link_map entries
49 mov esi, _bold__functions_hash ; Implicitly zero-extended
50 mov edi, _bold__functions_pointers ; ditto
51 push byte _bold__functions_count ; Warning: Max 127 external symbols.
52 pop rcx ; Linker should enforce this.
54 ; Load all the symbols
56 lodsd ; Load symbol hash
57 xchg ebx, eax ; into ebx
63 ; Iterate over libraries found in link_map
65 mov rdx, [r14 + 16] ; link_map->l_ld
67 ; Find the interesting entries in the DYNAMIC table.
72 cmp [rdx], dword 4 ; DT_HASH == 4
73 jne .no_hash ; Why the heck does it segfault when
74 mov ecx, [rsi+4] ; I use cmove ecx, [rsi+4] instead
75 .no_hash: ; of this jne construction ????
77 cmp [rdx], dword 5 ; DT_STRTAB == 5
78 cmove r10, rsi ; r10 : pointer to strtab
80 cmp [rdx], dword 6 ; DT_SYMTAB == 6
81 cmove r11, rsi ; r11 : pointer to symtab
83 cmp [rdx], dword 0x6ffffef5 ; DT_GNU_HASH
85 mov ecx, [rsi] ; ecx is nbuckets
86 mov r9d, [rsi + 8] ; maskwords (64 bits entries)
87 lea r9, [rsi + 16 + r9 * 8] ; rdx points to the first bucket
90 .walk_buckets: ; Find the last chain
93 add r9, 4 ; next bucket
94 loop .walk_buckets ; eax is offset to the last chain
95 ; Now, rdx points to the beginning of the first chain
97 mov ecx, [rsi+4] ; symndx
99 shl rax, 2 ; symndx * 4
100 sub r9, rax ; hash values - symndx * 4
102 bt dword [r9 + rcx*4], 0 ;
103 inc ecx ; Increment ecx for each entry found
104 jc .walk_chain ; in the chain.
111 jnz short .dynamic_loop
113 ; All DYNAMIC entries have been read.
115 ; Iterate over the symbols in the library (symtab entries).
117 ; Find the symbol name in strtab
118 mov esi, [r11] ; st_name, offset in strtab
119 add rsi, r10 ; pointer to symbol name
124 .hash_loop: ; over each char
125 imul edx, edx, byte 0x21
132 cmp edx, ebx ; Compare with stored hash
134 lea r11, [r11 + 24] ; Next symtab entry
137 ; Symbol was not found in this library
138 mov r14, [r14 + 24] ; Next link_map entry
141 mov rax, [r11 + 8] ; st_value, offset of the symbol
142 add rax, [r14] ; add link_map->l_addr
143 stosq ; Store function pointer
153 ; When all is resolved, call main()
163 %assign code_size $ - _bold__ibh_start
164 %warning Code size is: code_size