sighnd.inc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. {
  2. This file is part of the Free Pascal run time library.
  3. (c) 2000-2003 by Marco van de Voort
  4. member of the Free Pascal development team.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. Signalhandler for FreeBSD/i386
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY;without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. }
  12. CONST FPU_ALL=$7F;
  13. {$ifdef cpui386}
  14. function getfpustate(sininfo:psiginfo):longint; {inline;}
  15. begin
  16. if ptruint(sininfo)> high(word) then
  17. getfpustate:=sininfo^.si_code
  18. else
  19. getfpustate:=word(ptruint(sininfo));
  20. end;
  21. function getaltfpustate(sigcontext:psigcontextrec):longint; {inline;}
  22. begin
  23. if assigned(sigcontext) then
  24. begin
  25. if has_mmx_support then
  26. getaltfpustate:=sigcontext^.sc_fpustate^.xmmState.fx_fsw
  27. else
  28. getaltfpustate:=sigcontext^.sc_fpustate^.x87state.en_sw
  29. end
  30. else
  31. getaltfpustate:=0;
  32. end;
  33. {$endif}
  34. procedure SignalToRunerror(Sig: longint;sininfo:psiginfo; SigContext: PSigContextRec); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
  35. var
  36. res,fpustate : word;
  37. oldact: SigActionRec;
  38. begin
  39. res:=0;
  40. {$ifdef BSD}
  41. {$ifdef cpui386}
  42. fpustate:=0;
  43. asm
  44. fnstsw fpustate
  45. end;
  46. {$endif cpui386}
  47. {$endif BSD}
  48. case sig of
  49. SIGFPE :
  50. begin
  51. { this is not allways necessary but I don't know yet
  52. how to tell if it is or not PM }
  53. res:=200;
  54. {$ifdef cpui386}
  55. fpustate:=GetaltFPUState(sigcontext);
  56. {$else}
  57. fpustate:=0;
  58. {$endif}
  59. if (FpuState and FPU_All) <> 0 then
  60. begin
  61. { first check the more precise options }
  62. if (FpuState and FPU_DivisionByZero)<>0 then
  63. res:=200
  64. else if (FpuState and FPU_Overflow)<>0 then
  65. res:=205
  66. else if (FpuState and FPU_Underflow)<>0 then
  67. res:=206
  68. else if (FpuState and FPU_Denormal)<>0 then
  69. res:=216
  70. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 then
  71. res:=207
  72. else if (FpuState and FPU_Invalid)<>0 then
  73. res:=216
  74. else
  75. res:=207; {'Coprocessor Error'}
  76. end;
  77. SysResetFPU;
  78. end;
  79. SIGILL,
  80. SIGBUS,
  81. SIGSEGV :
  82. res:=216;
  83. SIGINT:
  84. res:=217;
  85. SIGQUIT:
  86. res:=233;
  87. end;
  88. {$ifdef DEBUG_SIGNAL_HANDLER}
  89. InstallDefaultSignalHandler(sig,oldact);
  90. InstallDefaultSignalHandler(sig,oldact);
  91. {$endif}
  92. reenable_signal(sig);
  93. { give runtime error at the position where the signal was raised }
  94. if res<>0 then
  95. begin
  96. {$ifdef cpui386}
  97. HandleErrorAddrFrame(res,pointer(SigContext^.sc_eip),pointer(SigContext^.sc_ebp));
  98. {$endif}
  99. end;
  100. end;