sighnd.inc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. getaltfpustate:=sigcontext^.sc_fpustate^.en_sw
  25. else
  26. getaltfpustate:=0;
  27. end;
  28. {$endif}
  29. procedure signal_trampoline; cdecl;
  30. begin
  31. asm
  32. mov %r15,%rdi
  33. mov $0x134,%rax
  34. syscall
  35. mov $0xffffffffffffffff,%rdi
  36. mov $0x1,%rax
  37. syscall
  38. end;
  39. end;
  40. procedure SignalToRunerror(Sig: longint;sininfo:psiginfo; SigContext: PSigContextRec); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
  41. var
  42. res,fpustate : word;
  43. begin
  44. res:=0;
  45. {$ifdef BSD}
  46. {$ifdef cpui386}
  47. fpustate:=0;
  48. asm
  49. fnstsw fpustate
  50. end;
  51. {$endif cpui386}
  52. {$endif BSD}
  53. case sig of
  54. SIGFPE :
  55. begin
  56. { this is not allways necessary but I don't know yet
  57. how to tell if it is or not PM }
  58. res:=200;
  59. {$ifdef cpui386}
  60. fpustate:=GetaltFPUState(sigcontext);
  61. {$else}
  62. fpustate:=0;
  63. {$endif}
  64. if (FpuState and FPU_All) <> 0 then
  65. begin
  66. { first check the more precise options }
  67. if (FpuState and FPU_DivisionByZero)<>0 then
  68. res:=200
  69. else if (FpuState and FPU_Overflow)<>0 then
  70. res:=205
  71. else if (FpuState and FPU_Underflow)<>0 then
  72. res:=206
  73. else if (FpuState and FPU_Denormal)<>0 then
  74. res:=216
  75. else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 then
  76. res:=207
  77. else if (FpuState and FPU_Invalid)<>0 then
  78. res:=216
  79. else
  80. res:=207; {'Coprocessor Error'}
  81. end;
  82. SysResetFPU;
  83. end;
  84. SIGILL,
  85. SIGBUS,
  86. SIGSEGV :
  87. res:=216;
  88. SIGINT:
  89. res:=217;
  90. SIGQUIT:
  91. res:=233;
  92. end;
  93. reenable_signal(sig);
  94. { give runtime error at the position where the signal was raised }
  95. if res<>0 then
  96. begin
  97. {$ifdef cpux86_64}
  98. HandleErrorAddrFrame(res,pointer(SigContext^.sc_rip),pointer(SigContext^.sc_rbp));
  99. {$endif}
  100. end;
  101. end;