machdep.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* machdep.S - machine dependent assembly routines for the GDB stub */
  2. /*
  3. * Copyright (C) 2006 Lubomir Kundrak
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  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. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <grub/cpu/gdb.h>
  20. #include <grub/symbol.h>
  21. #define EC_PRESENT 1
  22. #define EC_ABSENT 0
  23. #define GRUB_GDB_STACKSIZE 40000
  24. #define SEP ,
  25. #ifdef __APPLE__
  26. .zerofill __DATA, __bss, LOCAL(grub_gdb_stack_end), GRUB_GDB_STACKSIZE, 4
  27. LOCAL(grub_gdb_stack) = LOCAL(grub_gdb_stack_end)
  28. #else
  29. /*
  30. * The .data index for the address vector.
  31. */
  32. #define VECTOR 1
  33. .bss
  34. .space GRUB_GDB_STACKSIZE
  35. VARIABLE(grub_gdb_stack)
  36. #endif
  37. /*
  38. * Supplemental macros for register saving/restoration
  39. * on exception handler entry/leave.
  40. */
  41. #ifdef __APPLE__
  42. .macro save32
  43. #define REG $0
  44. #define NDX $1
  45. #else
  46. .macro save32 reg ndx
  47. #define REG \reg
  48. #define NDX \ndx
  49. #endif
  50. movl REG, EXT_C(grub_gdb_regs)+(NDX * 4)
  51. .endm
  52. #undef REG
  53. #undef NDX
  54. #ifdef __APPLE__
  55. .macro save16
  56. #define REG $0
  57. #define NDX $1
  58. #else
  59. .macro save16 reg ndx
  60. #define REG \reg
  61. #define NDX \ndx
  62. #endif
  63. xorl %eax, %eax
  64. movw REG, EXT_C(grub_gdb_regs)+(NDX * 4)
  65. movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2)
  66. movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax
  67. .endm
  68. #undef REG
  69. #undef NDX
  70. #ifdef __APPLE__
  71. .macro load32
  72. #define NDX $0
  73. #define REG $1
  74. #else
  75. .macro load32 ndx reg
  76. #define REG \reg
  77. #define NDX \ndx
  78. #endif
  79. movl EXT_C(grub_gdb_regs)+(NDX * 4), REG
  80. .endm
  81. #undef REG
  82. #undef NDX
  83. #ifdef __APPLE__
  84. .macro load16
  85. #define NDX $0
  86. #define REG $1
  87. #else
  88. .macro load16 ndx reg
  89. #define NDX \ndx
  90. #define REG \reg
  91. #endif
  92. movw EXT_C(grub_gdb_regs)+(NDX * 4), REG
  93. .endm
  94. #undef REG
  95. #undef NDX
  96. .macro save_context
  97. save32 %eax, EAX
  98. save32 %ecx, ECX
  99. save32 %edx, EDX
  100. save32 %ebx, EBX
  101. save32 %ebp, EBP
  102. save32 %esi, ESI
  103. save32 %edi, EDI
  104. popl %ebx
  105. save32 %ebx, EIP
  106. popl %ebx
  107. save32 %ebx, CS
  108. popl %ebx
  109. save32 %ebx, EFLAGS
  110. save32 %esp, ESP
  111. save16 %ds, DS
  112. save16 %es, ES
  113. save16 %fs, FS
  114. save16 %gs, GS
  115. save16 %ss, SS
  116. .endm
  117. .macro load_context
  118. load16 SS, %ss
  119. load32 ESP, %esp
  120. load32 EBP, %ebp
  121. load32 ESI, %esi
  122. load32 EDI, %edi
  123. load16 DS, %ds
  124. load16 ES, %es
  125. load16 FS, %fs
  126. load16 GS, %gs
  127. load32 EFLAGS, %eax
  128. pushl %eax
  129. load32 CS, %eax
  130. pushl %eax
  131. load32 EIP, %eax
  132. pushl %eax
  133. load32 EBX, %ebx
  134. load32 EDX, %edx
  135. load32 ECX, %ecx
  136. load32 EAX, %eax
  137. .endm
  138. /*
  139. * This macro creates handlers for a given range of exception numbers
  140. * and adds their addresses to the grub_gdb_trapvec array.
  141. */
  142. #ifdef __APPLE__
  143. .macro ent
  144. #define EC $0
  145. #define BEG $1
  146. #define END $2
  147. #else
  148. .macro ent ec beg end=0
  149. #define EC \ec
  150. #define BEG \beg
  151. #define END \end
  152. #endif
  153. /*
  154. * Wrapper body itself.
  155. */
  156. .text
  157. 1:
  158. .if EC
  159. add MACRO_DOLLAR(4), %esp
  160. .endif
  161. save_context
  162. #ifdef __APPLE__
  163. mov $LOCAL(grub_gdb_stack), %esp
  164. #else
  165. mov $EXT_C(grub_gdb_stack), %esp
  166. #endif
  167. mov $(BEG), %eax /* trap number */
  168. call EXT_C(grub_gdb_trap)
  169. load_context
  170. iret
  171. /*
  172. * Address entry in trapvec array.
  173. */
  174. #ifdef __APPLE__
  175. .section __DATA, VECTOR
  176. #else
  177. .data VECTOR
  178. #endif
  179. .long 1b
  180. /*
  181. * Next... (recursion).
  182. */
  183. .if END-BEG > 0
  184. #ifdef __APPLE__
  185. ent EC, (BEG+1), END
  186. #else
  187. ent \ec "(\beg+1)" \end
  188. #endif
  189. .endif
  190. .endm
  191. /*
  192. * Here does the actual construction of the address array and handlers
  193. * take place.
  194. */
  195. #ifdef __APPLE__
  196. .section __DATA, VECTOR
  197. #else
  198. .data VECTOR
  199. #endif
  200. VARIABLE(grub_gdb_trapvec)
  201. ent EC_ABSENT, 0, 7
  202. ent EC_PRESENT, 8
  203. ent EC_ABSENT, 9
  204. ent EC_PRESENT, 10, 14
  205. /*
  206. * You may have to split this further or as(1)
  207. * will complain about nesting being too deep.
  208. */
  209. ent EC_ABSENT, 15, GRUB_GDB_LAST_TRAP