chkstk.S 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* ---------------------------------------------- */
  2. /* chkstk86.s */
  3. /* ---------------------------------------------- */
  4. #ifndef __x86_64__
  5. /* ---------------------------------------------- */
  6. .globl __chkstk
  7. __chkstk:
  8. xchg (%esp),%ebp /* store ebp, get ret.addr */
  9. push %ebp /* push ret.addr */
  10. lea 4(%esp),%ebp /* setup frame ptr */
  11. push %ecx /* save ecx */
  12. mov %ebp,%ecx
  13. P0:
  14. sub $4096,%ecx
  15. test %eax,(%ecx)
  16. sub $4096,%eax
  17. cmp $4096,%eax
  18. jge P0
  19. sub %eax,%ecx
  20. test %eax,(%ecx)
  21. mov %esp,%eax
  22. mov %ecx,%esp
  23. mov (%eax),%ecx /* restore ecx */
  24. jmp *4(%eax)
  25. /* ---------------------------------------------- */
  26. #else
  27. /* ---------------------------------------------- */
  28. .globl __chkstk
  29. __chkstk:
  30. xchg (%rsp),%rbp /* store ebp, get ret.addr */
  31. push %rbp /* push ret.addr */
  32. lea 8(%rsp),%rbp /* setup frame ptr */
  33. push %rcx /* save ecx */
  34. mov %rbp,%rcx
  35. movslq %eax,%rax
  36. P0:
  37. sub $4096,%rcx
  38. test %rax,(%rcx)
  39. sub $4096,%rax
  40. cmp $4096,%rax
  41. jge P0
  42. sub %rax,%rcx
  43. test %rax,(%rcx)
  44. mov %rsp,%rax
  45. mov %rcx,%rsp
  46. mov (%rax),%rcx /* restore ecx */
  47. jmp *8(%rax)
  48. /* ---------------------------------------------- */
  49. /* setjmp/longjmp support */
  50. .globl tinyc_getbp
  51. tinyc_getbp:
  52. mov %rbp,%rax
  53. ret
  54. /* ---------------------------------------------- */
  55. #endif
  56. /* ---------------------------------------------- */
  57. /* ---------------------------------------------- */
  58. #ifndef __x86_64__
  59. /* ---------------------------------------------- */
  60. /*
  61. int _except_handler3(
  62. PEXCEPTION_RECORD exception_record,
  63. PEXCEPTION_REGISTRATION registration,
  64. PCONTEXT context,
  65. PEXCEPTION_REGISTRATION dispatcher
  66. );
  67. int __cdecl _XcptFilter(
  68. unsigned long xcptnum,
  69. PEXCEPTION_POINTERS pxcptinfoptrs
  70. );
  71. struct _sehrec {
  72. void *esp; // 0
  73. void *exception_pointers; // 1
  74. void *prev; // 2
  75. void *handler; // 3
  76. void *scopetable; // 4
  77. int trylevel; // 5
  78. void *ebp // 6
  79. };
  80. // this is what the assembler code below means:
  81. __try
  82. {
  83. // ...
  84. }
  85. __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation()))
  86. {
  87. exit(GetExceptionCode());
  88. }
  89. */
  90. .globl _exception_info
  91. _exception_info:
  92. mov 1*4-24(%ebp),%eax
  93. ret
  94. .globl _exception_code
  95. _exception_code:
  96. call _exception_info
  97. mov (%eax),%eax
  98. mov (%eax),%eax
  99. ret
  100. seh_filter:
  101. call _exception_info
  102. push %eax
  103. call _exception_code
  104. push %eax
  105. call _XcptFilter
  106. add $ 8,%esp
  107. ret
  108. seh_except:
  109. mov 0*4-24(%ebp),%esp
  110. call _exception_code
  111. push %eax
  112. call _exit
  113. // msvcrt wants scopetables aligned and in read-only segment (using .text)
  114. .align 4
  115. seh_scopetable:
  116. .long -1
  117. .long seh_filter
  118. .long seh_except
  119. seh_handler:
  120. jmp _except_handler3
  121. .globl ___try__
  122. ___try__:
  123. .globl __try__
  124. __try__:
  125. push %ebp
  126. mov 8(%esp),%ebp
  127. // void *esp;
  128. lea 12(%esp),%eax
  129. mov %eax,0*4(%ebp)
  130. // void *exception_pointers;
  131. xor %eax,%eax
  132. mov %eax,1*4(%ebp)
  133. // void *prev;
  134. mov %fs:0,%eax
  135. mov %eax,2*4(%ebp)
  136. // void *handler;
  137. mov $ seh_handler,%eax
  138. mov %eax,3*4(%ebp)
  139. // void *scopetable;
  140. mov $ seh_scopetable,%eax
  141. mov %eax,4*4(%ebp)
  142. // int trylevel;
  143. xor %eax,%eax
  144. mov %eax,5*4(%ebp)
  145. // register new SEH
  146. lea 2*4(%ebp),%eax
  147. mov %eax,%fs:0
  148. pop %ebp
  149. ret
  150. /* ---------------------------------------------- */
  151. #else
  152. /* ---------------------------------------------- */
  153. /* SEH on x86-64 not implemented */
  154. /* ---------------------------------------------- */
  155. #endif
  156. /* ---------------------------------------------- */