Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gendef « cygwin « winsup - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2457314b278a9d70b4485adaeb6d330fa56ba52d (plain)
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#!/usr/bin/perl
use strict;
my $in = shift;
my $tls_offsets = shift;
my $out = shift;
my $sigfe = shift;

$main::first = 0;
if (!defined($in) || !defined($out) || !defined($sigfe)) {
    die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n";
}

require $tls_offsets;

open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
my @top = ();
while (<IN>) {
    push(@top, $_);
    last if /^\s*exports\s*$/i;
}
my $libline = <IN>;
my @in = <IN>;
close(IN);

my %sigfe = ();
my @data = ();
my @nosigfuncs = ();
my @out = ();
for (@in) {
    /\sDATA$/o and do {
	push(@data, $_);
	next;
    };
    chomp;
    if (/=/o) {
	if (s/\s+NOSIGFE\s*$//) {
	} elsif (s/ SIGFE$//) {
	  my $func = (split(' '))[2];
	  $sigfe{$func} = '_sigfe_' . $func;
	}
    } else {
	my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGR?FE))?$%o;
	if (defined($sigfe) && $sigfe =~ /^NO/o) {
	    $_ = $func;
	} else {
	    $sigfe ||= 'sigfe';
	    $_ = '_' . lc($sigfe) . '_' . $func;
	    $sigfe{$func} = $_;
	    $_ = $func . ' = ' . $_;
	}
    }
    s/(\S)\s+(\S)/$1 $2/go;
    s/(\S)\s+$/$1/o;
    s/^\s+(\S)/$1/o;
    push(@out, $_ . "\n");
}

for (@out) {
    my ($alias, $func) = /^(\S+) = (\S+)\s*$/o;
    $_ = $alias . ' = ' . $sigfe{$func} . "\n"
      if defined($func) && $sigfe{$func};
}
open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n";
print OUT @top, @data, @out;
close OUT;

open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n";

for my $k (sort keys %sigfe) {
    print SIGFE fefunc($k, $sigfe{$k});
}
close SIGFE;

