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
|
// 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.
//; ==++==
//;
//;
//; ==--==
#include "asmconstants.h"
#include "unixasmmacros.inc"
.syntax unified
.thumb
// ------------------------------------------------------------------
// Macro to generate PInvoke Stubs.
// Params :-
// \__PInvokeStubFuncName : function which calls the actual stub obtained from VASigCookie
// \__PInvokeGenStubFuncName : function which generates the IL stubs for PInvoke
// \__PInvokeStubWorkerName : prefix of the function name for the stub
// \VASigCookieReg : register which contains the VASigCookie
// \SaveFPArgs : "1" or "0" . For varidic functions FP Args are not present in FP regs
// So need not save FP Args registers for vararg Pinvoke
.macro PINVOKE_STUB __PInvokeStubFuncName,__PInvokeGenStubFuncName,__PInvokeStubWorkerName,VASigCookieReg,SaveFPArgs
NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler
// save reg value before using the reg
PROLOG_PUSH {\VASigCookieReg}
// get the stub
ldr \VASigCookieReg, [\VASigCookieReg,#VASigCookie__pNDirectILStub]
// if null goto stub generation
cbz \VASigCookieReg, \__PInvokeStubFuncName\()Label
EPILOG_STACK_FREE 4
EPILOG_BRANCH_REG \VASigCookieReg
\__PInvokeStubFuncName\()Label:
EPILOG_POP {\VASigCookieReg}
EPILOG_BRANCH \__PInvokeGenStubFuncName
NESTED_END \__PInvokeStubFuncName, _TEXT
NESTED_ENTRY \__PInvokeGenStubFuncName, _TEXT, NoHandler
PROLOG_WITH_TRANSITION_BLOCK 0, \SaveFPArgs
// r2 = UnmanagedTarget\ MethodDesc
mov r2, r12
// r1 = VaSigCookie
.ifnc \VASigCookieReg, r1
mov r1, \VASigCookieReg
.endif
// r0 = pTransitionBlock
add r0, sp, #__PWTB_TransitionBlock
// save hidden arg
mov r4, r12
bl \__PInvokeStubWorkerName
// restore hidden arg (method desc or unmanaged target)
mov r12, r4
EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
EPILOG_BRANCH \__PInvokeStubFuncName
NESTED_END \__PInvokeGenStubFuncName, _TEXT
.endmacro
// ------------------------------------------------------------------
// VarargPInvokeStub & VarargPInvokeGenILStub
// There is a separate stub when the method has a hidden return buffer arg.
//
// in:
// r0 = VASigCookie*
// r12 = MethodDesc *
//
PINVOKE_STUB VarargPInvokeStub, VarargPInvokeGenILStub, VarargPInvokeStubWorker, r0, 0
// ------------------------------------------------------------------
// GenericPInvokeCalliHelper & GenericPInvokeCalliGenILStub
// Helper for generic pinvoke calli instruction
//
// in:
// r4 = VASigCookie*
// r12 = Unmanaged target
//
PINVOKE_STUB GenericPInvokeCalliHelper, GenericPInvokeCalliGenILStub, GenericPInvokeCalliStubWorker r4, 1
// ------------------------------------------------------------------
// VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg
// Vararg PInvoke Stub when the method has a hidden return buffer arg
//
// in:
// r1 = VASigCookie*
// r12 = MethodDesc*
//
PINVOKE_STUB VarargPInvokeStub_RetBuffArg, VarargPInvokeGenILStub_RetBuffArg, VarargPInvokeStubWorker, r1, 0
|