mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:09:27 +02:00
add signal handler trampoline return for buggy OS like fedora core
git-svn-id: trunk@3311 -
This commit is contained in:
parent
e9420ae581
commit
7911be08f5
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user