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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# Copyright 2013 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# MakeFunc amd64 assembly code.
#include "config.h"
.global reflect.makeFuncStub
#ifdef __ELF__
.type reflect.makeFuncStub,@function
#endif
reflect.makeFuncStub:
.LFB1:
# Store all the parameter registers in a struct that looks
# like:
# struct {
# rax uint64 // 0x0
# rdi uint64 // 0x8
# rsi uint64 // 0x10
# rdx uint64 // 0x18
# rcx uint64 // 0x20
# r8 uint64 // 0x28
# r9 uint64 // 0x30
# rsp uint64 // 0x38 Pointer to arguments on stack.
# xmm0 [2]uint64 // 0x40
# xmm1 [2]uint64 // 0x50
# xmm2 [2]uint64 // 0x60
# xmm3 [2]uint64 // 0x70
# xmm4 [2]uint64 // 0x80
# xmm5 [2]uint64 // 0x90
# xmm6 [2]uint64 // 0xa0
# xmm7 [2]uint64 // 0xb0
# };
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $0xc0, %rsp # Space for struct on stack.
movq %rax, 0x0(%rsp)
movq %rdi, 0x8(%rsp)
movq %rsi, 0x10(%rsp)
movq %rdx, 0x18(%rsp)
movq %rcx, 0x20(%rsp)
movq %r8, 0x28(%rsp)
movq %r9, 0x30(%rsp)
leaq 16(%rbp), %rax
movq %rax, 0x38(%rsp)
movdqa %xmm0, 0x40(%rsp)
movdqa %xmm1, 0x50(%rsp)
movdqa %xmm2, 0x60(%rsp)
movdqa %xmm3, 0x70(%rsp)
movdqa %xmm4, 0x80(%rsp)
movdqa %xmm5, 0x90(%rsp)
movdqa %xmm6, 0xa0(%rsp)
movdqa %xmm7, 0xb0(%rsp)
/* For MakeFunc functions that call recover. */
movq 8(%rbp), %rdi
#ifdef __PIC__
call __go_makefunc_can_recover@PLT
#else
call __go_makefunc_can_recover
#endif
# Get function type.
#ifdef __PIC__
call __go_get_closure@PLT
#else
call __go_get_closure
#endif
movq %rax, %rsi
movq %rsp, %rdi
#ifdef __PIC__
call reflect.MakeFuncStubGo@PLT
#else
call reflect.MakeFuncStubGo
#endif
/* MakeFunc functions can no longer call recover. */
#ifdef __PIC__
call __go_makefunc_returning@PLT
#else
call __go_makefunc_returning
#endif
# The structure will be updated with any return values. Load
# all possible return registers before returning to the caller.
movq 0x0(%rsp), %rax
movq 0x18(%rsp), %rdx
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movdqa 0x40(%rsp), %xmm0
movdqa 0x50(%rsp), %xmm1
# long double values are returned on the floating point stack,
# but we don't worry about that since Go doesn't have a long
# double type.
leave
.LCFI2:
ret
.LFE1:
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub
#endif
#ifdef __ELF__
#ifdef HAVE_AS_X86_64_UNWIND_SECTION_TYPE
.section .eh_frame,"a",@unwind
#else
.section .eh_frame,"a",@progbits
#endif
.Lframe1:
.long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
.LSCIE1:
.long 0x0 /* CIE Identifier Tag */
.byte 0x1 /* CIE Version */
.ascii "zR\0" /* CIE Augmentation */
.uleb128 1 /* CIE Code Alignment Factor */
.sleb128 -8 /* CIE Data Alignment Factor */
.byte 0x10 /* CIE RA Column */
.uleb128 1 /* Augmentation size */
.byte 0x1b /* FDE Encoding (pcrel sdata4) */
.byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
.uleb128 7
.uleb128 8
.byte 0x80+16 /* DW_CFA_offset, %rip offset 1*-8 */
.uleb128 1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1 /* FDE Length */
.LASFDE1:
.long .LASFDE1-.Lframe1 /* FDE CIE offset */
#if HAVE_AS_X86_PCREL
.long .LFB1-. /* FDE initial location */
#else
.long .LFB1@rel
#endif
.long .LFE1-.LFB1 /* FDE address range */
.uleb128 0x0 /* Augmentation size */
.byte 0x4 /* DW_CFA_advance_loc4 */
.long .LCFI0-.LFB1
.byte 0xe /* DW_CFA_def_cfa_offset */
.uleb128 16
.byte 0x86 /* DW_CFA_offset, column 0x6 */
.uleb128 2
.byte 0x4 /* DW_CFA_advance_loc4 */
.long .LCFI1-.LCFI0
.byte 0xd /* DW_CFA_def_cfa_register */
.uleb128 6
.byte 0x2 /* DW_CFA_advance_loc1 */
.byte .LCFI2-.LCFI1
.byte 0xc /* DW_CFA_def_cfa */
.uleb128 7
.uleb128 8
.align 8
.LEFDE1:
#endif /* __ELF__ */
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",@progbits
.section .note.GNU-split-stack,"",@progbits
.section .note.GNU-no-split-stack,"",@progbits
#endif
|