RegisterState.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. #include <LibC/sys/arch/i386/regs.h>
  9. #include <Kernel/Arch/x86/ASM_wrapper.h>
  10. #include <Kernel/Arch/x86/CPU.h>
  11. namespace Kernel {
  12. struct [[gnu::packed]] RegisterState {
  13. #if ARCH(I386)
  14. FlatPtr ss;
  15. FlatPtr gs;
  16. FlatPtr fs;
  17. FlatPtr es;
  18. FlatPtr ds;
  19. FlatPtr edi;
  20. FlatPtr esi;
  21. FlatPtr ebp;
  22. FlatPtr esp;
  23. FlatPtr ebx;
  24. FlatPtr edx;
  25. FlatPtr ecx;
  26. FlatPtr eax;
  27. #else
  28. FlatPtr rdi;
  29. FlatPtr rsi;
  30. FlatPtr rbp;
  31. FlatPtr rsp;
  32. FlatPtr rbx;
  33. FlatPtr rdx;
  34. FlatPtr rcx;
  35. FlatPtr rax;
  36. FlatPtr r8;
  37. FlatPtr r9;
  38. FlatPtr r10;
  39. FlatPtr r11;
  40. FlatPtr r12;
  41. FlatPtr r13;
  42. FlatPtr r14;
  43. FlatPtr r15;
  44. #endif
  45. u16 exception_code;
  46. u16 isr_number;
  47. #if ARCH(X86_64)
  48. u32 padding;
  49. #endif
  50. #if ARCH(I386)
  51. FlatPtr eip;
  52. #else
  53. FlatPtr rip;
  54. #endif
  55. FlatPtr cs;
  56. #if ARCH(I386)
  57. FlatPtr eflags;
  58. FlatPtr userspace_esp;
  59. FlatPtr userspace_ss;
  60. #else
  61. FlatPtr rflags;
  62. FlatPtr userspace_rsp;
  63. FlatPtr userspace_ss;
  64. #endif
  65. FlatPtr userspace_sp() const
  66. {
  67. #if ARCH(I386)
  68. return userspace_esp;
  69. #else
  70. return userspace_rsp;
  71. #endif
  72. }
  73. FlatPtr ip() const
  74. {
  75. #if ARCH(I386)
  76. return eip;
  77. #else
  78. return rip;
  79. #endif
  80. }
  81. FlatPtr bp() const
  82. {
  83. #if ARCH(I386)
  84. return ebp;
  85. #else
  86. return rbp;
  87. #endif
  88. }
  89. FlatPtr flags() const
  90. {
  91. #if ARCH(I386)
  92. return eflags;
  93. #else
  94. return rflags;
  95. #endif
  96. }
  97. void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3) const
  98. {
  99. #if ARCH(I386)
  100. function = eax;
  101. arg1 = edx;
  102. arg2 = ecx;
  103. arg3 = ebx;
  104. #else
  105. function = rax;
  106. arg1 = rdx;
  107. arg2 = rcx;
  108. arg3 = rbx;
  109. #endif
  110. }
  111. void set_ip_reg(FlatPtr value)
  112. {
  113. #if ARCH(I386)
  114. eip = value;
  115. #else
  116. rip = value;
  117. #endif
  118. }
  119. void set_return_reg(FlatPtr value)
  120. {
  121. #if ARCH(I386)
  122. eax = value;
  123. #else
  124. rax = value;
  125. #endif
  126. }
  127. };
  128. #if ARCH(I386)
  129. # define REGISTER_STATE_SIZE (19 * 4)
  130. #else
  131. # define REGISTER_STATE_SIZE (22 * 8)
  132. #endif
  133. static_assert(REGISTER_STATE_SIZE == sizeof(RegisterState));
  134. inline void copy_kernel_registers_into_ptrace_registers(PtraceRegisters& ptrace_regs, const RegisterState& kernel_regs)
  135. {
  136. #if ARCH(I386)
  137. ptrace_regs.eax = kernel_regs.eax,
  138. ptrace_regs.ecx = kernel_regs.ecx,
  139. ptrace_regs.edx = kernel_regs.edx,
  140. ptrace_regs.ebx = kernel_regs.ebx,
  141. ptrace_regs.esp = kernel_regs.userspace_esp,
  142. ptrace_regs.ebp = kernel_regs.ebp,
  143. ptrace_regs.esi = kernel_regs.esi,
  144. ptrace_regs.edi = kernel_regs.edi,
  145. ptrace_regs.eip = kernel_regs.eip,
  146. ptrace_regs.eflags = kernel_regs.eflags,
  147. #else
  148. ptrace_regs.rax = kernel_regs.rax,
  149. ptrace_regs.rcx = kernel_regs.rcx,
  150. ptrace_regs.rdx = kernel_regs.rdx,
  151. ptrace_regs.rbx = kernel_regs.rbx,
  152. ptrace_regs.rsp = kernel_regs.userspace_rsp,
  153. ptrace_regs.rbp = kernel_regs.rbp,
  154. ptrace_regs.rsi = kernel_regs.rsi,
  155. ptrace_regs.rdi = kernel_regs.rdi,
  156. ptrace_regs.rip = kernel_regs.rip,
  157. ptrace_regs.r8 = kernel_regs.r8;
  158. ptrace_regs.r9 = kernel_regs.r9;
  159. ptrace_regs.r10 = kernel_regs.r10;
  160. ptrace_regs.r11 = kernel_regs.r11;
  161. ptrace_regs.r12 = kernel_regs.r12;
  162. ptrace_regs.r13 = kernel_regs.r13;
  163. ptrace_regs.r14 = kernel_regs.r14;
  164. ptrace_regs.r15 = kernel_regs.r15;
  165. ptrace_regs.rflags = kernel_regs.rflags,
  166. #endif
  167. ptrace_regs.cs = 0;
  168. ptrace_regs.ss = 0;
  169. ptrace_regs.ds = 0;
  170. ptrace_regs.es = 0;
  171. ptrace_regs.fs = 0;
  172. ptrace_regs.gs = 0;
  173. }
  174. inline void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, const PtraceRegisters& ptrace_regs)
  175. {
  176. #if ARCH(I386)
  177. kernel_regs.eax = ptrace_regs.eax;
  178. kernel_regs.ecx = ptrace_regs.ecx;
  179. kernel_regs.edx = ptrace_regs.edx;
  180. kernel_regs.ebx = ptrace_regs.ebx;
  181. kernel_regs.esp = ptrace_regs.esp;
  182. kernel_regs.ebp = ptrace_regs.ebp;
  183. kernel_regs.esi = ptrace_regs.esi;
  184. kernel_regs.edi = ptrace_regs.edi;
  185. kernel_regs.eip = ptrace_regs.eip;
  186. kernel_regs.eflags = (kernel_regs.eflags & ~safe_eflags_mask) | (ptrace_regs.eflags & safe_eflags_mask);
  187. #else
  188. kernel_regs.rax = ptrace_regs.rax;
  189. kernel_regs.rcx = ptrace_regs.rcx;
  190. kernel_regs.rdx = ptrace_regs.rdx;
  191. kernel_regs.rbx = ptrace_regs.rbx;
  192. kernel_regs.rsp = ptrace_regs.rsp;
  193. kernel_regs.rbp = ptrace_regs.rbp;
  194. kernel_regs.rsi = ptrace_regs.rsi;
  195. kernel_regs.rdi = ptrace_regs.rdi;
  196. kernel_regs.rip = ptrace_regs.rip;
  197. kernel_regs.r8 = ptrace_regs.r8;
  198. kernel_regs.r9 = ptrace_regs.r9;
  199. kernel_regs.r10 = ptrace_regs.r10;
  200. kernel_regs.r11 = ptrace_regs.r11;
  201. kernel_regs.r12 = ptrace_regs.r12;
  202. kernel_regs.r13 = ptrace_regs.r13;
  203. kernel_regs.r14 = ptrace_regs.r14;
  204. kernel_regs.r15 = ptrace_regs.r15;
  205. // FIXME: do we need a separate safe_rflags_mask here?
  206. kernel_regs.rflags = (kernel_regs.rflags & ~safe_eflags_mask) | (ptrace_regs.rflags & safe_eflags_mask);
  207. #endif
  208. }
  209. struct [[gnu::packed]] DebugRegisterState {
  210. FlatPtr dr0;
  211. FlatPtr dr1;
  212. FlatPtr dr2;
  213. FlatPtr dr3;
  214. FlatPtr dr6;
  215. FlatPtr dr7;
  216. };
  217. inline void read_debug_registers_into(DebugRegisterState& state)
  218. {
  219. state.dr0 = read_dr0();
  220. state.dr1 = read_dr1();
  221. state.dr2 = read_dr2();
  222. state.dr3 = read_dr3();
  223. state.dr6 = read_dr6();
  224. state.dr7 = read_dr7();
  225. }
  226. inline void write_debug_registers_from(const DebugRegisterState& state)
  227. {
  228. write_dr0(state.dr0);
  229. write_dr1(state.dr1);
  230. write_dr2(state.dr2);
  231. write_dr3(state.dr3);
  232. write_dr6(state.dr6);
  233. write_dr7(state.dr7);
  234. }
  235. inline void clear_debug_registers()
  236. {
  237. write_dr0(0);
  238. write_dr1(0);
  239. write_dr2(0);
  240. write_dr3(0);
  241. write_dr7(1 << 10); // Bit 10 is reserved and must be set to 1.
  242. }
  243. }