-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
StubDispatch.S
92 lines (71 loc) · 3.7 KB
/
StubDispatch.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
// 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 <AsmOffsets.inc> // generated by the build from AsmOffsets.cpp
#include <unixasmmacros.inc>
// trick to avoid PLT relocation at runtime which corrupts registers
#define REL_C_FUNC(name) C_FUNC(name)@gotpcrel
// Macro that generates a stub consuming a cache with the given number of entries.
.macro DEFINE_INTERFACE_DISPATCH_STUB entries
LEAF_ENTRY RhpInterfaceDispatch\entries, _TEXT
// r10 currently contains the indirection cell address.
// load r11 to point to the cache block.
mov r11, [r10 + OFFSETOF__InterfaceDispatchCell__m_pCache]
// Load the MethodTable from the object instance in rdi.
ALTERNATE_ENTRY RhpInterfaceDispatchAVLocation\entries
mov rax, [rdi]
CurrentOffset = OFFSETOF__InterfaceDispatchCache__m_rgEntries
// For each entry in the cache, see if its MethodTable type matches the MethodTable in rax.
// If so, call the second cache entry. If not, skip the InterfaceDispatchCacheEntry.
.rept \entries
cmp rax, [r11 + CurrentOffset]
jne 0f
jmp [r11 + CurrentOffset + 8]
0:
CurrentOffset = CurrentOffset + 16
.endr
// r10 still contains the indirection cell address.
jmp C_FUNC(RhpInterfaceDispatchSlow)
LEAF_END RhpInterfaceDispatch\entries, _TEXT
.endm // DEFINE_INTERFACE_DISPATCH_STUB
// Define all the stub routines we currently need.
//
// The mrt100dbi requires these be exported to identify mrt100 code that dispatches back into managed.
// If you change or add any new dispatch stubs, please also change slr.def and dbi\process.cpp CordbProcess::GetExportStepInfo
//
// If you change or add any new dispatch stubs, exception handling might need to be aware because it refers to the
// *AVLocation symbols defined by the dispatch stubs to be able to unwind and blame user code if a NullRef happens
// during the interface dispatch.
//
DEFINE_INTERFACE_DISPATCH_STUB 1
DEFINE_INTERFACE_DISPATCH_STUB 2
DEFINE_INTERFACE_DISPATCH_STUB 4
DEFINE_INTERFACE_DISPATCH_STUB 8
DEFINE_INTERFACE_DISPATCH_STUB 16
DEFINE_INTERFACE_DISPATCH_STUB 32
DEFINE_INTERFACE_DISPATCH_STUB 64
// Stub dispatch routine for dispatch to a vtable slot
LEAF_ENTRY RhpVTableOffsetDispatch, _TEXT
// UNIXTODO: Implement this function
int 3
LEAF_END RhpVTableOffsetDispatch, _TEXT
// Initial dispatch on an interface when we don't have a cache yet.
LEAF_ENTRY RhpInitialInterfaceDispatch, _TEXT
ALTERNATE_ENTRY RhpInitialDynamicInterfaceDispatch
// Trigger an AV if we're dispatching on a null this.
// The exception handling infrastructure is aware of the fact that this is the first
// instruction of RhpInitialInterfaceDispatch and uses it to translate an AV here
// to a NullReferenceException at the callsite.
cmp byte ptr [rdi], 0
// Just tail call to the cache miss helper.
jmp C_FUNC(RhpInterfaceDispatchSlow)
LEAF_END RhpInitialInterfaceDispatch, _TEXT
// Cache miss case, call the runtime to resolve the target and update the cache.
// Use universal transition helper to allow an exception to flow out of resolution
LEAF_ENTRY RhpInterfaceDispatchSlow, _TEXT
// r10 contains indirection cell address, move to r11 where it will be passed by
// the universal transition thunk as an argument to RhpCidResolve
mov r11, r10
mov r10, [rip + REL_C_FUNC(RhpCidResolve)]
jmp qword ptr [rip + REL_C_FUNC(RhpUniversalTransition_DebugStepTailCall)]
LEAF_END RhpInterfaceDispatchSlow, _TEXT