summaryrefslogtreecommitdiff
path: root/mips/rtl/linux/mips/sighnd.inc
diff options
context:
space:
mode:
Diffstat (limited to 'mips/rtl/linux/mips/sighnd.inc')
-rw-r--r--mips/rtl/linux/mips/sighnd.inc35
1 files changed, 32 insertions, 3 deletions
diff --git a/mips/rtl/linux/mips/sighnd.inc b/mips/rtl/linux/mips/sighnd.inc
index ae71d813c4..2a782e21f1 100644
--- a/mips/rtl/linux/mips/sighnd.inc
+++ b/mips/rtl/linux/mips/sighnd.inc
@@ -15,10 +15,11 @@
**********************************************************************}
-procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext);cdecl;
+procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; UContext: PUContext);cdecl;
var
res : word;
addr : pointer;
+ frame : pointer;
begin
res:=0;
addr:=nil;
@@ -27,11 +28,12 @@ begin
begin
addr := siginfo^._sifields._sigfault._addr;
res := 207;
+
case siginfo^.si_code of
FPE_INTDIV:
res:=200;
FPE_INTOVF:
- res:=205;
+ res:=215;
FPE_FLTDIV:
res:=200;
FPE_FLTOVF:
@@ -57,5 +59,32 @@ begin
reenable_signal(sig);
{ give runtime error at the position where the signal was raised }
if res<>0 then
- HandleErrorAddrFrame(res,addr,nil);
+ begin
+ if assigned(UContext) then
+ begin
+ frame:=pointer(ptruint(UContext^.uc_mcontext.sigc_regs[29])); { stack pointer }
+ addr:=pointer(ptruint(UContext^.uc_mcontext.sigc_pc)); { program counter }
+ if sig=SIGFPE then
+ begin
+ { Clear FPU exception bits }
+ UContext^.uc_mcontext.sigc_fpc_csr := UContext^.uc_mcontext.sigc_fpc_csr
+ and not (fpu_cause_mask or fpu_flags_mask);
+ end;
+ { Change $a1, $a2, $a3 and sig_pc to HandleErrorAddrFrame parameters }
+ UContext^.uc_mcontext.sigc_regs[4]:=res;
+ UContext^.uc_mcontext.sigc_regs[5]:=ptrint(addr);
+ UContext^.uc_mcontext.sigc_regs[6]:=ptrint(frame);
+ UContext^.uc_mcontext.sigc_pc:=ptrint(@HandleErrorAddrFrame);
+ { Let the system call HandleErrorAddrFrame }
+ exit;
+ end
+ else
+ begin
+ frame:=nil;
+ addr:=nil;
+ end;
+ if sig=SIGFPE then
+ set_fsr(get_fsr and not (fpu_cause_mask or fpu_flags_mask));
+ HandleErrorAddrFrame(res,addr,frame);
+ end;
end;