forked from hnes/libaco
-
Notifications
You must be signed in to change notification settings - Fork 0
/
acosw.S
168 lines (155 loc) Β· 4.74 KB
/
acosw.S
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
.text
.globl acosw
.type acosw, @function
.intel_syntax noprefix
acosw:
/*
extern void acosw(aco_t* from_co, aco_t* to_co);
struct aco_t {
void* reg[X];
// ...
}
reference:
https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
pitfall:
http://man7.org/linux/man-pages/man7/signal.7.html
http://man7.org/linux/man-pages/man2/sigaltstack.2.html
> $ man 7 signal
> ...
> By default, the signal handler is invoked on the normal process
> stack. It is possible to arrange that the signal handler
> uses an alternate stack; see sigaltstack(2) for a discussion of
> how to do this and when it might be useful.
> ...
This is a BUG example:
https://github.com/Tencent/libco/blob/v1.0/coctx_swap.S#L27
proof of correctness:
https://github.com/hnes/libaco
mxcsr & fpu:
fnstcw * m2byte
Store FPU control word to m2byte without checking for
pending unmasked floating-point exceptions.
fldcw m2byte
Load FPU control word from m2byte.
stmxcsr m32
Store contents of MXCSR register to m32
ldmxcsr m32
Load MXCSR register from m32.
*/
/*
0x00 --> 0xff
eip esp ebp edi esi ebx fpucw16 mxcsr32
0 4 8 c 10 14 18 1c
*/
#ifdef __i386__
mov eax,DWORD PTR [esp+0x4] // from_co
mov edx,DWORD PTR [esp] // retaddr
lea ecx,[esp+0x4] // esp
mov DWORD PTR [eax+0x8],ebp //<ebp
mov DWORD PTR [eax+0x4],ecx //<esp
mov DWORD PTR [eax+0x0],edx //<retaddr
mov DWORD PTR [eax+0xc],edi //<edi
mov ecx,DWORD PTR [esp+0x8] // to_co
mov DWORD PTR [eax+0x10],esi //<esi
mov DWORD PTR [eax+0x14],ebx //<ebx
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
fnstcw WORD PTR [eax+0x18] //<fpucw
stmxcsr DWORD PTR [eax+0x1c] //<mxcsr
#endif
mov edx,DWORD PTR [ecx+0x4] //>esp
mov ebp,DWORD PTR [ecx+0x8] //>ebp
mov eax,DWORD PTR [ecx+0x0] //>retaddr
mov edi,DWORD PTR [ecx+0xc] //>edi
mov esi,DWORD PTR [ecx+0x10] //>esi
mov ebx,DWORD PTR [ecx+0x14] //>ebx
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
fldcw WORD PTR [ecx+0x18] //>fpucw
ldmxcsr DWORD PTR [ecx+0x1c] //>mxcsr
#endif
xor ecx,ecx
mov esp,edx
xor edx,edx
jmp eax
#elif __x86_64__
/*
0x00 --> 0xff
r12 r13 r14 r15 rip rsp rbx rbp fpucw16 mxcsr32
0 8 10 18 20 28 30 38 40 44
*/
// rdi - from_co | rsi - to_co
mov rdx,QWORD PTR [rsp] // retaddr
lea rcx,[rsp+0x8] // rsp
mov QWORD PTR [rdi+0x0], r12
mov QWORD PTR [rdi+0x8], r13
mov QWORD PTR [rdi+0x10],r14
mov QWORD PTR [rdi+0x18],r15
mov QWORD PTR [rdi+0x20],rdx // retaddr
mov QWORD PTR [rdi+0x28],rcx // rsp
mov QWORD PTR [rdi+0x30],rbx
mov QWORD PTR [rdi+0x38],rbp
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
fnstcw WORD PTR [rdi+0x40]
stmxcsr DWORD PTR [rdi+0x44]
#endif
mov r12,QWORD PTR [rsi+0x0]
mov r13,QWORD PTR [rsi+0x8]
mov r14,QWORD PTR [rsi+0x10]
mov r15,QWORD PTR [rsi+0x18]
mov rax,QWORD PTR [rsi+0x20] // retaddr
mov rcx,QWORD PTR [rsi+0x28] // rsp
mov rbx,QWORD PTR [rsi+0x30]
mov rbp,QWORD PTR [rsi+0x38]
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
fldcw WORD PTR [rsi+0x40]
ldmxcsr DWORD PTR [rsi+0x44]
#endif
mov rsp,rcx
jmp rax
#else
#error "platform not support"
#endif
.globl aco_save_fpucw_mxcsr
.type aco_save_fpucw_mxcsr, @function
.intel_syntax noprefix
aco_save_fpucw_mxcsr:
#ifdef __i386__
mov eax,DWORD PTR [esp+0x4] // ptr
fnstcw WORD PTR [eax]
stmxcsr DWORD PTR [eax+0x4]
ret
#elif __x86_64__
fnstcw WORD PTR [rdi]
stmxcsr DWORD PTR [rdi+0x4]
ret
#else
#error "platform not support"
#endif
.globl abort
.globl aco_funcp_protector
.globl aco_funcp_protector_asm
.type aco_funcp_protector_asm, @function
.intel_syntax noprefix
aco_funcp_protector_asm:
#ifdef __i386__
and esp,0xfffffff0
#if defined(__pic__) || defined(__PIC__)
call aco_funcp_protector@PLT
call abort@PLT
#else
call aco_funcp_protector
call abort
#endif
ret
#elif __x86_64__
and rsp,0xfffffffffffffff0
#if defined(__pic__) || defined(__PIC__)
call aco_funcp_protector@PLT
call abort@PLT
#else
call aco_funcp_protector
call abort
#endif
ret
#else
#error "platform not support"
#endif