-
Notifications
You must be signed in to change notification settings - Fork 31
/
table.S.tpl
100 lines (84 loc) · 2.41 KB
/
table.S.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
* Copyright 2018-2020 Yury Gribov
*
* The MIT License (MIT)
*
* Use of this source code is governed by MIT license that can be
* found in the LICENSE.txt file.
*/
.data
.globl _${lib_suffix}_tramp_table
.hidden _${lib_suffix}_tramp_table
.align 8
_${lib_suffix}_tramp_table:
.zero $table_size
.text
.globl _${lib_suffix}_tramp_resolve
.hidden _${lib_suffix}_tramp_resolve
.globl _${lib_suffix}_save_regs_and_resolve
.hidden _${lib_suffix}_save_regs_and_resolve
.type _${lib_suffix}_save_regs_and_resolve, %function
_${lib_suffix}_save_regs_and_resolve:
.cfi_startproc
#define PUSH_REG(reg) pushq %reg ; .cfi_adjust_cfa_offset 8; .cfi_rel_offset reg, 0
#define POP_REG(reg) popq %reg ; .cfi_adjust_cfa_offset -8; .cfi_restore reg
#define DEC_STACK(d) subq $$d, %rsp; .cfi_adjust_cfa_offset d
#define INC_STACK(d) addq $$d, %rsp; .cfi_adjust_cfa_offset -d
#define PUSH_XMM_REG(reg) DEC_STACK(16); movdqa %reg, (%rsp); .cfi_rel_offset reg, 0
#define POP_XMM_REG(reg) movdqa (%rsp), %reg; .cfi_restore reg; INC_STACK(16)
// Slow path which calls dlsym, taken only on first call.
// All registers are stored to handle arbitrary calling conventions
// (except x87 FPU registers which do not have to be preserved).
// For Dwarf directives, read https://www.imperialviolet.org/2017/01/18/cfi.html.
// FIXME: AVX (YMM, ZMM) registers are NOT saved to simplify code.
PUSH_REG(rdi) // 16
mov 0x10(%rsp), %rdi
PUSH_REG(rax)
PUSH_REG(rbx) // 16
PUSH_REG(rcx)
PUSH_REG(rdx) // 16
PUSH_REG(rbp)
PUSH_REG(rsi) // 16
PUSH_REG(r8)
PUSH_REG(r9) // 16
PUSH_REG(r10)
PUSH_REG(r11) // 16
PUSH_REG(r12)
PUSH_REG(r13) // 16
PUSH_REG(r14)
PUSH_REG(r15) // 16
PUSH_XMM_REG(xmm0)
PUSH_XMM_REG(xmm1)
PUSH_XMM_REG(xmm2)
PUSH_XMM_REG(xmm3)
PUSH_XMM_REG(xmm4)
PUSH_XMM_REG(xmm5)
PUSH_XMM_REG(xmm6)
PUSH_XMM_REG(xmm7)
// Stack is just 8-byte aligned but callee will re-align to 16
call _${lib_suffix}_tramp_resolve
POP_XMM_REG(xmm7)
POP_XMM_REG(xmm6)
POP_XMM_REG(xmm5)
POP_XMM_REG(xmm4)
POP_XMM_REG(xmm3)
POP_XMM_REG(xmm2)
POP_XMM_REG(xmm1)
POP_XMM_REG(xmm0) // 16
POP_REG(r15)
POP_REG(r14) // 16
POP_REG(r13)
POP_REG(r12) // 16
POP_REG(r11)
POP_REG(r10) // 16
POP_REG(r9)
POP_REG(r8) // 16
POP_REG(rsi)
POP_REG(rbp) // 16
POP_REG(rdx)
POP_REG(rcx) // 16
POP_REG(rbx)
POP_REG(rax) // 16
POP_REG(rdi)
ret
.cfi_endproc