mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-07-08 09:16:02 +02:00
106 lines
3.9 KiB
PHP
106 lines
3.9 KiB
PHP
{
|
|
This file is part of the Free Pascal run time library.
|
|
(c) 2000-2003 by Marco van de Voort
|
|
member of the Free Pascal development team.
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
Signalhandler for FreeBSD/i386
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY;without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
}
|
|
|
|
procedure SignalToRunerror(Sig: cint; info : psiginfo; SigContext:PSigContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
|
|
|
|
var
|
|
p: pbyte;
|
|
res : word;
|
|
|
|
begin
|
|
res:=0;
|
|
case sig of
|
|
SIGFPE :
|
|
begin
|
|
Case Info^.si_code Of
|
|
FPE_INTDIV : Res:=200; { integer divide by zero -NOTIMP on Mac OS X 10.4.7 }
|
|
FPE_FLTDIV : Res:=208; { floating point divide by zero }
|
|
FPE_FLTOVF : Res:=205; { floating point overflow }
|
|
FPE_FLTUND : Res:=206; { floating point underflow }
|
|
FPE_FLTRES, { floating point inexact result }
|
|
FPE_FLTINV : Res:=207; { invalid floating point operation }
|
|
else
|
|
begin
|
|
{ Assume that if an integer divide was executed, the }
|
|
{ error was a divide-by-zero (FPE_INTDIV is not }
|
|
{ implemented as of 10.5.0) }
|
|
{$ifdef cpu64}
|
|
p:=pbyte(sigcontext^.uc_mcontext^.ts.rip);
|
|
{$else cpu64}
|
|
p:=pbyte(sigcontext^.uc_mcontext^.ts.eip);
|
|
{$endif cpu64}
|
|
{ skip some prefix bytes }
|
|
while (p^ in [{$ifdef cpu64}$40..$4f,{$endif}$66,$67]) do
|
|
inc(p);
|
|
if (p^ in [$f6,$f7]) and
|
|
(((p+1)^ and (%110 shl 3)) = (%110 shl 3)) then
|
|
Res:=200
|
|
else
|
|
Res:=207; { coprocessor error }
|
|
end;
|
|
end;
|
|
{ make sure any fpu operations won't trigger new exceptions in handler }
|
|
sysResetFPU;
|
|
{ Now clear exception flags in the context }
|
|
{ perform an fnclex: clear exception and busy flags }
|
|
sigcontext^.uc_mcontext^.fs.fpu_fsw.flag0:=
|
|
sigcontext^.uc_mcontext^.fs.fpu_fsw.flag0 and (not(%11111111) and not(1 shl 15));
|
|
{ also clear sse exception flags }
|
|
sigcontext^.uc_mcontext^.fs.fpu_mxcsr:=
|
|
sigcontext^.uc_mcontext^.fs.fpu_mxcsr and not(%111111)
|
|
end;
|
|
SIGILL,
|
|
SIGBUS,
|
|
SIGSEGV :
|
|
res:=216;
|
|
SIGINT:
|
|
res:=217;
|
|
SIGQUIT:
|
|
res:=233;
|
|
end;
|
|
{$ifdef FPC_USE_SIGPROCMASK}
|
|
reenable_signal(sig);
|
|
{$endif }
|
|
|
|
if (res <> 0) then
|
|
begin
|
|
{$ifdef cpu64}
|
|
sigcontext^.uc_mcontext^.ts.rdi:=res;
|
|
sigcontext^.uc_mcontext^.ts.rsi:=sigcontext^.uc_mcontext^.ts.rip;
|
|
sigcontext^.uc_mcontext^.ts.rdx:=sigcontext^.uc_mcontext^.ts.rbp;
|
|
{ the ABI expects the stack pointer to be 8 bytes off alignment
|
|
due to the return address which has been pushed -- but take into account
|
|
that rsp may already unaligned in case of a leaf routine }
|
|
if (sigcontext^.uc_mcontext^.ts.rsp and 15)=0 then
|
|
dec(sigcontext^.uc_mcontext^.ts.rsp,sizeof(pointer));
|
|
{ return to run time error handler }
|
|
sigcontext^.uc_mcontext^.ts.rip:=ptruint(@HandleErrorAddrFrame);
|
|
{$else cpu64}
|
|
{ assume regcall calling convention is the default }
|
|
sigcontext^.uc_mcontext^.ts.eax:=res;
|
|
sigcontext^.uc_mcontext^.ts.edx:=sigcontext^.uc_mcontext^.ts.eip;
|
|
sigcontext^.uc_mcontext^.ts.ecx:=sigcontext^.uc_mcontext^.ts.ebp;
|
|
{ the ABI expects the stack pointer to be 4 bytes off alignment }
|
|
{ due to the return address which has been pushed -- but take into account
|
|
that esp may already unaligned in case of a leaf routine }
|
|
if (sigcontext^.uc_mcontext^.ts.esp and 15)=0 then
|
|
dec(sigcontext^.uc_mcontext^.ts.esp,sizeof(pointer));
|
|
{ return to run time error handler }
|
|
sigcontext^.uc_mcontext^.ts.eip:=ptruint(@HandleErrorAddrFrame);
|
|
{$endif cpu64}
|
|
end;
|
|
end;
|
|
|