mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 09:19:23 +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;
|
end;
|
||||||
{$endif cpusparc}
|
{$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.
|
Change action of process upon receipt of a signal.
|
||||||
Signum specifies the signal (all except SigKill and SigStop).
|
Signum specifies the signal (all except SigKill and SigStop).
|
||||||
@ -219,9 +260,25 @@ function Fpsigaction(sig: cint; act : psigactionrec; oact : psigactionrec): cint
|
|||||||
begin
|
begin
|
||||||
{$ifdef cpusparc}
|
{$ifdef cpusparc}
|
||||||
{ Sparc has an extra stub parameter }
|
{ 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}
|
{$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}
|
{$endif cpusparc}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ Const
|
|||||||
SA_NOCLDSTOP = 1;
|
SA_NOCLDSTOP = 1;
|
||||||
SA_NOCLDWAIT = 2;
|
SA_NOCLDWAIT = 2;
|
||||||
SA_SIGINFO = 4;
|
SA_SIGINFO = 4;
|
||||||
SA_SHIRQ = $04000000;
|
SA_RESTORER = $04000000;
|
||||||
SA_STACK = $08000000;
|
SA_ONSTACK = $08000000;
|
||||||
SA_RESTART = $10000000;
|
SA_RESTART = $10000000;
|
||||||
SA_INTERRUPT = $20000000;
|
SA_INTERRUPT = $20000000;
|
||||||
SA_NOMASK = $40000000;
|
SA_NOMASK = $40000000;
|
||||||
@ -133,11 +133,9 @@ const
|
|||||||
SI_PAD_SIZE = ((128 div sizeof(longint)) - 3);
|
SI_PAD_SIZE = ((128 div sizeof(longint)) - 3);
|
||||||
|
|
||||||
type
|
type
|
||||||
SigSet = array[0..wordsinsigset-1] of cuLong;
|
sigset_t = array[0..wordsinsigset-1] of cuLong;
|
||||||
sigset_t= SigSet;
|
tsigset = sigset_t;
|
||||||
PSigSet = ^SigSet;
|
psigset = ^tsigset;
|
||||||
psigset_t=psigset;
|
|
||||||
TSigSet = SigSet;
|
|
||||||
|
|
||||||
psiginfo = ^tsiginfo;
|
psiginfo = ^tsiginfo;
|
||||||
tsiginfo = record
|
tsiginfo = record
|
||||||
@ -181,37 +179,22 @@ type
|
|||||||
{$i sighndh.inc}
|
{$i sighndh.inc}
|
||||||
|
|
||||||
type
|
type
|
||||||
SignalHandler = Procedure(Sig : Longint);cdecl;
|
signalhandler_t = procedure(signal: longint); cdecl;
|
||||||
PSignalHandler = ^SignalHandler;
|
sigactionhandler_t = procedure(signal: longint; info: psiginfo; context: psigcontext); cdecl;
|
||||||
SignalRestorer = Procedure;cdecl;
|
sigrestorerhandler_t = procedure; cdecl;
|
||||||
PSignalRestorer = ^SignalRestorer;
|
|
||||||
SigActionHandler = procedure(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext);cdecl;
|
|
||||||
|
|
||||||
{$ifdef CPUARM}
|
signalhandler = signalhandler_t;
|
||||||
{$define NEWSIGNAL}
|
sigactionhandler = sigactionhandler_t;
|
||||||
{$endif CPUARM}
|
sigrestorerhandler = sigrestorerhandler_t;
|
||||||
|
tsignalhandler = signalhandler_t;
|
||||||
|
tsigactionhandler = sigactionhandler_t;
|
||||||
|
tsigrestorerhandler = sigrestorerhandler_t;
|
||||||
|
|
||||||
{$ifdef CPUx86_64}
|
psigactionrec = ^sigactionrec;
|
||||||
{$define NEWSIGNAL}
|
sigactionrec = packed record
|
||||||
{$endif CPUx86_64}
|
sa_handler: sigactionhandler_t;
|
||||||
|
sa_flags: dword;
|
||||||
{$ifdef CPUPOWERPC64}
|
sa_restorer: sigrestorerhandler_t;
|
||||||
{$define NEWSIGNAL}
|
sa_mask: sigset_t;
|
||||||
{$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}
|
|
||||||
end;
|
end;
|
||||||
TSigActionRec = SigActionRec;
|
|
||||||
PSigActionRec = ^SigActionRec;
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ var sa,osa : sigactionrec;
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
sa.sa_handler:=SigActionHandler(handler);
|
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;
|
sa.sa_flags := 0;
|
||||||
{ if (sigintr and signum) =0 then
|
{ if (sigintr and signum) =0 then
|
||||||
{restart behaviour needs libc}
|
{restart behaviour needs libc}
|
||||||
|
Loading…
Reference in New Issue
Block a user