]>
Commit | Line | Data |
---|---|---|
9a4d574b | 1 | #!/usr/bin/perl |
6e75c72b CF |
2 | # Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013 |
3 | # Red Hat, Inc. | |
ee933758 CF |
4 | # |
5 | # This file is part of Cygwin. | |
6 | # | |
7 | # This software is a copyrighted work licensed under the terms of the | |
8 | # Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
9 | # details. | |
10 | # | |
9a4d574b | 11 | use strict; |
91000b5d CF |
12 | sub cleanup(@); |
13 | ||
9a4d574b CF |
14 | my $in = shift; |
15 | my $tls_offsets = shift; | |
61522196 | 16 | my $cpu = shift; |
9a4d574b CF |
17 | my $out = shift; |
18 | my $sigfe = shift; | |
19 | ||
20 | $main::first = 0; | |
61522196 CV |
21 | if (!defined($in) || !defined($cpu) || !defined($out) || !defined($sigfe)) { |
22 | die "usage: $0 deffile.in cygtls.h target-cpu deffile.def sigfe.s\n"; | |
9a4d574b CF |
23 | } |
24 | ||
25 | require $tls_offsets; | |
26 | ||
61522196 CV |
27 | my $is64bit = ($cpu eq 'x86_64' ? 1 : 0); |
28 | my $sym_prefix = ($is64bit ? '' : '_'); | |
29 | ||
9a4d574b CF |
30 | open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n"; |
31 | my @top = (); | |
32 | while (<IN>) { | |
91000b5d | 33 | push(@top, cleanup $_); |
588b40e2 | 34 | last if /^\s*exports$/i; |
9a4d574b | 35 | } |
91000b5d | 36 | my @in = cleanup <IN>; |
9a4d574b CF |
37 | close(IN); |
38 | ||
39 | my %sigfe = (); | |
40 | my @data = (); | |
41 | my @nosigfuncs = (); | |
59328e28 | 42 | my @text = (); |
9a4d574b | 43 | for (@in) { |
59328e28 | 44 | chomp; |
588b40e2 | 45 | s/\s+DATA$//o and do { |
59328e28 | 46 | push @data, $_; |
9a4d574b CF |
47 | next; |
48 | }; | |
9a4d574b CF |
49 | if (/=/o) { |
50 | if (s/\s+NOSIGFE\s*$//) { | |
51f90b2f | 51 | # nothing |
588b40e2 | 52 | } elsif (s/\s+SIGFE(_MAYBE)?$//) { |
51f90b2f | 53 | my $func = (split(' '))[2]; |
61522196 | 54 | my $maybe = (defined($1) ? lc $1 : '') . '_'; |
51f90b2f | 55 | $sigfe{$func} = '_sigfe' . $maybe . $func; |
9a4d574b CF |
56 | } |
57 | } else { | |
51f90b2f | 58 | my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGFE(?:_MAYBE)?))?$%o; |
9a4d574b CF |
59 | if (defined($sigfe) && $sigfe =~ /^NO/o) { |
60 | $_ = $func; | |
61 | } else { | |
62 | $sigfe ||= 'sigfe'; | |
63 | $_ = '_' . lc($sigfe) . '_' . $func; | |
64 | $sigfe{$func} = $_; | |
65 | $_ = $func . ' = ' . $_; | |
66 | } | |
67 | } | |
68 | s/(\S)\s+(\S)/$1 $2/go; | |
69 | s/(\S)\s+$/$1/o; | |
70 | s/^\s+(\S)/$1/o; | |
59328e28 | 71 | push @text, $_; |
9a4d574b CF |
72 | } |
73 | ||
59328e28 | 74 | for (@text) { |
588b40e2 | 75 | my ($alias, $func) = /^(\S+)\s+=\s+(\S+)\s*$/o; |
59328e28 | 76 | $_ = $alias . ' = ' . $sigfe{$func} |
9a4d574b CF |
77 | if defined($func) && $sigfe{$func}; |
78 | } | |
59328e28 | 79 | |
9a4d574b | 80 | open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n"; |
59328e28 CF |
81 | push @top, (map {$_ . " DATA\n"} @data), (map {$_ . "\n"} @text); |
82 | print OUT @top; | |
9a4d574b CF |
83 | close OUT; |
84 | ||
85 | open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n"; | |
86 | ||
87 | for my $k (sort keys %sigfe) { | |
88 | print SIGFE fefunc($k, $sigfe{$k}); | |
89 | } | |
90 | close SIGFE; | |
91 | ||
92 | sub fefunc { | |
61522196 CV |
93 | my $func = $sym_prefix . shift; |
94 | my $fe = $sym_prefix . shift; | |
95 | my $sigfe_func; | |
96 | if ($is64bit) { | |
97 | $sigfe_func = ($fe =~ /^(.*)_${func}$/)[0]; | |
98 | } else { | |
99 | $sigfe_func = ($fe =~ /^(.*)${func}$/)[0]; | |
100 | } | |
9a4d574b | 101 | my $extra; |
61522196 CV |
102 | my $res; |
103 | if ($is64bit) { | |
104 | $res = <<EOF; | |
9a4d574b CF |
105 | .extern $func |
106 | .global $fe | |
61522196 | 107 | .seh_proc $fe |
9a4d574b | 108 | $fe: |
61522196 CV |
109 | leaq $func(%rip),%r10 |
110 | pushq %r10 | |
111 | .seh_pushreg %r10 | |
112 | .seh_endprologue | |
51f90b2f | 113 | jmp $sigfe_func |
61522196 CV |
114 | .seh_endproc |
115 | ||
116 | EOF | |
117 | } else { | |
118 | $res = <<EOF; | |
119 | .extern $func | |
120 | .global $fe | |
121 | $fe: | |
122 | pushl \$$func | |
123 | jmp $sigfe_func | |
9a4d574b CF |
124 | |
125 | EOF | |
61522196 | 126 | } |
9a4d574b | 127 | if (!$main::first++) { |
61522196 CV |
128 | if ($is64bit) { |
129 | $res = <<EOF . longjmp () . $res; | |
130 | .text | |
131 | ||
132 | .seh_proc _sigfe_maybe | |
133 | _sigfe_maybe: | |
134 | pushq %r12 | |
135 | .seh_pushreg %r12 | |
136 | .seh_endprologue | |
137 | movq %gs:8,%r12 # location of bottom of stack | |
138 | addq \$$tls::initialized,%r12 # where we will be looking | |
139 | cmpq %r12,%rsp # stack loc > than tls | |
140 | jge 0f # yep. we don't have a tls. | |
141 | subq \$$tls::initialized,%r12 # where we will be looking | |
142 | movl $tls::initialized(%r12),%r11d | |
143 | cmpl \$0xc763173f,%r11d # initialized? | |
144 | je 1f | |
145 | 0: | |
146 | popq %r12 | |
147 | ret | |
148 | .seh_endproc | |
149 | ||
150 | .seh_proc _sigfe | |
151 | _sigfe: # stack is aligned on entry! | |
152 | pushq %r12 | |
153 | .seh_pushreg %r12 | |
154 | .seh_endprologue | |
155 | movq %gs:8,%r12 # location of bottom of stack | |
156 | 1: movl \$1,%r11d # potential lock value | |
157 | xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it | |
158 | movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock | |
159 | testl %r11d,%r11d # it will be zero | |
160 | jz 2f # if so | |
161 | pause | |
162 | jmp 1b # loop | |
163 | 2: movq \$8,%rax # have the lock, now increment the | |
164 | xaddq %rax,$tls::stackptr(%r12) # stack pointer and get pointer | |
165 | leaq _sigbe(%rip),%r11 # new place to return to | |
166 | xchgq %r11,16(%rsp) # exchange with real return value | |
167 | movq %r11,(%rax) # store real return value on alt stack | |
168 | incl $tls::incyg(%r12) | |
169 | decl $tls::stacklock(%r12) # remove lock | |
170 | popq %r12 # restore saved value | |
171 | popq %rax # pop real function address from stack | |
172 | jmp *%rax # and jmp to it | |
173 | .seh_endproc | |
174 | ||
175 | .seh_proc _sigfe | |
176 | _sigbe: # return here after cygwin syscall | |
177 | # stack is aligned on entry! | |
178 | pushq %r12 | |
179 | .seh_pushreg %r12 | |
180 | .seh_endprologue | |
181 | movq %gs:8,%r12 # address of bottom of tls | |
182 | 1: movl \$1,%r11d # potential lock value | |
183 | xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it | |
184 | movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock | |
185 | testl %r11d,%r11d # it will be zero | |
186 | jz 2f # if so | |
187 | pause | |
188 | jmp 1b # and loop | |
189 | 2: movq \$-8,%r11 # now decrement aux stack | |
190 | xaddq %r11,$tls::stackptr(%r12) # and get pointer | |
191 | movq -8(%r11),%r11 # get return address from signal stack | |
192 | decl $tls::incyg(%r12) | |
193 | decl $tls::stacklock(%r12) # release lock | |
194 | popq %r12 | |
195 | jmp *%r11 # "return" to caller | |
196 | .seh_endproc | |
197 | ||
198 | .global sigdelayed | |
199 | .seh_proc sigdelayed | |
200 | sigdelayed: | |
201 | pushq %r10 # used for return address injection | |
202 | .seh_pushreg %rbp | |
203 | pushq %rbp | |
204 | .seh_pushreg %rbp | |
205 | movq %rsp,%rbp | |
206 | # stack is aligned or unaligned on entry! | |
207 | # make sure it is aligned from here on | |
208 | # We could be called from an interrupted thread which doesn't know | |
209 | # about his fate, so save and restore everything and the kitchen sink. | |
210 | andq \$0xfffffffffffffff0,%rsp | |
211 | .seh_setframe %rbp,0 | |
212 | pushq %r15 | |
213 | .seh_pushreg %r15 | |
214 | pushq %r14 | |
215 | .seh_pushreg %r14 | |
216 | pushq %r13 | |
217 | .seh_pushreg %r13 | |
218 | pushq %r12 | |
219 | .seh_pushreg %r12 | |
220 | pushq %r11 | |
221 | .seh_pushreg %r11 | |
222 | pushq %r9 | |
223 | .seh_pushreg %r9 | |
224 | pushq %r8 | |
225 | .seh_pushreg %r8 | |
226 | pushq %rsi | |
227 | .seh_pushreg %rsi | |
228 | pushq %rdi | |
229 | .seh_pushreg %rdi | |
230 | pushq %rdx | |
231 | .seh_pushreg %rdx | |
232 | pushq %rcx | |
233 | .seh_pushreg %rcx | |
234 | pushq %rbx | |
235 | .seh_pushreg %rbx | |
236 | pushq %rax | |
237 | .seh_pushreg %rax | |
238 | pushf | |
239 | subq \$0x120,%rsp | |
240 | .seh_stackalloc 0x120 | |
241 | movdqa %xmm15,0x110(%rsp) | |
242 | movdqa %xmm14,0x100(%rsp) | |
243 | movdqa %xmm13,0xf0(%rsp) | |
244 | movdqa %xmm12,0xe0(%rsp) | |
245 | movdqa %xmm11,0xd0(%rsp) | |
246 | movdqa %xmm10,0xc0(%rsp) | |
247 | movdqa %xmm9,0xb0(%rsp) | |
248 | movdqa %xmm8,0xa0(%rsp) | |
249 | movdqa %xmm7,0x90(%rsp) | |
250 | movdqa %xmm6,0x80(%rsp) | |
251 | movdqa %xmm5,0x70(%rsp) | |
252 | movdqa %xmm4,0x60(%rsp) | |
253 | movdqa %xmm3,0x50(%rsp) | |
254 | movdqa %xmm2,0x40(%rsp) | |
255 | movdqa %xmm1,0x30(%rsp) | |
256 | movdqa %xmm0,0x20(%rsp) | |
257 | .seh_endprologue | |
258 | ||
259 | movq %gs:8,%r12 # get tls | |
260 | movl $tls::saved_errno(%r12),%r15d # temporarily save saved_errno | |
261 | movq \$$tls::start_offset,%rcx # point to beginning of tls block | |
262 | addq %r12,%rcx # and store as first arg to method | |
263 | call _ZN7_cygtls19call_signal_handlerEv # call handler | |
264 | ||
265 | 1: movl \$1,%r11d # potential lock value | |
266 | xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it | |
267 | movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock | |
268 | testl %r11d,%r11d # it will be zero | |
269 | jz 2f # if so | |
270 | pause | |
271 | jmp 1b # and loop | |
272 | 2: testl %r15d,%r15d # was saved_errno < 0 | |
273 | jl 3f # yup. ignore it | |
274 | movq $tls::errno_addr(%r12),%r11 | |
275 | movl %r15d,(%r11) | |
276 | 3: movq \$-8,%r11 # now decrement aux stack | |
277 | xaddq %r11,$tls::stackptr(%r12) # and get pointer | |
278 | xorq %r10,%r10 | |
279 | xchgq %r10,-8(%r11) # get return address from signal stack | |
280 | xorl %r11d,%r11d | |
281 | movl %r11d,$tls::incyg(%r12) | |
282 | movl %r11d,$tls::stacklock(%r12) # unlock | |
283 | movdqa 0x20(%rsp),%xmm0 | |
284 | movdqa 0x30(%rsp),%xmm1 | |
285 | movdqa 0x40(%rsp),%xmm2 | |
286 | movdqa 0x50(%rsp),%xmm3 | |
287 | movdqa 0x60(%rsp),%xmm4 | |
288 | movdqa 0x70(%rsp),%xmm5 | |
289 | movdqa 0x80(%rsp),%xmm6 | |
290 | movdqa 0x90(%rsp),%xmm7 | |
291 | movdqa 0xa0(%rsp),%xmm8 | |
292 | movdqa 0xb0(%rsp),%xmm9 | |
293 | movdqa 0xc0(%rsp),%xmm10 | |
294 | movdqa 0xd0(%rsp),%xmm11 | |
295 | movdqa 0xe0(%rsp),%xmm12 | |
296 | movdqa 0xf0(%rsp),%xmm13 | |
297 | movdqa 0x100(%rsp),%xmm14 | |
298 | movdqa 0x110(%rsp),%xmm15 | |
299 | addq \$0x120,%rsp | |
300 | popf | |
301 | popq %rax | |
302 | popq %rbx | |
303 | popq %rcx | |
304 | popq %rdx | |
305 | popq %rdi | |
306 | popq %rsi | |
307 | popq %r8 | |
308 | popq %r9 | |
309 | popq %r11 | |
310 | popq %r12 | |
311 | popq %r13 | |
312 | popq %r14 | |
313 | popq %r15 | |
314 | movq %rbp,%rsp | |
315 | popq %rbp | |
316 | xchgq %r10,(%rsp) | |
317 | ret | |
318 | .seh_endproc | |
319 | ||
320 | # _cygtls::pop | |
321 | .global _ZN7_cygtls3popEv | |
322 | .seh_proc _ZN7_cygtls3popEv | |
323 | _ZN7_cygtls3popEv: | |
324 | .seh_endprologue | |
325 | movq \$-8,%r11 | |
326 | xaddq %r11,$tls::pstackptr(%rcx) | |
327 | movq -8(%r11),%rax | |
328 | ret | |
329 | .seh_endproc | |
330 | ||
331 | # _cygtls::lock | |
332 | .global _ZN7_cygtls4lockEv | |
333 | .seh_proc _ZN7_cygtls4lockEv | |
334 | _ZN7_cygtls4lockEv: | |
335 | pushq %r12 | |
336 | .seh_pushreg %r12 | |
337 | .seh_endprologue | |
338 | movq %rcx,%r12 | |
339 | 1: movl \$1,%r11d | |
340 | xchgl %r11d,$tls::pstacklock(%r12) | |
341 | testl %r11d,%r11d | |
342 | jz 2f | |
343 | pause | |
344 | jmp 1b | |
345 | 2: popq %r12 | |
346 | ret | |
347 | .seh_endproc | |
348 | ||
349 | # _cygtls::unlock | |
350 | .global _ZN7_cygtls6unlockEv | |
351 | .seh_proc _ZN7_cygtls6unlockEv | |
352 | _ZN7_cygtls6unlockEv: | |
353 | .seh_endprologue | |
354 | decl $tls::pstacklock(%rcx) | |
355 | ret | |
356 | .seh_endproc | |
357 | ||
358 | # _cygtls::locked | |
359 | .global _ZN7_cygtls6lockedEv | |
360 | .seh_proc _ZN7_cygtls6lockedEv | |
361 | _ZN7_cygtls6lockedEv: | |
362 | .seh_endprologue | |
363 | movl $tls::pstacklock(%rcx),%eax | |
364 | ret | |
365 | .seh_endproc | |
366 | ||
367 | .seh_proc stabilize_sig_stack | |
368 | stabilize_sig_stack: | |
369 | pushq %r12 | |
370 | .seh_pushreg %r12 | |
371 | subq \$0x20,%rsp | |
372 | .seh_stackalloc 32 | |
373 | .seh_endprologue | |
374 | movq %gs:8,%r12 | |
375 | 1: movl \$1,%r10d | |
376 | xchgl %r10d,$tls::stacklock(%r12) | |
377 | movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock | |
378 | testl %r10d,%r10d | |
379 | jz 2f | |
380 | pause | |
381 | jmp 1b | |
382 | 2: incl $tls::incyg(%r12) | |
383 | cmpl \$0,$tls::sig(%r12) | |
384 | jz 3f | |
385 | decl $tls::stacklock(%r12) # unlock | |
386 | movq \$$tls::start_offset,%rcx # point to beginning | |
387 | addq %r12,%rcx # of tls block | |
388 | call _ZN7_cygtls19call_signal_handlerEv | |
389 | jmp 1b | |
390 | 3: decl $tls::incyg(%r12) | |
391 | addq \$0x20,%rsp | |
392 | movq %r12,%r11 # return tls addr in r11 | |
393 | popq %r12 | |
394 | ret | |
395 | .seh_endproc | |
396 | EOF | |
397 | } else { | |
398 | $res = <<EOF . longjmp () . $res; | |
9a4d574b | 399 | .text |
9a4d574b | 400 | |
51f90b2f CF |
401 | __sigfe_maybe: |
402 | pushl %ebx | |
403 | pushl %edx | |
404 | movl %fs:4,%ebx # location of bottom of stack | |
2346864a CF |
405 | addl \$$tls::initialized,%ebx # where we will be looking |
406 | cmpl %ebx,%esp # stack loc > than tls | |
407 | jge 0f # yep. we don't have a tls. | |
408 | subl \$$tls::initialized,%ebx # where we will be looking | |
51f90b2f CF |
409 | movl $tls::initialized(%ebx),%eax |
410 | cmpl \$0xc763173f,%eax # initialized? | |
411 | je 1f | |
2346864a | 412 | 0: popl %edx |
51f90b2f | 413 | popl %ebx |
9badd94a | 414 | ret |
51f90b2f | 415 | |
9a4d574b | 416 | __sigfe: |
e431827c | 417 | pushl %ebx |
9a4d574b | 418 | pushl %edx |
7ea8e226 CF |
419 | movl %fs:4,%ebx # location of bottom of stack |
420 | 1: movl \$1,%eax # potential lock value | |
3a7c5515 | 421 | xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it |
7ea8e226 | 422 | movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock |
3a1ccfc8 | 423 | testl %eax,%eax # it will be zero |
e431827c | 424 | jz 2f # if so |
3a7c5515 | 425 | call _yield # should be a short-time thing, so |
e431827c | 426 | jmp 1b # sleep and loop |
5fb0fe79 | 427 | 2: movl \$4,%eax # have the lock, now increment the |
7ea8e226 CF |
428 | xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer |
429 | leal __sigbe,%edx # new place to return to | |
430 | xchgl %edx,12(%esp) # exchange with real return value | |
431 | movl %edx,(%eax) # store real return value on alt stack | |
432 | incl $tls::incyg(%ebx) | |
433 | decl $tls::stacklock(%ebx) # remove lock | |
e431827c CF |
434 | popl %edx # restore saved value |
435 | popl %ebx | |
9a4d574b CF |
436 | ret |
437 | ||
6946073e | 438 | .global __sigbe |
f02b22dc | 439 | __sigbe: # return here after cygwin syscall |
e431827c | 440 | pushl %eax # don't clobber |
0b6fbd39 | 441 | pushl %ebx # tls pointer |
7ea8e226 | 442 | 1: movl %fs:4,%ebx # address of bottom of tls |
e431827c | 443 | movl \$1,%eax # potential lock value |
3a7c5515 | 444 | xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it |
7ea8e226 | 445 | movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock |
3a1ccfc8 | 446 | testl %eax,%eax # it will be zero |
e431827c | 447 | jz 2f # if so |
3a7c5515 | 448 | call _yield # sleep |
e431827c CF |
449 | jmp 1b # and loop |
450 | 2: movl \$-4,%eax # now decrement aux stack | |
7ea8e226 | 451 | xadd %eax,$tls::stackptr(%ebx) # and get pointer |
0b6fbd39 CF |
452 | movl -4(%eax),%eax # get return address from signal stack |
453 | xchgl %eax,4(%esp) # swap return address with saved eax | |
a680a532 | 454 | decl $tls::incyg(%ebx) |
7ea8e226 | 455 | decl $tls::stacklock(%ebx) # release lock |
7ea8e226 | 456 | popl %ebx |
6946073e CF |
457 | ret |
458 | ||
f2afcfa6 | 459 | .global _sigdelayed |
f2afcfa6 | 460 | _sigdelayed: |
dd063819 CF |
461 | pushl %ebp |
462 | movl %esp,%ebp | |
f2afcfa6 | 463 | pushf |
dd063819 CF |
464 | pushl %esi |
465 | pushl %edi | |
466 | pushl %edx | |
467 | pushl %ecx | |
468 | pushl %ebx | |
469 | pushl %eax | |
470 | movl %fs:4,%ebx # get tls | |
471 | pushl $tls::saved_errno(%ebx) # saved errno | |
f2afcfa6 | 472 | |
dd063819 CF |
473 | movl \$$tls::start_offset,%eax # point to beginning |
474 | addl %ebx,%eax # of tls block | |
6e75c72b | 475 | call __ZN7_cygtls19call_signal_handlerEv\@4 # call handler |
56d06b9a | 476 | |
dd063819 | 477 | movl %fs:4,%ebx # reget tls |
56d06b9a CF |
478 | 1: movl \$1,%eax # potential lock value |
479 | xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it | |
480 | movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock | |
481 | testl %eax,%eax # it will be zero | |
482 | jz 2f # if so | |
483 | call _yield # sleep | |
484 | jmp 1b # and loop | |
485 | 2: popl %edx # saved errno | |
486 | testl %edx,%edx # Is it < 0 | |
487 | jl 3f # yup. ignore it | |
488 | movl $tls::errno_addr(%ebx),%eax | |
489 | movl %edx,(%eax) | |
490 | 3: movl \$-4,%eax # now decrement aux stack | |
491 | xadd %eax,$tls::stackptr(%ebx) # and get pointer | |
492 | xorl %ebp,%ebp | |
493 | xchgl %ebp,-4(%eax) # get return address from signal stack | |
494 | xchgl %ebp,28(%esp) # store real return address | |
d57a4725 CF |
495 | leave: xorl %eax,%eax |
496 | movl %eax,$tls::incyg(%ebx) | |
497 | movl %eax,$tls::stacklock(%ebx) # unlock | |
56d06b9a CF |
498 | |
499 | popl %eax | |
500 | popl %ebx | |
501 | popl %ecx | |
502 | popl %edx | |
503 | popl %edi | |
504 | popl %esi | |
505 | popf | |
506 | ret | |
507 | ||
6e75c72b CF |
508 | .global __ZN7_cygtls3popEv\@4 |
509 | __ZN7_cygtls3popEv\@4: | |
6946073e | 510 | 1: pushl %ebx |
3a7c5515 CF |
511 | movl %eax,%ebx # this |
512 | movl \$-4,%eax | |
513 | xadd %eax,$tls::pstackptr(%ebx) | |
0b6fbd39 | 514 | movl -4(%eax),%eax |
6946073e | 515 | popl %ebx |
9a4d574b CF |
516 | ret |
517 | ||
9873ac53 | 518 | # _cygtls::lock |
6e75c72b CF |
519 | .global __ZN7_cygtls4lockEv\@4 |
520 | __ZN7_cygtls4lockEv\@4: | |
7ea8e226 CF |
521 | pushl %ebx |
522 | movl %eax,%ebx | |
6946073e | 523 | 1: movl \$1,%eax |
3a7c5515 | 524 | xchgl %eax,$tls::pstacklock(%ebx) |
3a1ccfc8 | 525 | testl %eax,%eax |
6946073e | 526 | jz 2f |
084ea510 | 527 | call _yield |
6946073e | 528 | jmp 1b |
7ea8e226 | 529 | 2: popl %ebx |
6946073e CF |
530 | ret |
531 | ||
9873ac53 | 532 | # _cygtls::unlock |
6e75c72b CF |
533 | .global __ZN7_cygtls6unlockEv\@4 |
534 | __ZN7_cygtls6unlockEv\@4: | |
6946073e CF |
535 | decl $tls::pstacklock(%eax) |
536 | ret | |
537 | ||
e431827c CF |
538 | .global __ZN7_cygtls6lockedEv |
539 | __ZN7_cygtls6lockedEv: | |
540 | movl $tls::pstacklock(%eax),%eax | |
541 | ret | |
542 | ||
6e75c72b | 543 | .extern __ZN7_cygtls19call_signal_handlerEv\@4 |
08b0a057 | 544 | stabilize_sig_stack: |
7ea8e226 | 545 | movl %fs:4,%ebx |
7ea8e226 | 546 | 1: movl \$1,%eax |
3a7c5515 | 547 | xchgl %eax,$tls::stacklock(%ebx) |
7ea8e226 | 548 | movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock |
3a1ccfc8 | 549 | testl %eax,%eax |
08b0a057 | 550 | jz 2f |
084ea510 | 551 | call _yield |
08b0a057 | 552 | jmp 1b |
0b6fbd39 CF |
553 | 2: incl $tls::incyg(%ebx) |
554 | cmpl \$0,$tls::sig(%ebx) | |
08b0a057 | 555 | jz 3f |
7ea8e226 | 556 | decl $tls::stacklock(%ebx) # unlock |
dd063819 | 557 | movl \$$tls::start_offset,%eax # point to beginning |
7ea8e226 | 558 | addl %ebx,%eax # of tls block |
6e75c72b | 559 | call __ZN7_cygtls19call_signal_handlerEv\@4 |
08b0a057 | 560 | jmp 1b |
7ea8e226 | 561 | 3: decl $tls::incyg(%ebx) |
5fb0fe79 | 562 | ret |
9a4d574b | 563 | EOF |
61522196 | 564 | } |
9a4d574b CF |
565 | } |
566 | return $res; | |
567 | } | |
568 | ||
569 | sub longjmp { | |
61522196 CV |
570 | if ($is64bit) { |
571 | return <<EOF; | |
572 | ||
573 | .globl setjmp | |
574 | .seh_proc setjmp | |
575 | setjmp: | |
576 | .seh_endprologue | |
577 | # We use the Windows jmp_buf layout. Store ExceptionList in Frame. | |
578 | # Store alternative stackptr in Spare. | |
579 | movq %gs:0,%r10 | |
580 | movq %r10,(%rcx) | |
581 | movq %rbx,0x8(%rcx) | |
582 | movq %rsp,0x10(%rcx) | |
583 | movq %rbp,0x18(%rcx) | |
584 | movq %rsi,0x20(%rcx) | |
585 | movq %rdi,0x28(%rcx) | |
586 | movq %r12,0x30(%rcx) | |
587 | movq %r13,0x38(%rcx) | |
588 | movq %r14,0x40(%rcx) | |
589 | movq %r15,0x48(%rcx) | |
590 | movq (%rsp),%r10 | |
591 | movq %r10,0x50(%rcx) | |
592 | # jmp_buf is potentially unaligned! | |
593 | movdqu %xmm6,0x60(%rcx) | |
594 | movdqu %xmm7,0x70(%rcx) | |
595 | movdqu %xmm8,0x80(%rcx) | |
596 | movdqu %xmm9,0x90(%rcx) | |
597 | movdqu %xmm10,0xa0(%rcx) | |
598 | movdqu %xmm11,0xb0(%rcx) | |
599 | movdqu %xmm12,0xc0(%rcx) | |
600 | movdqu %xmm13,0xd0(%rcx) | |
601 | movdqu %xmm14,0xe0(%rcx) | |
602 | movdqu %xmm15,0xf0(%rcx) | |
603 | pushq %rcx | |
604 | .seh_pushreg %rcx | |
605 | call stabilize_sig_stack # returns tls in r11 | |
606 | popq %rcx | |
607 | movq $tls::stackptr(%r11),%r10 | |
608 | movq %r10,0x58(%rcx) | |
609 | decl $tls::stacklock(%r11) | |
610 | movl \$0,%eax | |
611 | ret | |
612 | .seh_endproc | |
613 | ||
614 | .globl __sjfault | |
615 | .seh_proc __sjfault | |
616 | __sjfault: | |
617 | .seh_endprologue | |
618 | # Like setjmp, just w/o storing the alternate stackptr. | |
619 | movq %gs:0,%r10 | |
620 | movq %r10,(%rcx) | |
621 | movq %rbx,0x8(%rcx) | |
622 | movq %rsp,0x10(%rcx) | |
623 | movq %rbp,0x18(%rcx) | |
624 | movq %rsi,0x20(%rcx) | |
625 | movq %rdi,0x28(%rcx) | |
626 | movq %r12,0x30(%rcx) | |
627 | movq %r13,0x38(%rcx) | |
628 | movq %r14,0x40(%rcx) | |
629 | movq %r15,0x48(%rcx) | |
630 | movq (%rsp),%r10 | |
631 | movq %r10,0x50(%rcx) | |
632 | # jmp_buf is potentially unaligned! | |
633 | movdqu %xmm6,0x60(%rcx) | |
634 | movdqu %xmm7,0x70(%rcx) | |
635 | movdqu %xmm8,0x80(%rcx) | |
636 | movdqu %xmm9,0x90(%rcx) | |
637 | movdqu %xmm10,0xa0(%rcx) | |
638 | movdqu %xmm11,0xb0(%rcx) | |
639 | movdqu %xmm12,0xc0(%rcx) | |
640 | movdqu %xmm13,0xd0(%rcx) | |
641 | movdqu %xmm14,0xe0(%rcx) | |
642 | movdqu %xmm15,0xf0(%rcx) | |
643 | movl \$0,%eax | |
644 | ret | |
645 | .seh_endproc | |
646 | ||
647 | .globl __ljfault | |
648 | .seh_proc __ljfault | |
649 | __ljfault: | |
650 | movq (%rcx),%r10 | |
651 | movq %r10,%gs:0 | |
652 | movq 0x8(%rcx),%rbx | |
653 | movq 0x10(%rcx),%rsp | |
654 | movq 0x18(%rcx),%rbp | |
655 | movq 0x20(%rcx),%rsi | |
656 | movq 0x28(%rcx),%rdi | |
657 | movq 0x30(%rcx),%r12 | |
658 | movq 0x38(%rcx),%r13 | |
659 | movq 0x40(%rcx),%r14 | |
660 | movq 0x48(%rcx),%r15 | |
661 | movq 0x50(%rcx),%r10 | |
662 | movq %r10,(%rsp) | |
663 | # jmp_buf is potentially unaligned! | |
664 | movdqu 0x60(%rcx),%xmm6 | |
665 | movdqu 0x70(%rcx),%xmm7 | |
666 | movdqu 0x80(%rcx),%xmm8 | |
667 | movdqu 0x90(%rcx),%xmm9 | |
668 | movdqu 0xa0(%rcx),%xmm10 | |
669 | movdqu 0xb0(%rcx),%xmm11 | |
670 | movdqu 0xc0(%rcx),%xmm12 | |
671 | movdqu 0xd0(%rcx),%xmm13 | |
672 | movdqu 0xe0(%rcx),%xmm14 | |
673 | movdqu 0xf0(%rcx),%xmm15 | |
674 | movl %edx,%eax | |
675 | testl %eax,%eax | |
676 | jne 0f | |
677 | incl %eax | |
678 | 0: ret | |
679 | .seh_endproc | |
680 | ||
681 | .globl longjmp | |
682 | .seh_proc longjmp | |
683 | longjmp: | |
684 | pushq %rcx | |
685 | .seh_pushreg %rcx | |
686 | .seh_endprologue | |
687 | movl %edx,%r12d # save return value (r12 is overwritten anyway) | |
688 | call stabilize_sig_stack # returns tls in r11 | |
689 | popq %rcx | |
690 | movl %r12d,%eax # restore return value | |
691 | movq 0x58(%rcx),%r10 # get old signal stack | |
692 | movq %r10,$tls::stackptr(%r11) # restore | |
693 | decl $tls::stacklock(%r11) # relinquish lock | |
694 | xorl %r10d,%r10d | |
695 | movl %r10d,$tls::incyg(%r11) # we're definitely not in cygwin anymore | |
696 | movq (%rcx),%r10 | |
697 | movq %r10,%gs:0 | |
698 | movq 0x8(%rcx),%rbx | |
699 | movq 0x10(%rcx),%rsp | |
700 | movq 0x18(%rcx),%rbp | |
701 | movq 0x20(%rcx),%rsi | |
702 | movq 0x28(%rcx),%rdi | |
703 | movq 0x30(%rcx),%r12 | |
704 | movq 0x38(%rcx),%r13 | |
705 | movq 0x40(%rcx),%r14 | |
706 | movq 0x48(%rcx),%r15 | |
707 | movq 0x50(%rcx),%r10 | |
708 | movq %r10,(%rsp) | |
709 | # jmp_buf is potentially unaligned! | |
710 | movdqu 0x60(%rcx),%xmm6 | |
711 | movdqu 0x70(%rcx),%xmm7 | |
712 | movdqu 0x80(%rcx),%xmm8 | |
713 | movdqu 0x90(%rcx),%xmm9 | |
714 | movdqu 0xa0(%rcx),%xmm10 | |
715 | movdqu 0xb0(%rcx),%xmm11 | |
716 | movdqu 0xc0(%rcx),%xmm12 | |
717 | movdqu 0xd0(%rcx),%xmm13 | |
718 | movdqu 0xe0(%rcx),%xmm14 | |
719 | movdqu 0xf0(%rcx),%xmm15 | |
720 | testl %eax,%eax | |
721 | jne 0f | |
722 | incl %eax | |
723 | 0: ret | |
724 | .seh_endproc | |
725 | EOF | |
726 | } else { | |
727 | return <<EOF; | |
9a4d574b | 728 | |
c461fbf1 | 729 | .globl _setjmp |
2d6c4a1a | 730 | _setjmp: |
9a4d574b CF |
731 | pushl %ebp |
732 | movl %esp,%ebp | |
2d6c4a1a | 733 | pushl %edi |
9a4d574b | 734 | movl 8(%ebp),%edi |
2d6c4a1a CF |
735 | movl %eax,0(%edi) |
736 | movl %ebx,4(%edi) | |
737 | movl %ecx,8(%edi) | |
738 | movl %edx,12(%edi) | |
739 | movl %esi,16(%edi) | |
740 | movl -4(%ebp),%eax | |
741 | movl %eax,20(%edi) | |
742 | movl 0(%ebp),%eax | |
743 | movl %eax,24(%edi) | |
744 | movl %esp,%eax | |
745 | addl \$12,%eax | |
746 | movl %eax,28(%edi) | |
747 | movl 4(%ebp),%eax | |
748 | movl %eax,32(%edi) | |
749 | movw %es,%ax | |
750 | movw %ax,36(%edi) | |
751 | movw %fs,%ax | |
752 | movw %ax,38(%edi) | |
753 | movw %gs,%ax | |
754 | movw %ax,40(%edi) | |
755 | movw %ss,%ax | |
756 | movw %ax,42(%edi) | |
813767de CF |
757 | movl %fs:0,%eax |
758 | movl %eax,44(%edi) | |
7ea8e226 | 759 | pushl %ebx |
2d6c4a1a | 760 | call stabilize_sig_stack |
7ea8e226 CF |
761 | movl $tls::stackptr(%ebx),%eax # save stack pointer contents |
762 | decl $tls::stacklock(%ebx) | |
763 | popl %ebx | |
813767de | 764 | movl %eax,48(%edi) |
2d6c4a1a CF |
765 | popl %edi |
766 | movl \$0,%eax | |
767 | leave | |
768 | ret | |
769 | ||
c461fbf1 CF |
770 | .globl ___sjfault |
771 | ___sjfault: | |
772 | pushl %ebp | |
773 | movl %esp,%ebp | |
774 | pushl %edi | |
775 | movl 8(%ebp),%edi | |
776 | movl %eax,0(%edi) | |
777 | movl %ebx,4(%edi) | |
778 | movl %ecx,8(%edi) | |
779 | movl %edx,12(%edi) | |
780 | movl %esi,16(%edi) | |
781 | movl -4(%ebp),%eax | |
782 | movl %eax,20(%edi) | |
783 | movl 0(%ebp),%eax | |
784 | movl %eax,24(%edi) | |
785 | movl %esp,%eax | |
786 | addl \$12,%eax | |
787 | movl %eax,28(%edi) | |
788 | movl 4(%ebp),%eax | |
789 | movl %eax,32(%edi) | |
790 | movw %es,%ax | |
791 | movw %ax,36(%edi) | |
792 | movw %fs,%ax | |
793 | movw %ax,38(%edi) | |
794 | movw %gs,%ax | |
795 | movw %ax,40(%edi) | |
796 | movw %ss,%ax | |
797 | movw %ax,42(%edi) | |
813767de CF |
798 | movl %fs:0,%eax |
799 | movl %eax,44(%edi) | |
c461fbf1 CF |
800 | popl %edi |
801 | movl \$0,%eax | |
802 | leave | |
803 | ret | |
804 | ||
805 | .global ___ljfault | |
806 | ___ljfault: | |
807 | pushl %ebp | |
808 | movl %esp,%ebp | |
809 | movl 8(%ebp),%edi | |
810 | ||
811 | movl 12(%ebp),%eax | |
812 | testl %eax,%eax | |
813 | jne 0f | |
814 | incl %eax | |
815 | ||
816 | 0: movl %eax,0(%edi) | |
817 | movl 24(%edi),%ebp | |
818 | pushfl | |
819 | popl %ebx | |
813767de CF |
820 | movl 44(%edi),%eax |
821 | movl %eax,%fs:0 | |
c461fbf1 CF |
822 | movw 42(%edi),%ax |
823 | movw %ax,%ss | |
824 | movl 28(%edi),%esp | |
825 | pushl 32(%edi) | |
826 | pushl %ebx | |
827 | movw 36(%edi),%ax | |
828 | movw %ax,%es | |
829 | movw 40(%edi),%ax | |
830 | movw %ax,%gs | |
831 | movl 0(%edi),%eax | |
832 | movl 4(%edi),%ebx | |
833 | movl 8(%edi),%ecx | |
834 | movl 16(%edi),%esi | |
835 | movl 12(%edi),%edx | |
836 | movl 20(%edi),%edi | |
837 | popfl | |
838 | ret | |
839 | ||
2d6c4a1a CF |
840 | .globl _longjmp |
841 | _longjmp: | |
842 | pushl %ebp | |
843 | movl %esp,%ebp | |
844 | movl 8(%ebp),%edi # address of buffer | |
845 | call stabilize_sig_stack | |
813767de | 846 | movl 48(%edi),%eax # get old signal stack |
7ea8e226 CF |
847 | movl %eax,$tls::stackptr(%ebx) # restore |
848 | decl $tls::stacklock(%ebx) # relinquish lock | |
09b01096 CF |
849 | xorl %eax,%eax |
850 | movl %eax,$tls::incyg(%ebx) # we're definitely not in cygwin anymore | |
2d6c4a1a | 851 | |
9a4d574b CF |
852 | movl 12(%ebp),%eax |
853 | testl %eax,%eax | |
e431827c | 854 | jne 3f |
9a4d574b | 855 | incl %eax |
e431827c CF |
856 | |
857 | 3: movl %eax,0(%edi) | |
9a4d574b CF |
858 | movl 24(%edi),%ebp |
859 | pushfl | |
860 | popl %ebx | |
813767de CF |
861 | movl 44(%edi),%eax |
862 | movl %eax,%fs:0 | |
9a4d574b CF |
863 | movw 42(%edi),%ax |
864 | movw %ax,%ss | |
865 | movl 28(%edi),%esp | |
866 | pushl 32(%edi) | |
867 | pushl %ebx | |
868 | movw 36(%edi),%ax | |
869 | movw %ax,%es | |
870 | movw 40(%edi),%ax | |
871 | movw %ax,%gs | |
9a4d574b CF |
872 | movl 0(%edi),%eax |
873 | movl 4(%edi),%ebx | |
874 | movl 8(%edi),%ecx | |
9a4d574b | 875 | movl 16(%edi),%esi |
e431827c | 876 | movl 12(%edi),%edx |
9a4d574b CF |
877 | movl 20(%edi),%edi |
878 | popfl | |
879 | ret | |
9a4d574b | 880 | EOF |
61522196 | 881 | } |
9a4d574b | 882 | } |
efc7accc | 883 | |
91000b5d | 884 | sub cleanup(@) { |
efc7accc | 885 | map {s/\r//g; $_} @_; |
91000b5d CF |
886 | map {s/#.*//g; $_} @_; |
887 | map {s/[ \t]+$//g; $_} @_; | |
efc7accc | 888 | } |