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