sighnd.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. Signal handler is arch dependant due to processor to language
  6. exception conversion.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. { use a trampoline which pushes the return address for proper unwinding }
  14. Procedure SignalToHandleErrorAddrFrame (Errno : longint;addr : CodePointer; frame : Pointer); nostackframe; assembler;
  15. asm
  16. pushl addr
  17. jmp HandleErrorAddrFrame
  18. end;
  19. procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; UContext: Pucontext);public name '_FPC_DEFAULTSIGHANDLER';cdecl;
  20. var
  21. res,fpustate,MMState : word;
  22. begin
  23. res:=0;
  24. case sig of
  25. SIGFPE :
  26. begin
  27. { this is not allways necessary but I don't know yet
  28. how to tell if it is or not PM }
  29. res:=200;
  30. if SigInfo^.si_code<>FPE_INTDIV then
  31. begin
  32. if assigned(ucontext^.uc_mcontext.fpstate) then
  33. begin
  34. FpuState:=ucontext^.uc_mcontext.fpstate^.sw;
  35. if (FpuState and FPU_ExceptionMask) <> 0 then
  36. begin
  37. { first check the more precise options }
  38. if (FpuState and FPU_DivisionByZero)<>0 then
  39. res:=208
  40. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow or FPU_Invalid))<>0 Then
  41. res:=207
  42. else if (FpuState and FPU_Overflow)<>0 then
  43. res:=205
  44. else if (FpuState and FPU_Underflow)<>0 then
  45. res:=206
  46. else if (FpuState and FPU_Denormal)<>0 then
  47. res:=216
  48. else
  49. res:=207; {'Coprocessor Error'}
  50. end;
  51. { SSE data? }
  52. if ucontext^.uc_mcontext.fpstate^.magic<>$ffff then
  53. begin
  54. MMState:=ucontext^.uc_mcontext.fpstate^.mxcsr;
  55. if (MMState and MM_ExceptionMask)<>0 then
  56. begin
  57. { first check the more precise options }
  58. if (MMState and MM_DivisionByZero)<>0 then
  59. res:=208
  60. else if (MMState and MM_Invalid)<>0 Then
  61. res:=207
  62. else if (MMState and MM_Overflow)<>0 then
  63. res:=205
  64. else if (MMState and MM_Underflow)<>0 then
  65. res:=206
  66. else if (MMState and MM_Denormal)<>0 then
  67. res:=216
  68. else
  69. res:=207; {'Coprocessor Error'}
  70. end;
  71. end;
  72. with ucontext^.uc_mcontext.fpstate^ do
  73. begin
  74. { Reset Status word }
  75. sw:=sw and not FPU_ExceptionMask;
  76. { Restoree default control word }
  77. cw:=Default8087CW;
  78. { Reset Tag word to $ffff for all empty }
  79. tag:=$ffff;
  80. end;
  81. end;
  82. end;
  83. end;
  84. SIGBUS:
  85. res:=214;
  86. SIGILL:
  87. if sse_check then
  88. begin
  89. os_supports_sse:=false;
  90. res:=0;
  91. inc(ucontext^.uc_mcontext.eip,3);
  92. end
  93. else
  94. res:=216;
  95. SIGSEGV :
  96. res:=216;
  97. SIGINT:
  98. res:=217;
  99. SIGQUIT:
  100. res:=233;
  101. end;
  102. reenable_signal(sig);
  103. { give runtime error at the position where the signal was raised }
  104. if res<>0 then
  105. begin
  106. ucontext^.uc_mcontext.eax := res;
  107. ucontext^.uc_mcontext.edx := ucontext^.uc_mcontext.eip;
  108. ucontext^.uc_mcontext.ecx := ucontext^.uc_mcontext.ebp;
  109. ucontext^.uc_mcontext.eip := ptruint(@SignalToHandleErrorAddrFrame);
  110. end;
  111. end;