* x86_64 exception handling fixed

This commit is contained in:
florian 2004-05-01 15:59:17 +00:00
parent dedf697f3a
commit ee4b23ccac
5 changed files with 148 additions and 50 deletions

View File

@ -507,8 +507,6 @@ var
act: SigActionRec;
Procedure InstallSignals;
var
oldact: SigActionRec;
begin
{ Initialize the sigaction structure }
{ all flags and information set to zero }
@ -516,7 +514,11 @@ begin
{ initialize handler }
act.sa_handler := signalhandler(@SignalToRunError);
{$ifdef RTSIGACTION}
act.sa_flags:=4;
act.sa_flags:=4
{$ifdef x86_64}
or $4000000
{$endif x86_64}
;
{$endif RTSIGACTION}
FpSigAction(SIGFPE,@act,nil);
FpSigAction(SIGSEGV,@act,nil);
@ -584,7 +586,10 @@ end;
{
$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
Revision 1.15 2004/04/22 21:16:35 peter

View File

@ -15,6 +15,13 @@
****************************************************************************
}
{$ifdef CPUARM}
{$define RTSIGACTION}
{$endif CPUARM}
{$ifdef CPUx86_64}
{$define RTSIGACTION}
{$endif CPUx86_64}
{$I syscallh.inc}
{$I ostypes.inc}
@ -206,14 +213,6 @@ end;
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'];
{
@ -452,6 +451,27 @@ begin
Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen);
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'];
begin
FpNanoSleep:=Do_SysCall(syscall_nr_nanosleep,TSysParam(req),TSysParam(rem));
@ -509,7 +529,10 @@ end;
{
$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
Revision 1.22 2004/04/25 07:18:49 florian

View File

@ -242,9 +242,53 @@ type
{$endif cpusparc}
{$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;
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;
{$endif cpux86_64}
@ -376,7 +420,10 @@ type
{
$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
Revision 1.17 2004/03/27 14:35:13 florian

View File

@ -20,31 +20,43 @@
const
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
{!!!!!!!
if assigned(SigContext.fpstate) then
GetfpuState:=SigContext.fpstate^.sw;
{$ifdef SYSTEM_DEBUG}
writeln('xx:',sigcontext.en_tw,' ',sigcontext.en_cw);
{$endif SYSTEM_DEBUG}
{$ifdef SYSTEM_DEBUG}
Writeln(stderr,'FpuState = ',GetFpuState);
{$endif SYSTEM_DEBUG}
}
fillchar(e,sizeof(e),#0);
{ set is 1 based PM }
dec(sig);
i:=sig mod 32;
j:=sig div 32;
e[j]:=1 shl i;
fpsigprocmask(SIG_UNBLOCK,@e,nil);
reenable_signal:=geterrno=0;
end;
procedure SignalToRunerror(Sig: longint; SigContext: SigContextRec); cdecl;
var
res,fpustate : word;
begin
res:=0;
case sig of
SIGFPE :
begin
{ this is not allways necessary but I don't know yet
how to tell if it is or not PM }
procedure SignalToRunerror(sig : longint; SigContext: SigContextRec); cdecl;
var
res,fpustate : word;
begin
res:=0;
case sig of
SIGFPE :
begin
{ this is not allways necessary but I don't know yet
how to tell if it is or not PM }
res:=200;
fpustate:=GetFPUState(SigContext);
if (FpuState and FPU_All) <> 0 then
@ -65,23 +77,24 @@ begin
else
res:=207; {'Coprocessor Error'}
end;
sysResetFPU;
SysResetFPU;
end;
SIGILL,
SIGBUS,
SIGSEGV :
SIGILL,
SIGBUS,
SIGSEGV:
res:=216;
end;
reenable_signal(sig);
if res<>0 then
HandleErrorAddrFrame(res,pointer(SigContext.rip),pointer(SigContext.rbp));
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$
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
Revision 1.2 2003/11/01 01:58:11 marco

View File

@ -343,9 +343,19 @@ const
FPU_StackOverflow = $40;
FPU_ExceptionMask = $ff;
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
Procedure SysResetFPU;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
asm
fninit
fldcw fpucw
end;
{
$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
Revision 1.10 2004/04/26 15:55:01 peter