tpexcept.pas 7.8 KB

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