forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathContext.S
71 lines (62 loc) · 3.08 KB
/
Context.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
.intel_syntax noprefix
#include "unixasmmacros.inc"
#include "asmconstants.h"
// Some constants for CONTEXT.ContextFlags. The arch bit (CONTEXT_AMD64) is normally set in these flag constants below. Since
// this is already arch-specific code and the arch bit is not relevant, the arch bit is excluded from the flag constants below
// for simpler tests.
#define CONTEXT_CONTROL 1
#define CONTEXT_INTEGER 2
// Signature: EXTERN_C void STDCALL ClrRestoreNonvolatileContextWorker(PCONTEXT ContextRecord, DWORD64 ssp);
// Note that this method is used to invoke EH funclets that take arguments in rcx and rdx, which is why those
// registers are restored below in addition to the non-volatile registers.
NESTED_ENTRY ClrRestoreNonvolatileContextWorker, _TEXT, NoHandler
push_nonvol_reg rbp
set_cfa_register rbp, 0
END_PROLOGUE
mov r10, rdi
mov r11, rsi
test byte ptr [r10 + OFFSETOF__CONTEXT__ContextFlags], CONTEXT_INTEGER
je Done_Restore_CONTEXT_INTEGER
mov rbx, [r10 + OFFSETOF__CONTEXT__Rbx]
mov rcx, [r10 + OFFSETOF__CONTEXT__Rcx]
mov rdx, [r10 + OFFSETOF__CONTEXT__Rdx]
mov r8, [r10 + OFFSETOF__CONTEXT__R8]
mov r9, [r10 + OFFSETOF__CONTEXT__R9]
mov rbp, [r10 + OFFSETOF__CONTEXT__Rbp]
mov rsi, [r10 + OFFSETOF__CONTEXT__Rsi]
mov rdi, [r10 + OFFSETOF__CONTEXT__Rdi]
mov r12, [r10 + OFFSETOF__CONTEXT__R12]
mov r13, [r10 + OFFSETOF__CONTEXT__R13]
mov r14, [r10 + OFFSETOF__CONTEXT__R14]
mov r15, [r10 + OFFSETOF__CONTEXT__R15]
Done_Restore_CONTEXT_INTEGER:
test byte ptr [r10 + OFFSETOF__CONTEXT__ContextFlags], CONTEXT_CONTROL
je Done_Restore_CONTEXT_CONTROL
test r11, r11
je No_Ssp_Update
rdsspq rax
sub r11, rax
shr r11, 3
// the incsspq instruction uses only the lowest 8 bits of the argument, so we need to loop in case the increment is larger than 255
mov rax, 255
Update_Loop:
cmp r11, rax
cmovb rax, r11
incsspq rax
sub r11, rax
ja Update_Loop
No_Ssp_Update:
// When user-mode shadow stacks are enabled, and for example the intent is to continue execution in managed code after
// exception handling, iret and ret can't be used because their shadow stack enforcement would not allow that transition,
// and using them would require writing to the shadow stack, which is not preferable. Instead, iret is partially
// simulated.
mov rax, [r10 + OFFSETOF__CONTEXT__Rip]
mov rsp, [r10 + OFFSETOF__CONTEXT__Rsp]
jmp rax
Done_Restore_CONTEXT_CONTROL:
// The function was not asked to restore the control registers so we return back to the caller
pop rbp
ret
NESTED_END ClrRestoreNonvolatileContextWorker, _TEXT