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.
Files changed (72) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE.txt +22 -165
  3. package/README.md +2 -2
  4. package/doc/index.rst +2 -2
  5. package/doc/static/custom.css +18 -10
  6. package/package.json +3 -3
  7. package/src/cnoke/LICENSE.txt +22 -165
  8. package/src/cnoke/assets/FindCNoke.cmake +18 -10
  9. package/src/cnoke/assets/win_delay_hook.c +18 -10
  10. package/src/cnoke/cnoke.js +18 -10
  11. package/src/cnoke/package.json +1 -1
  12. package/src/cnoke/src/builder.js +18 -10
  13. package/src/cnoke/src/index.js +18 -10
  14. package/src/cnoke/src/tools.js +18 -10
  15. package/src/core/libcc/libcc.cc +20 -12
  16. package/src/core/libcc/libcc.hh +20 -12
  17. package/src/koffi/CMakeLists.txt +27 -19
  18. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_arm32hf/koffi.node +0 -0
  19. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_arm64/koffi.node +0 -0
  20. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_ia32/koffi.node +0 -0
  21. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_riscv64hf64/koffi.node +0 -0
  22. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_openbsd_ia32/koffi.node +0 -0
  23. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_openbsd_x64/koffi.node +0 -0
  24. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.node +0 -0
  25. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.node +0 -0
  26. package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_x64/koffi.node +0 -0
  27. package/src/koffi/src/abi_arm32.cc +19 -11
  28. package/src/koffi/src/abi_arm32_asm.S +211 -0
  29. package/src/koffi/src/abi_arm64.cc +19 -11
  30. package/src/koffi/src/abi_arm64_asm.S +238 -0
  31. package/src/koffi/src/abi_arm64_asm.asm +207 -0
  32. package/src/koffi/src/abi_riscv64.cc +19 -11
  33. package/src/koffi/src/abi_riscv64_asm.S +239 -0
  34. package/src/koffi/src/abi_x64_sysv.cc +19 -11
  35. package/src/koffi/src/abi_x64_sysv_asm.S +272 -0
  36. package/src/koffi/src/abi_x64_win.cc +19 -11
  37. package/src/koffi/src/abi_x64_win_asm.asm +203 -0
  38. package/src/koffi/src/abi_x86.cc +19 -11
  39. package/src/koffi/src/abi_x86_asm.S +213 -0
  40. package/src/koffi/src/abi_x86_asm.asm +191 -0
  41. package/src/koffi/src/call.cc +18 -10
  42. package/src/koffi/src/call.hh +18 -10
  43. package/src/koffi/src/ffi.cc +18 -10
  44. package/src/koffi/src/ffi.hh +18 -10
  45. package/src/koffi/src/index.d.ts +22 -14
  46. package/src/koffi/src/index.js +18 -10
  47. package/src/koffi/src/parser.cc +18 -10
  48. package/src/koffi/src/parser.hh +18 -10
  49. package/src/koffi/src/{abi_arm64_fwd.asm → trampolines/armasm.inc} +18 -193
  50. package/src/koffi/src/{abi_arm64_fwd.S → trampolines/gnu.inc} +18 -226
  51. package/src/koffi/src/{abi_x86_fwd.asm → trampolines/masm32.inc} +1042 -1203
  52. package/src/koffi/src/{abi_x64_win_fwd.asm → trampolines/masm64.inc} +1042 -1215
  53. package/src/koffi/src/{abi_trampolines.inc → trampolines/prototypes.inc} +18 -10
  54. package/src/koffi/src/util.cc +18 -10
  55. package/src/koffi/src/util.hh +18 -10
  56. package/src/koffi/src/win32.hh +18 -10
  57. package/src/koffi/src/abi_arm32_fwd.S +0 -6344
  58. package/src/koffi/src/abi_riscv64_fwd.S +0 -6375
  59. package/src/koffi/src/abi_x64_sysv_fwd.S +0 -6410
  60. package/src/koffi/src/abi_x86_fwd.S +0 -6346
  61. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_darwin_arm64/koffi.node +0 -0
  62. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_darwin_x64/koffi.node +0 -0
  63. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_arm64/koffi.node +0 -0
  64. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_ia32/koffi.node +0 -0
  65. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_freebsd_x64/koffi.node +0 -0
  66. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_linux_x64/koffi.node +0 -0
  67. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.exp +0 -0
  68. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_arm64/koffi.lib +0 -0
  69. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.exp +0 -0
  70. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_ia32/koffi.lib +0 -0
  71. /package/src/koffi/build/{2.3.8 → 2.3.9}/koffi_win32_x64/koffi.exp +0 -0
  72. /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
@@ -1,15 +1,23 @@
1
- // This program is free software: you can redistribute it and/or modify
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
- // This program is distributed in the hope that it will be useful,
7
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
8
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
- // GNU Lesser General Public License for more details.
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
- // You should have received a copy of the GNU Lesser General Public License
12
- // along with this program. If not, see https://www.gnu.org/licenses/.
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 "abi_trampolines.inc"
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
@@ -1,15 +1,23 @@
1
- // This program is free software: you can redistribute it and/or modify
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
- // This program is distributed in the hope that it will be useful,
7
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
8
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
- // GNU Lesser General Public License for more details.
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
- // You should have received a copy of the GNU Lesser General Public License
12
- // along with this program. If not, see https://www.gnu.org/licenses/.
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"