koffi 2.3.8 → 2.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/LICENSE.txt +22 -165
- package/README.md +2 -2
- package/doc/index.rst +2 -2
- package/doc/static/custom.css +18 -10
- package/package.json +3 -3
- package/src/cnoke/LICENSE.txt +22 -165
- package/src/cnoke/assets/FindCNoke.cmake +18 -10
- package/src/cnoke/assets/win_delay_hook.c +18 -10
- package/src/cnoke/cnoke.js +18 -10
- package/src/cnoke/package.json +1 -1
- package/src/cnoke/src/builder.js +18 -10
- package/src/cnoke/src/index.js +18 -10
- package/src/cnoke/src/tools.js +18 -10
- package/src/core/libcc/libcc.cc +20 -12
- package/src/core/libcc/libcc.hh +20 -12
- package/src/koffi/CMakeLists.txt +27 -19
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/src/abi_arm32.cc +19 -11
- package/src/koffi/src/abi_arm32_asm.S +211 -0
- package/src/koffi/src/abi_arm64.cc +19 -11
- package/src/koffi/src/abi_arm64_asm.S +238 -0
- package/src/koffi/src/abi_arm64_asm.asm +207 -0
- package/src/koffi/src/abi_riscv64.cc +19 -11
- package/src/koffi/src/abi_riscv64_asm.S +239 -0
- package/src/koffi/src/abi_x64_sysv.cc +19 -11
- package/src/koffi/src/abi_x64_sysv_asm.S +272 -0
- package/src/koffi/src/abi_x64_win.cc +19 -11
- package/src/koffi/src/abi_x64_win_asm.asm +203 -0
- package/src/koffi/src/abi_x86.cc +19 -11
- package/src/koffi/src/abi_x86_asm.S +213 -0
- package/src/koffi/src/abi_x86_asm.asm +191 -0
- package/src/koffi/src/call.cc +18 -10
- package/src/koffi/src/call.hh +18 -10
- package/src/koffi/src/ffi.cc +18 -10
- package/src/koffi/src/ffi.hh +18 -10
- package/src/koffi/src/index.d.ts +22 -14
- package/src/koffi/src/index.js +18 -10
- package/src/koffi/src/parser.cc +18 -10
- package/src/koffi/src/parser.hh +18 -10
- package/src/koffi/src/{abi_arm64_fwd.asm → trampolines/armasm.inc} +18 -193
- package/src/koffi/src/{abi_arm64_fwd.S → trampolines/gnu.inc} +18 -226
- package/src/koffi/src/{abi_x86_fwd.asm → trampolines/masm32.inc} +1042 -1203
- package/src/koffi/src/{abi_x64_win_fwd.asm → trampolines/masm64.inc} +1042 -1215
- package/src/koffi/src/{abi_trampolines.inc → trampolines/prototypes.inc} +18 -10
- package/src/koffi/src/util.cc +18 -10
- package/src/koffi/src/util.hh +18 -10
- package/src/koffi/src/win32.hh +18 -10
- package/src/koffi/src/abi_arm32_fwd.S +0 -6344
- package/src/koffi/src/abi_riscv64_fwd.S +0 -6375
- package/src/koffi/src/abi_x64_sysv_fwd.S +0 -6410
- package/src/koffi/src/abi_x86_fwd.S +0 -6346
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_darwin_arm64/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_darwin_x64/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_arm64/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_ia32/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_x64/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_x64/koffi.node +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.lib +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.lib +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_x64/koffi.exp +0 -0
- /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_x64/koffi.lib +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
; Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
;
|
|
3
|
+
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
; this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
; the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
; copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
; Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
; subject to the following conditions:
|
|
9
|
+
;
|
|
10
|
+
; The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
; copies or substantial portions of the Software.
|
|
12
|
+
;
|
|
13
|
+
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
; OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
; Forward
|
|
23
|
+
; ----------------------------
|
|
24
|
+
|
|
25
|
+
; These three are the same, but they differ (in the C side) by their return type.
|
|
26
|
+
; Unlike the three next functions, these ones don't forward XMM argument registers.
|
|
27
|
+
public ForwardCallG
|
|
28
|
+
public ForwardCallF
|
|
29
|
+
public ForwardCallD
|
|
30
|
+
|
|
31
|
+
; The X variants are slightly slower, and are used when XMM arguments must be forwarded.
|
|
32
|
+
public ForwardCallXG
|
|
33
|
+
public ForwardCallXF
|
|
34
|
+
public ForwardCallXD
|
|
35
|
+
|
|
36
|
+
.code
|
|
37
|
+
|
|
38
|
+
; Copy function pointer to RAX, in order to save it through argument forwarding.
|
|
39
|
+
; Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
40
|
+
; Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
41
|
+
prologue macro
|
|
42
|
+
endbr64
|
|
43
|
+
mov rax, rcx
|
|
44
|
+
push rbp
|
|
45
|
+
.pushreg rbp
|
|
46
|
+
mov rbp, rsp
|
|
47
|
+
mov qword ptr [r8+0], rsp
|
|
48
|
+
.setframe rbp, 0
|
|
49
|
+
.endprolog
|
|
50
|
+
mov rsp, rdx
|
|
51
|
+
endm
|
|
52
|
+
|
|
53
|
+
; Call native function.
|
|
54
|
+
; Once done, restore normal stack pointer and return.
|
|
55
|
+
; The return value is passed untouched through RAX or XMM0.
|
|
56
|
+
epilogue macro
|
|
57
|
+
call rax
|
|
58
|
+
mov rsp, rbp
|
|
59
|
+
pop rbp
|
|
60
|
+
ret
|
|
61
|
+
endm
|
|
62
|
+
|
|
63
|
+
; Prepare integer argument registers from array passed by caller.
|
|
64
|
+
forward_gpr macro
|
|
65
|
+
mov r9, qword ptr [rdx+24]
|
|
66
|
+
mov r8, qword ptr [rdx+16]
|
|
67
|
+
mov rcx, qword ptr [rdx+0]
|
|
68
|
+
mov rdx, qword ptr [rdx+8]
|
|
69
|
+
endm
|
|
70
|
+
|
|
71
|
+
; Prepare XMM argument registers from array passed by caller.
|
|
72
|
+
forward_xmm macro
|
|
73
|
+
movsd xmm3, qword ptr [rdx+24]
|
|
74
|
+
movsd xmm2, qword ptr [rdx+16]
|
|
75
|
+
movsd xmm1, qword ptr [rdx+8]
|
|
76
|
+
movsd xmm0, qword ptr [rdx+0]
|
|
77
|
+
endm
|
|
78
|
+
|
|
79
|
+
ForwardCallG proc frame
|
|
80
|
+
prologue
|
|
81
|
+
forward_gpr
|
|
82
|
+
epilogue
|
|
83
|
+
ForwardCallG endp
|
|
84
|
+
|
|
85
|
+
ForwardCallF proc frame
|
|
86
|
+
prologue
|
|
87
|
+
forward_gpr
|
|
88
|
+
epilogue
|
|
89
|
+
ForwardCallF endp
|
|
90
|
+
|
|
91
|
+
ForwardCallD proc frame
|
|
92
|
+
prologue
|
|
93
|
+
forward_gpr
|
|
94
|
+
epilogue
|
|
95
|
+
ForwardCallD endp
|
|
96
|
+
|
|
97
|
+
ForwardCallXG proc frame
|
|
98
|
+
prologue
|
|
99
|
+
forward_xmm
|
|
100
|
+
forward_gpr
|
|
101
|
+
epilogue
|
|
102
|
+
ForwardCallXG endp
|
|
103
|
+
|
|
104
|
+
ForwardCallXF proc frame
|
|
105
|
+
prologue
|
|
106
|
+
forward_xmm
|
|
107
|
+
forward_gpr
|
|
108
|
+
epilogue
|
|
109
|
+
ForwardCallXF endp
|
|
110
|
+
|
|
111
|
+
ForwardCallXD proc frame
|
|
112
|
+
prologue
|
|
113
|
+
forward_xmm
|
|
114
|
+
forward_gpr
|
|
115
|
+
epilogue
|
|
116
|
+
ForwardCallXD endp
|
|
117
|
+
|
|
118
|
+
; Callbacks
|
|
119
|
+
; ----------------------------
|
|
120
|
+
|
|
121
|
+
extern RelayCallback : PROC
|
|
122
|
+
public CallSwitchStack
|
|
123
|
+
|
|
124
|
+
; First, make a copy of the GPR argument registers (rcx, rdx, r8, r9).
|
|
125
|
+
; Then call the C function RelayCallback with the following arguments:
|
|
126
|
+
; static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
127
|
+
; arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
128
|
+
; After the call, simply load these registers from the output struct.
|
|
129
|
+
trampoline macro ID
|
|
130
|
+
endbr64
|
|
131
|
+
sub rsp, 120
|
|
132
|
+
.allocstack 120
|
|
133
|
+
.endprolog
|
|
134
|
+
mov qword ptr [rsp+32], rcx
|
|
135
|
+
mov qword ptr [rsp+40], rdx
|
|
136
|
+
mov qword ptr [rsp+48], r8
|
|
137
|
+
mov qword ptr [rsp+56], r9
|
|
138
|
+
mov rcx, ID
|
|
139
|
+
lea rdx, qword ptr [rsp+32]
|
|
140
|
+
lea r8, qword ptr [rsp+160]
|
|
141
|
+
lea r9, qword ptr [rsp+96]
|
|
142
|
+
call RelayCallback
|
|
143
|
+
mov rax, qword ptr [rsp+96]
|
|
144
|
+
add rsp, 120
|
|
145
|
+
ret
|
|
146
|
+
endm
|
|
147
|
+
|
|
148
|
+
; Same thing, but also forward the XMM argument registers and load the XMM result registers.
|
|
149
|
+
trampoline_vec macro ID
|
|
150
|
+
endbr64
|
|
151
|
+
sub rsp, 120
|
|
152
|
+
.allocstack 120
|
|
153
|
+
.endprolog
|
|
154
|
+
mov qword ptr [rsp+32], rcx
|
|
155
|
+
mov qword ptr [rsp+40], rdx
|
|
156
|
+
mov qword ptr [rsp+48], r8
|
|
157
|
+
mov qword ptr [rsp+56], r9
|
|
158
|
+
movsd qword ptr [rsp+64], xmm0
|
|
159
|
+
movsd qword ptr [rsp+72], xmm1
|
|
160
|
+
movsd qword ptr [rsp+80], xmm2
|
|
161
|
+
movsd qword ptr [rsp+88], xmm3
|
|
162
|
+
mov rcx, ID
|
|
163
|
+
lea rdx, qword ptr [rsp+32]
|
|
164
|
+
lea r8, qword ptr [rsp+160]
|
|
165
|
+
lea r9, qword ptr [rsp+96]
|
|
166
|
+
call RelayCallback
|
|
167
|
+
mov rax, qword ptr [rsp+96]
|
|
168
|
+
movsd xmm0, qword ptr [rsp+104]
|
|
169
|
+
add rsp, 120
|
|
170
|
+
ret
|
|
171
|
+
endm
|
|
172
|
+
|
|
173
|
+
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
174
|
+
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
175
|
+
; probably misdetect this as a "stack overflow". We have to restore the old
|
|
176
|
+
; stack pointer, call Node.js/V8 and go back to ours.
|
|
177
|
+
; The first three parameters (rcx, rdx, r8) are passed through untouched.
|
|
178
|
+
CallSwitchStack proc frame
|
|
179
|
+
endbr64
|
|
180
|
+
push rbp
|
|
181
|
+
.pushreg rbp
|
|
182
|
+
mov rbp, rsp
|
|
183
|
+
.setframe rbp, 0
|
|
184
|
+
.endprolog
|
|
185
|
+
mov rax, qword ptr [rsp+56]
|
|
186
|
+
mov r10, rsp
|
|
187
|
+
mov r11, qword ptr [rsp+48]
|
|
188
|
+
sub r10, qword ptr [r11+0]
|
|
189
|
+
and r10, -16
|
|
190
|
+
mov qword ptr [r11+8], r10
|
|
191
|
+
lea rsp, [r9-32]
|
|
192
|
+
call rax
|
|
193
|
+
mov rsp, rbp
|
|
194
|
+
pop rbp
|
|
195
|
+
ret
|
|
196
|
+
CallSwitchStack endp
|
|
197
|
+
|
|
198
|
+
; Trampolines
|
|
199
|
+
; ----------------------------
|
|
200
|
+
|
|
201
|
+
include trampolines/masm64.inc
|
|
202
|
+
|
|
203
|
+
end
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// it under the terms of the GNU Lesser General Public License as published by
|
|
3
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
-
// (at your option) any later version.
|
|
1
|
+
// Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
5
2
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
13
21
|
|
|
14
22
|
#if defined(__i386__) || defined(_M_IX86)
|
|
15
23
|
|
|
@@ -47,7 +55,7 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
47
55
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
48
56
|
napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
|
|
49
57
|
|
|
50
|
-
#include "
|
|
58
|
+
#include "trampolines/prototypes.inc"
|
|
51
59
|
|
|
52
60
|
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
53
61
|
{
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
# subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
#define SYMBOL(Symbol) Symbol
|
|
23
|
+
|
|
24
|
+
# Forward
|
|
25
|
+
# ----------------------------
|
|
26
|
+
|
|
27
|
+
.global ForwardCallG
|
|
28
|
+
.global ForwardCallF
|
|
29
|
+
.global ForwardCallD
|
|
30
|
+
.global ForwardCallRG
|
|
31
|
+
.global ForwardCallRF
|
|
32
|
+
.global ForwardCallRD
|
|
33
|
+
|
|
34
|
+
#define ENDBR32 .byte 0xf3, 0x0f, 0x1e, 0xfb
|
|
35
|
+
|
|
36
|
+
# Copy function pointer to EAX, in order to save it through argument forwarding.
|
|
37
|
+
# Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
38
|
+
# Save ESP in EBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
39
|
+
.macro prologue
|
|
40
|
+
.cfi_startproc
|
|
41
|
+
.cfi_def_cfa esp, 4
|
|
42
|
+
ENDBR32
|
|
43
|
+
push %ebp
|
|
44
|
+
.cfi_def_cfa esp, 8
|
|
45
|
+
movl %esp, %ebp
|
|
46
|
+
.cfi_def_cfa ebp, 8
|
|
47
|
+
movl 16(%esp), %eax
|
|
48
|
+
movl %esp, 0(%eax)
|
|
49
|
+
movl 8(%esp), %eax
|
|
50
|
+
movl 12(%esp), %esp
|
|
51
|
+
.endm
|
|
52
|
+
|
|
53
|
+
.macro fastcall
|
|
54
|
+
movl 0(%esp), %ecx
|
|
55
|
+
movl 4(%esp), %edx
|
|
56
|
+
addl $16, %esp
|
|
57
|
+
.endm
|
|
58
|
+
|
|
59
|
+
# Call native function.
|
|
60
|
+
# Once done, restore normal stack pointer and return.
|
|
61
|
+
# The return value is passed back untouched.
|
|
62
|
+
.macro epilogue
|
|
63
|
+
call *%eax
|
|
64
|
+
movl %ebp, %esp
|
|
65
|
+
pop %ebp
|
|
66
|
+
.cfi_def_cfa esp, 4
|
|
67
|
+
ret
|
|
68
|
+
.cfi_endproc
|
|
69
|
+
.endm
|
|
70
|
+
|
|
71
|
+
ForwardCallG:
|
|
72
|
+
prologue
|
|
73
|
+
epilogue
|
|
74
|
+
|
|
75
|
+
ForwardCallF:
|
|
76
|
+
prologue
|
|
77
|
+
epilogue
|
|
78
|
+
|
|
79
|
+
ForwardCallD:
|
|
80
|
+
prologue
|
|
81
|
+
epilogue
|
|
82
|
+
|
|
83
|
+
ForwardCallRG:
|
|
84
|
+
prologue
|
|
85
|
+
fastcall
|
|
86
|
+
epilogue
|
|
87
|
+
|
|
88
|
+
ForwardCallRF:
|
|
89
|
+
prologue
|
|
90
|
+
fastcall
|
|
91
|
+
epilogue
|
|
92
|
+
|
|
93
|
+
ForwardCallRD:
|
|
94
|
+
prologue
|
|
95
|
+
fastcall
|
|
96
|
+
epilogue
|
|
97
|
+
|
|
98
|
+
# Callbacks
|
|
99
|
+
# ----------------------------
|
|
100
|
+
|
|
101
|
+
.global RelayCallback
|
|
102
|
+
.global CallSwitchStack
|
|
103
|
+
|
|
104
|
+
# Call the C function RelayCallback with the following arguments:
|
|
105
|
+
# static trampoline ID, the current stack pointer, a pointer to the stack arguments of this call,
|
|
106
|
+
# and a pointer to a struct that will contain the result registers.
|
|
107
|
+
# After the call, simply load these registers from the output struct.
|
|
108
|
+
# Depending on ABI, call convention and return value size, we need to issue ret <something>. Since ret
|
|
109
|
+
# only takes an immediate value, and I prefer not to branch, the return address is moved instead according
|
|
110
|
+
# to BackRegisters::ret_pop before ret is issued.
|
|
111
|
+
.macro trampoline id
|
|
112
|
+
.cfi_startproc
|
|
113
|
+
.cfi_def_cfa esp, 4
|
|
114
|
+
ENDBR32
|
|
115
|
+
sub $44, %esp
|
|
116
|
+
.cfi_def_cfa esp, 48
|
|
117
|
+
movl $\id, 0(%esp)
|
|
118
|
+
movl %esp, 4(%esp)
|
|
119
|
+
leal 48(%esp), %eax
|
|
120
|
+
movl %eax, 8(%esp)
|
|
121
|
+
leal 16(%esp), %eax
|
|
122
|
+
movl %eax, 12(%esp)
|
|
123
|
+
call GetEIP
|
|
124
|
+
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
125
|
+
call *RelayCallback@GOT(%ecx)
|
|
126
|
+
movl 44(%esp), %edx
|
|
127
|
+
movl 36(%esp), %ecx
|
|
128
|
+
movl %edx, 44(%esp, %ecx)
|
|
129
|
+
movl 16(%esp), %eax
|
|
130
|
+
movl 20(%esp), %edx
|
|
131
|
+
leal 44(%esp, %ecx), %esp
|
|
132
|
+
.cfi_def_cfa esp, 4
|
|
133
|
+
ret
|
|
134
|
+
.cfi_endproc
|
|
135
|
+
.endm
|
|
136
|
+
|
|
137
|
+
# This version also loads the x87 stack with the result, if need be.
|
|
138
|
+
# We have to branch to avoid x87 stack imbalance.
|
|
139
|
+
.macro trampoline_vec id
|
|
140
|
+
.cfi_startproc
|
|
141
|
+
.cfi_def_cfa esp, 4
|
|
142
|
+
ENDBR32
|
|
143
|
+
sub $44, %esp
|
|
144
|
+
.cfi_def_cfa esp, 48
|
|
145
|
+
movl $\id, 0(%esp)
|
|
146
|
+
movl %esp, 4(%esp)
|
|
147
|
+
leal 48(%esp), %eax
|
|
148
|
+
movl %eax, 8(%esp)
|
|
149
|
+
leal 16(%esp), %eax
|
|
150
|
+
movl %eax, 12(%esp)
|
|
151
|
+
call GetEIP
|
|
152
|
+
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
153
|
+
call *RelayCallback@GOT(%ecx)
|
|
154
|
+
movl 44(%esp), %edx
|
|
155
|
+
movl 36(%esp), %ecx
|
|
156
|
+
movl %edx, 44(%esp, %ecx, 4)
|
|
157
|
+
cmpb $0, 32(%esp)
|
|
158
|
+
jne 2f
|
|
159
|
+
1:
|
|
160
|
+
flds 24(%esp)
|
|
161
|
+
leal 44(%esp, %ecx), %esp
|
|
162
|
+
.cfi_def_cfa esp, 4
|
|
163
|
+
ret
|
|
164
|
+
2:
|
|
165
|
+
fldl 24(%esp)
|
|
166
|
+
leal 44(%esp, %ecx), %esp
|
|
167
|
+
.cfi_def_cfa esp, 4
|
|
168
|
+
ret
|
|
169
|
+
.cfi_endproc
|
|
170
|
+
.endm
|
|
171
|
+
|
|
172
|
+
GetEIP:
|
|
173
|
+
movl (%esp), %ecx
|
|
174
|
+
ret
|
|
175
|
+
|
|
176
|
+
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
177
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
178
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
179
|
+
# stack pointer, call Node.js/V8 and go back to ours.
|
|
180
|
+
CallSwitchStack:
|
|
181
|
+
.cfi_startproc
|
|
182
|
+
.cfi_def_cfa esp, 4
|
|
183
|
+
ENDBR32
|
|
184
|
+
push %ebp
|
|
185
|
+
.cfi_def_cfa esp, 8
|
|
186
|
+
movl %esp, %ebp
|
|
187
|
+
.cfi_def_cfa ebp, 8
|
|
188
|
+
movl 28(%esp), %edx
|
|
189
|
+
movl 24(%esp), %ecx
|
|
190
|
+
movl %esp, %eax
|
|
191
|
+
subl 0(%ecx), %eax
|
|
192
|
+
andl $-16, %eax
|
|
193
|
+
movl %eax, 4(%ecx)
|
|
194
|
+
movl 20(%esp), %esp
|
|
195
|
+
subl $28, %esp
|
|
196
|
+
movl 8(%ebp), %eax
|
|
197
|
+
movl %eax, 0(%esp)
|
|
198
|
+
movl 12(%ebp), %eax
|
|
199
|
+
movl %eax, 4(%esp)
|
|
200
|
+
movl 16(%ebp), %eax
|
|
201
|
+
movl %eax, 8(%esp)
|
|
202
|
+
call *%edx
|
|
203
|
+
mov %ebp, %esp
|
|
204
|
+
.cfi_def_cfa esp, 8
|
|
205
|
+
pop %ebp
|
|
206
|
+
.cfi_def_cfa esp, 4
|
|
207
|
+
ret
|
|
208
|
+
.cfi_endproc
|
|
209
|
+
|
|
210
|
+
# Trampolines
|
|
211
|
+
# ----------------------------
|
|
212
|
+
|
|
213
|
+
#include "trampolines/gnu.inc"
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
; Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
;
|
|
3
|
+
; Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
; this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
; the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
; copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
; Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
; subject to the following conditions:
|
|
9
|
+
;
|
|
10
|
+
; The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
; copies or substantial portions of the Software.
|
|
12
|
+
;
|
|
13
|
+
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
; OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
; Forward
|
|
23
|
+
; ----------------------------
|
|
24
|
+
|
|
25
|
+
public ForwardCallG
|
|
26
|
+
public ForwardCallF
|
|
27
|
+
public ForwardCallD
|
|
28
|
+
public ForwardCallRG
|
|
29
|
+
public ForwardCallRF
|
|
30
|
+
public ForwardCallRD
|
|
31
|
+
|
|
32
|
+
.model flat, C
|
|
33
|
+
.code
|
|
34
|
+
|
|
35
|
+
; Copy function pointer to EAX, in order to save it through argument forwarding.
|
|
36
|
+
; Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
37
|
+
; Save ESP in EBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
38
|
+
prologue macro
|
|
39
|
+
endbr32
|
|
40
|
+
push ebp
|
|
41
|
+
mov ebp, esp
|
|
42
|
+
mov eax, dword ptr [esp+16]
|
|
43
|
+
mov dword ptr [eax+0], esp
|
|
44
|
+
mov eax, dword ptr [esp+8]
|
|
45
|
+
mov esp, dword ptr [esp+12]
|
|
46
|
+
endm
|
|
47
|
+
|
|
48
|
+
fastcall macro
|
|
49
|
+
mov ecx, dword ptr [esp+0]
|
|
50
|
+
mov edx, dword ptr [esp+4]
|
|
51
|
+
add esp, 16
|
|
52
|
+
endm
|
|
53
|
+
|
|
54
|
+
; Call native function.
|
|
55
|
+
; Once done, restore normal stack pointer and return.
|
|
56
|
+
; The return value is passed back untouched.
|
|
57
|
+
epilogue macro
|
|
58
|
+
call eax
|
|
59
|
+
mov esp, ebp
|
|
60
|
+
pop ebp
|
|
61
|
+
ret
|
|
62
|
+
endm
|
|
63
|
+
|
|
64
|
+
ForwardCallG proc
|
|
65
|
+
prologue
|
|
66
|
+
epilogue
|
|
67
|
+
ForwardCallG endp
|
|
68
|
+
|
|
69
|
+
ForwardCallF proc
|
|
70
|
+
prologue
|
|
71
|
+
epilogue
|
|
72
|
+
ForwardCallF endp
|
|
73
|
+
|
|
74
|
+
ForwardCallD proc
|
|
75
|
+
prologue
|
|
76
|
+
epilogue
|
|
77
|
+
ForwardCallD endp
|
|
78
|
+
|
|
79
|
+
ForwardCallRG proc
|
|
80
|
+
prologue
|
|
81
|
+
fastcall
|
|
82
|
+
epilogue
|
|
83
|
+
ForwardCallRG endp
|
|
84
|
+
|
|
85
|
+
ForwardCallRF proc
|
|
86
|
+
prologue
|
|
87
|
+
fastcall
|
|
88
|
+
epilogue
|
|
89
|
+
ForwardCallRF endp
|
|
90
|
+
|
|
91
|
+
ForwardCallRD proc
|
|
92
|
+
prologue
|
|
93
|
+
fastcall
|
|
94
|
+
epilogue
|
|
95
|
+
ForwardCallRD endp
|
|
96
|
+
|
|
97
|
+
; Callbacks
|
|
98
|
+
; ----------------------------
|
|
99
|
+
|
|
100
|
+
extern RelayCallback : PROC
|
|
101
|
+
public CallSwitchStack
|
|
102
|
+
|
|
103
|
+
; Call the C function RelayCallback with the following arguments:
|
|
104
|
+
; static trampoline ID, the current stack pointer, a pointer to the stack arguments of this call,
|
|
105
|
+
; and a pointer to a struct that will contain the result registers.
|
|
106
|
+
; After the call, simply load these registers from the output struct.
|
|
107
|
+
; Depending on ABI, call convention and return value size, we need to issue ret <something>. Since ret
|
|
108
|
+
; only takes an immediate value, and I prefer not to branch, the return address is moved instead according
|
|
109
|
+
; to BackRegisters::ret_pop before ret is issued.
|
|
110
|
+
trampoline macro ID
|
|
111
|
+
endbr32
|
|
112
|
+
sub esp, 44
|
|
113
|
+
mov dword ptr [esp+0], ID
|
|
114
|
+
mov dword ptr [esp+4], esp
|
|
115
|
+
lea eax, dword ptr [esp+48]
|
|
116
|
+
mov dword ptr [esp+8], eax
|
|
117
|
+
lea eax, dword ptr [esp+16]
|
|
118
|
+
mov dword ptr [esp+12], eax
|
|
119
|
+
call RelayCallback
|
|
120
|
+
mov edx, dword ptr [esp+44]
|
|
121
|
+
mov ecx, dword ptr [esp+36]
|
|
122
|
+
mov dword ptr [esp+ecx+44], edx
|
|
123
|
+
mov eax, dword ptr [esp+16]
|
|
124
|
+
mov edx, dword ptr [esp+20]
|
|
125
|
+
lea esp, [esp+ecx+44]
|
|
126
|
+
ret
|
|
127
|
+
endm
|
|
128
|
+
|
|
129
|
+
; This version also loads the x87 stack with the result, if need be.
|
|
130
|
+
; We have to branch to avoid x87 stack imbalance.
|
|
131
|
+
trampoline_vec macro ID
|
|
132
|
+
local l1, l2, l3
|
|
133
|
+
|
|
134
|
+
endbr32
|
|
135
|
+
sub esp, 44
|
|
136
|
+
mov dword ptr [esp+0], ID
|
|
137
|
+
mov dword ptr [esp+4], esp
|
|
138
|
+
lea eax, dword ptr [esp+48]
|
|
139
|
+
mov dword ptr [esp+8], eax
|
|
140
|
+
lea eax, dword ptr [esp+16]
|
|
141
|
+
mov dword ptr [esp+12], eax
|
|
142
|
+
call RelayCallback
|
|
143
|
+
mov edx, dword ptr [esp+44]
|
|
144
|
+
mov ecx, dword ptr [esp+36]
|
|
145
|
+
mov dword ptr [esp+ecx+44], edx
|
|
146
|
+
cmp byte ptr [esp+32], 0
|
|
147
|
+
jne l2
|
|
148
|
+
l1:
|
|
149
|
+
fld dword ptr [esp+24]
|
|
150
|
+
lea esp, dword ptr [esp+ecx+44]
|
|
151
|
+
ret
|
|
152
|
+
l2:
|
|
153
|
+
fld qword ptr [esp+24]
|
|
154
|
+
lea esp, dword ptr [esp+ecx+44]
|
|
155
|
+
ret
|
|
156
|
+
endm
|
|
157
|
+
|
|
158
|
+
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
159
|
+
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
160
|
+
; probably misdetect this as a "stack overflow". We have to restore the old
|
|
161
|
+
; stack pointer, call Node.js/V8 and go back to ours.
|
|
162
|
+
CallSwitchStack proc
|
|
163
|
+
endbr32
|
|
164
|
+
push ebp
|
|
165
|
+
mov ebp, esp
|
|
166
|
+
mov edx, dword ptr [esp+28]
|
|
167
|
+
mov ecx, dword ptr [esp+24]
|
|
168
|
+
mov eax, esp
|
|
169
|
+
sub eax, dword ptr [ecx+0]
|
|
170
|
+
and eax, -16
|
|
171
|
+
mov dword ptr [ecx+4], eax
|
|
172
|
+
mov esp, dword ptr [esp+20]
|
|
173
|
+
sub esp, 28
|
|
174
|
+
mov eax, dword ptr [ebp+8]
|
|
175
|
+
mov dword ptr [esp+0], eax
|
|
176
|
+
mov eax, dword ptr [ebp+12]
|
|
177
|
+
mov dword ptr [esp+4], eax
|
|
178
|
+
mov eax, dword ptr [ebp+16]
|
|
179
|
+
mov dword ptr [esp+8], eax
|
|
180
|
+
call edx
|
|
181
|
+
mov esp, ebp
|
|
182
|
+
pop ebp
|
|
183
|
+
ret
|
|
184
|
+
CallSwitchStack endp
|
|
185
|
+
|
|
186
|
+
; Trampolines
|
|
187
|
+
; ----------------------------
|
|
188
|
+
|
|
189
|
+
include trampolines/masm32.inc
|
|
190
|
+
|
|
191
|
+
end
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// it under the terms of the GNU Lesser General Public License as published by
|
|
3
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
-
// (at your option) any later version.
|
|
1
|
+
// Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
5
2
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
13
21
|
|
|
14
22
|
#include "src/core/libcc/libcc.hh"
|
|
15
23
|
#include "call.hh"
|