2
0
Эх сурвалжийг харах

* initial version from 1.0.x branch

marco 22 жил өмнө
parent
commit
417d359871
1 өөрчлөгдсөн 107 нэмэгдсэн , 0 устгасан
  1. 107 0
      rtl/linux/i386/sighnd.inc

+ 107 - 0
rtl/linux/i386/sighnd.inc

@@ -0,0 +1,107 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Michael Van Canneyt,
+    member of the Free Pascal development team.
+
+    Signal handler is arch dependant due to processor to language
+    exception conversion.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    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.
+
+ **********************************************************************}
+
+const
+  fpucw : word = $1332;
+  FPU_Invalid = 1;
+  FPU_Denormal = 2;
+  FPU_DivisionByZero = 4;
+  FPU_Overflow = 8;
+  FPU_Underflow = $10;
+  FPU_StackUnderflow = $20;
+  FPU_StackOverflow = $40;
+  FPU_All = $7f;
+
+Procedure ResetFPU;
+begin
+{$ifndef CORRECTFLDCW}
+  {$asmmode direct}
+{$endif}
+  asm
+    fninit
+    fldcw   fpucw
+  end;
+{$ifndef CORRECTFLDCW}
+  {$asmmode att}
+{$endif}
+end;
+
+function GetFPUState(const SigContext : SigContextRec) : longint;
+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}
+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 }
+          res:=200;
+          fpustate:=GetFPUState(SigContext);
+
+          if (FpuState and FPU_All) <> 0 then
+            begin
+              { first check the more precise options }
+              if (FpuState and FPU_DivisionByZero)<>0 then
+                res:=200
+              else if (FpuState and FPU_Overflow)<>0 then
+                res:=205
+              else if (FpuState and FPU_Underflow)<>0 then
+                res:=206
+              else if (FpuState and FPU_Denormal)<>0 then
+                res:=216
+              else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 Then
+                res:=207
+              else if (FpuState and FPU_Invalid)<>0 then
+                res:=216
+              else
+                res:=207;  {'Coprocessor Error'}
+            end;
+      ResetFPU;
+        end;
+    SIGILL,
+    SIGBUS,
+    SIGSEGV :
+        res:=216;
+  end;
+{ give runtime error at the position where the signal was raised }
+  if res<>0 then
+    HandleErrorAddrFrame(res,SigContext.eip,SigContext.ebp);
+end;
+
+{
+  $Log$
+  Revision 1.1  2003-11-01 01:27:20  marco
+   * initial version from 1.0.x branch
+
+
+}
+