psarch.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. psarch.c
  9. Abstract:
  10. This module implements architecture specific functionality for the process
  11. and thread library.
  12. Author:
  13. Evan Green 11-Jun-2017
  14. Environment:
  15. Kernel
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/kernel.h>
  21. #include <minoca/kernel/x64.h>
  22. #include <minoca/debug/dbgproto.h>
  23. #include "../psp.h"
  24. //
  25. // --------------------------------------------------------------------- Macros
  26. //
  27. //
  28. // This macro returns non-zero if the given segment descriptor is a valid
  29. // user segment selector.
  30. //
  31. #define VALID_USER_SEGMENT(_Segment) \
  32. (((_Segment) & SEGMENT_PRIVILEGE_USER) == SEGMENT_PRIVILEGE_USER)
  33. //
  34. // ---------------------------------------------------------------- Definitions
  35. //
  36. //
  37. // Define the length of both the int $N instruction and the syscall instruction.
  38. //
  39. #define X86_SYSCALL_INSTRUCTION_LENGTH 2
  40. //
  41. // ------------------------------------------------------ Data Type Definitions
  42. //
  43. //
  44. // ----------------------------------------------- Internal Function Prototypes
  45. //
  46. //
  47. // -------------------------------------------------------------------- Globals
  48. //
  49. //
  50. // Define the initial architecture-specific contents of the thread pointer data
  51. // for a newly created thread.
  52. //
  53. const ULONGLONG PsInitialThreadPointer = 0;
  54. //
  55. // ------------------------------------------------------------------ Functions
  56. //
  57. ULONG
  58. PsDequeuePendingSignal (
  59. PSIGNAL_PARAMETERS SignalParameters,
  60. PTRAP_FRAME TrapFrame
  61. )
  62. /*++
  63. Routine Description:
  64. This routine dequeues the first signal in the thread or process signal mask
  65. of the current thread that is not handled by any default processing.
  66. Arguments:
  67. SignalParameters - Supplies a pointer to a caller-allocated structure where
  68. the signal parameter information might get returned.
  69. TrapFrame - Supplies a pointer to the current trap frame. If this trap frame
  70. is not destined for user mode, this function exits immediately.
  71. Return Value:
  72. Returns a signal number if a signal was queued.
  73. -1 if no signal was dispatched.
  74. --*/
  75. {
  76. BOOL SignalHandled;
  77. ULONG SignalNumber;
  78. //
  79. // If the trap frame is not destined for user mode, then forget it.
  80. //
  81. if (IS_TRAP_FRAME_FROM_PRIVILEGED_MODE(TrapFrame) != FALSE) {
  82. return -1;
  83. }
  84. do {
  85. SignalNumber = PspDequeuePendingSignal(SignalParameters,
  86. TrapFrame,
  87. NULL);
  88. if (SignalNumber == -1) {
  89. break;
  90. }
  91. SignalHandled = PspSignalAttemptDefaultProcessing(SignalNumber);
  92. } while (SignalHandled != FALSE);
  93. return SignalNumber;
  94. }
  95. VOID
  96. PsApplySynchronousSignal (
  97. PTRAP_FRAME TrapFrame,
  98. PSIGNAL_PARAMETERS SignalParameters,
  99. BOOL InSystemCall
  100. )
  101. /*++
  102. Routine Description:
  103. This routine applies the given signal onto the current thread. It is
  104. required that no signal is already in progress, nor will any other signals
  105. be applied for the duration of the system call.
  106. Arguments:
  107. TrapFrame - Supplies a pointer to the current trap frame. This trap frame
  108. must be destined for user mode.
  109. SignalParameters - Supplies a pointer to the signal information to apply.
  110. InSystemCall - Supplies a boolean indicating if the trap frame came from
  111. a system call, in which case this routine will look inside to
  112. potentially prepare restart information.
  113. Return Value:
  114. None.
  115. --*/
  116. {
  117. PSIGNAL_CONTEXT_X64 Context;
  118. UINTN ContextSp;
  119. ULONG Flags;
  120. PSIGNAL_SET RestoreSignals;
  121. BOOL Result;
  122. KSTATUS Status;
  123. INTN SystemCallResult;
  124. PKTHREAD Thread;
  125. Thread = KeGetCurrentThread();
  126. ContextSp = TrapFrame->Rsp - X64_RED_ZONE - sizeof(SIGNAL_CONTEXT_X64);
  127. ContextSp = ALIGN_RANGE_DOWN(ContextSp, FPU_CONTEXT_ALIGNMENT);
  128. Context = (PVOID)ContextSp;
  129. Flags = 0;
  130. Result = MmUserWrite(&(Context->Common.Next), 0);
  131. RestoreSignals = &(Thread->BlockedSignals);
  132. if ((Thread->Flags & THREAD_FLAG_RESTORE_SIGNALS) != 0) {
  133. RestoreSignals = &(Thread->RestoreSignals);
  134. Thread->Flags &= ~THREAD_FLAG_RESTORE_SIGNALS;
  135. }
  136. Status = MmCopyToUserMode(&(Context->Common.Mask),
  137. RestoreSignals,
  138. sizeof(SIGNAL_SET));
  139. //
  140. // The trap frame had better be complete or else kernel data might be being
  141. // leaked.
  142. //
  143. ASSERT(ArIsTrapFrameComplete(TrapFrame));
  144. //
  145. // TODO: Support alternate signal stacks.
  146. //
  147. Result &= MmUserWrite(&(Context->Common.Stack.Base), 0);
  148. Result &= MmUserWrite(&(Context->Common.Stack.Size), 0);
  149. Result &= MmUserWrite32(&(Context->Common.Stack.Flags), 0);
  150. ASSERT(ArIsTrapFrameComplete(TrapFrame) != FALSE);
  151. Status |= MmCopyToUserMode(&(Context->TrapFrame),
  152. TrapFrame,
  153. sizeof(TRAP_FRAME));
  154. TrapFrame->Rsp = ContextSp;
  155. TrapFrame->Rsi = TrapFrame->Rsp;
  156. if ((Thread->FpuFlags & THREAD_FPU_FLAG_IN_USE) != 0) {
  157. Flags |= SIGNAL_CONTEXT_FLAG_FPU_VALID;
  158. if ((Thread->FpuFlags & THREAD_FPU_FLAG_OWNER) != 0) {
  159. ArSaveFpuState(Thread->FpuContext);
  160. }
  161. Status |= MmCopyToUserMode(&(Context->FpuContext),
  162. Thread->FpuContext,
  163. sizeof(FPU_CONTEXT));
  164. }
  165. //
  166. // If this signal is being applied in the middle of a system call, the trap
  167. // frame needs modification if it is restartable. EAX holds the system call
  168. // result.
  169. //
  170. SystemCallResult = (INTN)TrapFrame->Rax;
  171. if ((InSystemCall != FALSE) &&
  172. (IS_SYSTEM_CALL_NUMBER_RESTARTABLE(TrapFrame->Rdi)) &&
  173. (IS_SYSTEM_CALL_RESULT_RESTARTABLE(SystemCallResult) != FALSE)) {
  174. //
  175. // If the result indicates that the system call is restartable after a
  176. // signal is applied, then let user mode know by setting the restart
  177. // flag in the context.
  178. //
  179. if (IS_SYSTEM_CALL_RESULT_RESTARTABLE_AFTER_SIGNAL(SystemCallResult)) {
  180. Flags |= SIGNAL_CONTEXT_FLAG_RESTART;
  181. }
  182. //
  183. // In case the handler does not allow restarts, convert the saved
  184. // restart status to the interrupted status.
  185. //
  186. MmUserWrite(&(Context->TrapFrame.Rax), STATUS_INTERRUPTED);
  187. }
  188. Result &= MmUserWrite32(&(Context->Common.Flags), Flags);
  189. TrapFrame->Rsp -= sizeof(SIGNAL_PARAMETERS);
  190. TrapFrame->Rdi = TrapFrame->Rsp;
  191. Status |= MmCopyToUserMode((PVOID)(TrapFrame->Rsp),
  192. SignalParameters,
  193. sizeof(SIGNAL_PARAMETERS));
  194. if ((Status != STATUS_SUCCESS) || (Result == FALSE)) {
  195. PsHandleUserModeFault((PVOID)(TrapFrame->Rsp),
  196. FAULT_FLAG_WRITE | FAULT_FLAG_PAGE_NOT_PRESENT,
  197. TrapFrame,
  198. Thread->OwningProcess);
  199. PsApplyPendingSignals(TrapFrame);
  200. }
  201. TrapFrame->Rip = (UINTN)(Thread->OwningProcess->SignalHandlerRoutine);
  202. TrapFrame->Rflags &= ~IA32_EFLAG_TF;
  203. ADD_SIGNAL(Thread->BlockedSignals, SignalParameters->SignalNumber);
  204. return;
  205. }
  206. INTN
  207. PspRestorePreSignalTrapFrame (
  208. PTRAP_FRAME TrapFrame,
  209. PSIGNAL_CONTEXT UserContext
  210. )
  211. /*++
  212. Routine Description:
  213. This routine restores the original user mode thread context for the thread
  214. before a signal was invoked.
  215. Arguments:
  216. TrapFrame - Supplies a pointer to the trap frame from this system call.
  217. UserContext - Supplies the user context to restore.
  218. Return Value:
  219. Returns the architecture-specific return register from the thread context.
  220. --*/
  221. {
  222. PSIGNAL_CONTEXT_X64 Context;
  223. ULONG Flags;
  224. TRAP_FRAME Frame;
  225. UINTN Rflags;
  226. SIGNAL_SET SignalMask;
  227. KSTATUS Status;
  228. PKTHREAD Thread;
  229. Context = (PSIGNAL_CONTEXT_X64)UserContext;
  230. Thread = KeGetCurrentThread();
  231. Status = MmCopyFromUserMode(&Frame,
  232. &(Context->TrapFrame),
  233. sizeof(TRAP_FRAME));
  234. Status |= MmCopyFromUserMode(&SignalMask,
  235. &(Context->Common.Mask),
  236. sizeof(SIGNAL_SET));
  237. if (!MmUserRead32(&(UserContext->Flags), &Flags)) {
  238. Status = STATUS_ACCESS_VIOLATION;
  239. }
  240. if (!KSUCCESS(Status)) {
  241. goto RestorePreSignalTrapFrameEnd;
  242. }
  243. PsSetSignalMask(&SignalMask, NULL);
  244. //
  245. // Sanitize RFLAGS, ES, and DS. Then copy the whole trap frame.
  246. //
  247. Rflags = TrapFrame->Rflags & ~IA32_EFLAG_USER;
  248. Frame.Rflags = (Frame.Rflags & IA32_EFLAG_USER) | Rflags;
  249. Frame.Ds = USER_DS;
  250. Frame.Es = USER_DS;
  251. RtlCopyMemory(TrapFrame, &Frame, sizeof(TRAP_FRAME));
  252. if (((Flags & SIGNAL_CONTEXT_FLAG_FPU_VALID) != 0) &&
  253. (Thread->FpuContext != NULL)) {
  254. Status = MmCopyFromUserMode(Thread->FpuContext,
  255. &(Context->FpuContext),
  256. sizeof(FPU_CONTEXT));
  257. if (!KSUCCESS(Status)) {
  258. goto RestorePreSignalTrapFrameEnd;
  259. }
  260. Thread->FpuFlags |= THREAD_FPU_FLAG_IN_USE;
  261. if ((Thread->FpuFlags & THREAD_FPU_FLAG_OWNER) != 0) {
  262. ArDisableFpu();
  263. Thread->FpuFlags &= ~THREAD_FPU_FLAG_OWNER;
  264. }
  265. }
  266. //
  267. // If the signal context indicates that a system call restart is necessary,
  268. // then back up RIP so that the system call gets executed again when the
  269. // trap frame gets restored. Both int $N and syscall instructions are two
  270. // bytes long, so there's no need to distinguish.
  271. //
  272. if ((Flags & SIGNAL_CONTEXT_FLAG_RESTART) != 0) {
  273. TrapFrame->Rip -= X86_SYSCALL_INSTRUCTION_LENGTH;
  274. }
  275. RestorePreSignalTrapFrameEnd:
  276. if (!KSUCCESS(Status)) {
  277. PsSignalThread(Thread, SIGNAL_ACCESS_VIOLATION, NULL, TRUE);
  278. }
  279. //
  280. // Preserve RAX by returning it. The system call assembly return path
  281. // guarantees this.
  282. //
  283. return (INTN)TrapFrame->Rax;
  284. }
  285. VOID
  286. PspArchRestartSystemCall (
  287. PTRAP_FRAME TrapFrame
  288. )
  289. /*++
  290. Routine Description:
  291. This routine determines whether or not a system call needs to be restarted.
  292. If so, it modifies the given trap frame such that the system call return
  293. to user mode will fall right back into calling the system call.
  294. Arguments:
  295. TrapFrame - Supplies a pointer to the full trap frame saved by a system
  296. call in order to attempt dispatching a signal.
  297. Return Value:
  298. None.
  299. --*/
  300. {
  301. //
  302. // On x86, the trap frame holds the system call return value in RAX. Check
  303. // to see if the system call can be restarted. If not, exit.
  304. //
  305. if (!IS_SYSTEM_CALL_NUMBER_RESTARTABLE(TrapFrame->Rdi) ||
  306. !IS_SYSTEM_CALL_RESULT_RESTARTABLE_NO_SIGNAL((INTN)TrapFrame->Rax)) {
  307. return;
  308. }
  309. //
  310. // Back up over the syscall instruction.
  311. //
  312. TrapFrame->Rip -= X86_SYSCALL_INSTRUCTION_LENGTH;
  313. return;
  314. }
  315. VOID
  316. PspPrepareThreadForFirstRun (
  317. PKTHREAD Thread,
  318. PTRAP_FRAME TrapFrame,
  319. BOOL ParameterIsStack
  320. )
  321. /*++
  322. Routine Description:
  323. This routine performs any architecture specific initialization to prepare a
  324. thread for being context swapped for the first time.
  325. Arguments:
  326. Thread - Supplies a pointer to the thread being prepared for its first run.
  327. TrapFrame - Supplies an optional pointer for the thread to restore on its
  328. first run.
  329. ParameterIsStack - Supplies a boolean indicating whether the thread
  330. parameter is the value that should be used as the initial stack pointer.
  331. Return Value:
  332. None.
  333. --*/
  334. {
  335. ULONG CodeSelector;
  336. ULONG DataSelector;
  337. UINTN Rip;
  338. PUINTN StackPointer;
  339. PTRAP_FRAME StackTrapFrame;
  340. UINTN TrapStackPointer;
  341. PUINTN UserStackPointer;
  342. TrapStackPointer = (UINTN)Thread->KernelStack + Thread->KernelStackSize -
  343. sizeof(UINTN);
  344. StackPointer = (PUINTN)TrapStackPointer;
  345. //
  346. // Zero out the last word so that debugger call stacks terminate, and a
  347. // return from the thread function would fault predictably.
  348. //
  349. *StackPointer = 0;
  350. //
  351. // Determine the appropriate value for the flags, code selector, and entry
  352. // point.
  353. //
  354. if ((Thread->Flags & THREAD_FLAG_USER_MODE) != 0) {
  355. ASSERT((TrapFrame == NULL) || (ParameterIsStack == FALSE));
  356. //
  357. // Set up the values on the user mode stack. Push a dummy return
  358. // address.
  359. //
  360. if (TrapFrame == NULL) {
  361. if (ParameterIsStack != FALSE) {
  362. UserStackPointer = Thread->ThreadParameter - sizeof(PVOID);
  363. ASSERT(((PVOID)UserStackPointer >= Thread->UserStack) &&
  364. ((PVOID)UserStackPointer <
  365. Thread->UserStack + Thread->UserStackSize));
  366. } else {
  367. UserStackPointer = Thread->UserStack + Thread->UserStackSize -
  368. sizeof(PVOID);
  369. }
  370. MmUserWrite(UserStackPointer, 0);
  371. TrapStackPointer = (UINTN)UserStackPointer;
  372. }
  373. //
  374. // Set the variables that will be used to set up the kernel stack.
  375. //
  376. CodeSelector = USER64_CS;
  377. DataSelector = USER_DS;
  378. Rip = (UINTN)Thread->ThreadRoutine;
  379. } else {
  380. CodeSelector = KERNEL_CS;
  381. DataSelector = KERNEL_DS;
  382. Rip = (UINTN)PspKernelThreadStart;
  383. }
  384. //
  385. // Make room for a trap frame to be restored.
  386. //
  387. StackPointer = (PUINTN)((PUCHAR)StackPointer - sizeof(TRAP_FRAME));
  388. StackTrapFrame = (PTRAP_FRAME)StackPointer;
  389. if (TrapFrame != NULL) {
  390. if (ArIsTrapFrameComplete(TrapFrame) != FALSE) {
  391. RtlCopyMemory(StackTrapFrame, TrapFrame, sizeof(TRAP_FRAME));
  392. //
  393. // Return a process ID of 0 to the child on fork, and return the
  394. // child's process ID in the parent.
  395. //
  396. StackTrapFrame->Rax = 0;
  397. } else {
  398. //
  399. // User mode tried to pull a fast one by forking with the fast
  400. // system call handler path. Joke's on them; zero out the registers
  401. // that didn't get saved.
  402. //
  403. RtlZeroMemory(StackTrapFrame, sizeof(TRAP_FRAME));
  404. StackTrapFrame->Rip = TrapFrame->Rip;
  405. StackTrapFrame->Rsp = TrapFrame->Rsp;
  406. }
  407. } else {
  408. RtlZeroMemory(StackTrapFrame, sizeof(TRAP_FRAME));
  409. StackTrapFrame->Rip = Rip;
  410. StackTrapFrame->Rsp = TrapStackPointer;
  411. StackTrapFrame->Rdi = (UINTN)Thread->ThreadParameter;
  412. }
  413. StackTrapFrame->Ds = DataSelector;
  414. StackTrapFrame->Es = DataSelector;
  415. StackTrapFrame->Fs = DataSelector;
  416. StackTrapFrame->Gs = DataSelector;
  417. StackTrapFrame->Ss = DataSelector;
  418. StackTrapFrame->Cs = CodeSelector;
  419. StackTrapFrame->Rflags = IA32_EFLAG_ALWAYS_1 | IA32_EFLAG_IF;
  420. Thread->KernelStackPointer = StackPointer;
  421. return;
  422. }
  423. INTN
  424. PspArchResetThreadContext (
  425. PKTHREAD Thread,
  426. PTRAP_FRAME TrapFrame
  427. )
  428. /*++
  429. Routine Description:
  430. This routine sets up the given trap frame as if the user mode portion of
  431. the thread was running for the first time.
  432. Arguments:
  433. Thread - Supplies a pointer to the thread being reset.
  434. TrapFrame - Supplies a pointer where the initial thread's trap frame will
  435. be returned.
  436. Return Value:
  437. The value that the thread should return when exiting back to user mode.
  438. --*/
  439. {
  440. PUINTN UserStackPointer;
  441. Thread->ThreadPointer = 0;
  442. UserStackPointer = Thread->ThreadParameter - sizeof(PVOID);
  443. ASSERT(((PVOID)UserStackPointer >= Thread->UserStack) &&
  444. ((PVOID)UserStackPointer <
  445. Thread->UserStack + Thread->UserStackSize));
  446. MmUserWrite(UserStackPointer, 0);
  447. RtlZeroMemory(TrapFrame, sizeof(TRAP_FRAME));
  448. TrapFrame->Cs = USER64_CS;
  449. TrapFrame->Ds = USER_DS;
  450. TrapFrame->Es = USER_DS;
  451. TrapFrame->Fs = USER_DS;
  452. TrapFrame->Gs = USER_DS;
  453. TrapFrame->Ss = USER_DS;
  454. TrapFrame->Rip = (UINTN)Thread->ThreadRoutine;
  455. TrapFrame->Rflags = IA32_EFLAG_ALWAYS_1 | IA32_EFLAG_IF;
  456. TrapFrame->Rsp = (UINTN)UserStackPointer;
  457. TrapFrame->Rdi = (UINTN)Thread->ThreadParameter;
  458. if ((Thread->FpuFlags & THREAD_FPU_FLAG_IN_USE) != 0) {
  459. Thread->FpuFlags &= ~(THREAD_FPU_FLAG_IN_USE | THREAD_FPU_FLAG_OWNER);
  460. ArDisableFpu();
  461. }
  462. //
  463. // Return 0 as this will make its way to EAX when the system call returns.
  464. //
  465. return 0;
  466. }
  467. KSTATUS
  468. PspArchCloneThread (
  469. PKTHREAD OldThread,
  470. PKTHREAD NewThread
  471. )
  472. /*++
  473. Routine Description:
  474. This routine performs architecture specific operations upon cloning a
  475. thread.
  476. Arguments:
  477. OldThread - Supplies a pointer to the thread being copied.
  478. NewThread - Supplies a pointer to the newly created thread.
  479. Return Value:
  480. Status code.
  481. --*/
  482. {
  483. return STATUS_SUCCESS;
  484. }
  485. KSTATUS
  486. PspArchGetDebugBreakInformation (
  487. PTRAP_FRAME TrapFrame
  488. )
  489. /*++
  490. Routine Description:
  491. This routine gets the current debug break information.
  492. Arguments:
  493. TrapFrame - Supplies a pointer to the user mode trap frame that caused the
  494. break.
  495. Return Value:
  496. Status code.
  497. --*/
  498. {
  499. PBREAK_NOTIFICATION Break;
  500. PPROCESS_DEBUG_DATA DebugData;
  501. PKPROCESS Process;
  502. PKTHREAD Thread;
  503. Thread = KeGetCurrentThread();
  504. Process = Thread->OwningProcess;
  505. DebugData = Process->DebugData;
  506. ASSERT(DebugData != NULL);
  507. ASSERT(DebugData->DebugLeaderThread == Thread);
  508. ASSERT(DebugData->DebugCommand.Command == DebugCommandGetBreakInformation);
  509. ASSERT(DebugData->DebugCommand.Size == sizeof(BREAK_NOTIFICATION));
  510. Break = DebugData->DebugCommand.Data;
  511. Break->Exception = ExceptionSignal;
  512. Break->ProcessorOrThreadNumber = Thread->ThreadId;
  513. Break->ProcessorOrThreadCount = Process->ThreadCount;
  514. Break->Process = Process->Identifiers.ProcessId;
  515. Break->ProcessorBlock = (UINTN)NULL;
  516. Break->LoadedModuleCount = Process->ImageCount;
  517. Break->LoadedModuleSignature = Process->ImageListSignature;
  518. Break->InstructionPointer = TrapFrame->Rip;
  519. RtlZeroMemory(Break->InstructionStream, sizeof(Break->InstructionStream));
  520. MmCopyFromUserMode(Break->InstructionStream,
  521. (PVOID)TrapFrame->Rip,
  522. sizeof(Break->InstructionStream));
  523. if (ArIsTrapFrameComplete(TrapFrame) != FALSE) {
  524. Break->ErrorCode = TrapFrame->ErrorCode;
  525. Break->Registers.X64.Rax = TrapFrame->Rax;
  526. Break->Registers.X64.Rbx = TrapFrame->Rbx;
  527. Break->Registers.X64.Rcx = TrapFrame->Rcx;
  528. Break->Registers.X64.Rdx = TrapFrame->Rdx;
  529. Break->Registers.X64.Rbp = TrapFrame->Rbp;
  530. Break->Registers.X64.Rsi = TrapFrame->Rsi;
  531. Break->Registers.X64.Rdi = TrapFrame->Rdi;
  532. Break->Registers.X64.R8 = TrapFrame->R8;
  533. Break->Registers.X64.R9 = TrapFrame->R9;
  534. Break->Registers.X64.R10 = TrapFrame->R10;
  535. Break->Registers.X64.R11 = TrapFrame->R11;
  536. Break->Registers.X64.R12 = TrapFrame->R12;
  537. Break->Registers.X64.R13 = TrapFrame->R13;
  538. Break->Registers.X64.R14 = TrapFrame->R14;
  539. Break->Registers.X64.R15 = TrapFrame->R15;
  540. Break->Registers.X64.Rflags = TrapFrame->Rflags;
  541. Break->Registers.X64.Cs = TrapFrame->Cs;
  542. Break->Registers.X64.Ds = TrapFrame->Ds;
  543. Break->Registers.X64.Es = TrapFrame->Es;
  544. Break->Registers.X64.Fs = TrapFrame->Fs;
  545. Break->Registers.X64.Gs = TrapFrame->Gs;
  546. Break->Registers.X64.Ss = TrapFrame->Ss;
  547. } else {
  548. RtlZeroMemory(&(Break->Registers.X64), sizeof(Break->Registers.X64));
  549. Break->ErrorCode = 0;
  550. Break->Registers.X64.Cs = USER64_CS;
  551. Break->Registers.X64.Ds = USER_DS;
  552. Break->Registers.X64.Es = USER_DS;
  553. Break->Registers.X64.Fs = USER_DS;
  554. Break->Registers.X64.Gs = USER_DS;
  555. Break->Registers.X64.Ss = USER_DS;
  556. }
  557. Break->Registers.X64.Rip = TrapFrame->Rip;
  558. Break->Registers.X64.Rsp = TrapFrame->Rsp;
  559. return STATUS_SUCCESS;
  560. }
  561. KSTATUS
  562. PspArchSetDebugBreakInformation (
  563. PTRAP_FRAME TrapFrame
  564. )
  565. /*++
  566. Routine Description:
  567. This routine sets the current debug break information, mostly just the
  568. register.
  569. Arguments:
  570. TrapFrame - Supplies a pointer to the user mode trap frame that caused the
  571. break.
  572. Return Value:
  573. Status code.
  574. --*/
  575. {
  576. PBREAK_NOTIFICATION Break;
  577. PPROCESS_DEBUG_DATA DebugData;
  578. PKPROCESS Process;
  579. PKTHREAD Thread;
  580. Thread = KeGetCurrentThread();
  581. Process = Thread->OwningProcess;
  582. DebugData = Process->DebugData;
  583. ASSERT(DebugData != NULL);
  584. ASSERT(DebugData->DebugLeaderThread == Thread);
  585. ASSERT(DebugData->DebugCommand.Command == DebugCommandSetBreakInformation);
  586. ASSERT(DebugData->DebugCommand.Size == sizeof(BREAK_NOTIFICATION));
  587. Break = DebugData->DebugCommand.Data;
  588. if ((!VALID_USER_SEGMENT(Break->Registers.X64.Cs)) ||
  589. (!VALID_USER_SEGMENT(Break->Registers.X64.Ds)) ||
  590. (!VALID_USER_SEGMENT(Break->Registers.X64.Es)) ||
  591. (!VALID_USER_SEGMENT(Break->Registers.X64.Fs)) ||
  592. (!VALID_USER_SEGMENT(Break->Registers.X64.Gs)) ||
  593. (!VALID_USER_SEGMENT(Break->Registers.X64.Ss))) {
  594. return STATUS_INVALID_PARAMETER;
  595. }
  596. TrapFrame->Rax = Break->Registers.X64.Rax;
  597. TrapFrame->Rbx = Break->Registers.X64.Rbx;
  598. TrapFrame->Rcx = Break->Registers.X64.Rcx;
  599. TrapFrame->Rdx = Break->Registers.X64.Rdx;
  600. TrapFrame->Rbp = Break->Registers.X64.Rbp;
  601. TrapFrame->Rsp = Break->Registers.X64.Rsp;
  602. TrapFrame->Rsi = Break->Registers.X64.Rsi;
  603. TrapFrame->Rdi = Break->Registers.X64.Rdi;
  604. TrapFrame->R8 = Break->Registers.X64.R8;
  605. TrapFrame->R9 = Break->Registers.X64.R9;
  606. TrapFrame->R10 = Break->Registers.X64.R10;
  607. TrapFrame->R11 = Break->Registers.X64.R11;
  608. TrapFrame->R12 = Break->Registers.X64.R12;
  609. TrapFrame->R13 = Break->Registers.X64.R13;
  610. TrapFrame->R14 = Break->Registers.X64.R14;
  611. TrapFrame->R15 = Break->Registers.X64.R15;
  612. TrapFrame->Rip = Break->Registers.X64.Rip;
  613. TrapFrame->Rflags = (Break->Registers.X64.Rflags & IA32_EFLAG_USER) |
  614. IA32_EFLAG_ALWAYS_1 | IA32_EFLAG_IF;
  615. TrapFrame->Cs = Break->Registers.X64.Cs | SEGMENT_PRIVILEGE_USER;
  616. TrapFrame->Ds = Break->Registers.X64.Ds | SEGMENT_PRIVILEGE_USER;
  617. TrapFrame->Es = Break->Registers.X64.Es | SEGMENT_PRIVILEGE_USER;
  618. TrapFrame->Fs = Break->Registers.X64.Fs | SEGMENT_PRIVILEGE_USER;
  619. TrapFrame->Gs = Break->Registers.X64.Gs | SEGMENT_PRIVILEGE_USER;
  620. TrapFrame->Ss = Break->Registers.X64.Ss | SEGMENT_PRIVILEGE_USER;
  621. return STATUS_SUCCESS;
  622. }
  623. KSTATUS
  624. PspArchSetOrClearSingleStep (
  625. PTRAP_FRAME TrapFrame,
  626. BOOL Set
  627. )
  628. /*++
  629. Routine Description:
  630. This routine sets the current thread into single step mode.
  631. Arguments:
  632. TrapFrame - Supplies a pointer to the user mode trap frame that caused the
  633. break.
  634. Set - Supplies a boolean indicating whether to set single step mode (TRUE)
  635. or clear single step mode (FALSE).
  636. Return Value:
  637. Status code.
  638. --*/
  639. {
  640. PKPROCESS Process;
  641. Process = PsGetCurrentProcess();
  642. ASSERT(Process != PsGetKernelProcess());
  643. ASSERT(IS_TRAP_FRAME_FROM_PRIVILEGED_MODE(TrapFrame) == FALSE);
  644. if (Set != FALSE) {
  645. TrapFrame->Rflags |= IA32_EFLAG_TF;
  646. } else {
  647. TrapFrame->Rflags &= ~IA32_EFLAG_TF;
  648. }
  649. return STATUS_SUCCESS;
  650. }
  651. //
  652. // --------------------------------------------------------- Internal Functions
  653. //