sighnd.inc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. pushq addr
  17. jmp HandleErrorAddrFrame
  18. end;
  19. const
  20. FPU_All = $7f;
  21. function GetFPUState(const SigContext : TSigContext) : word;
  22. begin
  23. if assigned(SigContext.fpstate) then
  24. GetfpuState:=SigContext.fpstate^.swd
  25. else
  26. GetFPUState:=0;
  27. {$ifdef SYSTEM_DEBUG}
  28. writeln('xx:',sigcontext.twd,' ',sigcontext.cwd);
  29. {$endif SYSTEM_DEBUG}
  30. {$ifdef SYSTEM_DEBUG}
  31. Writeln(stderr,'FpuState = ',result);
  32. {$endif SYSTEM_DEBUG}
  33. end;
  34. function GetMMState(const SigContext : TSigContext) : dword;
  35. begin
  36. if assigned(SigContext.fpstate) then
  37. Result:=SigContext.fpstate^.mxcsr
  38. else
  39. Result:=0;
  40. {$ifdef SYSTEM_DEBUG}
  41. Writeln(stderr,'MMState = ',result);
  42. {$endif SYSTEM_DEBUG}
  43. end;
  44. procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
  45. var
  46. res,fpustate,MMState : word;
  47. begin
  48. res:=0;
  49. case sig of
  50. SIGFPE :
  51. begin
  52. { this is not allways necessary but I don't know yet
  53. how to tell if it is or not PM }
  54. res:=200;
  55. if SigInfo^.si_code<>FPE_INTDIV then
  56. begin
  57. fpustate:=GetFPUState(SigContext^);
  58. if (FpuState and FPU_All) <> 0 then
  59. begin
  60. { first check the more precise options }
  61. if (FpuState and FPU_DivisionByZero)<>0 then
  62. res:=208
  63. else if (FpuState and FPU_Overflow)<>0 then
  64. res:=205
  65. else if (FpuState and FPU_Underflow)<>0 then
  66. res:=206
  67. else if (FpuState and FPU_Denormal)<>0 then
  68. res:=216
  69. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow or FPU_Invalid))<>0 Then
  70. res:=207
  71. else
  72. res:=207; {'Coprocessor Error'}
  73. { exceptions are handled, clear all flags
  74. as we return from SignalToRunerrer, we have to clear the exception flags in the context }
  75. if assigned(SigContext^.fpstate) then
  76. SigContext^.fpstate^.swd:=SigContext^.fpstate^.swd and not(FPU_All);
  77. end;
  78. MMState:=getMMState(SigContext^);
  79. if (MMState and MM_ExceptionMask)<>0 then
  80. begin
  81. { first check the more precise options }
  82. if (MMState and MM_DivisionByZero)<>0 then
  83. res:=208
  84. else if (MMState and MM_Invalid)<>0 Then
  85. res:=207
  86. else if (MMState and MM_Overflow)<>0 then
  87. res:=205
  88. else if (MMState and MM_Underflow)<>0 then
  89. res:=206
  90. else if (MMState and MM_Denormal)<>0 then
  91. res:=216
  92. else
  93. res:=207; {'Coprocessor Error'}
  94. { exceptions are handled, clear all flags
  95. as we return from SignalToRunerrer, we have to clear the exception flags in the context }
  96. if assigned(SigContext^.fpstate) then
  97. SigContext^.fpstate^.mxcsr:=SigContext^.fpstate^.mxcsr and not(MM_ExceptionMask);
  98. end;
  99. end;
  100. SysResetFPU;
  101. end;
  102. SIGILL,
  103. SIGBUS,
  104. SIGSEGV:
  105. res:=216;
  106. SIGINT:
  107. res:=217;
  108. SIGQUIT:
  109. res:=233;
  110. end;
  111. reenable_signal(sig);
  112. if res<>0 then
  113. begin
  114. SigContext^.rdi := res;
  115. SigContext^.rsi := SigContext^.rip;
  116. SigContext^.rdx := SigContext^.rbp;
  117. SigContext^.rip := ptruint(@SignalToHandleErrorAddrFrame);
  118. end;
  119. end;