sub fefunc {
    my $func = '_' . shift;
    my $fe = '_' . shift;
    my $extra;
    my $res = <<EOF;
	.extern	_siglist_index
	.extern	_siglist
	.extern	$func
	.global	$fe
$fe:
	pushl	\$$func
	jmp	__sigfe

EOF
    if (!$main::first++) {
	$res = <<EOF . longjmp () . $res;
	.text

	.stabs	"_sigfe:F(0,1)",36,0,0,__sigbe
__sigfe:
	pushl	%edx
	movl	%fs:4,%edx
1:	movl	\$1,%eax
	lock	cmpxchg %eax,$tls::stacklock(%edx)
	jne	2f
	xorl	%eax,%eax
	call	_low_priority_sleep
	jmp	1b
2:	movl	\$4,%eax
	xadd	%eax,$tls::stackptr(%edx)
	decl	$tls::stacklock(%edx)
	leal	__sigbe,%edx
	xchg	%edx,8(%esp)
	movl	%edx,(%eax)
	popl	%edx
	ret

	.global	__sigbe
	.stabs	"_sigbe:F(0,1)",36,0,0,__sigbe
__sigbe:
	pushl	%edx
	pushl	%eax
	movl	%fs:4,%edx
1:	movl	\$1,%eax
	lock	cmpxchg %eax,$tls::stacklock(%edx)
	jne	2f
	xorl	%eax,%eax
	call	_low_priority_sleep
	jmp	1b
2:	movl	\$-4,%eax
	xadd	%eax,$tls::stackptr(%edx)
	xchg	%edx,-4(%eax)
	xchg	%edx,4(%esp)
	popl	%eax
	ret

	.global	__ZN11_threadinfo3popEv
__ZN11_threadinfo3popEv:
1:	pushl	%ebx
	movl	%eax,%edx
	movl	\$-4,%ebx
	xadd	%ebx,$tls::pstackptr(%edx)
	xorl	%eax,%eax
	xchg	%eax,-4(%ebx)
	decl	$tls::pstacklock(%edx)
	popl	%ebx
	ret

	.global	__ZN11_threadinfo4lockEi
__ZN11_threadinfo4lockEi:
	pushl	%ebx
	movl	%eax,%ebx
1:	movl	\$1,%eax
	lock	cmpxchg %eax,$tls::pstacklock(%ebx)
	jne	2f
	cmpl	%edx,%edx
	jz	2f
	xorl	%eax,%eax
	call	_low_priority_sleep
	jmp	1b
2:	xorl	\$1,%eax
	popl	%ebx
	ret

	.global	__ZN11_threadinfo6unlockEv
__ZN11_threadinfo6unlockEv:
	decl	$tls::pstacklock(%eax)
	ret

	.global	_sigreturn
	.stabs	"sigreturn:F(0,1)",36,0,0,_sigreturn
_sigreturn:
	addl	\$4,%esp			# Remove argument
	call	_set_process_mask\@4

	movl	%fs:4,%ebx

	cmpl	\$0,$tls::sig(%ebx)	# Did a signal come in?
	jnz	3f			# Yes, if non-zero

1:	popl	%edx			# saved errno
	testl	%edx,%edx		# Is it < 0
	jl	2f			# yup.  ignore it
	movl	$tls::errno_addr(%ebx),%eax
	movl	%edx,(%eax)
2:	popl	%eax
	popl	%ebx
	popl	%ecx
	popl	%edx
	popl	%edi
	popl	%esi
	popf
	popl	%ebp
	jmp	__sigbe

	.global	_sigdelayed
	.stabs	"sigdelayed:F(0,1)",36,0,0,_sigdelayed
_sigdelayed:
	pushl	%ebp
	movl	%esp,%ebp
	pushf
	pushl	%esi
	pushl	%edi
	pushl	%edx
	pushl	%ecx
	pushl	%ebx
	pushl	%eax
	movl	%fs:4,%ebx
	pushl	$tls::saved_errno(%ebx)	# saved errno
3:	pushl	$tls::oldmask(%ebx)	# oldmask
	pushl	$tls::sig(%ebx)		# signal argument
	pushl	\$_sigreturn

	call	_reset_signal_arrived\@0
	pushl	$tls::func(%ebx)	# signal func
	pushl	$tls::newmask(%ebx)	# newmask - eaten by set_process_mask

	call	_set_process_mask\@4
	cmpl	\$0,$tls::threadkill(%ebx)#pthread_kill signal?
	jnz	4f			#yes.  Callee clears signal number
	movl	\$0,$tls::sig(%ebx)	# zero the signal number as a
					# flag to the signal handler thread
					# that it is ok to set up sigsave
4:	popl	%ebx
	jmp	*%ebx

EOF
    }
    return $res;
}

sub longjmp {
    return <<EOF;

	.globl	_longjmp

_longjmp:
	pushl	%ebp
	movl	%esp,%ebp
	movl	8(%ebp),%edi
	movl	12(%ebp),%eax
	testl	%eax,%eax
	jne	0f
	incl	%eax
0:
	movl	%eax,0(%edi)
	movl	24(%edi),%ebp
	pushfl
	popl	%ebx
	movw	42(%edi),%ax
	movw	%ax,%ss
	movl	28(%edi),%esp
	pushl	32(%edi)
	pushl	%ebx
	movw	36(%edi),%ax
	movw	%ax,%es
	movw	40(%edi),%ax
	movw	%ax,%gs
	movl	%fs:4,%eax
	leal	($tls::stack)(%eax),%edx
	movl	%edx,($tls::stackptr)(%eax)
	movl	0(%edi),%eax
	movl	4(%edi),%ebx
	movl	8(%edi),%ecx
	movl	12(%edi),%edx
	movl	16(%edi),%esi
	movl	20(%edi),%edi
	popfl
	ret

EOF
}