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
|
;; Licensed to the .NET Foundation under one or more agreements.
;; The .NET Foundation licenses this file to you under the MIT license.
;; See the LICENSE file in the project root for more information.
.586
.model flat
option casemap:none
.code
;; -----------------------------------------------------------------------------------------------------------
;; standard macros
;; -----------------------------------------------------------------------------------------------------------
LEAF_ENTRY macro Name, Section
Section segment para 'CODE'
public Name
Name proc
endm
LEAF_END macro Name, Section
Name endp
Section ends
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA SECTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
__tls_array equ 2Ch ;; offsetof(TEB, ThreadLocalStoragePointer)
POINTER_SIZE equ 04h
;; TLS variables
_TLS SEGMENT ALIAS(".tls$")
ThunkParamSlot DD 00000000H
_TLS ENDS
ASSUME fs : NOTHING
EXTRN __tls_index:DWORD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Interop Thunks Helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; RhCommonStub
;;
LEAF_ENTRY RhCommonStub, _TEXT
;; There are arbitrary callers passing arguments with arbitrary signatures.
;; Custom calling convention:
;; eax: pointer to the current thunk's data block (data contains 2 pointer values: context + target pointers)
;; Save context data into the ThunkParamSlot thread-local variable
;; A pointer to the delegate and function pointer for open static delegate should have been saved in the thunk's context cell during thunk allocation
;; make some scratch regs
push ecx
push edx
mov ecx, [__tls_index]
mov edx, fs:[__tls_array]
mov ecx, [edx + ecx * POINTER_SIZE]
;; eax = address of context cell in thunk's data
;; ecx = base address of TLS data
;; edx = trashed
;; store thunk address in thread static
mov edx, [eax]
mov eax, [eax + POINTER_SIZE] ;; eax <- target slot data
mov [ecx + OFFSET ThunkParamSlot], edx ;; ThunkParamSlot <- context slot data
;; restore the regs we used
pop edx
pop ecx
;; jump to the target
jmp eax
LEAF_END RhCommonStub, _TEXT
;;
;; IntPtr RhGetCommonStubAddress()
;;
LEAF_ENTRY RhGetCommonStubAddress, _TEXT
lea eax, [RhCommonStub]
ret
LEAF_END RhGetCommonStubAddress, _TEXT
;;
;; IntPtr RhGetCurrentThunkContext()
;;
LEAF_ENTRY RhGetCurrentThunkContext, _TEXT
mov ecx, [__tls_index]
mov edx, fs:[__tls_array]
mov ecx, [edx + ecx * POINTER_SIZE]
mov eax, [ecx + OFFSET ThunkParamSlot] ;; eax <- ThunkParamSlot
ret
LEAF_END RhGetCurrentThunkContext, _TEXT
end
|