sighnd.inc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. Signal handler is arch dependant due to processor to language
  7. exception conversion.
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. const
  15. FPU_All = $7f;
  16. function GetFPUState(const SigContext : TSigContext) : word;
  17. begin
  18. if assigned(SigContext.fpstate) then
  19. GetfpuState:=SigContext.fpstate^.swd;
  20. {$ifdef SYSTEM_DEBUG}
  21. writeln('xx:',sigcontext.en_tw,' ',sigcontext.en_cw);
  22. {$endif SYSTEM_DEBUG}
  23. {$ifdef SYSTEM_DEBUG}
  24. Writeln(stderr,'FpuState = ',result);
  25. {$endif SYSTEM_DEBUG}
  26. end;
  27. function reenable_signal(sig : longint) : boolean;
  28. var
  29. e,olde : TSigSet;
  30. i,j : byte;
  31. begin
  32. fillchar(e,sizeof(e),#0);
  33. { set is 1 based PM }
  34. dec(sig);
  35. i:=sig mod 32;
  36. j:=sig div 32;
  37. e[j]:=1 shl i;
  38. fpsigprocmask(SIG_UNBLOCK,@e,nil);
  39. reenable_signal:=geterrno=0;
  40. end;
  41. procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext); cdecl;
  42. var
  43. res,fpustate : word;
  44. begin
  45. res:=0;
  46. case sig of
  47. SIGFPE :
  48. begin
  49. { this is not allways necessary but I don't know yet
  50. how to tell if it is or not PM }
  51. res:=200;
  52. fpustate:=GetFPUState(SigContext^);
  53. if (FpuState and FPU_All) <> 0 then
  54. begin
  55. { first check the more precise options }
  56. if (FpuState and FPU_DivisionByZero)<>0 then
  57. res:=200
  58. else if (FpuState and FPU_Overflow)<>0 then
  59. res:=205
  60. else if (FpuState and FPU_Underflow)<>0 then
  61. res:=206
  62. else if (FpuState and FPU_Denormal)<>0 then
  63. res:=216
  64. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 Then
  65. res:=207
  66. else if (FpuState and FPU_Invalid)<>0 then
  67. res:=216
  68. else
  69. res:=207; {'Coprocessor Error'}
  70. end;
  71. SysResetFPU;
  72. end;
  73. SIGILL,
  74. SIGBUS,
  75. SIGSEGV:
  76. res:=216;
  77. end;
  78. reenable_signal(sig);
  79. if res<>0 then
  80. HandleErrorAddrFrame(res,pointer(SigContext^.rip),pointer(SigContext^.rbp));
  81. end;
  82. {
  83. $Log$
  84. Revision 1.3 2005-01-30 18:01:15 peter
  85. * signal cleanup for linux
  86. * sigactionhandler instead of tsigaction for bsds
  87. * sigcontext moved to cpu dir
  88. Revision 1.2 2004/05/01 15:59:17 florian
  89. * x86_64 exception handling fixed
  90. Revision 1.1 2004/02/05 01:16:12 florian
  91. + completed x86-64/linux system unit
  92. Revision 1.2 2003/11/01 01:58:11 marco
  93. * more small fixes.
  94. Revision 1.1 2003/11/01 01:27:20 marco
  95. * initial version from 1.0.x branch
  96. }