add signal handler trampoline return for buggy OS like fedora core

git-svn-id: trunk@3311 -
This commit is contained in:
micha 2006-04-21 20:36:17 +00:00
parent e9420ae581
commit 7911be08f5
3 changed files with 83 additions and 43 deletions

View File

@ -208,8 +208,49 @@ asm
end;
{$endif cpusparc}
{$if defined(cpui386) or defined(cpuarm) or defined(cpux86_64)}
{$define NEED_USER_TRAMPOLINE}
{$endif}
{$if defined(cpui386) or defined(cpuarm)}
{$define NEED_USER_TRAMPOLINE_RT_DIFFERENT}
{$endif}
function Fpsigaction(sig: cint; act : psigactionrec; oact : psigactionrec): cint; [public, alias : 'FPC_SYSC_SIGACTION'];
{$ifdef NEED_USER_TRAMPOLINE}
procedure linux_restore; cdecl; nostackframe; assembler;
asm
{$ifdef cpuarm}
swi __NR_sigreturn;
{$endif}
{$ifdef cpui386}
popl %eax
movl $syscall_nr_sigreturn, %eax
int $0x80
{$endif}
{$ifdef cpux86_64}
moq $syscall_nr_rt_sigreturn, %rax
syscall
{$endif}
end;
{$endif}
{$ifdef NEED_USER_TRAMPOLINE_RT_DIFFERENT}
procedure linux_restore_rt; cdecl; nostackframe; assembler;
asm
{$ifdef cpuarm}
swi syscall_nr_rt_sigreturn
{$endif}
{$ifdef cpui386}
movl $syscall_nr_rt_sigreturn, %eax
int $0x80
{$endif}
end;
{$endif}
function Fpsigaction(sig: cint; new_action, old_action: psigactionrec): cint; [public, alias : 'FPC_SYSC_SIGACTION'];
{
Change action of process upon receipt of a signal.
Signum specifies the signal (all except SigKill and SigStop).
@ -219,9 +260,25 @@ function Fpsigaction(sig: cint; act : psigactionrec; oact : psigactionrec): cint
begin
{$ifdef cpusparc}
{ Sparc has an extra stub parameter }
Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig),TSysParam(act),TSysParam(oact),TSysParam(PtrInt(@Fprt_sigreturn_stub)-8),TSysParam(8));
Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig),TSysParam(new_action),TSysParam(old_action),TSysParam(PtrInt(@Fprt_sigreturn_stub)-8),TSysParam(8));
{$else cpusparc}
Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig),TSysParam(act),TSysParam(oact),TSysParam(8));
{$ifdef NEED_USER_TRAMPOLINE}
if new_action <> nil then
begin
// a different stack (SA_ONSTACK) requires sa_restorer field
if (new_action^.sa_flags and (SA_RESTORER or SA_ONSTACK)) = 0 then
begin
new_action^.sa_flags := new_action^.sa_flags or SA_RESTORER;
{$ifdef NEED_USER_TRAMPOLINE_RT_DIFFERENT}
if (new_action^.sa_flags and SA_SIGINFO) <> 0 then
new_action^.sa_restorer := @linux_restore_rt
else
{$endif}
new_action^.sa_restorer := @linux_restore;
end;
end;
{$endif}
Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig),TSysParam(new_action),TSysParam(old_action),TSysParam(8));
{$endif cpusparc}
end;

View File

@ -31,8 +31,8 @@ Const
SA_NOCLDSTOP = 1;
SA_NOCLDWAIT = 2;
SA_SIGINFO = 4;
SA_SHIRQ = $04000000;
SA_STACK = $08000000;
SA_RESTORER = $04000000;
SA_ONSTACK = $08000000;
SA_RESTART = $10000000;
SA_INTERRUPT = $20000000;
SA_NOMASK = $40000000;
@ -133,11 +133,9 @@ const
SI_PAD_SIZE = ((128 div sizeof(longint)) - 3);
type
SigSet = array[0..wordsinsigset-1] of cuLong;
sigset_t= SigSet;
PSigSet = ^SigSet;
psigset_t=psigset;
TSigSet = SigSet;
sigset_t = array[0..wordsinsigset-1] of cuLong;
tsigset = sigset_t;
psigset = ^tsigset;
psiginfo = ^tsiginfo;
tsiginfo = record
@ -181,37 +179,22 @@ type
{$i sighndh.inc}
type
SignalHandler = Procedure(Sig : Longint);cdecl;
PSignalHandler = ^SignalHandler;
SignalRestorer = Procedure;cdecl;
PSignalRestorer = ^SignalRestorer;
SigActionHandler = procedure(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext);cdecl;
{$ifdef CPUARM}
{$define NEWSIGNAL}
{$endif CPUARM}
{$ifdef CPUx86_64}
{$define NEWSIGNAL}
{$endif CPUx86_64}
{$ifdef CPUPOWERPC64}
{$define NEWSIGNAL}
{$endif CPUPOWERPC64}
SigActionRec = packed record // this is temporary for the migration
sa_handler : SigActionHandler;
{$ifdef NEWSIGNAL}
Sa_Flags : culong;
Sa_restorer : SignalRestorer; { Obsolete - Don't use }
Sa_Mask : SigSet;
{$else NEWSIGNAL}
Sa_Mask : SigSet;
Sa_Flags : cuLong;
Sa_restorer : SignalRestorer; { Obsolete - Don't use }
{$endif NEWSIGNAL}
signalhandler_t = procedure(signal: longint); cdecl;
sigactionhandler_t = procedure(signal: longint; info: psiginfo; context: psigcontext); cdecl;
sigrestorerhandler_t = procedure; cdecl;
signalhandler = signalhandler_t;
sigactionhandler = sigactionhandler_t;
sigrestorerhandler = sigrestorerhandler_t;
tsignalhandler = signalhandler_t;
tsigactionhandler = sigactionhandler_t;
tsigrestorerhandler = sigrestorerhandler_t;
psigactionrec = ^sigactionrec;
sigactionrec = packed record
sa_handler: sigactionhandler_t;
sa_flags: dword;
sa_restorer: sigrestorerhandler_t;
sa_mask: sigset_t;
end;
TSigActionRec = SigActionRec;
PSigActionRec = ^SigActionRec;

View File

@ -138,7 +138,7 @@ var sa,osa : sigactionrec;
begin
sa.sa_handler:=SigActionHandler(handler);
FillChar(sa.sa_mask,sizeof(sigset),#0);
FillChar(sa.sa_mask,sizeof(sa.sa_mask),#0);
sa.sa_flags := 0;
{ if (sigintr and signum) =0 then
{restart behaviour needs libc}