sighnd.inc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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:=200
  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. end;
  74. MMState:=getMMState(SigContext^);
  75. if (MMState and MM_ExceptionMask)<>0 then
  76. begin
  77. { first check the more precise options }
  78. if (MMState and MM_DivisionByZero)<>0 then
  79. res:=208
  80. else if (MMState and MM_Invalid)<>0 Then
  81. res:=207
  82. else if (MMState and MM_Overflow)<>0 then
  83. res:=205
  84. else if (MMState and MM_Underflow)<>0 then
  85. res:=206
  86. else if (MMState and MM_Denormal)<>0 then
  87. res:=216
  88. else
  89. res:=207; {'Coprocessor Error'}
  90. end;
  91. end;
  92. SysResetFPU;
  93. end;
  94. SIGILL,
  95. SIGBUS,
  96. SIGSEGV:
  97. res:=216;
  98. SIGINT:
  99. res:=217;
  100. SIGQUIT:
  101. res:=233;
  102. end;
  103. reenable_signal(sig);
  104. if res<>0 then
  105. begin
  106. SigContext^.rdi := res;
  107. SigContext^.rsi := SigContext^.rip;
  108. SigContext^.rdx := SigContext^.rbp;
  109. SigContext^.rip := ptruint(@SignalToHandleErrorAddrFrame);
  110. end;
  111. end;