]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/Ia32/LongJump.c
cf5fc5b58d0ffc3f5408f3fa80afc6023b308101
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / LongJump.c
1 /** @file
2 Implementation of _LongJump() on IA-32.
3
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9
10 #include "BaseLibInternals.h"
11
12
13 /**
14 Restores the CPU context that was saved with SetJump().
15
16 Restores the CPU context from the buffer specified by JumpBuffer.
17 This function never returns to the caller.
18 Instead is resumes execution based on the state of JumpBuffer.
19
20 @param JumpBuffer A pointer to CPU context buffer.
21 @param Value The value to return when the SetJump() context is restored.
22
23 **/
24 __declspec (naked)
25 VOID
26 EFIAPI
27 InternalLongJump (
28 IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer,
29 IN UINTN Value
30 )
31 {
32 _asm {
33 mov eax, [PcdGet32 (PcdControlFlowEnforcementPropertyMask)]
34 test eax, eax
35 jz CetDone
36 _emit 0x0F
37 _emit 0x20
38 _emit 0xE0 ; mov eax, cr4
39 bt eax, 23 ; check if CET is enabled
40 jnc CetDone
41
42 mov edx, [esp + 4] ; edx = JumpBuffer
43 mov edx, [edx + 24] ; edx = target SSP
44 _emit 0xF3
45 _emit 0x0F
46 _emit 0x1E
47 _emit 0xC8 ; READSSP EAX
48 sub edx, eax ; edx = delta
49 mov eax, edx ; eax = delta
50
51 shr eax, 2 ; eax = delta/sizeof(UINT32)
52 _emit 0xF3
53 _emit 0x0F
54 _emit 0xAE
55 _emit 0xE8 ; INCSSP EAX
56
57 CetDone:
58
59 pop eax ; skip return address
60 pop edx ; edx <- JumpBuffer
61 pop eax ; eax <- Value
62 mov ebx, [edx]
63 mov esi, [edx + 4]
64 mov edi, [edx + 8]
65 mov ebp, [edx + 12]
66 mov esp, [edx + 16]
67 jmp dword ptr [edx + 20]
68 }
69 }
70