tpexcept.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. SetJmp and LongJmp implementation for recovery handling of the
  5. compiler
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  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. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. unit tpexcept;
  19. interface
  20. {$S-}
  21. type
  22. jmp_buf = record
  23. {$ifdef TP}
  24. _ax,_bx,_cx,_dx,_si,_di,_bp,_sp,_ip,flags : word;
  25. _cs,_ds,_es,_ss : word;
  26. {$else}
  27. eax,ebx,ecx,edx,esi,edi,ebp,esp,eip,flags : longint;
  28. cs,ds,es,fs,gs,ss : word;
  29. {$endif TP}
  30. end;
  31. {$ifdef TP}
  32. function setjmp(var rec : jmp_buf) : integer;
  33. procedure longjmp(const rec : jmp_buf;return_value : integer);
  34. {$else}
  35. function setjmp(var rec : jmp_buf) : longint;
  36. procedure longjmp(const rec : jmp_buf;return_value : longint);
  37. {$endif TP}
  38. implementation
  39. {*****************************************************************************
  40. Exception Helpers
  41. *****************************************************************************}
  42. {$ifdef TP}
  43. function setjmp(var rec : jmp_buf) : integer;
  44. begin
  45. asm
  46. push di
  47. push es
  48. les di,rec
  49. mov es:[di].jmp_buf._ax,ax
  50. mov es:[di].jmp_buf._bx,bx
  51. mov es:[di].jmp_buf._cx,cx
  52. mov es:[di].jmp_buf._dx,dx
  53. mov es:[di].jmp_buf._si,si
  54. { load di }
  55. mov ax,[bp-4]
  56. { ... and store it }
  57. mov es:[di].jmp_buf._di,ax
  58. { load es }
  59. mov ax,[bp-6]
  60. { ... and store it }
  61. mov es:[di].jmp_buf._es,ax
  62. { bp ... }
  63. mov ax,[bp]
  64. mov es:[di].jmp_buf._bp,ax
  65. { sp ... }
  66. mov ax,bp
  67. add ax,10
  68. mov es:[di].jmp_buf._sp,ax
  69. { the return address }
  70. mov ax,[bp+2]
  71. mov es:[di].jmp_buf._ip,ax
  72. mov ax,[bp+4]
  73. mov es:[di].jmp_buf._cs,ax
  74. { flags ... }
  75. pushf
  76. pop word ptr es:[di].jmp_buf.flags
  77. mov es:[di].jmp_buf._ds,ds
  78. mov es:[di].jmp_buf._ss,ss
  79. { restore es:di }
  80. pop es
  81. pop di
  82. { we come from the initial call }
  83. xor ax,ax
  84. leave
  85. retf 4
  86. end;
  87. end;
  88. procedure longjmp(const rec : jmp_buf;return_value : integer);
  89. begin
  90. asm
  91. { this is the address of rec }
  92. lds di,rec
  93. { save return value }
  94. mov ax,return_value
  95. mov ds:[di].jmp_buf._ax,ax
  96. { restore compiler shit }
  97. pop bp
  98. { restore some registers }
  99. mov bx,ds:[di].jmp_buf._bx
  100. mov cx,ds:[di].jmp_buf._cx
  101. mov dx,ds:[di].jmp_buf._dx
  102. mov bp,ds:[di].jmp_buf._bp
  103. { create a stack frame for the return }
  104. mov es,ds:[di].jmp_buf._ss
  105. mov si,ds:[di].jmp_buf._sp
  106. sub si,12
  107. { store ds }
  108. mov ax,ds:[di].jmp_buf._ds
  109. mov es:[si],ax
  110. { store di }
  111. mov ax,ds:[di].jmp_buf._di
  112. mov es:[si+2],ax
  113. { store si }
  114. mov ax,ds:[di].jmp_buf._si
  115. mov es:[si+4],ax
  116. { store flags }
  117. mov ax,ds:[di].jmp_buf.flags
  118. mov es:[si+6],ax
  119. { store ip }
  120. mov ax,ds:[di].jmp_buf._ip
  121. mov es:[si+8],ax
  122. { store cs }
  123. mov ax,ds:[di].jmp_buf._cs
  124. mov es:[si+10],ax
  125. { load stack }
  126. mov ax,es
  127. mov ss,ax
  128. mov sp,si
  129. { load return value }
  130. mov ax,ds:[di].jmp_buf._ax
  131. { load old ES }
  132. mov es,ds:[di].jmp_buf._es
  133. pop ds
  134. pop di
  135. pop si
  136. popf
  137. retf
  138. end;
  139. end;
  140. {$else}
  141. function setjmp(var rec : jmp_buf) : longint;
  142. begin
  143. asm
  144. pushl %edi
  145. movl rec,%edi
  146. movl %eax,(%edi)
  147. movl %ebx,4(%edi)
  148. movl %ecx,8(%edi)
  149. movl %edx,12(%edi)
  150. movl %esi,16(%edi)
  151. { load edi }
  152. movl -4(%ebp),%eax
  153. { ... and store it }
  154. movl %eax,20(%edi)
  155. { ebp ... }
  156. movl (%ebp),%eax
  157. movl %eax,24(%edi)
  158. { esp ... }
  159. movl %esp,%eax
  160. addl $12,%eax
  161. movl %eax,28(%edi)
  162. { the return address }
  163. movl 4(%ebp),%eax
  164. movl %eax,32(%edi)
  165. { flags ... }
  166. pushfl
  167. popl 36(%edi)
  168. { !!!!! the segment registers, not yet needed }
  169. { you need them if the exception comes from
  170. an interrupt or a seg_move }
  171. movw %cs,40(%edi)
  172. movw %ds,42(%edi)
  173. movw %es,44(%edi)
  174. movw %fs,46(%edi)
  175. movw %gs,48(%edi)
  176. movw %ss,50(%edi)
  177. { restore EDI }
  178. pop %edi
  179. { we come from the initial call }
  180. xorl %eax,%eax
  181. leave
  182. ret $4
  183. end;
  184. end;
  185. procedure longjmp(const rec : jmp_buf;return_value : longint);
  186. begin
  187. asm
  188. { restore compiler shit }
  189. popl %ebp
  190. { this is the address of rec }
  191. movl 4(%esp),%edi
  192. { save return value }
  193. movl 8(%esp),%eax
  194. movl %eax,0(%edi)
  195. { !!!!! load segment registers }
  196. movw 46(%edi),%fs
  197. movw 48(%edi),%gs
  198. { ... and some other registers }
  199. movl 4(%edi),%ebx
  200. movl 8(%edi),%ecx
  201. movl 12(%edi),%edx
  202. movl 24(%edi),%ebp
  203. { !!!!! movw 50(%edi),%es }
  204. movl 28(%edi),%esi
  205. { create a stack frame for the return }
  206. subl $16,%esi
  207. {
  208. movzwl 42(%edi),%eax
  209. !!!!! es
  210. movl %eax,(%esi)
  211. }
  212. { edi }
  213. movl 20(%edi),%eax
  214. { !!!!! es }
  215. movl %eax,(%esi)
  216. { esi }
  217. movl 16(%edi),%eax
  218. { !!!!! es }
  219. movl %eax,4(%esi)
  220. { eip }
  221. movl 32(%edi),%eax
  222. { !!!!! es }
  223. movl %eax,12(%esi)
  224. { !!!!! cs
  225. movl 40(%edi),%eax
  226. es
  227. movl %eax,16(%esi)
  228. }
  229. { load and store flags }
  230. movl 36(%edi),%eax
  231. { !!!!!
  232. es
  233. }
  234. movl %eax,8(%esi)
  235. { load return value }
  236. movl 0(%edi),%eax
  237. { load old ES
  238. !!!!! movw 44(%edi),%es
  239. }
  240. { load stack
  241. !!!!! movw 50(%edi),%ss }
  242. movl %esi,%esp
  243. { !!!!
  244. popl %ds
  245. }
  246. popl %edi
  247. popl %esi
  248. popfl
  249. ret
  250. end;
  251. end;
  252. {$endif TP}
  253. end.
  254. {
  255. $Log$
  256. Revision 1.1 1998-08-10 10:18:36 peter
  257. + Compiler,Comphook unit which are the new interface units to the
  258. compiler
  259. }