Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/winecrt0/setjmp.c
12343 views
1
/*
2
* setjmpex/longjmp functions for Wine exception handling
3
*
4
* Copyright (c) 1999, 2010 Alexandre Julliard
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include <stdarg.h>
22
#include "excpt.h"
23
#undef USE_COMPILER_EXCEPTIONS
24
#undef GetExceptionInformation
25
#undef GetExceptionCode
26
#undef AbnormalTermination
27
#include "winternl.h"
28
#include "wine/exception.h"
29
#include "wine/asm.h"
30
31
#if defined(__GNUC__) || defined(__clang__)
32
33
#if defined(__i386__)
34
35
__ASM_GLOBAL_FUNC( __wine_setjmpex,
36
"movl 4(%esp),%ecx\n\t" /* jmp_buf */
37
"movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */
38
"movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */
39
"movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */
40
"movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */
41
"movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */
42
"movl 0(%esp),%eax\n\t"
43
"movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */
44
"xorl %eax,%eax\n\t"
45
"ret" )
46
47
__ASM_GLOBAL_FUNC( __wine_longjmp,
48
"movl 4(%esp),%ecx\n\t" /* jmp_buf */
49
"movl 8(%esp),%eax\n\t" /* retval */
50
"movl 0(%ecx),%ebp\n\t" /* jmp_buf.Ebp */
51
"movl 4(%ecx),%ebx\n\t" /* jmp_buf.Ebx */
52
"movl 8(%ecx),%edi\n\t" /* jmp_buf.Edi */
53
"movl 12(%ecx),%esi\n\t" /* jmp_buf.Esi */
54
"movl 16(%ecx),%esp\n\t" /* jmp_buf.Esp */
55
"addl $4,%esp\n\t" /* get rid of return address */
56
"jmp *20(%ecx)\n\t" /* jmp_buf.Eip */ )
57
58
#elif defined(__arm64ec__)
59
60
int __cdecl __attribute__((naked)) __wine_setjmpex( __wine_jmp_buf *buf, EXCEPTION_REGISTRATION_RECORD *frame )
61
{
62
asm( "stp x29, x30, [sp, #-16]!\n\t"
63
"stp x1, x27, [x0]\n\t" /* jmp_buf->Frame,Rbx */
64
"add x1, sp, #16\n\t"
65
"stp x1, x29, [x0, #0x10]\n\t" /* jmp_buf->Rsp,Rbp */
66
"mov x29, sp\n\t"
67
"stp x25, x26, [x0, #0x20]\n\t" /* jmp_buf->Rsi,Rdi */
68
"stp x19, x20, [x0, #0x30]\n\t" /* jmp_buf->R12,R13 */
69
"stp x21, x22, [x0, #0x40]\n\t" /* jmp_buf->R14,R15 */
70
"str x30, [x0, #0x50]\n\t" /* jmp_buf->Rip */
71
"stp d8, d9, [x0, #0x80]\n\t" /* jmp_buf->Xmm8,Xmm9 */
72
"stp d10, d11, [x0, #0xa0]\n\t" /* jmp_buf->Xmm10,Xmm11 */
73
"stp d12, d13, [x0, #0xc0]\n\t" /* jmp_buf->Xmm12,Xmm13 */
74
"stp d14, d15, [x0, #0xe0]\n\t" /* jmp_buf->Xmm14,Xmm15 */
75
"adrp x8, __os_arm64x_get_x64_information\n\t"
76
"ldr x8, [x8, :lo12:__os_arm64x_get_x64_information]\n\t"
77
"add x1, x0, #0x58\n\t" /* jmp_buf->Mxcsr */
78
"mov x0, #0\n\t"
79
"blr x8\n\t"
80
"mov x0, #0\n\t"
81
"ldp x29, x30, [sp], #16\n\t"
82
"ret" );
83
}
84
85
void __cdecl __attribute__((naked)) __wine_longjmp( __wine_jmp_buf *buf, int retval )
86
{
87
asm( "mov x19, x0\n\t"
88
"mov x20, x1\n\t"
89
"adrp x8, __os_arm64x_set_x64_information\n\t"
90
"ldr x8, [x8, :lo12:__os_arm64x_set_x64_information]\n\t"
91
"ldr w1, [x0, #0x58]\n\t" /* jmp_buf->Mxcsr */
92
"mov x0, #0\n\t"
93
"blr x8\n\t"
94
"mov x1, x19\n\t" /* jmp_buf */
95
"mov x0, x20\n\t" /* retval */
96
"ldr x27, [x1, #0x08]\n\t" /* jmp_buf->Rbx */
97
"ldp x2, x29, [x1, #0x10]\n\t" /* jmp_buf->Rsp,Rbp */
98
"ldp x25, x26, [x1, #0x20]\n\t" /* jmp_buf->Rsi,Rdi */
99
"ldp x19, x20, [x1, #0x30]\n\t" /* jmp_buf->R12,R13 */
100
"ldp x21, x22, [x1, #0x40]\n\t" /* jmp_buf->R14,R15 */
101
"ldr x30, [x1, #0x50]\n\t" /* jmp_buf->Rip */
102
"ldp d8, d9, [x1, #0x80]\n\t" /* jmp_buf->Xmm8,Xmm9 */
103
"ldp d10, d11, [x1, #0x90]\n\t" /* jmp_buf->Xmm10,Xmm11 */
104
"ldp d12, d13, [x1, #0xa0]\n\t" /* jmp_buf->Xmm12,Xmm13 */
105
"ldp d14, d15, [x1, #0xb0]\n\t" /* jmp_buf->Xmm14,Xmm15 */
106
"mov sp, x2\n\t"
107
"ret" );
108
}
109
110
#elif defined(__x86_64__)
111
112
__ASM_GLOBAL_FUNC( __wine_setjmpex,
113
"movq %rdx,(%rcx)\n\t" /* jmp_buf->Frame */
114
"movq %rbx,0x8(%rcx)\n\t" /* jmp_buf->Rbx */
115
"leaq 0x8(%rsp),%rax\n\t"
116
"movq %rax,0x10(%rcx)\n\t" /* jmp_buf->Rsp */
117
"movq %rbp,0x18(%rcx)\n\t" /* jmp_buf->Rbp */
118
"movq %rsi,0x20(%rcx)\n\t" /* jmp_buf->Rsi */
119
"movq %rdi,0x28(%rcx)\n\t" /* jmp_buf->Rdi */
120
"movq %r12,0x30(%rcx)\n\t" /* jmp_buf->R12 */
121
"movq %r13,0x38(%rcx)\n\t" /* jmp_buf->R13 */
122
"movq %r14,0x40(%rcx)\n\t" /* jmp_buf->R14 */
123
"movq %r15,0x48(%rcx)\n\t" /* jmp_buf->R15 */
124
"movq (%rsp),%rax\n\t"
125
"movq %rax,0x50(%rcx)\n\t" /* jmp_buf->Rip */
126
"stmxcsr 0x58(%rcx)\n\t" /* jmp_buf->MxCsr */
127
"fnstcw 0x5c(%rcx)\n\t" /* jmp_buf->FpCsr */
128
"movdqa %xmm6,0x60(%rcx)\n\t" /* jmp_buf->Xmm6 */
129
"movdqa %xmm7,0x70(%rcx)\n\t" /* jmp_buf->Xmm7 */
130
"movdqa %xmm8,0x80(%rcx)\n\t" /* jmp_buf->Xmm8 */
131
"movdqa %xmm9,0x90(%rcx)\n\t" /* jmp_buf->Xmm9 */
132
"movdqa %xmm10,0xa0(%rcx)\n\t" /* jmp_buf->Xmm10 */
133
"movdqa %xmm11,0xb0(%rcx)\n\t" /* jmp_buf->Xmm11 */
134
"movdqa %xmm12,0xc0(%rcx)\n\t" /* jmp_buf->Xmm12 */
135
"movdqa %xmm13,0xd0(%rcx)\n\t" /* jmp_buf->Xmm13 */
136
"movdqa %xmm14,0xe0(%rcx)\n\t" /* jmp_buf->Xmm14 */
137
"movdqa %xmm15,0xf0(%rcx)\n\t" /* jmp_buf->Xmm15 */
138
"xorq %rax,%rax\n\t"
139
"retq" )
140
141
__ASM_GLOBAL_FUNC( __wine_longjmp,
142
"movq %rdx,%rax\n\t" /* retval */
143
"movq 0x8(%rcx),%rbx\n\t" /* jmp_buf->Rbx */
144
"movq 0x18(%rcx),%rbp\n\t" /* jmp_buf->Rbp */
145
"movq 0x20(%rcx),%rsi\n\t" /* jmp_buf->Rsi */
146
"movq 0x28(%rcx),%rdi\n\t" /* jmp_buf->Rdi */
147
"movq 0x30(%rcx),%r12\n\t" /* jmp_buf->R12 */
148
"movq 0x38(%rcx),%r13\n\t" /* jmp_buf->R13 */
149
"movq 0x40(%rcx),%r14\n\t" /* jmp_buf->R14 */
150
"movq 0x48(%rcx),%r15\n\t" /* jmp_buf->R15 */
151
"ldmxcsr 0x58(%rcx)\n\t" /* jmp_buf->MxCsr */
152
"fnclex\n\t"
153
"fldcw 0x5c(%rcx)\n\t" /* jmp_buf->FpCsr */
154
"movdqa 0x60(%rcx),%xmm6\n\t" /* jmp_buf->Xmm6 */
155
"movdqa 0x70(%rcx),%xmm7\n\t" /* jmp_buf->Xmm7 */
156
"movdqa 0x80(%rcx),%xmm8\n\t" /* jmp_buf->Xmm8 */
157
"movdqa 0x90(%rcx),%xmm9\n\t" /* jmp_buf->Xmm9 */
158
"movdqa 0xa0(%rcx),%xmm10\n\t" /* jmp_buf->Xmm10 */
159
"movdqa 0xb0(%rcx),%xmm11\n\t" /* jmp_buf->Xmm11 */
160
"movdqa 0xc0(%rcx),%xmm12\n\t" /* jmp_buf->Xmm12 */
161
"movdqa 0xd0(%rcx),%xmm13\n\t" /* jmp_buf->Xmm13 */
162
"movdqa 0xe0(%rcx),%xmm14\n\t" /* jmp_buf->Xmm14 */
163
"movdqa 0xf0(%rcx),%xmm15\n\t" /* jmp_buf->Xmm15 */
164
"movq 0x50(%rcx),%rdx\n\t" /* jmp_buf->Rip */
165
"movq 0x10(%rcx),%rsp\n\t" /* jmp_buf->Rsp */
166
"jmp *%rdx" )
167
168
#elif defined(__arm__)
169
170
__ASM_GLOBAL_FUNC( __wine_setjmpex,
171
"stm r0, {r1,r4-r11}\n" /* jmp_buf->Frame,R4..R11 */
172
"str sp, [r0, #0x24]\n\t" /* jmp_buf->Sp */
173
"str lr, [r0, #0x28]\n\t" /* jmp_buf->Pc */
174
"vmrs r2, fpscr\n\t"
175
"str r2, [r0, #0x2c]\n\t" /* jmp_buf->Fpscr */
176
"add r0, r0, #0x30\n\t"
177
"vstm r0, {d8-d15}\n\t" /* jmp_buf->D[0..7] */
178
"mov r0, #0\n\t"
179
"bx lr" )
180
181
__ASM_GLOBAL_FUNC( __wine_longjmp,
182
"ldm r0, {r3-r11}\n\t" /* jmp_buf->Frame,R4..R11 */
183
"ldr sp, [r0, #0x24]\n\t" /* jmp_buf->Sp */
184
"ldr r2, [r0, #0x28]\n\t" /* jmp_buf->Pc */
185
"ldr r3, [r0, #0x2c]\n\t" /* jmp_buf->Fpscr */
186
"vmsr fpscr, r3\n\t"
187
"add r0, r0, #0x30\n\t"
188
"vldm r0, {d8-d15}\n\t" /* jmp_buf->D[0..7] */
189
"mov r0, r1\n\t" /* retval */
190
"bx r2" )
191
192
#elif defined(__aarch64__)
193
194
__ASM_GLOBAL_FUNC( __wine_setjmpex,
195
"str x1, [x0]\n\t" /* jmp_buf->Frame */
196
"stp x19, x20, [x0, #0x10]\n\t" /* jmp_buf->X19, X20 */
197
"stp x21, x22, [x0, #0x20]\n\t" /* jmp_buf->X21, X22 */
198
"stp x23, x24, [x0, #0x30]\n\t" /* jmp_buf->X23, X24 */
199
"stp x25, x26, [x0, #0x40]\n\t" /* jmp_buf->X25, X26 */
200
"stp x27, x28, [x0, #0x50]\n\t" /* jmp_buf->X27, X28 */
201
"stp x29, x30, [x0, #0x60]\n\t" /* jmp_buf->Fp, Lr */
202
"mov x2, sp\n\t"
203
"str x2, [x0, #0x70]\n\t" /* jmp_buf->Sp */
204
"mrs x2, fpcr\n\t"
205
"str w2, [x0, #0x78]\n\t" /* jmp_buf->Fpcr */
206
"mrs x2, fpsr\n\t"
207
"str w2, [x0, #0x7c]\n\t" /* jmp_buf->Fpsr */
208
"stp d8, d9, [x0, #0x80]\n\t" /* jmp_buf->D[0-1] */
209
"stp d10, d11, [x0, #0x90]\n\t" /* jmp_buf->D[2-3] */
210
"stp d12, d13, [x0, #0xa0]\n\t" /* jmp_buf->D[4-5] */
211
"stp d14, d15, [x0, #0xb0]\n\t" /* jmp_buf->D[6-7] */
212
"mov x0, #0\n\t"
213
"ret" )
214
215
__ASM_GLOBAL_FUNC( __wine_longjmp,
216
"ldp x19, x20, [x0, #0x10]\n\t" /* jmp_buf->X19, X20 */
217
"ldp x21, x22, [x0, #0x20]\n\t" /* jmp_buf->X21, X22 */
218
"ldp x23, x24, [x0, #0x30]\n\t" /* jmp_buf->X23, X24 */
219
"ldp x25, x26, [x0, #0x40]\n\t" /* jmp_buf->X25, X26 */
220
"ldp x27, x28, [x0, #0x50]\n\t" /* jmp_buf->X27, X28 */
221
"ldp x29, x30, [x0, #0x60]\n\t" /* jmp_buf->Fp, Lr */
222
"ldr x2, [x0, #0x70]\n\t" /* jmp_buf->Sp */
223
"mov sp, x2\n\t"
224
"ldr w2, [x0, #0x78]\n\t" /* jmp_buf->Fpcr */
225
"msr fpcr, x2\n\t"
226
"ldr w2, [x0, #0x7c]\n\t" /* jmp_buf->Fpsr */
227
"msr fpsr, x2\n\t"
228
"ldp d8, d9, [x0, #0x80]\n\t" /* jmp_buf->D[0-1] */
229
"ldp d10, d11, [x0, #0x90]\n\t" /* jmp_buf->D[2-3] */
230
"ldp d12, d13, [x0, #0xa0]\n\t" /* jmp_buf->D[4-5] */
231
"ldp d14, d15, [x0, #0xb0]\n\t" /* jmp_buf->D[6-7] */
232
"mov x0, x1\n\t" /* retval */
233
"ret" )
234
235
#else
236
237
int __cdecl __wine_setjmpex( __wine_jmp_buf *buf, EXCEPTION_REGISTRATION_RECORD *frame )
238
{
239
return setjmp( buf );
240
}
241
242
void __cdecl __wine_longjmp( __wine_jmp_buf *buf, int retval )
243
{
244
for (;;) longjmp( buf, retval );
245
}
246
247
#endif
248
249
#endif /* __GNUC__ || __clang__ */
250
251