ef33379be8
signal_arrived and for sigCONT. (sigpacket::process): Enforce sending of both signal_arrived and sigCONT, where appropriate. * gendef (sigreturn): Save tls pointer in ebx so that it can jump into sigdelayed and use the same register.
226 lines
4.1 KiB
Perl
Executable File
226 lines
4.1 KiB
Perl
Executable File
#!/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
|
|
.global __sigbe
|
|
.global _sigreturn
|
|
.global _sigdelayed
|
|
|
|
.stabs "_sigfe:F(0,1)",36,0,0,__sigbe
|
|
__sigfe:
|
|
pushl %edx
|
|
movl %fs:4,%eax
|
|
movl \$4,%edx
|
|
xadd %edx,$tls::stackptr(%eax)
|
|
leal __sigbe,%eax
|
|
xchg %eax,8(%esp)
|
|
movl %eax,(%edx)
|
|
popl %edx
|
|
ret
|
|
|
|
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
|
__sigbe:
|
|
pushl %eax
|
|
pushl %edx
|
|
movl \$-4,%edx
|
|
1: movl %fs:4,%eax
|
|
xadd %edx,$tls::stackptr(%eax)
|
|
xorl %eax,%eax
|
|
lock xchg %eax,-4(%edx)
|
|
testl %eax,%eax
|
|
jnz 2f
|
|
call _low_priority_sleep
|
|
xorl %edx,%edx
|
|
jmp 1b
|
|
2: xchg %eax,4(%esp)
|
|
popl %edx
|
|
ret
|
|
|
|
.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
|
|
|
|
.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
|
|
}
|