]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/SetJump.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / SetJump.c
CommitLineData
e1f414b6 1/** @file\r
2 Implementation of SetJump() on IA-32.\r
3\r
0aac2f77 4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 6\r
7**/\r
8\r
1efcc4ae 9\r
47fc17d8 10#include "BaseLibInternals.h"\r
f734a10a 11\r
42eedea9 12/**\r
13 Worker function that checks ASSERT condition for JumpBuffer\r
e1f414b6 14\r
42eedea9 15 Checks ASSERT condition for JumpBuffer.\r
16\r
17 If JumpBuffer is NULL, then ASSERT().\r
18 For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().\r
19\r
20 @param JumpBuffer A pointer to CPU context buffer.\r
21\r
22**/\r
e1f414b6 23VOID\r
24EFIAPI\r
25InternalAssertJumpBuffer (\r
26 IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer\r
27 );\r
28\r
42eedea9 29/**\r
30 Saves the current CPU context that can be restored with a call to LongJump()\r
31 and returns 0.\r
32\r
33 Saves the current CPU context in the buffer specified by JumpBuffer and\r
34 returns 0. The initial call to SetJump() must always return 0. Subsequent\r
35 calls to LongJump() cause a non-zero value to be returned by SetJump().\r
36\r
37 If JumpBuffer is NULL, then ASSERT().\r
38 For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().\r
39\r
40 @param JumpBuffer A pointer to CPU context buffer.\r
41\r
42 @retval 0 Indicates a return from SetJump().\r
43\r
44**/\r
e1f414b6 45_declspec (naked)\r
2117989c 46RETURNS_TWICE\r
e1f414b6 47UINTN\r
48EFIAPI\r
49SetJump (\r
50 OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer\r
51 )\r
52{\r
53 _asm {\r
54 push [esp + 4]\r
55 call InternalAssertJumpBuffer\r
56 pop ecx\r
57 pop ecx\r
58 mov edx, [esp]\r
0aac2f77
JY
59\r
60 xor eax, eax\r
61 mov [edx + 24], eax ; save 0 to SSP\r
62\r
63 mov eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]\r
64 test eax, eax\r
65 jz CetDone\r
66 _emit 0x0F\r
67 _emit 0x20\r
68 _emit 0xE0 ; mov eax, cr4\r
69 bt eax, 23 ; check if CET is enabled\r
70 jnc CetDone\r
71\r
72 mov eax, 1\r
73 _emit 0xF3\r
74 _emit 0x0F\r
75 _emit 0xAE\r
76 _emit 0xE8 ; INCSSP EAX to read original SSP\r
77 _emit 0xF3\r
78 _emit 0x0F\r
79 _emit 0x1E\r
80 _emit 0xC8 ; READSSP EAX\r
81 mov [edx + 0x24], eax ; save SSP\r
82\r
83CetDone:\r
84\r
e1f414b6 85 mov [edx], ebx\r
86 mov [edx + 4], esi\r
87 mov [edx + 8], edi\r
88 mov [edx + 12], ebp\r
89 mov [edx + 16], esp\r
90 mov [edx + 20], ecx\r
91 xor eax, eax\r
92 jmp ecx\r
93 }\r
94}\r
95\r