1{
2    This file is part of the Free Pascal run time library.
3    Copyright (c) 1999-2000 by Michael Van Canneyt,
4    member of the Free Pascal development team.
5
6    Signal handler is arch dependant due to processor to language
7    exception conversion.
8
9    See the file COPYING.FPC, included in this distribution,
10    for details about the copyright.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 **********************************************************************}
17
18procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; UContext: PUContext);cdecl;public name '_FPC_DEFAULTSIGHANDLER';
19var
20  res : word;
21  addr : pointer;
22  frame : pointer;
23begin
24  res:=0;
25  addr:=nil;
26  case sig of
27    SIGFPE :
28        begin
29          addr := siginfo^._sifields._sigfault._addr;
30          res := 207;
31
32          case  siginfo^.si_code of
33            FPE_INTDIV:
34              res:=200;  // maps to EDivByZero
35            FPE_INTOVF:
36              res:=215;
37            FPE_FLTDIV:
38              res:=208;  // maps to EZeroDivide
39            FPE_FLTOVF:
40              res:=205;
41            FPE_FLTUND:
42              res:=206;
43            else
44              res:=207;
45          end;
46        end;
47    SIGILL,
48    SIGBUS,
49    SIGSEGV :
50        begin
51          addr := siginfo^._sifields._sigfault._addr;
52          res:=216;
53        end;
54  end;
55  reenable_signal(sig);
56  { give runtime error at the position where the signal was raised }
57  if res<>0 then
58    begin
59      if assigned(UContext) then
60        begin
61          frame:=pointer(ptruint(UContext^.uc_mcontext.sigc_regs[30]));   { base pointer }
62          addr:=pointer(ptruint(UContext^.uc_mcontext.sigc_pc));  { program counter }
63          if sig=SIGFPE then
64            begin
65              { Clear FPU exception bits }
66              UContext^.uc_mcontext.sigc_fpc_csr := UContext^.uc_mcontext.sigc_fpc_csr
67                and not (fpu_cause_mask or fpu_flags_mask);
68            end;
69          { Change $a0, $a1, $a2 and sig_pc to HandleErrorAddrFrame parameters }
70          UContext^.uc_mcontext.sigc_regs[4]:=res;
71          UContext^.uc_mcontext.sigc_regs[5]:=ptrint(addr);
72          UContext^.uc_mcontext.sigc_regs[6]:=ptrint(frame);
73          UContext^.uc_mcontext.sigc_pc:=ptrint(@HandleErrorAddrFrame);
74{$ifdef FPC_PIC}
75          { With PIC, we also have to set $t9 to procedure address }
76          UContext^.uc_mcontext.sigc_regs[25]:=ptrint(@HandleErrorAddrFrame);
77{$endif FPC_PIC}
78          { Let the system call HandleErrorAddrFrame }
79          exit;
80        end
81      else
82        begin
83          frame:=nil;
84          addr:=nil;
85        end;
86      if sig=SIGFPE then
87        set_fsr(get_fsr and not (fpu_cause_mask or fpu_flags_mask));
88      HandleErrorAddrFrame(res,addr,frame);
89    end;
90end;
91