2 # Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010 Red Hat, Inc.
4 # This file is part of Cygwin.
6 # This software is a copyrighted work licensed under the terms of the
7 # Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 my $tls_offsets = shift;
19 if (!defined($in) || !defined($out) || !defined($sigfe)) {
20 die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n";
25 open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
28 push(@top, cleanup $_);
29 last if /^\s*exports\s*$/i;
31 my $libline = cleanup scalar(<IN>);
32 my @in = cleanup <IN>;
46 if (s/\s+NOSIGFE\s*$//) {
48 } elsif (s/ SIGFE(_MAYBE)?$//) {
49 my $func = (split(' '))[2];
50 my $maybe = lc $1 . '_';
51 $sigfe{$func} = '_sigfe' . $maybe . $func;
54 my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGFE(?:_MAYBE)?))?$%o;
55 if (defined($sigfe) && $sigfe =~ /^NO/o) {
59 $_ = '_' . lc($sigfe) . '_' . $func;
61 $_ = $func . ' = ' . $_;
64 s/(\S)\s+(\S)/$1 $2/go;
71 my ($alias, $func) = /^(\S+) = (\S+)\s*$/o;
72 $_ = $alias . ' = ' . $sigfe{$func}
73 if defined($func) && $sigfe{$func};
76 open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n";
77 push @top, (map {$_ . " DATA\n"} @data), (map {$_ . "\n"} @text);
81 open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n";
83 for my $k (sort keys %sigfe) {
84 print SIGFE fefunc($k, $sigfe{$k});
89 my $func = '_' . shift;
91 my $sigfe_func = ($fe =~ /^(.*)$func/)[0];
101 if (!$main::first++) {
102 $res = <<EOF . longjmp () . $res;
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?
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
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
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
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
166 incl $tls::incyg(%ebx)
167 addl \$12,%esp # remove arguments
168 call _set_process_mask\@4
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
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
182 3: movl \$-4,%eax # now decrement aux stack
183 xadd %eax,$tls::stackptr(%ebx) # and get pointer
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
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
223 2: incl $tls::incyg(%ebx)
224 pushl $tls::saved_errno(%ebx) # saved errno
225 call _set_process_mask_delta
228 # fill out handler arguments
229 xorl %eax,%eax # ucontext_t (currently not set)
231 leal $tls::infodata(%ebx),%eax
233 pushl $tls::sig(%ebx) # signal number
235 call _reset_signal_arrived\@0
236 pushl \$_sigreturn # where to return
237 pushl $tls::func(%ebx) # user-supplied signal func
238 cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal?
239 jnz 4f # yes. callee clears signal number
240 movl \$0,$tls::sig(%ebx) # zero the signal number as a
241 # flag to the signal handler thread
242 # that it is ok to set up sigsave
243 4: decl $tls::incyg(%ebx)
244 decl $tls::stacklock(%ebx)
245 ret # return via signal handler
247 .global __ZN7_cygtls3popEv
250 movl %eax,%ebx # this
252 xadd %eax,$tls::pstackptr(%ebx)
257 .global __ZN7_cygtls4lockEv
262 xchgl %eax,$tls::pstacklock(%ebx)
270 .global __ZN7_cygtls6unlockEv
271 __ZN7_cygtls6unlockEv:
272 decl $tls::pstacklock(%eax)
275 .global __ZN7_cygtls6lockedEv
276 __ZN7_cygtls6lockedEv:
277 movl $tls::pstacklock(%eax),%eax
280 .extern __ZN7_cygtls19call_signal_handlerEv
284 xchgl %eax,$tls::stacklock(%ebx)
285 movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
290 2: incl $tls::incyg(%ebx)
291 cmpl \$0,$tls::sig(%ebx)
293 decl $tls::stacklock(%ebx) # unlock
294 movl \$-$tls::sizeof__cygtls,%eax # point to beginning
295 addl %ebx,%eax # of tls block
296 call __ZN7_cygtls19call_signal_handlerEv
298 3: decl $tls::incyg(%ebx)
339 call stabilize_sig_stack
340 movl $tls::stackptr(%ebx),%eax # save stack pointer contents
341 decl $tls::stacklock(%ebx)
423 movl 8(%ebp),%edi # address of buffer
424 call stabilize_sig_stack
425 movl 48(%edi),%eax # get old signal stack
426 movl %eax,$tls::stackptr(%ebx) # restore
427 decl $tls::stacklock(%ebx) # relinquish lock
429 movl %eax,$tls::incyg(%ebx) # we're definitely not in cygwin anymore
463 map {s/\r//g; $_} @_;
464 map {s/#.*//g; $_} @_;
465 map {s/[ \t]+$//g; $_} @_;