mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 17:49:25 +02:00
* x86_64 exception handling fixed
This commit is contained in:
parent
dedf697f3a
commit
ee4b23ccac
@ -507,8 +507,6 @@ var
|
|||||||
act: SigActionRec;
|
act: SigActionRec;
|
||||||
|
|
||||||
Procedure InstallSignals;
|
Procedure InstallSignals;
|
||||||
var
|
|
||||||
oldact: SigActionRec;
|
|
||||||
begin
|
begin
|
||||||
{ Initialize the sigaction structure }
|
{ Initialize the sigaction structure }
|
||||||
{ all flags and information set to zero }
|
{ all flags and information set to zero }
|
||||||
@ -516,7 +514,11 @@ begin
|
|||||||
{ initialize handler }
|
{ initialize handler }
|
||||||
act.sa_handler := signalhandler(@SignalToRunError);
|
act.sa_handler := signalhandler(@SignalToRunError);
|
||||||
{$ifdef RTSIGACTION}
|
{$ifdef RTSIGACTION}
|
||||||
act.sa_flags:=4;
|
act.sa_flags:=4
|
||||||
|
{$ifdef x86_64}
|
||||||
|
or $4000000
|
||||||
|
{$endif x86_64}
|
||||||
|
;
|
||||||
{$endif RTSIGACTION}
|
{$endif RTSIGACTION}
|
||||||
FpSigAction(SIGFPE,@act,nil);
|
FpSigAction(SIGFPE,@act,nil);
|
||||||
FpSigAction(SIGSEGV,@act,nil);
|
FpSigAction(SIGSEGV,@act,nil);
|
||||||
@ -584,7 +586,10 @@ end;
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.16 2004-04-27 20:47:00 florian
|
Revision 1.17 2004-05-01 15:59:17 florian
|
||||||
|
* x86_64 exception handling fixed
|
||||||
|
|
||||||
|
Revision 1.16 2004/04/27 20:47:00 florian
|
||||||
* tried to fix x86-64 signal handling
|
* tried to fix x86-64 signal handling
|
||||||
|
|
||||||
Revision 1.15 2004/04/22 21:16:35 peter
|
Revision 1.15 2004/04/22 21:16:35 peter
|
||||||
|
@ -15,6 +15,13 @@
|
|||||||
|
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
}
|
}
|
||||||
|
{$ifdef CPUARM}
|
||||||
|
{$define RTSIGACTION}
|
||||||
|
{$endif CPUARM}
|
||||||
|
|
||||||
|
{$ifdef CPUx86_64}
|
||||||
|
{$define RTSIGACTION}
|
||||||
|
{$endif CPUx86_64}
|
||||||
|
|
||||||
{$I syscallh.inc}
|
{$I syscallh.inc}
|
||||||
{$I ostypes.inc}
|
{$I ostypes.inc}
|
||||||
@ -206,14 +213,6 @@ end;
|
|||||||
If OldAct is non-nil the previous action is saved there.
|
If OldAct is non-nil the previous action is saved there.
|
||||||
}
|
}
|
||||||
|
|
||||||
{$ifdef CPUARM}
|
|
||||||
{$define RTSIGACTION}
|
|
||||||
{$endif CPUARM}
|
|
||||||
|
|
||||||
{$ifdef CPUx86_64}
|
|
||||||
{$define RTSIGACTION}
|
|
||||||
{$endif CPUx86_64}
|
|
||||||
|
|
||||||
function Fpsigaction(sig: cint; act : psigactionrec; oact : psigactionrec): cint; [public, alias : 'FPC_SYSC_SIGACTION'];
|
function Fpsigaction(sig: cint; act : psigactionrec; oact : psigactionrec): cint; [public, alias : 'FPC_SYSC_SIGACTION'];
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -452,6 +451,27 @@ begin
|
|||||||
Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen);
|
Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function FPSigProcMask(how:cint;nset : psigset;oset : psigset):cint; [public, alias : 'FPC_SYSC_SIGPROCMASK'];
|
||||||
|
|
||||||
|
{
|
||||||
|
Change the list of currently blocked signals.
|
||||||
|
How determines which signals will be blocked :
|
||||||
|
SigBlock : Add SSet to the current list of blocked signals
|
||||||
|
SigUnBlock : Remove the signals in SSet from the list of blocked signals.
|
||||||
|
SigSetMask : Set the list of blocked signals to SSet
|
||||||
|
if OldSSet is non-null, the old set will be saved there.
|
||||||
|
}
|
||||||
|
|
||||||
|
begin
|
||||||
|
{$ifdef RTSIGACTION}
|
||||||
|
FPsigprocmask:=do_syscall(syscall_nr_rt_sigprocmask,TSysParam(how),TSysParam(nset),TSysParam(oset),TSysParam(8));
|
||||||
|
{$else RTSIGACTION}
|
||||||
|
FPsigprocmask:=do_syscall(syscall_nr_sigprocmask,TSysParam(how),TSysParam(nset),TSysParam(oset),TSysParam(8));
|
||||||
|
{$endif RTSIGACTION}
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
Function FpNanoSleep(req : ptimespec;rem : ptimespec):cint; [public, alias : 'FPC_SYSC_NANOSLEEP'];
|
Function FpNanoSleep(req : ptimespec;rem : ptimespec):cint; [public, alias : 'FPC_SYSC_NANOSLEEP'];
|
||||||
begin
|
begin
|
||||||
FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(req),TSysParam(rem));
|
FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(req),TSysParam(rem));
|
||||||
@ -509,7 +529,10 @@ end;
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.23 2004-04-27 20:47:00 florian
|
Revision 1.24 2004-05-01 15:59:17 florian
|
||||||
|
* x86_64 exception handling fixed
|
||||||
|
|
||||||
|
Revision 1.23 2004/04/27 20:47:00 florian
|
||||||
* tried to fix x86-64 signal handling
|
* tried to fix x86-64 signal handling
|
||||||
|
|
||||||
Revision 1.22 2004/04/25 07:18:49 florian
|
Revision 1.22 2004/04/25 07:18:49 florian
|
||||||
|
@ -242,9 +242,53 @@ type
|
|||||||
{$endif cpusparc}
|
{$endif cpusparc}
|
||||||
|
|
||||||
{$ifdef cpux86_64}
|
{$ifdef cpux86_64}
|
||||||
{ get it from glibc/sysdeps/unix/sysv/linux/x86_64/sys/uncontext.h }
|
|
||||||
|
p_fpstate = ^_fpstate;
|
||||||
|
_fpstate = packed record
|
||||||
|
cwd,
|
||||||
|
swd,
|
||||||
|
twd, // Note this is not the same as the 32bit/x87/FSAVE twd
|
||||||
|
fop : word;
|
||||||
|
rip,
|
||||||
|
rdp : qword;
|
||||||
|
mxcsr,
|
||||||
|
mxcsr_mask : dword;
|
||||||
|
st_space : array[0..31] of dword; // 8*16 bytes for each FP-reg
|
||||||
|
xmm_space : array[0..63] of dword; // 16*16 bytes for each XMM-reg
|
||||||
|
reserved2 : array[0..23] of dword;
|
||||||
|
end;
|
||||||
|
|
||||||
PSigContextRec = ^SigContextRec;
|
PSigContextRec = ^SigContextRec;
|
||||||
SigContextRec = record
|
SigContextRec = packed record
|
||||||
|
__pad00 : array[0..4] of qword;
|
||||||
|
r8,
|
||||||
|
r9,
|
||||||
|
r10,
|
||||||
|
r11,
|
||||||
|
r12,
|
||||||
|
r13,
|
||||||
|
r14,
|
||||||
|
r15,
|
||||||
|
rdi,
|
||||||
|
rsi,
|
||||||
|
rbp,
|
||||||
|
rbx,
|
||||||
|
rdx,
|
||||||
|
rax,
|
||||||
|
rcx,
|
||||||
|
rsp,
|
||||||
|
rip,
|
||||||
|
eflags : qword;
|
||||||
|
cs,
|
||||||
|
gs,
|
||||||
|
fs,
|
||||||
|
__pad0 : word;
|
||||||
|
err,
|
||||||
|
trapno,
|
||||||
|
oldmask,
|
||||||
|
cr2 : qword;
|
||||||
|
fpstate : p_fpstate; // zero when no FPU context */
|
||||||
|
reserved1 : array[0..7] of qword;
|
||||||
end;
|
end;
|
||||||
{$endif cpux86_64}
|
{$endif cpux86_64}
|
||||||
|
|
||||||
@ -376,7 +420,10 @@ type
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.18 2004-04-27 20:47:00 florian
|
Revision 1.19 2004-05-01 15:59:17 florian
|
||||||
|
* x86_64 exception handling fixed
|
||||||
|
|
||||||
|
Revision 1.18 2004/04/27 20:47:00 florian
|
||||||
* tried to fix x86-64 signal handling
|
* tried to fix x86-64 signal handling
|
||||||
|
|
||||||
Revision 1.17 2004/03/27 14:35:13 florian
|
Revision 1.17 2004/03/27 14:35:13 florian
|
||||||
|
@ -20,31 +20,43 @@
|
|||||||
const
|
const
|
||||||
FPU_All = $7f;
|
FPU_All = $7f;
|
||||||
|
|
||||||
function GetFPUState(const SigContext : SigContextRec) : longint;
|
function GetFPUState(const SigContext : SigContextRec) : word;
|
||||||
|
begin
|
||||||
|
if assigned(SigContext.fpstate) then
|
||||||
|
GetfpuState:=SigContext.fpstate^.swd;
|
||||||
|
{$ifdef SYSTEM_DEBUG}
|
||||||
|
writeln('xx:',sigcontext.en_tw,' ',sigcontext.en_cw);
|
||||||
|
{$endif SYSTEM_DEBUG}
|
||||||
|
{$ifdef SYSTEM_DEBUG}
|
||||||
|
Writeln(stderr,'FpuState = ',result);
|
||||||
|
{$endif SYSTEM_DEBUG}
|
||||||
|
end;
|
||||||
|
|
||||||
|
function reenable_signal(sig : longint) : boolean;
|
||||||
|
var
|
||||||
|
e,olde : TSigSet;
|
||||||
|
i,j : byte;
|
||||||
begin
|
begin
|
||||||
{!!!!!!!
|
fillchar(e,sizeof(e),#0);
|
||||||
if assigned(SigContext.fpstate) then
|
{ set is 1 based PM }
|
||||||
GetfpuState:=SigContext.fpstate^.sw;
|
dec(sig);
|
||||||
{$ifdef SYSTEM_DEBUG}
|
i:=sig mod 32;
|
||||||
writeln('xx:',sigcontext.en_tw,' ',sigcontext.en_cw);
|
j:=sig div 32;
|
||||||
{$endif SYSTEM_DEBUG}
|
e[j]:=1 shl i;
|
||||||
{$ifdef SYSTEM_DEBUG}
|
fpsigprocmask(SIG_UNBLOCK,@e,nil);
|
||||||
Writeln(stderr,'FpuState = ',GetFpuState);
|
reenable_signal:=geterrno=0;
|
||||||
{$endif SYSTEM_DEBUG}
|
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure SignalToRunerror(Sig: longint; SigContext: SigContextRec); cdecl;
|
procedure SignalToRunerror(sig : longint; SigContext: SigContextRec); cdecl;
|
||||||
|
var
|
||||||
var
|
res,fpustate : word;
|
||||||
res,fpustate : word;
|
begin
|
||||||
begin
|
res:=0;
|
||||||
res:=0;
|
case sig of
|
||||||
case sig of
|
SIGFPE :
|
||||||
SIGFPE :
|
begin
|
||||||
begin
|
{ this is not allways necessary but I don't know yet
|
||||||
{ this is not allways necessary but I don't know yet
|
how to tell if it is or not PM }
|
||||||
how to tell if it is or not PM }
|
|
||||||
res:=200;
|
res:=200;
|
||||||
fpustate:=GetFPUState(SigContext);
|
fpustate:=GetFPUState(SigContext);
|
||||||
if (FpuState and FPU_All) <> 0 then
|
if (FpuState and FPU_All) <> 0 then
|
||||||
@ -65,23 +77,24 @@ begin
|
|||||||
else
|
else
|
||||||
res:=207; {'Coprocessor Error'}
|
res:=207; {'Coprocessor Error'}
|
||||||
end;
|
end;
|
||||||
sysResetFPU;
|
SysResetFPU;
|
||||||
end;
|
end;
|
||||||
SIGILL,
|
SIGILL,
|
||||||
SIGBUS,
|
SIGBUS,
|
||||||
SIGSEGV :
|
SIGSEGV:
|
||||||
res:=216;
|
res:=216;
|
||||||
|
end;
|
||||||
|
reenable_signal(sig);
|
||||||
|
if res<>0 then
|
||||||
|
HandleErrorAddrFrame(res,pointer(SigContext.rip),pointer(SigContext.rbp));
|
||||||
end;
|
end;
|
||||||
{ give runtime error at the position where the signal was raised }
|
|
||||||
{!!!!
|
|
||||||
if res<>0 then
|
|
||||||
HandleErrorAddrFrame(res,pointer(SigContext.eip),pointer(SigContext.ebp));
|
|
||||||
}
|
|
||||||
end;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.1 2004-02-05 01:16:12 florian
|
Revision 1.2 2004-05-01 15:59:17 florian
|
||||||
|
* x86_64 exception handling fixed
|
||||||
|
|
||||||
|
Revision 1.1 2004/02/05 01:16:12 florian
|
||||||
+ completed x86-64/linux system unit
|
+ completed x86-64/linux system unit
|
||||||
|
|
||||||
Revision 1.2 2003/11/01 01:58:11 marco
|
Revision 1.2 2003/11/01 01:58:11 marco
|
||||||
|
@ -343,9 +343,19 @@ const
|
|||||||
FPU_StackOverflow = $40;
|
FPU_StackOverflow = $40;
|
||||||
FPU_ExceptionMask = $ff;
|
FPU_ExceptionMask = $ff;
|
||||||
|
|
||||||
|
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
|
||||||
|
Procedure SysResetFPU;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
asm
|
||||||
|
fninit
|
||||||
|
fldcw fpucw
|
||||||
|
end;
|
||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.11 2004-04-29 19:50:13 peter
|
Revision 1.12 2004-05-01 15:59:17 florian
|
||||||
|
* x86_64 exception handling fixed
|
||||||
|
|
||||||
|
Revision 1.11 2004/04/29 19:50:13 peter
|
||||||
* x86-64 fixes
|
* x86-64 fixes
|
||||||
|
|
||||||
Revision 1.10 2004/04/26 15:55:01 peter
|
Revision 1.10 2004/04/26 15:55:01 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user