forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpinvokestubs.S
130 lines (101 loc) · 4.03 KB
/
pinvokestubs.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 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"
//
// IN:
// InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
// before actual InlinedCallFrame data)
//
//
LEAF_ENTRY JIT_PInvokeBegin, _TEXT
// set first slot to the value of InlinedCallFrame identifier (checked by runtime code)
mov dword ptr [ecx], FRAMETYPE_InlinedCallFrame
mov dword ptr [ecx + InlinedCallFrame__m_Datum], 0
mov eax, esp
add eax, 4
mov dword ptr [ecx + InlinedCallFrame__m_pCallSiteSP], eax
mov dword ptr [ecx + InlinedCallFrame__m_pCalleeSavedFP], ebp
mov eax, [esp]
mov dword ptr [ecx + InlinedCallFrame__m_pCallerReturnAddress], eax
// edx = GetThread(). Trashes eax
push ecx
push edx
push esi
push edi
call C_FUNC(GetThreadHelper)
pop edi
pop esi
pop edx
pop ecx
mov edx, eax
// pFrame->m_Next = pThread->m_pFrame;
mov eax, dword ptr [edx + Thread_m_pFrame]
mov dword ptr [ecx + Frame__m_Next], eax
// pThread->m_pFrame = pFrame;
mov dword ptr [edx + Thread_m_pFrame], ecx
// pThread->m_fPreemptiveGCDisabled = 0
mov dword ptr [edx + Thread_m_fPreemptiveGCDisabled], 0
ret
LEAF_END JIT_PInvokeBegin, _TEXT
//
// IN:
// InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
// before actual InlinedCallFrame data)
//
//
LEAF_ENTRY JIT_PInvokeEnd, _TEXT
// edx = GetThread(). Trashes eax
push ecx
push edx
push esi
push edi
call C_FUNC(GetThreadHelper)
pop edi
pop esi
pop edx
pop ecx
mov edx, eax
// ecx = pFrame
// edx = pThread
// pThread->m_fPreemptiveGCDisabled = 1
mov dword ptr [edx + Thread_m_fPreemptiveGCDisabled], 1
// Check return trap
PREPARE_EXTERNAL_VAR g_TrapReturningThreads, eax
cmp DWORD PTR [eax], 0
jnz C_FUNC(JIT_PInvokeEndRarePath)
// pThread->m_pFrame = pFrame->m_Next
mov eax, dword ptr [ecx + Frame__m_Next]
mov dword ptr [edx + Thread_m_pFrame], eax
ret
LEAF_END JIT_PInvokeEnd, _TEXT
//
// IN:
// InlinedCallFrame (edi) = pointer to the InlinedCallFrame data
// OUT:
// Thread (esi) = pointer to Thread data
//
//
LEAF_ENTRY JIT_InitPInvokeFrame, _TEXT
// esi = GetThread(). Trashes eax
push ecx
push edx
call GetThreadHelper
pop edx
pop ecx
mov esi, eax
// edi = pFrame
// esi = pThread
// set first slot to the value of InlinedCallFrame identifier (checked by runtime code)
mov dword ptr [edi], FRAMETYPE_InlinedCallFrame
// pFrame->m_Next = pThread->m_pFrame;
mov eax, dword ptr [esi + Thread_m_pFrame]
mov dword ptr [edi + Frame__m_Next], eax
mov dword ptr [edi + InlinedCallFrame__m_pCalleeSavedFP], ebp
mov dword ptr [edi + InlinedCallFrame__m_pCallerReturnAddress], 0
// pThread->m_pFrame = pFrame;
mov dword ptr [esi + Thread_m_pFrame], edi
// leave current Thread in ESI
ret
LEAF_END JIT_InitPInvokeFrame, _TEXT