]> git.alrj.org Git - bold.git/blob - data/bold_ibh-x86_64.asm
555555192544030d376e200bd14e5424549b9fec
[bold.git] / data / bold_ibh-x86_64.asm
1 ; Bold - Import by hash for linux/amd64 (elf64-x86-64)
2 ; © 2009 Amand "alrj" Tihon
3 ; kate: syntax Intel x86 (NASM);
4
5 ; alrj's x86_64 version of the import by hash method by parapete, las, leblane.
6 ; See the wonderful thread at http://www.pouet.net/topic.php?which=5392 to
7 ; learn everything about import by hash on Linux.
8
9 ; Compile with
10 ; yasm -f elf64 -o bold_ibh-x86_64.o bold_ibh-x86_64.asm
11 ; (or replace yasm by nasm)
12
13
14 BITS 64
15 CPU X64
16
17 global _bold__ibh
18 global exit
19
20 extern _dt_debug                        ; defined by bold linker
21 extern _bold__functions_hash            ; in .data, generated by bold
22 extern _bold__functions_pointers        ; in .bss, generated by bold
23 extern _bold__functions_count           ; immediate 32 bits
24 extern main                             ; must be declared when using this
25
26
27 %define SYS_exit      60
28 %define DT_HASH       4
29
30 segment .text
31
32 _bold__ibh:
33 ; {{{ Do the RTLD
34   mov rbx, [_dt_debug]                  ; rbx points to r_debug
35   mov rbx, [rbx + 8]                    ; rbx points to link_map
36   mov rbx, [rbx + 24]                   ; skip the first two link_map entries
37   mov rbx, [rbx + 24]
38
39   mov esi, [rel _bold__functions_hash]        ; Implicitly zero-extended
40   mov edi, [rel _bold__functions_pointers]    ; ditto
41   mov ecx, _bold__functions_count
42
43   ; Load all the symbols
44   .symbol_loop:
45     lodsd                               ; Load symbol hash in eax
46     push rsi
47     push rcx
48
49 ;   {{{ For each hash
50     mov r15d, eax                         ; Save function hash
51     mov r13, rbx                          ; copy link_map's pseudo-head
52
53     ; Iterate over libraries found in link_map
54     .libloop:
55       mov rdx, [r13 + 16]                 ; link_map->l_ld
56
57       ; Find the interesting entries in the DYNAMIC table.
58       .dynamic_loop:
59         xor eax, eax                      ; enough because hash was 32 bits
60
61         mov al, DT_HASH                   ; DT_HASH == 4
62         cmp [rdx], rax
63         cmove r9, [rdx+8]
64
65         inc al                            ; DT_STRTAB == 5
66         cmp [rdx], rax
67         cmove r10, [rdx+8]
68
69         inc al                            ; DT_SYMTAB == 6
70         cmp [rdx], rax
71         cmove r11, [rdx+8]
72
73         ; Next dynamic entry
74         add rdx, 16
75         xor al, al
76         cmp [rdx], rax
77         jnz .dynamic_loop
78
79       ; All DYNAMIC entries have been read.
80       mov ecx, [r9 + 4]                   ; nchain, number of exported symbols
81
82       ; Iterate over the symbols in the library (symtab entries).
83       .symbolloop:
84         ; Find the symbol name in strtab
85         mov esi, [r11]                    ; st_name, offset in strtab
86         add rsi, r10                      ; pointer to symbol name
87
88         ; Compute the hash
89         xor edx, edx
90         .hash_loop:                       ; over each char
91           xor eax, eax
92           lodsb
93           test al, al
94           jz .hash_end
95
96           sub eax, edx
97           shl edx, 6
98           add eax, edx
99           shl edx, 10
100           add edx, eax
101           jmp short .hash_loop
102
103         .hash_end:
104         cmp edx, r15d                     ; Compare with stored hash
105         je .found
106         add r11, 24                       ; Next symtab entry
107       loop .symbolloop
108
109       ; Symbol was not found in this library
110       mov r13, [r13 + 24]                 ; Next link_map entry
111       jmp short .libloop
112     .found:
113     mov rax, [r11 + 8]                    ; st_value, offset of the symbol
114     add rax, [r13]                        ; add link_map->l_addr
115 ;   }}}
116
117     pop rcx
118     pop rsi
119     stosq                               ; Store function pointer
120     loop .symbol_loop
121 ; }}}
122
123   ; When all is resolved, call main()
124   call main
125   mov edi, eax
126
127 exit:
128   ; Exit cleanly
129   mov eax, SYS_exit
130   syscall