OSDN Git Service

Rename cygWFMO to cygwait throughout and use the magic of polymorphism to "wait
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / gendef
1 #!/usr/bin/perl
2 # Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010 Red Hat, Inc.
3 #
4 # This file is part of Cygwin.
5 #
6 # This software is a copyrighted work licensed under the terms of the
7 # Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
8 # details.
9 #
10 use strict;
11 sub cleanup(@);
12
13 my $in = shift;
14 my $tls_offsets = shift;
15 my $out = shift;
16 my $sigfe = shift;
17
18 $main::first = 0;
19 if (!defined($in) || !defined($out) || !defined($sigfe)) {
20     die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n";
21 }
22
23 require $tls_offsets;
24
25 open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
26 my @top = ();
27 while (<IN>) {
28     push(@top, cleanup $_);
29     last if /^\s*exports\s*$/i;
30 }
31 my $libline = cleanup scalar(<IN>);
32 my @in = cleanup <IN>;
33 close(IN);
34
35 my %sigfe = ();
36 my @data = ();
37 my @nosigfuncs = ();
38 my @text = ();
39 for (@in) {
40     chomp;
41     s/\sDATA$//o and do {
42         push @data, $_;
43         next;
44     };
45     if (/=/o) {
46         if (s/\s+NOSIGFE\s*$//) {
47             # nothing
48         } elsif (s/ SIGFE(_MAYBE)?$//) {
49             my $func = (split(' '))[2];
50             my $maybe = lc $1 . '_';
51             $sigfe{$func} = '_sigfe' . $maybe . $func;
52         }
53     } else {
54         my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGFE(?:_MAYBE)?))?$%o;
55         if (defined($sigfe) && $sigfe =~ /^NO/o) {
56             $_ = $func;
57         } else {
58             $sigfe ||= 'sigfe';
59             $_ = '_' . lc($sigfe) . '_' . $func;
60             $sigfe{$func} = $_;
61             $_ = $func . ' = ' . $_;
62         }
63     }
64     s/(\S)\s+(\S)/$1 $2/go;
65     s/(\S)\s+$/$1/o;
66     s/^\s+(\S)/$1/o;
67     push @text, $_;
68 }
69
70 for (@text) {
71     my ($alias, $func) = /^(\S+) = (\S+)\s*$/o;
72     $_ = $alias . ' = ' . $sigfe{$func}
73       if defined($func) && $sigfe{$func};
74 }
75
76 open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n";
77 push @top, (map {$_ . " DATA\n"} @data), (map {$_ . "\n"} @text);
78 print OUT @top;
79 close OUT;
80
81 open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n";
82
83 for my $k (sort keys %sigfe) {
84     print SIGFE fefunc($k, $sigfe{$k});
85 }
86 close SIGFE;
87
88 sub fefunc {
89     my $func = '_' . shift;
90     my $fe = '_' . shift;
91     my $sigfe_func = ($fe =~ /^(.*)$func/)[0];
92     my $extra;
93     my $res = <<EOF;
94         .extern $func
95         .global $fe
96 $fe:
97         pushl   \$$func
98         jmp     $sigfe_func
99
100 EOF
101     if (!$main::first++) {
102         $res = <<EOF . longjmp () . $res;
103         .text
104
105 __sigfe_maybe:
106         pushl   %ebx
107         pushl   %edx
108         movl    %fs:4,%ebx                              # location of bottom of stack
109         addl    \$$tls::initialized,%ebx                # where we will be looking
110         cmpl    %ebx,%esp                               # stack loc > than tls
111         jge     0f                                      # yep.  we don't have a tls.
112         subl    \$$tls::initialized,%ebx                # where we will be looking
113         movl    $tls::initialized(%ebx),%eax
114         cmpl    \$0xc763173f,%eax                       # initialized?
115         je      1f
116 0:      popl    %edx
117         popl    %ebx
118         ret
119
120 __sigfe:
121         pushl   %ebx
122         pushl   %edx
123         movl    %fs:4,%ebx                              # location of bottom of stack
124 1:      movl    \$1,%eax                                # potential lock value
125         xchgl   %eax,$tls::stacklock(%ebx)              # see if we can grab it
126         movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
127         testl   %eax,%eax                               # it will be zero
128         jz      2f                                      #  if so
129         call    _yield                                  # should be a short-time thing, so
130         jmp     1b                                      # sleep and loop
131 2:      movl    \$4,%eax                                # have the lock, now increment the
132         xadd    %eax,$tls::stackptr(%ebx)               #  stack pointer and get pointer
133         leal    __sigbe,%edx                            # new place to return to
134         xchgl   %edx,12(%esp)                           # exchange with real return value
135         movl    %edx,(%eax)                             # store real return value on alt stack
136         incl    $tls::incyg(%ebx)
137         decl    $tls::stacklock(%ebx)                   # remove lock
138         popl    %edx                                    # restore saved value
139         popl    %ebx
140         ret
141
142         .global __sigbe
143 __sigbe:                                                # return here after cygwin syscall
144         pushl   %eax                                    # don't clobber
145         pushl   %ebx                                    # tls pointer
146 1:      movl    %fs:4,%ebx                              # address of bottom of tls
147         movl    \$1,%eax                                # potential lock value
148         xchgl   %eax,$tls::stacklock(%ebx)              # see if we can grab it
149         movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
150         testl   %eax,%eax                               # it will be zero
151         jz      2f                                      #  if so
152         call    _yield                                  # sleep
153         jmp     1b                                      #  and loop
154 2:      movl    \$-4,%eax                               # now decrement aux stack
155         xadd    %eax,$tls::stackptr(%ebx)               #  and get pointer
156         movl    -4(%eax),%eax                           # get return address from signal stack
157         xchgl   %eax,4(%esp)                            # swap return address with saved eax
158         decl    $tls::incyg(%ebx)
159         decl    $tls::stacklock(%ebx)                   # release lock
160         popl    %ebx
161         ret
162
163         .global _sigreturn
164 _sigreturn:
165         movl    %fs:4,%ebx
166         incl    $tls::incyg(%ebx)
167         addl    \$12,%esp                               # remove arguments
168         call    _set_process_mask\@4
169
170 1:      movl    \$1,%eax                                # potential lock value
171         xchgl   %eax,$tls::stacklock(%ebx)              # see if we can grab it
172         movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
173         testl   %eax,%eax                               # it will be zero
174         jz      2f                                      #  if so
175         call    _yield                                  # sleep
176         jmp     1b                                      #  and loop
177 2:      popl    %edx                                    # saved errno
178         testl   %edx,%edx                               # Is it < 0
179         jl      3f                                      # yup.  ignore it
180         movl    $tls::errno_addr(%ebx),%eax
181         movl    %edx,(%eax)
182 3:      movl    \$-4,%eax                               # now decrement aux stack
183         xadd    %eax,$tls::stackptr(%ebx)               #  and get pointer
184         xorl    %ebp,%ebp
185         xchgl   %ebp,-4(%eax)                           # get return address from signal stack
186         xchgl   %ebp,28(%esp)                           # store real return address
187         decl    $tls::incyg(%ebx)
188         decl    $tls::stacklock(%ebx)                   # unlock
189
190         popl    %eax
191         popl    %ebx
192         popl    %ecx
193         popl    %edx
194         popl    %edi
195         popl    %esi
196         popf
197         ret
198
199         .global _sigdelayed
200 _sigdelayed:
201         pushl   %ebp
202         movl    %esp,%ebp
203         pushf
204         pushl   %esi
205         pushl   %edi
206         pushl   %edx
207         pushl   %ecx
208         pushl   %ebx
209         pushl   %eax
210         movl    %fs:4,%ebx
211 1:      movl    \$1,%eax
212         xchgl   %eax,$tls::stacklock(%ebx)
213         movl    %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
214                                           # If %eax is 1 then someone else has
215                                           # the lock but we want to flag that
216                                           # we're waiting for it.  If %eax is 0
217                                           # then we're not spinning and 0 will
218                                           # reflect that.
219         testl   %eax,%eax
220         jz      2f
221         call    _yield
222         jmp     1b
223 2:      incl    $tls::incyg(%ebx)
224         pushl   $tls::saved_errno(%ebx) # saved errno
225         call    _set_process_mask_delta
226         pushl   %eax
227
228         # fill out handler arguments
229         xorl    %eax,%eax               # ucontext_t (currently not set)
230         pushl   %eax
231         leal    $tls::infodata(%ebx),%eax
232         pushl   %eax                    # siginfo
233         pushl   $tls::sig(%ebx)         # signal number
234
235         pushl   \$_sigreturn            # where to return
236         pushl   $tls::func(%ebx)        # user-supplied signal func
237         cmpl    \$0,$tls::threadkill(%ebx)#pthread_kill signal?
238         jnz     4f                      # yes.  callee clears signal number
239         movl    \$0,$tls::sig(%ebx)     # zero the signal number as a
240                                         # flag to the signal handler thread
241                                         # that it is ok to set up sigsave
242 4:      decl    $tls::incyg(%ebx)
243         decl    $tls::stacklock(%ebx)
244         ret                             # return via signal handler
245
246         .global __ZN7_cygtls3popEv
247 __ZN7_cygtls3popEv:
248 1:      pushl   %ebx
249         movl    %eax,%ebx                       # this
250         movl    \$-4,%eax
251         xadd    %eax,$tls::pstackptr(%ebx)
252         movl    -4(%eax),%eax
253         popl    %ebx
254         ret
255
256         .global __ZN7_cygtls4lockEv
257 __ZN7_cygtls4lockEv:
258         pushl   %ebx
259         movl    %eax,%ebx
260 1:      movl    \$1,%eax
261         xchgl   %eax,$tls::pstacklock(%ebx)
262         testl   %eax,%eax
263         jz      2f
264         call    _yield
265         jmp     1b
266 2:      popl    %ebx
267         ret
268
269         .global __ZN7_cygtls6unlockEv
270 __ZN7_cygtls6unlockEv:
271         decl    $tls::pstacklock(%eax)
272         ret
273
274         .global __ZN7_cygtls6lockedEv
275 __ZN7_cygtls6lockedEv:
276         movl    $tls::pstacklock(%eax),%eax
277         ret
278
279         .extern __ZN7_cygtls19call_signal_handlerEv
280 stabilize_sig_stack:
281         movl    %fs:4,%ebx
282 1:      movl    \$1,%eax
283         xchgl   %eax,$tls::stacklock(%ebx)
284         movl    %eax,$tls::spinning(%ebx)               # flag if we are waiting for lock
285         testl   %eax,%eax
286         jz      2f
287         call    _yield
288         jmp     1b
289 2:      incl    $tls::incyg(%ebx)
290         cmpl    \$0,$tls::sig(%ebx)
291         jz      3f
292         decl    $tls::stacklock(%ebx)                   # unlock
293         movl    \$-$tls::sizeof__cygtls,%eax            # point to beginning
294         addl    %ebx,%eax                               #  of tls block
295         call    __ZN7_cygtls19call_signal_handlerEv
296         jmp     1b
297 3:      decl    $tls::incyg(%ebx)
298         ret
299 EOF
300     }
301     return $res;
302 }
303
304 sub longjmp {
305     return <<EOF;
306
307         .globl  _setjmp
308 _setjmp:
309         pushl   %ebp
310         movl    %esp,%ebp
311         pushl   %edi
312         movl    8(%ebp),%edi
313         movl    %eax,0(%edi)
314         movl    %ebx,4(%edi)
315         movl    %ecx,8(%edi)
316         movl    %edx,12(%edi)
317         movl    %esi,16(%edi)
318         movl    -4(%ebp),%eax
319         movl    %eax,20(%edi)
320         movl    0(%ebp),%eax
321         movl    %eax,24(%edi)
322         movl    %esp,%eax
323         addl    \$12,%eax
324         movl    %eax,28(%edi)
325         movl    4(%ebp),%eax
326         movl    %eax,32(%edi)
327         movw    %es,%ax
328         movw    %ax,36(%edi)
329         movw    %fs,%ax
330         movw    %ax,38(%edi)
331         movw    %gs,%ax
332         movw    %ax,40(%edi)
333         movw    %ss,%ax
334         movw    %ax,42(%edi)
335         movl    %fs:0,%eax
336         movl    %eax,44(%edi)
337         pushl   %ebx
338         call    stabilize_sig_stack
339         movl    $tls::stackptr(%ebx),%eax               # save stack pointer contents
340         decl    $tls::stacklock(%ebx)
341         popl    %ebx
342         movl    %eax,48(%edi)
343         popl    %edi
344         movl    \$0,%eax
345         leave
346         ret
347
348         .globl  ___sjfault
349 ___sjfault:
350         pushl   %ebp
351         movl    %esp,%ebp
352         pushl   %edi
353         movl    8(%ebp),%edi
354         movl    %eax,0(%edi)
355         movl    %ebx,4(%edi)
356         movl    %ecx,8(%edi)
357         movl    %edx,12(%edi)
358         movl    %esi,16(%edi)
359         movl    -4(%ebp),%eax
360         movl    %eax,20(%edi)
361         movl    0(%ebp),%eax
362         movl    %eax,24(%edi)
363         movl    %esp,%eax
364         addl    \$12,%eax
365         movl    %eax,28(%edi)
366         movl    4(%ebp),%eax
367         movl    %eax,32(%edi)
368         movw    %es,%ax
369         movw    %ax,36(%edi)
370         movw    %fs,%ax
371         movw    %ax,38(%edi)
372         movw    %gs,%ax
373         movw    %ax,40(%edi)
374         movw    %ss,%ax
375         movw    %ax,42(%edi)
376         movl    %fs:0,%eax
377         movl    %eax,44(%edi)
378         popl    %edi
379         movl    \$0,%eax
380         leave
381         ret
382
383         .global ___ljfault
384 ___ljfault:
385         pushl   %ebp
386         movl    %esp,%ebp
387         movl    8(%ebp),%edi
388
389         movl    12(%ebp),%eax
390         testl   %eax,%eax
391         jne     0f
392         incl    %eax
393
394 0:      movl    %eax,0(%edi)
395         movl    24(%edi),%ebp
396         pushfl
397         popl    %ebx
398         movl    44(%edi),%eax
399         movl    %eax,%fs:0
400         movw    42(%edi),%ax
401         movw    %ax,%ss
402         movl    28(%edi),%esp
403         pushl   32(%edi)
404         pushl   %ebx
405         movw    36(%edi),%ax
406         movw    %ax,%es
407         movw    40(%edi),%ax
408         movw    %ax,%gs
409         movl    0(%edi),%eax
410         movl    4(%edi),%ebx
411         movl    8(%edi),%ecx
412         movl    16(%edi),%esi
413         movl    12(%edi),%edx
414         movl    20(%edi),%edi
415         popfl
416         ret
417
418         .globl  _longjmp
419 _longjmp:
420         pushl   %ebp
421         movl    %esp,%ebp
422         movl    8(%ebp),%edi                            # address of buffer
423         call    stabilize_sig_stack
424         movl    48(%edi),%eax                           # get old signal stack
425         movl    %eax,$tls::stackptr(%ebx)               # restore
426         decl    $tls::stacklock(%ebx)                   # relinquish lock
427         xorl    %eax,%eax
428         movl    %eax,$tls::incyg(%ebx)                  # we're definitely not in cygwin anymore
429
430         movl    12(%ebp),%eax
431         testl   %eax,%eax
432         jne     3f
433         incl    %eax
434
435 3:      movl    %eax,0(%edi)
436         movl    24(%edi),%ebp
437         pushfl
438         popl    %ebx
439         movl    44(%edi),%eax
440         movl    %eax,%fs:0
441         movw    42(%edi),%ax
442         movw    %ax,%ss
443         movl    28(%edi),%esp
444         pushl   32(%edi)
445         pushl   %ebx
446         movw    36(%edi),%ax
447         movw    %ax,%es
448         movw    40(%edi),%ax
449         movw    %ax,%gs
450         movl    0(%edi),%eax
451         movl    4(%edi),%ebx
452         movl    8(%edi),%ecx
453         movl    16(%edi),%esi
454         movl    12(%edi),%edx
455         movl    20(%edi),%edi
456         popfl
457         ret
458 EOF
459 }
460
461 sub cleanup(@) {
462     map {s/\r//g; $_} @_;
463     map {s/#.*//g; $_} @_;
464     map {s/[ \t]+$//g; $_} @_;
465 }