From f36521cbd07d82c4116b08903a696fcce0410027 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 12 Jul 2026 00:53:43 +0000 Subject: [PATCH 1/2] deps: update libffi to 3.7.1 --- deps/libffi/ChangeLog | 950 ++++++++++++++++++ deps/libffi/LICENSE | 2 +- deps/libffi/README.md | 26 +- deps/libffi/configure | 27 +- deps/libffi/configure.ac | 12 +- deps/libffi/doc/libffi.info | 122 ++- deps/libffi/doc/libffi.pdf | Bin 174265 -> 178018 bytes deps/libffi/doc/libffi.texi | 51 +- deps/libffi/doc/stamp-vti | 8 +- deps/libffi/doc/version.texi | 8 +- deps/libffi/generate-headers.py | 4 +- deps/libffi/include/ffi.h.in | 28 +- deps/libffi/libffi.map.in | 11 + deps/libffi/libtool-version | 2 +- deps/libffi/msvcc.sh | 33 +- deps/libffi/src/aarch64/ffi.c | 27 +- deps/libffi/src/alpha/ffi.c | 2 +- deps/libffi/src/alpha/ffitarget.h | 2 +- deps/libffi/src/closures.c | 2 +- deps/libffi/src/dlmalloc.c | 4 +- deps/libffi/src/frv/ffi.c | 2 +- deps/libffi/src/ia64/ffi.c | 2 +- deps/libffi/src/m32r/ffi.c | 14 +- deps/libffi/src/moxie/ffi.c | 14 +- deps/libffi/src/or1k/ffi.c | 11 +- deps/libffi/src/pa/ffi.c | 31 +- deps/libffi/src/pa/ffitarget.h | 20 +- deps/libffi/src/powerpc/ffi.c | 2 +- deps/libffi/src/powerpc/ffi_darwin.c | 1 + deps/libffi/src/powerpc/ffi_linux64.c | 2 +- deps/libffi/src/powerpc/ffi_powerpc.h | 2 +- deps/libffi/src/powerpc/ffi_sysv.c | 2 +- deps/libffi/src/powerpc/ffitarget.h | 2 +- deps/libffi/src/prep_cif.c | 41 +- deps/libffi/src/s390/ffitarget.h | 2 +- deps/libffi/src/sh64/ffi.c | 2 +- deps/libffi/src/sparc/ffi.c | 12 +- deps/libffi/src/sparc/ffi64.c | 14 +- deps/libffi/src/tramp.c | 18 +- deps/libffi/src/types.c | 2 +- deps/libffi/src/wasm/ffi.c | 71 +- deps/libffi/src/x86/ffi.c | 12 +- deps/libffi/src/x86/ffi64.c | 351 ++++++- deps/libffi/src/x86/ffitarget.h | 2 +- deps/libffi/src/x86/ffiw64.c | 13 +- deps/libffi/src/x86/sysv.S | 4 +- deps/libffi/src/x86/sysv_intel.S | 4 +- deps/libffi/src/x86/unix64.S | 151 ++- deps/libffi/src/x86/win64.S | 2 +- deps/libffi/src/x86/win64_intel.S | 2 +- deps/libffi/testsuite/Makefile.am | 8 +- deps/libffi/testsuite/Makefile.in | 8 +- deps/libffi/testsuite/lib/libffi.exp | 4 + deps/libffi/testsuite/libffi.call/i128-1.c | 103 ++ .../libffi.call/large_struct_by_value.c | 63 ++ .../libffi.call/many_small_structs.c | 92 ++ deps/libffi/testsuite/libffi.call/plan.c | 127 +++ .../libffi/testsuite/libffi.call/plan_mixed.c | 153 +++ .../libffi/testsuite/libffi.call/plan_spill.c | 142 +++ .../testsuite/libffi.call/plan_struct.c | 163 +++ deps/libffi/testsuite/libffi.call/plan_var.c | 73 ++ .../testsuite/libffi.closures/closure.exp | 2 +- .../libffi.closures/closure_loc_fn0.c | 7 +- .../testsuite/libffi.complex/complex_i128.c | 118 +++ deps/libffi/testsuite/libffi.go/go.exp | 15 +- 65 files changed, 3063 insertions(+), 144 deletions(-) create mode 100644 deps/libffi/testsuite/libffi.call/i128-1.c create mode 100644 deps/libffi/testsuite/libffi.call/large_struct_by_value.c create mode 100644 deps/libffi/testsuite/libffi.call/many_small_structs.c create mode 100644 deps/libffi/testsuite/libffi.call/plan.c create mode 100644 deps/libffi/testsuite/libffi.call/plan_mixed.c create mode 100644 deps/libffi/testsuite/libffi.call/plan_spill.c create mode 100644 deps/libffi/testsuite/libffi.call/plan_struct.c create mode 100644 deps/libffi/testsuite/libffi.call/plan_var.c create mode 100644 deps/libffi/testsuite/libffi.complex/complex_i128.c diff --git a/deps/libffi/ChangeLog b/deps/libffi/ChangeLog index f2d63988dcf70a..0dde93e6adad9e 100644 --- a/deps/libffi/ChangeLog +++ b/deps/libffi/ChangeLog @@ -1,3 +1,953 @@ +commit 5c1c43091ed611fdea774374355eb938c73a9157 +Author: Anthony Green +Date: Fri Jul 10 09:50:53 2026 -0400 + + Prepare for 3.7.1 + + Bump version to 3.7.1 and libtool -version-info to 12:1:4 (revision + bump; no ABI change). See the README for the change list. + + Co-Authored-By: Claude Fable 5 + +commit aaeaafb04a8335bea93b2873ca9a2d01107737eb +Author: Anthony Green +Date: Fri Jul 10 09:24:36 2026 -0400 + + testsuite: Make closure_thiscall_fastcall_pop portable across compilers + + The i386 esp-balance shim faulted on Android i686 (clang, -O2): it read + the closure code pointer through an esp-relative memory operand after + manually moving esp, and it did not 16-byte align the stack for the + call, so the -O2-built closure body faulted on aligned SSE. + + Read every operand into a register while esp is still at its incoming + value, 16-byte align the stack at the call per the i386 psABI, avoid ebx + so it works under -fPIC, and return the delta via memory. Verified with + gcc and clang at -O0 and -O2: passes with the fix, still catches the + under-pop without it. + + Co-Authored-By: Claude Fable 5 + +commit ebe306becb167937ead4332290868e041d0c08a7 +Author: Anthony Green +Date: Fri Jul 10 08:54:39 2026 -0400 + + x86: Fix i386 THISCALL/FASTCALL closure stack-pop accounting + + For THISCALL and FASTCALL, ffi_closure_inner force-bumps narg_reg to 2 + when an argument is a 64-bit integer or a struct, so that following + integer arguments are placed on the stack (the Issue #434 rule). The + closure return path then computed the callee stack pop as + cif->bytes - narg_reg * 4, which discounts register slots that were + never used once narg_reg has been forced, under-popping the stack. + + For example FASTCALL void(uint64_t) has cif->bytes == 8 with the uint64 + placed on the stack, but the formula yields a pop of 0 instead of 8; a + callee-clean call site that does not re-sync ESP from a frame pointer is + then left with the argument bytes in place of its return address. + + Encode the pop as the number of bytes actually consumed from the + incoming stack (argp - stack, dir == 1 for these ABIs), which equals the + old formula in the non-forced cases and is correct in the forced ones. + + Adds closure_thiscall_fastcall_pop.c (i386/GNU), which invokes the + generated closure through a minimal callee-clean call site and checks + ESP is balanced; without this fix the imbalance is 8 (FASTCALL uint64) + or 4 (THISCALL this+uint64). + + Co-Authored-By: Claude Fable 5 + +commit a2ef91c79f4f193dd1e828f615c818fb6bcaff0d +Author: Anthony Green +Date: Fri Jul 10 08:20:39 2026 -0400 + + aarch64: Fix argument slab under-budget for large by-value structs + + On AArch64, composites larger than 16 bytes (that are not HFAs) are + passed by invisible reference. ffi_call copies each payload into the + argument slab from the top (next_struct_area, growing down) and, once + X0-X7 are exhausted, spills the by-ref pointer into the same slab from + the bottom (the NSAA, growing up). The generic prep_cif accounting in + cif->bytes only charges the payload copy, not the extra 8-byte pointer + slot, so with enough large structs the two regions collide: a later + payload copy overwrites an already-spilled pointer, and the callee then + receives a corrupt pointer for a by-value argument. + + Reserve an additional 8 bytes in ffi_prep_cif_machdep for each large + by-reference struct argument so the copy and spill regions can never + overlap. + + Adds many_large_structs.c, which passes sixteen 32-byte structs by + value; it crashes without this fix and passes with it. + + Co-Authored-By: Claude Fable 5 + +commit 25283b0d812b6729299a21a1c02433bc291174e9 +Merge: e87b59f5 665c5c00 +Author: Anthony Green +Date: Fri Jul 10 08:22:39 2026 -0400 + + Merge pull request #997 from libffi/windows-arm64-ci + + Add Windows ARM64 (MSVC) CI; fix latent msvcc.sh and testsuite bugs it exposed + +commit 665c5c00f2f492e199a1c9e01bda57a82f4440ef +Author: Anthony Green +Date: Fri Jul 10 07:46:24 2026 -0400 + + testsuite: Pass MSVC warning suppressions in go.exp + + Same latent issue as closure.exp: the Go closure tests ran with no + MSVC warning options, so ffitest.h's benign C4005 PRI-macro + redefinition warnings count as excess errors. Latent until the + msvcc.sh -E fix let the FFI_GO_CLOSURES feature probe succeed under + MSVC; the execution tests themselves pass on both x86 MSVC jobs. + Mirror the call.exp/closure.exp warning-suppression block. + + Co-Authored-By: Claude Fable 5 + +commit 2e897db821a43068e3851a414bd47b2b5592d403 +Author: Anthony Green +Date: Fri Jul 10 07:25:53 2026 -0400 + + testsuite: Skip closure_loc_fn0 memcmp check under trampoline tables + + Now that closure_loc_fn0.c actually executes, it fails on Apple + aarch64: with FFI_EXEC_TRAMPOLINE_TABLE, codeloc points at a + trampoline table entry rather than a copy of the closure, so the + memcmp sanity check is invalid there -- the same reason it is already + skipped for static trampolines. fficonfig.h (included by ffitest.h) + provides the macro. + + Co-Authored-By: Claude Fable 5 + +commit 15b9abc239a1a2f6964a4cfc92f8fb78b3475d37 +Author: Anthony Green +Date: Fri Jul 10 07:19:28 2026 -0400 + + ci: Add Windows ARM64 Visual C++ to the MSVC build matrix + + Build and test on GitHub's windows-11-arm runners. Cygwin and the + amd64_arm64 cross tools (cl, armasm64) are x64-hosted and run under + the runner's x64 emulation; the ARM64 binaries they produce execute + natively, so the full testsuite runs (784 passes, 0 failures). This + is the first CI coverage for the win64_armasm.S closure trampolines. + + The matrix entries grow runner/mflag/pkg/rcedit_arch parameters; the + existing x86 job names and release artifact names are unchanged. + Release tags now also publish ARM64 MSVC binaries + (libffi--arm64-msvc-binaries). + + Replaces the temporary winarm64.yml iteration workflow. + + Co-Authored-By: Claude Fable 5 + +commit e4435739c82106cf13336bf26da99a03281848a0 +Author: Anthony Green +Date: Fri Jul 10 06:58:17 2026 -0400 + + testsuite: Actually run closure_loc_fn0; fix msvcc.sh -S + + closure_loc_fn0.c is the only test in the suite without a dg-do + directive, so DejaGnu has been defaulting to its compile-only action + on every platform -- the ffi_closure_alloc/ffi_prep_closure_loc path + it exists to exercise was never executed. Add the missing + /* { dg-do run } */. + + The compile-only default also exposed msvcc.sh's broken -S handling: + it mapped -S to -FAs alone, which emits a listing but still runs the + link step, failing with unresolved externals since compile-only + invocations pass no libraries. Map -S to a true compile-to-assembly: + -c -FAs with the listing written to the -o target. + + Co-Authored-By: Claude Fable 5 + +commit bf2fa49b6dbe68dac021c02ee3deddb343ec3541 +Author: Anthony Green +Date: Fri Jul 10 06:36:26 2026 -0400 + + testsuite: Pass MSVC warning suppressions to closures C tests + + closure.exp defines additional_options with the same -wd warning + suppressions call.exp uses, but only passed them to the C++ tests; + the C tests ran with "". Under MSVC the benign C4005/C4305/C4477 + warnings then count as excess errors and fail every C test's compile + check. This was latent until the previous commit made the + FFI_CLOSURES feature probe work under msvcc.sh, allowing the closures + suite to run on MSVC at all. + + Co-Authored-By: Claude Fable 5 + +commit c2ace700754b6e63f07efdec39fc8c09ed960d63 +Author: Anthony Green +Date: Fri Jul 10 06:11:00 2026 -0400 + + msvcc.sh: Handle -E (preprocess) so DejaGnu feature tests work + + The testsuite's libffi_feature_test probes compile a snippet with + "-E -o " and treat any compiler output as failure. msvcc.sh + had no -E handling: cl's preprocessed text went to stdout, where the + awk diagnostics filter passed through every line containing the + string "warning" -- including ffi.h's own #pragma warning lines -- + and cl printed the source file name to stderr. The probes therefore + always failed under msvcc.sh, silently marking the entire closures + suite (99 tests) and the bhaible callback tests (80) UNSUPPORTED on + every MSVC CI job. + + Recognize -E, write the preprocessed output to the -o target, and + swallow cl's stderr banner so feature probes see clean output. + + Co-Authored-By: Claude Fable 5 + +commit e994c8a22d6bc480cd13c9daa2abaedf42627f88 +Author: Anthony Green +Date: Fri Jul 10 05:49:48 2026 -0400 + + ci: Add Windows ARM64 Visual C++ job (iteration branch) + + Build and test libffi on GitHub's windows-11-arm runners using + msvcc.sh -marm64 (cl + armasm64 via the amd64_arm64 cross tools, + running under x64 emulation; the resulting ARM64 binaries execute + natively). msvcc.sh already understands -marm64. + + This is a temporary standalone workflow scoped to the + windows-arm64-ci branch so the job can be iterated on without + triggering the full CI matrix; it will be folded into build.yml + once green. + + Co-Authored-By: Claude Fable 5 + +commit e87b59f53f3879cb254a4c331fd0d2c221d6ea73 +Author: Anthony Green +Date: Fri Jul 10 05:40:57 2026 -0400 + + aarch64: Fix clang-cl link failure for HFA helper functions + + clang-cl defines both __clang__ and _MSC_VER. Since the build system + detects clang before MSVC, it sets MSVC=0 and builds sysv.S rather + than win64_armasm.S. But ffi.c gated its C implementations of + extend_hfa_type and compress_hfa_type on !defined(_MSC_VER), so under + clang-cl neither implementation was built and linking failed. + + Gate on defined(_MSC_VER) && !defined(__clang__) instead: clang-cl + supports GCC-style extended inline asm, so the C implementations work + there. Also replace ssize_t (POSIX-only, absent on Windows) with + ptrdiff_t in extend_hfa_type now that it compiles for MSVC targets. + + Fixes #996 + + Co-Authored-By: Claude Fable 5 + +commit cacaf519159668bce9fcbab64082bc85c277e89d +Author: Anthony Green +Date: Thu Jul 9 21:34:47 2026 -0400 + + x86-64: build generic ffi_call_plan fallback on Windows x86-64 + + The ffi_call_plan_* API has two providers: the accelerated x86-64 SysV + implementation in src/x86/ffi64.c, and the portable fallback in + src/prep_cif.c that just wraps ffi_call. ffi64.c is not compiled for + X86_WIN64 (that target builds ffiw64.c/win64.S instead), but clang-cl + and MSYS/mingw both define __x86_64__, so prep_cif.c's guard suppressed + the fallback too -- leaving ffi_call_plan_alloc/invoke/free undefined at + link time on those toolchains. MSVC cl escaped this only because it does + not define __x86_64__. + + Suppress the generic fallback only when ffi64.c actually provides the + functions, i.e. add && !defined(X86_WIN64) to the guard. X86_WIN64 is a + command-line define visible to the generic sources (cf. src/closures.c). + + Fixes #995. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit c2c2e538c7c5403bd4edc3e77220bbe25a3ad47f +Merge: 132fb82f 7c3144c8 +Author: Anthony Green +Date: Thu Jul 9 09:10:49 2026 -0400 + + Merge pull request #994 from libffi/fix-993-aarch64-darwin-int128 + + aarch64: Don't split an int128 between x7 and the stack on Darwin + +commit 7c3144c80d8077b745588ee64bffd8504c44f5c9 +Author: Anthony Green +Date: Wed Jul 8 21:23:31 2026 -0400 + + aarch64: Don't split an int128 between x7 and the stack on Darwin + + The Apple arm64 ABI does not round NGRN up to an even number for + 128-bit integer arguments, but like AAPCS64 it still requires the + value to fit entirely in registers: if only x7 remains, the whole + value goes on the stack. allocate_int128_to_reg_or_stack only + checked ngrn < 8, so with ngrn == 7 it wrote the low half to x7 + and the high half past the end of the register array, while the + callee reads the argument from the stack. + + This fixes the libffi.call/i128-1.c failure at iteration 7 (seven + int args followed by an __int128) on aarch64-darwin, for both the + call and closure paths. + + Fixes #993 + + Co-Authored-By: Claude Fable 5 + +commit 132fb82ff4b43c9b8eaeeb533f38c95ae925131c +Author: Anthony Green +Date: Wed Jul 8 07:40:34 2026 -0400 + + Update libtool version to 12:0:4 for 3.7.0 + + 3.7.0 adds three new public interfaces (ffi_call_plan_alloc, + ffi_call_plan_invoke, ffi_call_plan_free) additively, with no + existing interface removed or changed. Per the libtool rules: + increment current, reset revision, increment age (11:1:3 -> 12:0:4). + This keeps the change ABI backward-compatible; the soname stays + libffi.so.8 (current - age = 8). + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 0ad8fd46c0a32cbbf18260c72cc60679da66c89f +Author: Anthony Green +Date: Wed Jul 8 06:43:03 2026 -0400 + + Prepare for 3.7.0 + +commit c9275302baf0d109ec474972d4679a6afe8fe64d +Author: Anthony Green +Date: Wed Jul 8 06:29:29 2026 -0400 + + Bump version to 3.7.0 + + Set AC_INIT to 3.7.0 and update the manual's edition/version/date + stamps to match. + + Co-Authored-By: Claude Fable 5 + +commit 4f7ef24565eb60e8a093bfeba0bb77d5c576c311 +Author: Anthony Green +Date: Wed Jul 8 06:28:30 2026 -0400 + + Update copyright year + + Bump the LICENSE year range to 2026. + + Co-Authored-By: Claude Fable 5 + +commit 5ab7b328c3adde14105b1f36ae30adc9cdefae0a +Author: Anthony Green +Date: Wed Jul 8 06:24:26 2026 -0400 + + Add Anthony Green copyright line for 2026 authorship + + Attribute this year's work in the wasm and PA backends and the darwin + PowerPC closure code: + - wasm/ffi.c: widen narrow/unboxed returns to ffi_arg; NULL rvalue. + - pa/ffi.c: bump year (5-8 byte struct slot-sizing fix + avalue copy). + - powerpc/ffi_darwin.c: PPC_LD_* jump-table indexes for the aix/darwin + closure build fix. + + Co-Authored-By: Claude Fable 5 + +commit 5e334c6aa70b937b5c0d30ba10a373e34d7526b6 +Author: Anthony Green +Date: Wed Jul 8 06:17:58 2026 -0400 + + x86-64: add copyright line for the 2026 unix64.S plan trampolines + + The fast-path plan trampoline (ffi_plan_fast_call) and the pure-GP64 + direct thunks (ffi_plan_gp0..6) were added to unix64.S this year, so + add an Anthony Green copyright line alongside the original authors'. + + Co-Authored-By: Claude Fable 5 + +commit 70106b98d0a333a13b509b4bdc554018785be50c +Author: Anthony Green +Date: Wed Jul 8 06:15:53 2026 -0400 + + Update copyright year to 2026 + + Add 2026 to the copyright line on the source files, headers and the + manual touched during this year's development. Following existing + practice, only the maintainer's own copyright line is bumped (the + Anthony Green line, plus the Red Hat line in types.c); the years on + third-party-held backends are left as their original authors set them. + + Co-Authored-By: Claude Fable 5 + +commit 621874d6726007a6470b9c0c90b5a27c3c3ed932 +Author: Anthony Green +Date: Wed Jul 8 05:43:18 2026 -0400 + + configure: derive FFI_VERSION_STRING/NUMBER from AC_INIT + + The 3.6.0 release bumped AC_INIT but left FFI_VERSION_STRING and + FFI_VERSION_NUMBER at 3.5.2/30502, so the released headers report the + wrong version. Compute both from AC_PACKAGE_VERSION instead of + duplicating the version by hand: the string is the package version + verbatim, and the number encodes X.Y.Z as X*10000 + Y*100 + Z with any + non-numeric suffix (e.g. -rc0) ignored. + + Co-Authored-By: Claude Fable 5 + +commit b8c60b06597cc77cbe66bd208083acc20251fae0 +Author: Anthony Green +Date: Tue Jul 7 12:57:06 2026 -0400 + + README: note the ffi_call fixes in the 3.7.0 history + + Co-Authored-By: Claude Fable 5 + +commit ed5da041796cd6e38d2f30b948eadf63cf96139a +Author: Anthony Green +Date: Tue Jul 7 12:30:56 2026 -0400 + + wasm: don't widen unboxed small-struct returns + + The previous commit widened narrow integral returns to ffi_arg, but + unbox_small_structs had already collapsed single-member struct returns + into those same scalar type ids, and a struct return is stored at its + natural size -- the caller's buffer is exactly the struct. This broke + cls_1_1byte and the bhaible small-struct return tests. + + Remember whether the original return type was a struct and widen only + genuine scalar returns. + + Co-Authored-By: Claude Fable 5 + +commit 59a9e68e59205da9c4db854dd1f1bce4e8b58dad +Author: Anthony Green +Date: Tue Jul 7 12:02:20 2026 -0400 + + wasm: widen narrow integral returns to ffi_arg + + The return store wrote only the natural width for integer returns + narrower than a register (one byte for U8/S8, two for U16/S16, four on + wasm64 for 32-bit types), leaving the rest of the caller's ffi_arg + buffer as stack garbage. The documented API widens such returns to a + full ffi_arg, and every native port stores the full register width. + This is what plan_mixed.c caught: two identical calls disagreed in the + garbage bytes of their ffi_arg results. + + Mask or sign-extend the JS result explicitly and store a full ffi_arg + (32 bits on wasm32, 64 on wasm64). + + Co-Authored-By: Claude Fable 5 + +commit 6954bd1715b8a5895adfad7c2196d4eb41094dc7 +Author: Anthony Green +Date: Tue Jul 7 11:30:55 2026 -0400 + + testsuite: use ffi_arg for the integral return in plan.c + + The struct-argument block stored an ffi_type_slong return into a plain + long. Integral returns narrower than a register are widened to + ffi_arg, so on LLP64 targets libffi writes 8 bytes into the 4-byte + variable and clobbers its neighbor; this is what broke plan.c on MSVC + Win64 while mingw survived by stack-layout luck. + + Co-Authored-By: Claude Fable 5 + +commit 822d2e555fd97271c7c0ba8b6325cf4b541e3e9c +Author: Anthony Green +Date: Tue Jul 7 11:30:55 2026 -0400 + + Allow a NULL rvalue in ffi_call; handle it in the wasm port + + Most ports already quietly supported calling with rvalue == NULL by + substituting scratch space for in-memory returns, and the new plan + tests rely on it, but the manual never promised it and the wasm port + passed NULL straight to the callee as the return-by-argument pointer, + writing the result through address zero. + + Document NULL rvalue as supported for any return type, and in the wasm + port allocate stack scratch for return-by-argument callees and skip the + store-back for scalar returns when rvalue is NULL. + + Co-Authored-By: Claude Fable 5 + +commit 110156e1cceab76b4440ced9d95b5abaa84f30f7 +Author: Anthony Green +Date: Tue Jul 7 11:30:55 2026 -0400 + + ffi_call: never modify the caller's avalue array + + Eight ports made large struct arguments pass-by-value by alloca'ing a + copy inside ffi_call and writing the copy's address back into the + caller's avalue[]. Those pointers dangle as soon as ffi_call returns, + so any caller that legally reuses its avalue array for a second call + reads dead stack. The new ffi_call_plan equivalence tests do exactly + that and exposed it as plan_struct.c failures on hppa, MSVC Win64 and + macOS x86_64 under Rosetta; other targets passed only because the dead + copy usually survives between back-to-back calls. + + Clone the pointer array once, on the first argument that needs a copy, + and redirect the clone instead. Document that ffi_call leaves the + caller's vector untouched. + + Co-Authored-By: Claude Fable 5 + +commit e3dae4657710a9ddd4eb4bdbefbcc73722aad9fe +Author: Anthony Green +Date: Tue Jul 7 09:18:31 2026 -0400 + + testsuite: add ffi_call_plan equivalence tests; fix EXTRA_DIST gaps + + Add plan.c, plan_mixed.c, plan_spill.c, plan_struct.c and plan_var.c. + Each builds a reusable call plan (ffi_call_plan_alloc/invoke/free) and + checks it against ffi_call across the x86-64 argument-placement matrix: + the pure-GP64 direct thunks, the mixed GP+SSE fast path, stack-spilled + arguments, struct returns (in-memory including a NULL rvalue, and the + register pair), a struct-by-value argument that falls back to ffi_call, + and variadic calls. On targets without the accelerated backend the + generic plan simply wraps ffi_call, so the tests still pass there. + + While adding these to EXTRA_DIST, register four existing tests that were + never listed (i128-1.c, large_struct_by_value.c, many_small_structs.c + and complex_i128.c). They ran via the .exp globs but were missing from + distribution tarballs. + + Co-Authored-By: Claude Fable 5 + +commit a40ab3a7e85f8c9b193b8a442297bb20de2b4293 +Author: Anthony Green +Date: Tue Jul 7 08:19:33 2026 -0400 + + README: update 3.7.0 history entry + + Co-Authored-By: Claude Fable 5 + +commit 50baa0458db6b2d617e0d661292bbf12354b22ce +Author: Anthony Green +Date: Tue Jul 7 08:10:29 2026 -0400 + + x86_64: size closure argument buffer to match copy loop + + ffi_closure_unix64_inner allocated a fixed 16 bytes when gathering a + register-passed argument's eightbytes, but the copy loop writes n * 8 + bytes and examine_argument can classify up to MAX_CLASSES (4) + eightbytes for vector-classified types. Allocate n * 8 bytes so the + buffer always matches the loop bound. + + Co-Authored-By: Claude Fable 5 + +commit ff30d37615f82ef7bf1130b34528e01e1479b63d +Author: Anthony Green +Date: Tue Jul 7 08:10:29 2026 -0400 + + tramp.c: bound sscanf path field when parsing /proc/self/maps + + The %s conversion into file[PATH_MAX] was unbounded while the input + line buffer is PATH_MAX+100 bytes, so a mapping with a very long + pathname could overflow the destination. Give the conversion an + explicit PATH_MAX field width and size the buffer PATH_MAX+1 to + accommodate the terminating NUL. + + Co-Authored-By: Claude Fable 5 + +commit ed1844e6b50d0498d2b88d1b3ef31cc39b6cf117 +Author: Anthony Green +Date: Tue Jul 7 08:10:29 2026 -0400 + + .gitignore: ignore local build and scan artifact directories + + Co-Authored-By: Claude Fable 5 + +commit 854df63dbbda802985facbfab7a0e7c4169aefd1 +Merge: 2a595a18 731ec08f +Author: Anthony Green +Date: Tue Jul 7 08:06:25 2026 -0400 + + Merge pull request #991 from rorth/freebsd-libffi-note-gnu-stack + + Include .note.GNU-stack on FreeBSD/x86 + +commit 731ec08f3c3bbec883d823a71f1b0f86731cf312 +Author: Rainer Orth +Date: Tue Jul 7 11:14:09 2026 +0200 + + Fix typo. + +commit 19cc1424e924767c7ca43f9e4d4c27fbae27d1d9 +Author: Rainer Orth +Date: Tue Jul 7 10:27:55 2026 +0200 + + Include .note.GNU-stack on FreeBSD/x86 + + When building libffi on FreeBSD/x86 with --disable-shared as is done inside + the GCC tree, all tests FAIL when using GNU ld: + + gld-2.46: warning: win64.o: missing .note.GNU-stack section implies executable stack + gld-2.46: NOTE: This behaviour is deprecated and will be removed in a future version of the linker + + The emission of .note.GNU-stack in src/x86/*.S is currently guarded by + __ELF__ && __linux__, but FreeBSD/x86 uses that NOTE section, too. This + doesn't happen with libffi.so which lacks that NOTE. + + Therefore this patch extends the emission accordingly. + + Tested on amd64-pc-freebsd15.1 with and without --disable-shared. + +commit 2a595a183be146974bdf55716969e7a3e860f112 +Merge: c93f9428 f7b36640 +Author: Anthony Green +Date: Thu Jul 2 20:03:30 2026 -0400 + + Merge pull request #989 from rvandermeulen/dlmalloc-msvc-lock-cast + + dlmalloc: cast Win32 spin-lock word to LONG volatile* in CAS_LOCK/CLEAR_LOCK + +commit f7b36640544a59813ee372ed1a763affe7a67562 +Author: Ryan VanderMeulen +Date: Thu Jul 2 19:32:00 2026 -0400 + + dlmalloc: cast Win32 spin-lock word to LONG volatile* in CAS_LOCK/CLEAR_LOCK + + MLOCK_T is int, but on the Win32 MSC path CAS_LOCK/CLEAR_LOCK map to + _InterlockedExchange(LONG volatile *, LONG), so the int* lock word is + passed to a LONG volatile * parameter. clang 22 promotes + -Wincompatible-pointer-types to an error by default, which breaks the + clang-cl build (32- and 64-bit) with: + + error: incompatible pointer types passing 'int *' to parameter of type + 'volatile long *' [-Wincompatible-pointer-types] + + Cast to (LONG volatile *), matching what the ffi_spin_peek macro just + below already does in its _MSC_VER branch. LONG and int are both 32-bit + on Windows, so this is a type-correctness fix with no behavioral change. + +commit c93f9428d17cde4eb35517b58feeae6fb43aba5b +Author: Anthony Green +Date: Mon Jun 22 17:33:33 2026 -0400 + + testsuite: link threads tests against libpthread on NetBSD + + The libffi.threads/tsan.c test calls pthread_create but the harness + only appended -lpthread for OpenBSD, FreeBSD, and some Linux targets. + On NetBSD this caused an undefined reference to pthread_create. + + Fixes #988 + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 9ca53a19833dabaf80b73763638ab988bdbc42cc +Author: Anthony Green +Date: Sun Jun 21 18:42:37 2026 -0400 + + powerpc: fix aix/darwin closure build errors + + unbuildable: the PPC_LD_* jump-table indexes (defined in ffi_powerpc.h, + which this file cannot include) were missing, and the closure helper + functions still declared an ffi_type* return type inconsistent with the + PPC_LD_* constants they now return. + + Define the PPC_LD_* constants locally and change the closure helper + return types to int. + + Fixes #987 + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 807a93115f927229f6e7cf5675384e8dc2bf76d5 +Author: Anthony Green +Date: Sun Jun 21 18:31:12 2026 -0400 + + doc: mark the 3.7.0 release date as TBD + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit c876d4663183c40edbe5218603a26290900e7794 +Author: Anthony Green +Date: Sun Jun 21 18:28:12 2026 -0400 + + doc: add 3.7.0 history entry + + Record the next release (3.7.0, a minor bump for the new reusable call-plan API + on master) and the two PA-RISC fixes merged in #986. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit c3e054afebb2d9121ff4d12a56a803eecc31cc41 +Merge: 3cc6beb7 1f04d458 +Author: Anthony Green +Date: Sun Jun 21 18:13:59 2026 -0400 + + Merge pull request #986 from libffi/ci-enable-parisc-regression + + Add PA32/ARCompact struct-by-value regression tests; enable hppa CI + +commit 1f04d458126bd79c58196073477515c88de8163d +Author: Anthony Green +Date: Sun Jun 21 17:37:26 2026 -0400 + + pa: fix stack sizing for 5-8 byte structs passed by value (FFI_PA32) + + ffi_size_stack_pa32 reserved a single stack slot for every struct argument, + but ffi_prep_args_pa32 passes a 5-8 byte struct inline in two even-aligned + slots (like a 64-bit value). With enough such arguments the marshaller's slot + count outgrew cif->bytes and it wrote past the allocated frame -- below sp and + over ffi_call_pa32's saved return pointer -- corrupting the call. + + Make the sizing mirror the marshalling exactly: 1-4 byte structs take one slot, + 5-8 byte structs take "2 + (z & 1)" slots (z stays offset from the marshaller's + slot by the odd FIRST_ARG_SLOT, so the parity matches), and larger structs are + passed by pointer in one slot. Split the PA_HPUX long double case out since it + is passed by pointer. + + Fixes the failure exercised by testsuite/libffi.call/many_small_structs.c. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit cf45dfc368ea7373fdd946603845782dbcc1549a +Author: Anthony Green +Date: Sun Jun 21 16:57:56 2026 -0400 + + testsuite: make many_small_structs actually trigger the PA32 overflow + + With only 16 structs the PA-RISC slot under-count overflows ~32 bytes below + sp, landing in the 64-byte register save area where it clobbers nothing live, + so the call still returned correctly and the test passed under qemu. + + Raise the count to 40 so the marshaller's writes sweep past the save area and + over ffi_call_pa32's saved return pointer (sp-20), corrupting the return path. + On a correct backend the arguments still marshal within the allocated frame and + the call returns the expected sums; the test now fails only on an unfixed + FFI_PA32. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit d55de2637abd9518d550d18a3e1d89a37bd32f47 +Author: Anthony Green +Date: Sun Jun 21 16:39:30 2026 -0400 + + pa: fix build broken by the int128 generic types + + FFI_TYPE_UINT128/FFI_TYPE_SINT128 were added after FFI_TYPE_COMPLEX, moving + FFI_TYPE_LAST to FFI_TYPE_SINT128. The PA-RISC tripwire still pinned + FFI_PA_TYPE_LAST to FFI_TYPE_COMPLEX, so "#error You likely have broken jump + tables" fired and PA-RISC stopped building once int128 support landed. + + ffi_prep_cif_machdep maps every return type it does not handle explicitly -- + including FFI_TYPE_COMPLEX and the 128-bit integer types -- to FFI_TYPE_INT via + its default case, so cif->flags never exceeds FFI_TYPE_COMPLEX and the linux.S / + hpux32.S return-value jump tables remain sufficient. Bump FFI_PA_TYPE_LAST to + FFI_TYPE_SINT128 to clear the tripwire, with a comment recording why no table + entries were needed. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit d7177f2db574c962b4366b1948b7f7e1aaf896c2 +Author: Anthony Green +Date: Sun Jun 21 16:26:53 2026 -0400 + + ci: run the testsuite on PA-RISC 32-bit (hppa) under qemu-user + + Add an hppa-linux-gnu entry to the build-cross-qemu matrix so the testsuite is + cross-compiled with the Debian gcc-hppa-linux-gnu toolchain and run under + qemu-user (binfmt). hppa-linux uses FFI_PA32, so this exercises the + ffi_prep_args_pa32 / ffi_size_stack_pa32 marshalling path and will surface the + many_small_structs.c regression until the backend is fixed. + + Also drop the stale g++-5-hppa-linux-gnu pin from install.sh; the toolchain and + qemu-user-static now come from the CROSS_QEMU block. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit a384cba94f3935ac54a38f7c6489b6fbe0488c8c +Author: Anthony Green +Date: Sun Jun 21 16:26:21 2026 -0400 + + testsuite: add struct-by-value regression tests for PA32 and ARCompact + + Two ffi_call tests covering argument-marshalling defects found by a security + review of the backends: + + * many_small_structs.c -- passes sixteen 8-byte structs by value. On + PA-RISC 32-bit (FFI_PA32), ffi_size_stack_pa32 reserves one stack slot per + struct while ffi_prep_args_pa32 consumes two slots for a 5-8 byte struct + passed inline, so enough such args write past the asm-allocated frame. + + * large_struct_by_value.c -- passes one 64-byte struct by value. On + ARCompact (FFI_ARCOMPACT), ffi_call_int sizes the stack arg area at two + words per argument, but a by-value struct is marshalled one word at a time + and words beyond the eight argument registers are written to that + under-sized area without bound. + + Both are written as ordinary correctness tests (valid CIFs, asserts on the + expected sums); they pass on unaffected targets and fail on PA32/ARCompact + until the backends are fixed. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 3cc6beb7d404e12d3458461d76557b79795816ff +Author: Anthony Green +Date: Sun Jun 21 09:47:10 2026 -0400 + + x86-64: replace the transparent plan cache with an explicit ffi_call_plan API + + The transparent plan cache sped up ffi_call and closures by caching a + precomputed argument-placement plan per signature, but it charged every + call a cache lookup and content fingerprint, and it slightly regressed + signatures with no fast path (struct-by-value) that paid the key + computation only to find there was nothing to do. + + Replace it with an opt-in API. ffi_call_plan_alloc builds a plan from a + prepared cif, ffi_call_plan_invoke applies it with no per-call lookup, + and ffi_call_plan_free releases it. The plan is opaque and caller-owned, + immutable once built (so it may be shared across threads), and falls back + to ffi_call for signatures with no fast path. ffi_call and the closure + path return to their original behaviour, so callers that don't adopt the + API pay nothing. + + The x86-64 backend provides an accelerated plan; every other target gets + a portable fallback in prep_cif.c that wraps ffi_call, so the symbols are + defined on all platforms. The per-thread cache, content fingerprint, + thread-exit cleanup and closure demarshal layout are removed. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 0c8f175eb650bb204b679996696b3e7706505d8f +Author: Anthony Green +Date: Sun Jun 21 08:18:14 2026 -0400 + + x86-64: trim the plan-cache fingerprint to the arg_types contents + + abi, nargs and rtype are stored in the slot and compared exactly on every + hit, so folding them into the fingerprint is redundant work on the hot + path. Hashing only the arg_types element pointers keeps the same collision + behaviour and the same protection against a reused arg_types address, while + shortening the per-call hash and speeding up the all-pointer thunk path. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 7b8c3283351298c55d09f580414ab937f358156c +Merge: d4995b5b f1e21329 +Author: Anthony Green +Date: Sat Jun 20 19:48:22 2026 -0400 + + Merge pull request #985 from libffi/plan-cache-fingerprint + + x86-64: content-based plan-cache key and thread-exit cleanup + +commit f1e2132940880128e26b885ee956e76fe3cad2d8 +Author: Anthony Green +Date: Sat Jun 20 19:46:50 2026 -0400 + + x86-64: content-based plan-cache key and thread-exit cleanup + + Follow-up to the plan cache (PR #984), addressing two issues. + + Content key: the cache keyed slots on the abi/nargs/rtype plus the arg_types + *array pointer*. If a cif's arg_types array was freed and the address later + reused for a different signature with the same abi/nargs/rtype, the keys + collided and a stale plan could be returned. Key on a 64-bit fingerprint that + folds in the element ffi_type pointers, so distinct argument types always get + distinct keys. Lookup is now O(nargs) cheap pointer reads -- still far less + than re-classifying the call. + + Thread-exit cleanup: the per-thread cache leaked its malloc'd plans when a + thread exited. Register a pthread key whose destructor frees the thread's + plans. pthread is referenced via weak symbols, so a program that never links + pthread simply skips the registration (the cache is already bounded per thread). + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit d4995b5bff6e5ecefb46eda218c40717f895baaf +Merge: 918ca8ed de3826a8 +Author: Anthony Green +Date: Sat Jun 20 18:43:14 2026 -0400 + + Merge pull request #984 from libffi/fast-libffi-plan + + x86-64: transparent plan cache for ffi_call and closures + +commit de3826a8063fde113ee8d1e455d459038d5814cc +Author: Anthony Green +Date: Sat Jun 20 18:14:08 2026 -0400 + + x86-64: limit the plan cache to the SysV ABI + + The Win64/EFI64 plan path failed an MSVC execution test (libffi.call/float3) + that can't be reproduced or validated without a Windows toolchain. Revert + ffiw64.c to the proven upstream implementation and build plans only for + FFI_UNIX64, leaving Win64/EFI64/GNUW64 on the existing path. The SysV fast + path -- the bulk of the speedup -- is unaffected. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit fdbf8deaf297b308731385f91868ea8b5e7dbd21 +Author: Anthony Green +Date: Sat Jun 20 17:59:54 2026 -0400 + + x86-64: fix Windows build of the plan cache + + Native Windows targets build only ffiw64.c + win64.S for the x86 backend; + ffi64.c (which instantiates the plan-cache storage and ffi_build_plan_arch) + is not compiled, so ffiw64.c's ffi_plan_get left ffi_plan_miss / ffi_plan_cache + unresolved at link time. Instantiate the cache in ffiw64.c when X86_WIN64 is + defined (i.e. when ffi64.c is absent); on Unix x86-64 ffi64.c still does it and + X86_WIN64 is undefined, so there is no duplicate definition. + + Also use a portable thread-local qualifier (FFI_TLS: __declspec(thread) on + MSVC, __thread elsewhere). + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 872365e143c521b4a84f712aa60f4e638a8b8053 +Author: Anthony Green +Date: Sat Jun 20 17:25:17 2026 -0400 + + x86-64: reword plan-cache comments to be self-contained + + Drop the in-development "Mechanism A" label and the stale references to the + earlier opt-in arena/slab storage, so the comments describe the cache as it + now stands. No functional change. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit c4c9750c37868f26d1ce914592ca826e4ffc0b35 +Author: Anthony Green +Date: Sat Jun 20 13:10:18 2026 -0400 + + x86-64: transparent plan cache for ffi_call and closures + + Precompute each signature's argument placement once and cache it, keyed on + (abi, nargs, rtype, arg_types) in a per-thread direct-mapped cache, so ffi_call + and closures skip the per-call ABI classification. No API or ABI change -- + every caller benefits transparently on a relink. + + - Cache: src/plan-cache.h (inline O(1) probe) + src/plan-cache-impl.h + (per-thread storage, evict-and-free, FFI_PLAN_NONE for non-plan-able sigs). + - SysV (ffi64.c, unix64.S): pure-GP64 direct thunks (avalue -> arg regs), a + lean trampoline for register-only calls, and a plan executor reusing + ffi_call_unix64; closures use a precomputed demarshal layout. CFI on the + thunks/trampoline so exceptions unwind through them. + - Win64/EFI64 (ffiw64.c): plan executor + demarshal. + - W^X preserved: no runtime codegen; thunks shipped in .text. + + Scalar/pointer/int128/float/double args are accelerated; struct/complex/x87 + args fall back to the existing path. Pointer-heavy calls ~5x faster. + + Co-Authored-By: Claude Opus 4.8 (1M context) + +commit 918ca8edddbf542d9034d8e58931edfea036ecca +Author: Anthony Green +Date: Sat Jun 20 12:34:46 2026 -0400 + + ci: actually zip the MSVC binaries before the release upload + + The MSVC 'Create binary distribution' step builds a *directory* + (libffi--x86-bit-msvc-binaries/), but 'Upload to GitHub Release' + pointed softprops/action-gh-release at a .zip file that was never created. With + no matching file the action just warns and succeeds, so on the v3.6.0 tag the + step reported success while attaching nothing. + + Add a pwsh Compress-Archive step to produce the .zip (contents at top level, like + the upload-artifact layout), and set fail_on_unmatched_files: true so a missing + file fails the step loudly instead of silently passing. + + Co-Authored-By: Claude Opus 4.8 (1M context) + commit f6303b8b0dd6353c6a5bb4de2e855a13b86f22cf Author: Anthony Green Date: Sat Jun 20 09:54:12 2026 -0400 diff --git a/deps/libffi/LICENSE b/deps/libffi/LICENSE index 12b4970e0ddcb4..90a8b230284e5c 100644 --- a/deps/libffi/LICENSE +++ b/deps/libffi/LICENSE @@ -1,4 +1,4 @@ -libffi - Copyright (c) 1996-2025 Anthony Green, Red Hat, Inc and others. +libffi - Copyright (c) 1996-2026 Anthony Green, Red Hat, Inc and others. See source files for details. Permission is hereby granted, free of charge, to any person obtaining diff --git a/deps/libffi/README.md b/deps/libffi/README.md index 7693f1daf6f850..19f78f632b0cd4 100644 --- a/deps/libffi/README.md +++ b/deps/libffi/README.md @@ -1,5 +1,5 @@ -libffi-3.6.0 was released on June 20, 2026. +libffi-3.7.1 was released on July 10, 2026. What is libffi? @@ -201,6 +201,30 @@ History See the git log for details at http://github.com/libffi/libffi. + 3.7.1 July-10-2026 + Fix aarch64 ffi_call memory corruption when passing many large + structs by value. + Fix i386 thiscall/fastcall closure stack cleanup for 64-bit + integer and struct arguments. + Fix aarch64 int128 argument split between x7 and the stack on + Darwin (#993). + Fix aarch64 clang-cl link failure for HFA helper functions (#996). + Build a generic ffi_call_plan fallback on Windows x86-64. + Add Windows ARM64 (MSVC) build and continuous integration support. + + 3.7.0 July-7-2026 + Add reusable call plans (ffi_call_plan_alloc/ffi_call_plan_invoke/ffi_call_plan_free). + Fix PA-RISC build broken by the conditional __int128 support added in 3.6.0. + Fix PA-RISC stack overflow passing many small structs by value. + Fix powerpc aix/darwin closure build errors (#987). + Include .note.GNU-stack on FreeBSD/x86 (#991). + Fix MSVC Win32 spin-lock atomics in bundled dlmalloc (#989). + Harden static trampoline and x86_64 closure internals. + Fix ffi_call clobbering the caller's argument pointer array + when passing large structs by value. + Allow a NULL rvalue in ffi_call to discard the return value. + Fix wasm widening of integral returns narrower than ffi_arg. + 3.6.0 Jun-20-2026 Add LoongArch32 support. Add RISC-V static trampoline support. diff --git a/deps/libffi/configure b/deps/libffi/configure index 15b227e6888f82..e050ddc8675da1 100755 --- a/deps/libffi/configure +++ b/deps/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libffi 3.6.0. +# Generated by GNU Autoconf 2.71 for libffi 3.7.1. # # Report bugs to . # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.6.0' -PACKAGE_STRING='libffi 3.6.0' +PACKAGE_VERSION='3.7.1' +PACKAGE_STRING='libffi 3.7.1' PACKAGE_BUGREPORT='http://github.com/libffi/libffi/issues' PACKAGE_URL='' @@ -1417,7 +1417,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.6.0 to adapt to many kinds of systems. +\`configure' configures libffi 3.7.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1489,7 +1489,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.6.0:";; + short | recursive ) echo "Configuration of libffi 3.7.1:";; esac cat <<\_ACEOF @@ -1628,7 +1628,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.6.0 +libffi configure 3.7.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2259,7 +2259,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.6.0, which was +It was created by libffi $as_me 3.7.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3233,8 +3233,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers fficonfig.h" -FFI_VERSION_STRING="3.5.2" -FFI_VERSION_NUMBER=30502 +FFI_VERSION_STRING="3.7.1" +ffi_version_major=`echo "3.7.1" | cut -d. -f1` +ffi_version_minor=`echo "3.7.1" | cut -d. -f2 | sed 's/[^0-9].*//'` +ffi_version_micro=`echo "3.7.1" | cut -d. -f3 | sed 's/[^0-9].*//'` +FFI_VERSION_NUMBER=`expr ${ffi_version_major:-0} \* 10000 + ${ffi_version_minor:-0} \* 100 + ${ffi_version_micro:-0}` @@ -3983,7 +3986,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='3.6.0' + VERSION='3.7.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -20658,7 +20661,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.6.0, which was +This file was extended by libffi $as_me 3.7.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20726,7 +20729,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -libffi config.status 3.6.0 +libffi config.status 3.7.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/deps/libffi/configure.ac b/deps/libffi/configure.ac index 2c8ba77970b3b0..3370acc3a39690 100644 --- a/deps/libffi/configure.ac +++ b/deps/libffi/configure.ac @@ -2,11 +2,17 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.68]) -AC_INIT([libffi],[3.6.0],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.7.1],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.2" -FFI_VERSION_NUMBER=30502 +dnl Derive the version macros from AC_INIT so they cannot drift when the +dnl release version is bumped. FFI_VERSION_NUMBER encodes X.Y.Z as +dnl X*10000 + Y*100 + Z, ignoring any non-numeric suffix (e.g. -rc0). +FFI_VERSION_STRING="AC_PACKAGE_VERSION" +ffi_version_major=`echo "AC_PACKAGE_VERSION" | cut -d. -f1` +ffi_version_minor=`echo "AC_PACKAGE_VERSION" | cut -d. -f2 | sed 's/[[^0-9]].*//'` +ffi_version_micro=`echo "AC_PACKAGE_VERSION" | cut -d. -f3 | sed 's/[[^0-9]].*//'` +FFI_VERSION_NUMBER=`expr ${ffi_version_major:-0} \* 10000 + ${ffi_version_minor:-0} \* 100 + ${ffi_version_micro:-0}` AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) diff --git a/deps/libffi/doc/libffi.info b/deps/libffi/doc/libffi.info index b5b81d5bcf815f..b43246f8ed4e3a 100644 --- a/deps/libffi/doc/libffi.info +++ b/deps/libffi/doc/libffi.info @@ -3,7 +3,7 @@ This is libffi.info, produced by makeinfo version 7.1 from libffi.texi. This manual is for libffi, a portable foreign function interface library. - Copyright © 2008-2025 Anthony Green and Red Hat, Inc. + Copyright © 2008-2026 Anthony Green and Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -38,7 +38,7 @@ libffi This manual is for libffi, a portable foreign function interface library. - Copyright © 2008-2025 Anthony Green and Red Hat, Inc. + Copyright © 2008-2026 Anthony Green and Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -112,6 +112,7 @@ File: libffi.info, Node: Using libffi, Next: Memory Usage, Prev: Introduction * Simple Example:: A simple example. * Types:: libffi type descriptions. * Multiple ABIs:: Different passing styles on one platform. +* Reusable Call Plans:: Building a call plan once and reusing it. * The Closure API:: Writing a generic function. * Closure Example:: A closure example. * Thread Safety:: Thread safety. @@ -200,6 +201,11 @@ function: responsibility to ensure this. If CIF declares that the function returns ‘void’ (using ‘ffi_type_void’), then RVALUE is ignored. + RVALUE may also be ‘NULL’, in which case the call is performed and + the return value is discarded. This works for any return type, + including structures returned in memory; ‘libffi’ supplies internal + scratch space for the callee when needed. + In most situations, ‘libffi’ will handle promotion according to the ABI. However, for historical reasons, there is a special case with return values that must be handled by your code. In particular, @@ -213,7 +219,9 @@ function: AVALUES is a vector of ‘void *’ pointers that point to the memory locations holding the argument values for a call. If CIF declares that the function has no arguments (i.e., NARGS was 0), then - AVALUES is ignored. + AVALUES is ignored. ‘ffi_call’ does not modify the vector or the + argument values it points to, so both may be reused for subsequent + calls. Note that while the return value must be register-sized, arguments should exactly match their declared type. For example, if an @@ -739,7 +747,7 @@ compilers that support them: type descriptors in the previous example.  -File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, Up: Using libffi +File: libffi.info, Node: Multiple ABIs, Next: Reusable Call Plans, Prev: Types, Up: Using libffi 2.4 Multiple ABIs ================= @@ -751,9 +759,46 @@ instance, the x86 platform has both ‘stdcall’ and ‘fastcall’ functions. necessarily platform-specific.  -File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi +File: libffi.info, Node: Reusable Call Plans, Next: The Closure API, Prev: Multiple ABIs, Up: Using libffi + +2.5 Reusable Call Plans +======================= + +When the same signature is called many times - as language bindings +typically do - you can build a “call plan” once and reuse it, so that +each call avoids the work ‘ffi_call’ would otherwise repeat on every +invocation. A plan is an opaque, caller-owned object built from a +prepared ‘ffi_cif’. + + -- Function: ffi_call_plan * ffi_call_plan_alloc (ffi_cif *CIF) + Builds and returns a reusable plan for the signature described by + CIF, which must already have been prepared with ‘ffi_prep_cif’. + The plan does not copy CIF; CIF must remain valid for as long as + the plan is used. + + Returns ‘NULL’ only when memory cannot be allocated. A signature + for which no accelerated path exists is still valid: the returned + plan simply falls back to ‘ffi_call’ when it is invoked. + + -- Function: void ffi_call_plan_invoke (ffi_call_plan *PLAN, void *FN, + void *RVALUE, void **AVALUES) + Calls FN using PLAN. The FN, RVALUE, and AVALUES arguments have + exactly the same meaning as for ‘ffi_call’ (*note The Basics::), + including the rule that integral return values narrower than a + register are widened to ‘ffi_arg’. + + A plan is immutable once built, so a single plan may be invoked + concurrently from multiple threads without additional locking. + + -- Function: void ffi_call_plan_free (ffi_call_plan *PLAN) + Releases a plan returned by ‘ffi_call_plan_alloc’. Passing ‘NULL’ + is harmless. The ‘ffi_cif’ the plan was built from is not + affected. + + +File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Reusable Call Plans, Up: Using libffi -2.5 The Closure API +2.6 The Closure API =================== ‘libffi’ also provides a way to write a generic function - a function @@ -857,7 +902,7 @@ executable addresses.  File: libffi.info, Node: Closure Example, Next: Thread Safety, Prev: The Closure API, Up: Using libffi -2.6 Closure Example +2.7 Closure Example =================== A trivial example that creates a new ‘puts’ by binding ‘fputs’ with @@ -916,7 +961,7 @@ A trivial example that creates a new ‘puts’ by binding ‘fputs’ with  File: libffi.info, Node: Thread Safety, Prev: Closure Example, Up: Using libffi -2.7 Thread Safety +2.8 Thread Safety ================= ‘libffi’ is not completely thread-safe. However, many parts are, and if @@ -1004,17 +1049,21 @@ Index * cif: The Basics. (line 14) * closure API: The Closure API. (line 13) * closures: The Closure API. (line 13) -* const char *: The Basics. (line 106) +* const char *: The Basics. (line 113) * FFI: Introduction. (line 31) * ffi_call: The Basics. (line 72) +* ffi_call_plan *: Reusable Call Plans. (line 12) +* ffi_call_plan_alloc: Reusable Call Plans. (line 12) +* ffi_call_plan_free: Reusable Call Plans. (line 32) +* ffi_call_plan_invoke: Reusable Call Plans. (line 22) * ffi_closure_alloc: The Closure API. (line 19) * ffi_closure_free: The Closure API. (line 26) * FFI_CLOSURES: The Closure API. (line 13) -* ffi_get_closure_size: The Basics. (line 118) -* ffi_get_default_abi: The Basics. (line 115) +* ffi_get_closure_size: The Basics. (line 125) +* ffi_get_default_abi: The Basics. (line 122) * ffi_get_struct_offsets: Size and Alignment. (line 39) -* ffi_get_version: The Basics. (line 106) -* ffi_get_version_number: The Basics. (line 110) +* ffi_get_version: The Basics. (line 113) +* ffi_get_version_number: The Basics. (line 117) * ffi_prep_cif: The Basics. (line 16) * ffi_prep_cif_var: The Basics. (line 39) * ffi_prep_closure_loc: The Closure API. (line 41) @@ -1051,12 +1100,14 @@ Index * ffi_type_ushort: Primitive Types. (line 53) * ffi_type_void: Primitive Types. (line 10) * Foreign Function Interface: Introduction. (line 31) -* size_t: The Basics. (line 118) -* unsigned int: The Basics. (line 115) -* unsigned long: The Basics. (line 110) +* size_t: The Basics. (line 125) +* unsigned int: The Basics. (line 122) +* unsigned long: The Basics. (line 117) * void: The Basics. (line 72) -* void <1>: The Closure API. (line 19) -* void <2>: The Closure API. (line 26) +* void <1>: Reusable Call Plans. (line 22) +* void <2>: Reusable Call Plans. (line 32) +* void <3>: The Closure API. (line 19) +* void <4>: The Closure API. (line 26)  @@ -1064,23 +1115,24 @@ Tag Table: Node: Top1387 Node: Introduction2909 Node: Using libffi4569 -Node: The Basics5098 -Node: Simple Example10868 -Node: Types11925 -Node: Primitive Types12436 -Node: Structures14753 -Node: Size and Alignment15864 -Node: Arrays Unions Enums18135 -Node: Type Example21112 -Node: Complex22418 -Node: Complex Type Example23932 -Node: Multiple ABIs26984 -Node: The Closure API27367 -Node: Closure Example31703 -Node: Thread Safety33347 -Node: Memory Usage34180 -Node: Missing Features35455 -Node: Index35832 +Node: The Basics5172 +Node: Simple Example11346 +Node: Types12403 +Node: Primitive Types12914 +Node: Structures15231 +Node: Size and Alignment16342 +Node: Arrays Unions Enums18613 +Node: Type Example21590 +Node: Complex22896 +Node: Complex Type Example24410 +Node: Multiple ABIs27462 +Node: Reusable Call Plans27849 +Node: The Closure API29566 +Node: Closure Example33908 +Node: Thread Safety35552 +Node: Memory Usage36385 +Node: Missing Features37660 +Node: Index38037  End Tag Table diff --git a/deps/libffi/doc/libffi.pdf b/deps/libffi/doc/libffi.pdf index 3aa5406e61e08688ea5b64e5a0479c00899f928c..250d34faf71159260bc7d8905a68cd9885767592 100644 GIT binary patch delta 80352 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
G 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 pLWP5gfN0%4y;OSsRjCK2R=j0XK) delta 76624 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: handled specially + # below, since cl writes preprocessed output to stdout and prints + # the source file name to stderr. + preprocess="true" + shift 1 + ;; -O0) args="$args -Od" shift 1 @@ -236,19 +243,25 @@ do shift 1 ;; -S) - args="$args -FAs" + # Compile to assembly without linking, like gcc -S: emit the + # listing and stop after the compile step. + args="$args -c -FAs" + compile_to_asm="true" shift 1 ;; -o) outdir="$(dirname $2)" base="$(basename $2|sed 's/\.[^.]*//g')" - if [ -n "$single" ]; then + ppout="$2" + if [ -n "$compile_to_asm" ]; then + output="-Fo$outdir/$base.obj -Fa$2" + elif [ -n "$single" ]; then output="-Fo$2" else output="-Fe$2" fi armasm_output="-o $2" - if [ -n "$assembly" ]; then + if [ -n "$assembly" ] || [ -n "$compile_to_asm" ]; then args="$args $output" else args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base" @@ -294,7 +307,19 @@ if [ -n "$debug_crt" ]; then md="${md}d" fi -if [ -n "$assembly" ]; then +if [ -n "$preprocess" ]; then + # Write the preprocessed output to the -o target (or stdout), and + # swallow stderr: cl prints the source file name there, which the + # testsuite's feature probes would mistake for a diagnostic. + args="$(echo $args | sed 's%[-/]F[edpoa][^ ]*%%g')" + + if test -n "$verbose"; then + echo "$cl -EP $args > ${ppout:-/dev/stdout}" + fi + + eval "\"$cl\" -EP $args" > "${ppout:-/dev/stdout}" 2>/dev/null + result=$? +elif [ -n "$assembly" ]; then if [ -z "$outdir" ]; then outdir="." fi diff --git a/deps/libffi/src/aarch64/ffi.c b/deps/libffi/src/aarch64/ffi.c index 715e478c0edd14..2e6a2ad2624c07 100644 --- a/deps/libffi/src/aarch64/ffi.c +++ b/deps/libffi/src/aarch64/ffi.c @@ -378,13 +378,13 @@ extend_integer_type (void *source, int type) } } -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) void extend_hfa_type (void *dest, void *src, int h); #else static void extend_hfa_type (void *dest, void *src, int h) { - ssize_t f = h - AARCH64_RET_S4; + ptrdiff_t f = h - AARCH64_RET_S4; void *x0; #define BTI_J "hint #36" @@ -449,7 +449,7 @@ extend_hfa_type (void *dest, void *src, int h) } #endif -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) void* compress_hfa_type (void *dest, void *src, int h); #else static void * @@ -550,7 +550,9 @@ allocate_int128_to_reg_or_stack (struct call_context *context, ngrn += ngrn & 1; #endif - if (ngrn < N_X_ARG_REG) + /* The value must fit entirely in registers, i.e. the low half may + not be allocated to x7 with the high half spilled to the stack. */ + if (ngrn + 2 <= N_X_ARG_REG) { ret = &context->x[ngrn]; ngrn += 2; @@ -642,6 +644,23 @@ ffi_prep_cif_machdep (ffi_cif *cif) break; } + /* Composites larger than 16 bytes (that are not HFAs) are passed by + invisible reference: ffi_call copies the payload into the argument + slab (next_struct_area, growing down) and, once the X registers are + exhausted, also spills the by-ref pointer into the same slab (the + NSAA, growing up). The generic prep_cif accounting in cif->bytes + only charges the payload copy, not that 8-byte pointer slot, so the + two regions can collide and a later struct copy can overwrite an + already-spilled pointer with the copied payload bytes. Reserve an + extra 8 bytes per such argument so the slab is always large enough + for both. */ + for (i = 0, n = cif->nargs; i < n; i++) + { + ffi_type *ty = cif->arg_types[i]; + if (ty->size > 16 && !is_vfp_type (ty)) + bytes += 8; + } + /* Round the stack up to a multiple of the stack alignment requirement. */ cif->bytes = (unsigned) FFI_ALIGN(bytes, 16); cif->flags = flags; diff --git a/deps/libffi/src/alpha/ffi.c b/deps/libffi/src/alpha/ffi.c index cb683ec14317f8..5830ee3f2109e4 100644 --- a/deps/libffi/src/alpha/ffi.c +++ b/deps/libffi/src/alpha/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2012 Anthony Green + ffi.c - Copyright (c) 2012, 2026 Anthony Green Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc. Alpha Foreign Function Interface diff --git a/deps/libffi/src/alpha/ffitarget.h b/deps/libffi/src/alpha/ffitarget.h index f80f13e85fe67e..da63dc08813a26 100644 --- a/deps/libffi/src/alpha/ffitarget.h +++ b/deps/libffi/src/alpha/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012 Anthony Green + ffitarget.h - Copyright (c) 2012, 2026 Anthony Green Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for Alpha. diff --git a/deps/libffi/src/closures.c b/deps/libffi/src/closures.c index 124e1f386a7138..c1fbcf87ce29b6 100644 --- a/deps/libffi/src/closures.c +++ b/deps/libffi/src/closures.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - closures.c - Copyright (c) 2019, 2022 Anthony Green + closures.c - Copyright (c) 2019, 2022, 2026 Anthony Green Copyright (c) 2007, 2009, 2010 Red Hat, Inc. Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc Copyright (c) 2011 Plausible Labs Cooperative, Inc. diff --git a/deps/libffi/src/dlmalloc.c b/deps/libffi/src/dlmalloc.c index 5b400d65de3db4..93e81967039359 100644 --- a/deps/libffi/src/dlmalloc.c +++ b/deps/libffi/src/dlmalloc.c @@ -1916,8 +1916,8 @@ static FORCEINLINE void x86_clear_lock(int* sl) { #define CLEAR_LOCK(sl) x86_clear_lock(sl) #else /* Win32 MSC */ -#define CAS_LOCK(sl) interlockedexchange(sl, (LONG)1) -#define CLEAR_LOCK(sl) interlockedexchange (sl, (LONG)0) +#define CAS_LOCK(sl) interlockedexchange((LONG volatile *)(sl), (LONG)1) +#define CLEAR_LOCK(sl) interlockedexchange ((LONG volatile *)(sl), (LONG)0) #endif /* ... gcc spins locks ... */ diff --git a/deps/libffi/src/frv/ffi.c b/deps/libffi/src/frv/ffi.c index 99dd41d32d4c8f..4eb8e1ddfb87c8 100644 --- a/deps/libffi/src/frv/ffi.c +++ b/deps/libffi/src/frv/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (C) 2004 Anthony Green + ffi.c - Copyright (C) 2004, 2026 Anthony Green Copyright (C) 2007 Free Software Foundation, Inc. Copyright (C) 2008 Red Hat, Inc. diff --git a/deps/libffi/src/ia64/ffi.c b/deps/libffi/src/ia64/ffi.c index c00ef08543289a..00e1ae15707c5f 100644 --- a/deps/libffi/src/ia64/ffi.c +++ b/deps/libffi/src/ia64/ffi.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1998, 2007, 2008, 2012 Red Hat, Inc. Copyright (c) 2000 Hewlett Packard Company - Copyright (c) 2011 Anthony Green + Copyright (c) 2011, 2026 Anthony Green IA64 Foreign Function Interface diff --git a/deps/libffi/src/m32r/ffi.c b/deps/libffi/src/m32r/ffi.c index 6fab50b115ed24..21d499abe00302 100644 --- a/deps/libffi/src/m32r/ffi.c +++ b/deps/libffi/src/m32r/ffi.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 2004 Renesas Technology Copyright (c) 2008 Red Hat, Inc. - Copyright (c) 2022 Anthony Green + Copyright (c) 2022, 2026 Anthony Green M32R Foreign Function Interface @@ -180,10 +180,10 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { extended_cif ecif; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; int i, nargs = cif->nargs; ecif.cif = cif; - ecif.avalue = avalue; /* If the return value is a struct and we don't have a return value address then we need to make one. */ @@ -196,7 +196,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ecif.rvalue = rvalue; /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -204,10 +205,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) if (at->type == FFI_TYPE_STRUCT && size > 4) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } } + ecif.avalue = avalue; switch (cif->abi) { diff --git a/deps/libffi/src/moxie/ffi.c b/deps/libffi/src/moxie/ffi.c index ace7b23f855763..582c06f5dcebab 100644 --- a/deps/libffi/src/moxie/ffi.c +++ b/deps/libffi/src/moxie/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (C) 2012, 2013, 2018, 2021, 2022 Anthony Green + ffi.c - Copyright (C) 2012, 2013, 2018, 2021, 2022, 2026 Anthony Green Moxie Foreign Function Interface @@ -129,10 +129,10 @@ void ffi_call(ffi_cif *cif, { extended_cif ecif; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; int i, nargs = cif->nargs; ecif.cif = cif; - ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ @@ -146,7 +146,8 @@ void ffi_call(ffi_cif *cif, ecif.rvalue = rvalue; /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -154,10 +155,17 @@ void ffi_call(ffi_cif *cif, if (at->type == FFI_TYPE_STRUCT) /* && size > 4) All struct args?? */ { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } } + ecif.avalue = avalue; switch (cif->abi) { diff --git a/deps/libffi/src/or1k/ffi.c b/deps/libffi/src/or1k/ffi.c index 0393ea4af42af6..9303880a5e82b8 100644 --- a/deps/libffi/src/or1k/ffi.c +++ b/deps/libffi/src/or1k/ffi.c @@ -121,6 +121,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) int i; int size; ffi_type **arg; + void **avalue_copy = NULL; /* Calculate size to allocate on stack */ @@ -135,13 +136,21 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) size += 8; /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns + avalue[] and may reuse it for another call, so it must not be + modified. */ { ffi_type *at = cif->arg_types[i]; int size = at->size; if (at->type == FFI_TYPE_STRUCT) /* && size > 4) All struct args? */ { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (cif->nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, cif->nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } diff --git a/deps/libffi/src/pa/ffi.c b/deps/libffi/src/pa/ffi.c index 5460ca2fdbe147..e5de1dc72eb38e 100644 --- a/deps/libffi/src/pa/ffi.c +++ b/deps/libffi/src/pa/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - (c) 2011 Anthony Green + ffi.c - (c) 2011, 2026 Anthony Green (c) 2008 Red Hat, Inc. (c) 2006 Free Software Foundation, Inc. (c) 2003-2004 Randolph Chung @@ -280,9 +280,24 @@ static void ffi_size_stack_pa32(ffi_cif *cif) #ifdef PA_HPUX case FFI_TYPE_LONGDOUBLE: + z += 1; /* passed by pointer, like a large struct */ + break; #endif + case FFI_TYPE_STRUCT: - z += 1; /* pass by ptr, callee will copy */ + /* This must mirror the slot accounting in ffi_prep_args_pa32: + structs of 1-4 bytes occupy one slot, structs of 5-8 bytes are + passed inline in two even-aligned slots (exactly like a 64-bit + value), and larger structs are passed by pointer in one slot. + z stays offset from the marshaller's slot by FIRST_ARG_SLOT (odd), + so (z & 1) tracks the same alignment the marshaller applies. */ + { + size_t len = (*ptr)->size; + if (len <= 4 || len > 8) + z += 1; + else + z += 2 + (z & 1); + } break; default: /* <= 32-bit values */ @@ -363,12 +378,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) extended_cif ecif; size_t i, nargs = cif->nargs; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; ecif.cif = cif; - ecif.avalue = avalue; /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -376,10 +392,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) if (at->type == FFI_TYPE_STRUCT && size > 8) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } } + ecif.avalue = avalue; /* If the return value is a struct and we don't have a return value address then we need to make one. */ diff --git a/deps/libffi/src/pa/ffitarget.h b/deps/libffi/src/pa/ffitarget.h index dae854a695bb30..f6f09975cfac36 100644 --- a/deps/libffi/src/pa/ffitarget.h +++ b/deps/libffi/src/pa/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012 Anthony Green + ffitarget.h - Copyright (c) 2012, 2026 Anthony Green Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for hppa. @@ -82,11 +82,19 @@ typedef enum ffi_abi { #define FFI_TYPE_SMALL_STRUCT7 -7 #define FFI_TYPE_SMALL_STRUCT8 -8 -/* linux.S and hpux32.S expect FFI_TYPE_COMPLEX is the last generic type. */ -#define FFI_PA_TYPE_LAST FFI_TYPE_COMPLEX - -/* If new generic types are added, the jump tables in linux.S and hpux32.S - likely need updating. */ +/* The return-value jump tables in linux.S and hpux32.S are indexed by + cif->flags, which ffi_prep_cif_machdep derives from the return type. Any + return type it does not handle explicitly -- including FFI_TYPE_COMPLEX and + the 128-bit integer types FFI_TYPE_UINT128/FFI_TYPE_SINT128 -- falls through + to the default case and is mapped to FFI_TYPE_INT, so cif->flags never + exceeds FFI_TYPE_COMPLEX and the existing tables remain sufficient. Bump + FFI_PA_TYPE_LAST to the current FFI_TYPE_LAST once you have confirmed any + newly added generic type is likewise handled (or the tables extended). */ +#define FFI_PA_TYPE_LAST FFI_TYPE_SINT128 + +/* Tripwire: when a new generic type is added FFI_TYPE_LAST changes and this + fires, forcing a review of ffi_prep_cif_machdep and the linux.S / hpux32.S + jump tables before FFI_PA_TYPE_LAST above is bumped. */ #if FFI_TYPE_LAST != FFI_PA_TYPE_LAST # error "You likely have broken jump tables" #endif diff --git a/deps/libffi/src/powerpc/ffi.c b/deps/libffi/src/powerpc/ffi.c index 1afa582ebead82..69725242344c32 100644 --- a/deps/libffi/src/powerpc/ffi.c +++ b/deps/libffi/src/powerpc/ffi.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (C) 2013 IBM - Copyright (C) 2011 Anthony Green + Copyright (C) 2011, 2026 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc diff --git a/deps/libffi/src/powerpc/ffi_darwin.c b/deps/libffi/src/powerpc/ffi_darwin.c index d62737f47150c2..01e2a43701d7a1 100644 --- a/deps/libffi/src/powerpc/ffi_darwin.c +++ b/deps/libffi/src/powerpc/ffi_darwin.c @@ -4,6 +4,7 @@ Copyright (C) 1998 Geoffrey Keating Copyright (C) 2001 John Hornkvist Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2026 Anthony Green FFI support for Darwin and AIX. diff --git a/deps/libffi/src/powerpc/ffi_linux64.c b/deps/libffi/src/powerpc/ffi_linux64.c index 4a4fe86beff1f2..b1f1468ed5f856 100644 --- a/deps/libffi/src/powerpc/ffi_linux64.c +++ b/deps/libffi/src/powerpc/ffi_linux64.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- ffi_linux64.c - Copyright (C) 2013 IBM - Copyright (C) 2011 Anthony Green + Copyright (C) 2011, 2026 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc diff --git a/deps/libffi/src/powerpc/ffi_powerpc.h b/deps/libffi/src/powerpc/ffi_powerpc.h index c366315baefefe..bad33efe3b8cc1 100644 --- a/deps/libffi/src/powerpc/ffi_powerpc.h +++ b/deps/libffi/src/powerpc/ffi_powerpc.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- ffi_powerpc.h - Copyright (C) 2013 IBM - Copyright (C) 2011 Anthony Green + Copyright (C) 2011, 2026 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc diff --git a/deps/libffi/src/powerpc/ffi_sysv.c b/deps/libffi/src/powerpc/ffi_sysv.c index 975c58c2c0e049..a33039e3dbdb1a 100644 --- a/deps/libffi/src/powerpc/ffi_sysv.c +++ b/deps/libffi/src/powerpc/ffi_sysv.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- ffi_sysv.c - Copyright (C) 2013 IBM - Copyright (C) 2011 Anthony Green + Copyright (C) 2011, 2026 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc diff --git a/deps/libffi/src/powerpc/ffitarget.h b/deps/libffi/src/powerpc/ffitarget.h index cf67a9bba6ee33..7ffe36b682e4a7 100644 --- a/deps/libffi/src/powerpc/ffitarget.h +++ b/deps/libffi/src/powerpc/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012 Anthony Green + ffitarget.h - Copyright (c) 2012, 2026 Anthony Green Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc Copyright (c) 1996-2003 Red Hat, Inc. diff --git a/deps/libffi/src/prep_cif.c b/deps/libffi/src/prep_cif.c index 47c9259470c5ee..1836270d1a9cb7 100644 --- a/deps/libffi/src/prep_cif.c +++ b/deps/libffi/src/prep_cif.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 2011, 2012, 2021, 2025 Anthony Green + prep_cif.c - Copyright (c) 2011, 2012, 2021, 2025, 2026 Anthony Green Copyright (c) 1996, 1998, 2007 Red Hat, Inc. Copyright (c) 2022 Oracle and/or its affiliates. @@ -278,3 +278,42 @@ ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets) return initialize_aggregate(struct_type, offsets); } + +/* Generic ffi_call_plan: a portable fallback compiled on every target that does + not provide its own accelerated implementation. The x86-64 SysV backend + (ffi64.c) defines these with a fast path under __x86_64__ && !__ILP32__, but + that file is not built for Windows x86-64 (X86_WIN64), which uses ffiw64.c + instead -- and clang-cl and MSYS/mingw both define __x86_64__ there. So + exclude the fallback only when ffi64.c actually provides it; everywhere else + this plan just records the cif and invoke calls ffi_call, so the API is + always present and links on all targets. The cif must outlive the plan. */ +#if !(defined(__x86_64__) && !defined(__ILP32__) && !defined(X86_WIN64)) + +struct ffi_call_plan +{ + ffi_cif *cif; +}; + +ffi_call_plan * +ffi_call_plan_alloc (ffi_cif *cif) +{ + ffi_call_plan *plan = malloc (sizeof (struct ffi_call_plan)); + if (plan != NULL) + plan->cif = cif; + return plan; +} + +void +ffi_call_plan_invoke (ffi_call_plan *plan, void (*fn) (void), + void *rvalue, void **avalue) +{ + ffi_call (plan->cif, fn, rvalue, avalue); +} + +void +ffi_call_plan_free (ffi_call_plan *plan) +{ + free (plan); +} + +#endif /* generic ffi_call_plan fallback */ diff --git a/deps/libffi/src/s390/ffitarget.h b/deps/libffi/src/s390/ffitarget.h index 6a9c3234289cb5..4fc8ef02cfe83b 100644 --- a/deps/libffi/src/s390/ffitarget.h +++ b/deps/libffi/src/s390/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012 Anthony Green + ffitarget.h - Copyright (c) 2012, 2026 Anthony Green Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for S390. diff --git a/deps/libffi/src/sh64/ffi.c b/deps/libffi/src/sh64/ffi.c index 4545b0fa72141b..2df6e23a3fda29 100644 --- a/deps/libffi/src/sh64/ffi.c +++ b/deps/libffi/src/sh64/ffi.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 2003, 2004, 2006, 2007, 2012 Kaz Kojima - Copyright (c) 2008 Anthony Green + Copyright (c) 2008, 2026 Anthony Green SuperH SHmedia Foreign Function Interface diff --git a/deps/libffi/src/sparc/ffi.c b/deps/libffi/src/sparc/ffi.c index 98142b206ecd44..bcda1ff2219703 100644 --- a/deps/libffi/src/sparc/ffi.c +++ b/deps/libffi/src/sparc/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2011, 2013 Anthony Green + ffi.c - Copyright (c) 2011, 2013, 2026 Anthony Green Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc. SPARC Foreign Function Interface @@ -288,6 +288,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, size_t bytes = cif->bytes; size_t i, nargs = cif->nargs; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; FFI_ASSERT (cif->abi == FFI_V8); @@ -298,7 +299,8 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, bytes += FFI_ALIGN (cif->rtype->size, 8); /* If we have any structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -306,6 +308,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, if (at->type == FFI_TYPE_STRUCT) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } diff --git a/deps/libffi/src/sparc/ffi64.c b/deps/libffi/src/sparc/ffi64.c index 09a5e59dfdd0c7..5eec1499e1708d 100644 --- a/deps/libffi/src/sparc/ffi64.c +++ b/deps/libffi/src/sparc/ffi64.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2011, 2013 Anthony Green + ffi.c - Copyright (c) 2011, 2013, 2026 Anthony Green Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc. SPARC Foreign Function Interface @@ -429,6 +429,7 @@ ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, size_t bytes = cif->bytes; size_t i, nargs = cif->nargs; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; FFI_ASSERT (cif->abi == FFI_V9); @@ -436,7 +437,8 @@ ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, bytes += FFI_ALIGN (cif->rtype->size, 16); /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -444,10 +446,16 @@ ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, if (at->type == FFI_TYPE_STRUCT && size > 4) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } - } + } ffi_call_v9(cif, fn, rvalue, avalue, -bytes, closure); } diff --git a/deps/libffi/src/tramp.c b/deps/libffi/src/tramp.c index 76a9dfe75c2c3b..525f8154715671 100644 --- a/deps/libffi/src/tramp.c +++ b/deps/libffi/src/tramp.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- tramp.c - Copyright (c) 2020 Madhavan T. Venkataraman - Copyright (c) 2022 Anthony Green + Copyright (c) 2022, 2026 Anthony Green API and support functions for managing statically defined closure trampolines. @@ -201,11 +201,18 @@ static int tramp_table_alloc (void); #if defined (__linux__) || defined (__CYGWIN__) +/* Stringify a macro value for use in a scanf field-width specifier. */ +#define FFI_TRAMP_STR_(x) #x +#define FFI_TRAMP_STR(x) FFI_TRAMP_STR_(x) + static int ffi_tramp_get_libffi (void) { FILE *fp; - char file[PATH_MAX], line[PATH_MAX+100], perm[10], dev[10]; + /* `file' is sized PATH_MAX+1 so a scanf field width of PATH_MAX + (which permits PATH_MAX characters plus the terminating NUL) cannot + overflow. */ + char file[PATH_MAX+1], line[PATH_MAX+100], perm[10], dev[10]; unsigned long start, end, offset, inode; uintptr_t addr = (uintptr_t) tramp_globals.text; int nfields, found; @@ -215,7 +222,7 @@ ffi_tramp_get_libffi (void) open_flags |= O_CLOEXEC; #endif - snprintf (file, PATH_MAX, "/proc/%d/maps", getpid()); + snprintf (file, sizeof (file), "/proc/%d/maps", getpid()); fp = fopen (file, "r"); if (fp == NULL) return 0; @@ -225,7 +232,10 @@ ffi_tramp_get_libffi (void) if (fgets (line, sizeof (line), fp) == 0) break; - nfields = sscanf (line, "%lx-%lx %9s %lx %9s %ld %s", + /* Bound the path field width so a long mapping name cannot overflow + the fixed-size `file' buffer. */ + nfields = sscanf (line, + "%lx-%lx %9s %lx %9s %ld %" FFI_TRAMP_STR(PATH_MAX) "s", &start, &end, perm, &offset, dev, &inode, file); if (nfields != 7) continue; diff --git a/deps/libffi/src/types.c b/deps/libffi/src/types.c index c6e8ebe2a881be..4ac45a4ac0d790 100644 --- a/deps/libffi/src/types.c +++ b/deps/libffi/src/types.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998, 2024, 2025 Red Hat, Inc. + types.c - Copyright (c) 1996, 1998, 2024, 2025, 2026 Red Hat, Inc. Predefined ffi_types needed by libffi. diff --git a/deps/libffi/src/wasm/ffi.c b/deps/libffi/src/wasm/ffi.c index 486ffa7856aa82..b631b1b2bef9cf 100644 --- a/deps/libffi/src/wasm/ffi.c +++ b/deps/libffi/src/wasm/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 2018-2023 Hood Chatham, Brion Vibber, Kleis Auke Wolthuizen, and others. + Copyright (c) 2026 Anthony Green wasm32/emscripten Foreign Function Interface @@ -70,6 +71,13 @@ EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$co #define DEREF_PTR(addr, offset) DEREF_U32(addr, offset) #define DEREF_PTR_NUMBER(addr, offset) DEREF_PTR(addr, offset) +// Store an integral return value widened to ffi_arg (32 bits on wasm32), as +// the libffi API promises for integral returns narrower than a register. +// The typed-array store wraps modulo 2^32, so a sign-extended negative +// Number is stored correctly by both variants. +#define STORE_ARG_WIDENED_UNSIGNED(rvalue, x) (DEREF_U32(rvalue, 0) = (x)) +#define STORE_ARG_WIDENED_SIGNED(rvalue, x) (DEREF_U32(rvalue, 0) = (x)) + CHECK_FIELD_OFFSET(ffi_cif, abi, 4*0); CHECK_FIELD_OFFSET(ffi_cif, nargs, 4*1); CHECK_FIELD_OFFSET(ffi_cif, arg_types, 4*2); @@ -109,6 +117,16 @@ CHECK_FIELD_OFFSET(ffi_type, elements, 8); #define DEREF_PTR(addr, offset) DEREF_U64(addr, offset) #define DEREF_PTR_NUMBER(addr, offset) DEC_PTR(DEREF_PTR(addr, offset)) +// Store an integral return value widened to ffi_arg (64 bits on wasm64), as +// the libffi API promises for integral returns narrower than a register. +// BigInt masking treats the value as infinite-precision two's complement, so +// the unsigned variant zero-extends a possibly-negative i32 Number, while +// the BigUint64Array store wraps the signed variant modulo 2^64, which is +// sign extension. +#define STORE_ARG_WIDENED_UNSIGNED(rvalue, x) \ + (DEREF_U64(rvalue, 0) = BigInt(x) & BigInt(4294967295)) +#define STORE_ARG_WIDENED_SIGNED(rvalue, x) (DEREF_U64(rvalue, 0) = BigInt(x)) + CHECK_FIELD_OFFSET(ffi_cif, abi, 0); CHECK_FIELD_OFFSET(ffi_cif, nargs, 4); CHECK_FIELD_OFFSET(ffi_cif, arg_types, 8); @@ -247,6 +265,10 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif)); var rtype_ptr = rtype_unboxed[0]; var rtype_id = rtype_unboxed[1]; + // A small struct return is unboxed to a scalar type id above, but it is + // still a struct to the caller: its buffer is exactly the struct's size, + // so it must not get the integral widening to ffi_arg. + var rtype_widen = FFI_TYPE__TYPEID(DEC_PTR(CIF__RTYPE(cif))) !== FFI_TYPE_STRUCT; var orig_stack_ptr = stackSave(); var cur_stack_ptr = orig_stack_ptr; @@ -267,6 +289,15 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), // just use this. We also mark a flag that we don't need to convert the return // value of the dynamic call back to C. if (rtype_id === FFI_TYPE_LONGDOUBLE || rtype_id === FFI_TYPE_STRUCT) { + if (rvalue === 0) { + // NULL rvalue: the caller discards the result, but the callee still + // needs somewhere to write it. Allocate scratch space on the stack; + // it is released by the stackRestore after the call. + var rsize = DEC_PTR(FFI_TYPE__SIZE(rtype_ptr)); + var ralign = FFI_TYPE__ALIGN(rtype_ptr); + STACK_ALLOC(cur_stack_ptr, rsize, ralign); + rvalue = cur_stack_ptr; + } args.push(ENC_PTR(rvalue)); ret_by_arg = true; } @@ -430,15 +461,31 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), return; } + // A NULL rvalue means the caller discards the return value. + if (rvalue === 0) { + return; + } + // Otherwise the result was automatically converted from C into Javascript and // we need to manually convert it back to C. + // Integral returns narrower than a register are widened to ffi_arg, as + // documented and as every native port does -- but only genuine scalar + // returns: an unboxed small-struct return keeps its natural width. switch (rtype_id) { case FFI_TYPE_VOID: break; case FFI_TYPE_INT: - case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - DEREF_U32(rvalue, 0) = result; + if (rtype_widen) + STORE_ARG_WIDENED_SIGNED(rvalue, result | 0); + else + DEREF_U32(rvalue, 0) = result; + break; + case FFI_TYPE_UINT32: + if (rtype_widen) + STORE_ARG_WIDENED_UNSIGNED(rvalue, result | 0); + else + DEREF_U32(rvalue, 0) = result; break; case FFI_TYPE_FLOAT: DEREF_F32(rvalue, 0) = result; @@ -447,12 +494,28 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), DEREF_F64(rvalue, 0) = result; break; case FFI_TYPE_UINT8: + if (rtype_widen) + STORE_ARG_WIDENED_UNSIGNED(rvalue, result & 0xff); + else + DEREF_U8(rvalue, 0) = result; + break; case FFI_TYPE_SINT8: - DEREF_U8(rvalue, 0) = result; + if (rtype_widen) + STORE_ARG_WIDENED_SIGNED(rvalue, (result << 24) >> 24); + else + DEREF_U8(rvalue, 0) = result; break; case FFI_TYPE_UINT16: + if (rtype_widen) + STORE_ARG_WIDENED_UNSIGNED(rvalue, result & 0xffff); + else + DEREF_U16(rvalue, 0) = result; + break; case FFI_TYPE_SINT16: - DEREF_U16(rvalue, 0) = result; + if (rtype_widen) + STORE_ARG_WIDENED_SIGNED(rvalue, (result << 16) >> 16); + else + DEREF_U16(rvalue, 0) = result; break; case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: diff --git a/deps/libffi/src/x86/ffi.c b/deps/libffi/src/x86/ffi.c index 40d153fb399e21..27f17b0c884957 100644 --- a/deps/libffi/src/x86/ffi.c +++ b/deps/libffi/src/x86/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2017, 2022 Anthony Green + ffi.c - Copyright (c) 2017, 2022, 2026 Anthony Green Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc. Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Bo Thorsen @@ -554,8 +554,14 @@ ffi_closure_inner (struct closure_frame *frame, char *stack) return flags | (cif->bytes << X86_RET_POP_SHIFT); case FFI_THISCALL: case FFI_FASTCALL: - return flags | ((cif->bytes - (narg_reg * FFI_SIZEOF_ARG)) - << X86_RET_POP_SHIFT); + /* The callee must pop exactly the bytes that were passed on the + stack. Deriving that from cif->bytes minus narg_reg * 4 is wrong + once narg_reg has been force-bumped to 2 (above) for a 64-bit or + struct argument that is itself placed on the stack: the subtraction + then discounts register slots that were never used, under-popping + the stack. argp has advanced past exactly the stack-resident + arguments (dir == 1 for these ABIs), so use that directly. */ + return flags | (((unsigned) (argp - stack)) << X86_RET_POP_SHIFT); default: return flags; } diff --git a/deps/libffi/src/x86/ffi64.c b/deps/libffi/src/x86/ffi64.c index db0aa563a87947..c24db38c4364b7 100644 --- a/deps/libffi/src/x86/ffi64.c +++ b/deps/libffi/src/x86/ffi64.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi64.c - Copyright (c) 2011, 2018, 2022 Anthony Green + ffi64.c - Copyright (c) 2011, 2018, 2022, 2026 Anthony Green Copyright (c) 2013 The Written Word, Inc. Copyright (c) 2008, 2010 Red Hat, Inc. Copyright (c) 2002, 2007 Bo Thorsen @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include "internal64.h" @@ -734,6 +736,340 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, } #ifndef __ILP32__ +/* ===================================================================== + Precompiled argument-placement plan, used by the ffi_call_plan API. + + ffi_prep_cif_machdep classifies the signature once, but ffi_call_int then + re-derives the same per-argument placement on every call (~650 instructions + for a 3-argument call). A "plan" captures that placement as a flat move + list, built once, so the register_args + stack buffer can be filled with no + re-classification before handing off to the unchanged ffi_call_unix64. For + the common case (only 64-bit GP arguments) a direct thunk loads the values + straight into the argument registers, skipping the buffer entirely. + + A plan is built by ffi_call_plan_alloc and applied by ffi_call_plan_invoke; + the caller owns it and reuses it across calls. + + Scalar, pointer, int128, float and double arguments are handled; any struct, + complex, or x87 long double argument has no plan, so the caller's invoke + falls back to ffi_call. */ + +enum ffi_move_op +{ + FFI_MOVE_SE8, FFI_MOVE_SE16, FFI_MOVE_SE32, /* sign-extend N bytes -> gpr */ + FFI_MOVE_GP64, /* copy a full 8-byte word -> gpr */ + FFI_MOVE_GP, /* zero gpr, copy len(<8) bytes */ + FFI_MOVE_SSE64, FFI_MOVE_SSE32, /* copy 8/4 bytes -> sse slot */ + FFI_MOVE_STACK /* copy len bytes -> stack */ +}; + +typedef struct +{ + unsigned src_idx; /* avalue[] index */ + unsigned src_off; /* byte offset within avalue[src_idx] (chunk * 8) */ + unsigned dst_off; /* byte offset within the register_args+stack buf */ + unsigned len; /* bytes for FFI_MOVE_GP / FFI_MOVE_STACK */ + unsigned char op; +} ffi_move; + +typedef struct +{ + unsigned nmoves; + unsigned ssecount; /* -> reg_args->rax */ + unsigned bytes; /* stack-arg area size (== cif->bytes) */ + unsigned flags; /* == cif->flags */ + unsigned ret_in_mem; /* nonzero -> reg_args->gpr[0] = rvalue */ + unsigned fast; /* nonzero -> lean trampoline eligible */ + unsigned retcode; /* UNIX64_RET_* (low byte of flags) for the store */ + int thunk_n; /* >=0 -> ffi_gp_thunks[thunk_n], else -1 */ + ffi_move moves[]; +} ffi_plan; + +/* Return of the lean trampoline / direct thunks: callee's rax in .i, xmm0 in .d. */ +struct ffi_ret2 { UINT64 i; double d; }; +extern struct ffi_ret2 ffi_plan_fast_call (struct register_args *img, + void (*fn) (void)) FFI_HIDDEN; + +/* Count-based direct thunks: load avalue[0..N-1] into arg registers, call. */ +extern struct ffi_ret2 ffi_plan_gp0 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp1 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp2 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp3 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp4 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp5 (void **, void (*)(void)) FFI_HIDDEN; +extern struct ffi_ret2 ffi_plan_gp6 (void **, void (*)(void)) FFI_HIDDEN; +static struct ffi_ret2 (*const ffi_gp_thunks[7]) (void **, void (*)(void)) = + { ffi_plan_gp0, ffi_plan_gp1, ffi_plan_gp2, ffi_plan_gp3, + ffi_plan_gp4, ffi_plan_gp5, ffi_plan_gp6 }; + +/* Store the callee return value, replicating the unix64.S store_table widths. */ +static inline void +store_ret (void *rvalue, unsigned retcode, struct ffi_ret2 r) +{ + switch (retcode) + { + case UNIX64_RET_VOID: break; + case UNIX64_RET_UINT8: *(UINT64 *) rvalue = (UINT8) r.i; break; + case UNIX64_RET_UINT16: *(UINT64 *) rvalue = (UINT16) r.i; break; + case UNIX64_RET_UINT32: *(UINT64 *) rvalue = (UINT32) r.i; break; + case UNIX64_RET_SINT8: *(UINT64 *) rvalue = (UINT64)(SINT64)(SINT8) r.i; break; + case UNIX64_RET_SINT16: *(UINT64 *) rvalue = (UINT64)(SINT64)(SINT16) r.i; break; + case UNIX64_RET_SINT32: *(UINT64 *) rvalue = (UINT64)(SINT64)(SINT32) r.i; break; + case UNIX64_RET_INT64: *(UINT64 *) rvalue = r.i; break; + case UNIX64_RET_XMM32: memcpy (rvalue, &r.d, 4); break; + case UNIX64_RET_XMM64: memcpy (rvalue, &r.d, 8); break; + } +} + +/* Build the move-list for CIF, or NULL if not plan-able (caller falls back). */ +static ffi_plan * +build_plan (ffi_cif *cif) +{ + unsigned i, avn = cif->nargs; + enum x86_64_reg_class classes[MAX_CLASSES]; + unsigned nm, gprcount, ssecount; + size_t argp_off; + ffi_plan *plan; + int all_gp64 = 1; /* every arg is exactly one 64-bit GP move? */ + + if (cif->abi != FFI_UNIX64) + return NULL; + + /* Reject arg types this cut doesn't encode; returns are handled by flags. */ + for (i = 0; i < avn; i++) + { + int t = cif->arg_types[i]->type; + if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX) + return NULL; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (t == FFI_TYPE_LONGDOUBLE) + return NULL; +#endif + } + + /* One self-contained allocation: header + moves, released with plain free(). */ + plan = malloc (sizeof (ffi_plan) + sizeof (ffi_move) * (2 * avn + 1)); + if (plan == NULL) + return NULL; + + nm = gprcount = ssecount = 0; + argp_off = 0; + plan->ret_in_mem = (cif->flags & UNIX64_FLAG_RET_IN_MEM) ? 1 : 0; + if (plan->ret_in_mem) + gprcount++; /* sret pointer occupies gpr[0] */ + + for (i = 0; i < avn; i++) + { + ffi_type *at = cif->arg_types[i]; + size_t size = at->size, n, rem; + int ngpr, nsse; + unsigned j; + + n = examine_argument (at, classes, 0, &ngpr, &nsse); + if (n == 0 + || gprcount + ngpr > MAX_GPR_REGS + || ssecount + nsse > MAX_SSE_REGS) + { + long align = at->alignment; + ffi_move *m = &plan->moves[nm++]; + all_gp64 = 0; + if (align < 8) + align = 8; + argp_off = FFI_ALIGN (argp_off, align); + m->op = FFI_MOVE_STACK; + m->src_idx = i; + m->src_off = 0; + m->dst_off = (unsigned) (sizeof (struct register_args) + argp_off); + m->len = (unsigned) size; + argp_off += size; + continue; + } + + for (j = 0, rem = size; j < n; j++, rem -= 8) + { + ffi_move m; + m.src_idx = i; + m.src_off = j * 8; + switch (classes[j]) + { + case X86_64_NO_CLASS: + case X86_64_SSEUP_CLASS: + continue; /* nothing placed for this 8-byte */ + case X86_64_INTEGER_CLASS: + case X86_64_INTEGERSI_CLASS: + m.dst_off = gprcount * 8; /* offsetof(register_args,gpr) == 0 */ + switch (at->type) + { + case FFI_TYPE_SINT8: m.op = FFI_MOVE_SE8; all_gp64 = 0; break; + case FFI_TYPE_SINT16: m.op = FFI_MOVE_SE16; all_gp64 = 0; break; + case FFI_TYPE_SINT32: m.op = FFI_MOVE_SE32; all_gp64 = 0; break; + default: + if (rem >= 8) + m.op = FFI_MOVE_GP64; + else + { m.op = FFI_MOVE_GP; m.len = (unsigned) rem; all_gp64 = 0; } + break; + } + gprcount++; + break; + case X86_64_SSE_CLASS: + case X86_64_SSEDF_CLASS: + m.dst_off = (unsigned) (offsetof (struct register_args, sse) + + ssecount * sizeof (union big_int_union)); + m.op = FFI_MOVE_SSE64; + ssecount++; + all_gp64 = 0; + break; + case X86_64_SSESF_CLASS: + m.dst_off = (unsigned) (offsetof (struct register_args, sse) + + ssecount * sizeof (union big_int_union)); + m.op = FFI_MOVE_SSE32; + ssecount++; + all_gp64 = 0; + break; + default: + free (plan); /* X87 etc. in registers: bail */ + return NULL; + } + plan->moves[nm++] = m; + } + } + + plan->nmoves = nm; + plan->ssecount = ssecount; + plan->bytes = cif->bytes; + plan->flags = cif->flags; + plan->retcode = cif->flags & 0xff; /* UNIX64_RET_* */ + /* Lean-trampoline eligible: no spilled stack args and a simple return + (VOID..XMM64, codes 0..9; RET_IN_MEM has low byte VOID). Struct-in-regs + (>=12) and x87 (10,11) returns stay on ffi_call_unix64. */ + plan->fast = (cif->bytes == 0 && plan->retcode <= UNIX64_RET_XMM64) ? 1 : 0; + /* Pure-GP64 direct thunk: every arg is one 64-bit GP value (so a plain load + per arg is exact), <=6 of them, no sret, simple return -> load avalue + straight into the arg registers, no register image. */ + plan->thunk_n = + (all_gp64 && !plan->ret_in_mem && nm == avn && avn <= MAX_GPR_REGS + && plan->fast) + ? (int) avn : -1; + return plan; +} + +/* Execute PLAN: rebuild register_args + stack buffer, then ffi_call_unix64. */ +FFI_ASAN_NO_SANITIZE +static inline __attribute__ ((always_inline)) void +plan_exec (ffi_cif *cif, ffi_plan *plan, void (*fn) (void), + void *rvalue, void **avalue) +{ + unsigned flags = plan->flags; + struct register_args local __attribute__ ((aligned (16))); + char *stack = NULL; + struct register_args *reg_args; + unsigned k; + + if (rvalue == NULL) + { + if (flags & UNIX64_FLAG_RET_IN_MEM) + rvalue = alloca (cif->rtype->size); + else + flags = UNIX64_RET_VOID; + } + + if (plan->thunk_n >= 0) + { + /* Pure-GP64: load avalue straight into arg regs, no image at all. */ + struct ffi_ret2 r = ffi_gp_thunks[plan->thunk_n] (avalue, fn); + if (rvalue != NULL) + store_ret (rvalue, plan->retcode, r); + return; + } + + if (plan->fast) + reg_args = &local; /* no stack args: fixed local image */ + else + { + stack = alloca (sizeof (struct register_args) + plan->bytes + 4 * 8); + reg_args = (struct register_args *) stack; + } + reg_args->r10 = 0; /* closure (none for ffi_call) */ + if (plan->ret_in_mem) + reg_args->gpr[0] = (UINT64) (uintptr_t) rvalue; + + for (k = 0; k < plan->nmoves; k++) + { + ffi_move *m = &plan->moves[k]; + char *src = (char *) avalue[m->src_idx] + m->src_off; + char *dst = (char *) reg_args + m->dst_off; + switch (m->op) + { + /* x86-64: unaligned scalar loads from avalue[] are fine. */ + case FFI_MOVE_SE8: *(UINT64 *) dst = (UINT64) (SINT64) *(SINT8 *) src; break; + case FFI_MOVE_SE16: *(UINT64 *) dst = (UINT64) (SINT64) *(SINT16 *) src; break; + case FFI_MOVE_SE32: *(UINT64 *) dst = (UINT64) (SINT64) *(SINT32 *) src; break; + case FFI_MOVE_GP64: *(UINT64 *) dst = *(UINT64 *) src; break; + case FFI_MOVE_GP: *(UINT64 *) dst = 0; memcpy (dst, src, m->len); break; + case FFI_MOVE_SSE64: *(UINT64 *) dst = *(UINT64 *) src; break; + case FFI_MOVE_SSE32: *(UINT32 *) dst = *(UINT32 *) src; break; + case FFI_MOVE_STACK: memcpy (dst, src, m->len); break; + } + } + reg_args->rax = plan->ssecount; + + if (plan->fast) + { + /* No stack args; lean trampoline + return store replicating the + unix64.S store_table widths. ret_in_mem already wrote gpr[0]. */ + struct ffi_ret2 r = ffi_plan_fast_call (reg_args, fn); + if (rvalue != NULL) + store_ret (rvalue, plan->retcode, r); + return; + } + + ffi_call_unix64 (stack, plan->bytes + sizeof (struct register_args), + flags, rvalue, fn); +} + +/* Reusable call plan: an opaque, caller-owned handle wrapping a prebuilt plan. + ffi_call_plan_invoke applies it directly, skipping the per-call argument + classification ffi_call does every time. Signatures with no fast path + (FAST is NULL) fall back to ffi_call. The plan is immutable after alloc, so + it carries no per-thread state and can be invoked from any thread. */ +struct ffi_call_plan +{ + ffi_cif *cif; + ffi_plan *fast; /* prebuilt plan, or NULL -> fall back to ffi_call */ +}; + +ffi_call_plan * +ffi_call_plan_alloc (ffi_cif *cif) +{ + ffi_call_plan *plan = malloc (sizeof (struct ffi_call_plan)); + if (plan == NULL) + return NULL; + plan->cif = cif; + plan->fast = build_plan (cif); /* NULL if this signature has no fast path */ + return plan; +} + +void +ffi_call_plan_invoke (ffi_call_plan *plan, void (*fn) (void), + void *rvalue, void **avalue) +{ + if (plan->fast != NULL) + plan_exec (plan->cif, plan->fast, fn, rvalue, avalue); + else + ffi_call (plan->cif, fn, rvalue, avalue); +} + +void +ffi_call_plan_free (ffi_call_plan *plan) +{ + if (plan != NULL) + { + free (plan->fast); + free (plan); + } +} + extern void ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); #endif @@ -742,11 +1078,13 @@ void ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; int i, nargs = cif->nargs; const int max_reg_struct_size = cif->abi == FFI_GNUW64 ? 8 : 16; /* If we have any large structure arguments, make a copy so we are passing - by value. */ + by value. The pointer array is cloned first: the caller owns avalue[] + and may reuse it for another call, so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -754,6 +1092,12 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) if (at->type == FFI_TYPE_STRUCT && size > max_reg_struct_size) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } @@ -884,6 +1228,7 @@ ffi_closure_unix64_inner(ffi_cif *cif, avn = cif->nargs; flags = cif->flags; + avalue = alloca(avn * sizeof(void *)); gprcount = ssecount = 0; @@ -940,7 +1285,7 @@ ffi_closure_unix64_inner(ffi_cif *cif, /* Otherwise, allocate space to make them consecutive. */ else { - char *a = alloca (16); + char *a = alloca (n * 8); unsigned int j; avalue[i] = a; diff --git a/deps/libffi/src/x86/ffitarget.h b/deps/libffi/src/x86/ffitarget.h index 995469b0f59b2c..d702235f90fed5 100644 --- a/deps/libffi/src/x86/ffitarget.h +++ b/deps/libffi/src/x86/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green + ffitarget.h - Copyright (c) 2012, 2014, 2018, 2026 Anthony Green Copyright (c) 1996-2003, 2010 Red Hat, Inc. Copyright (C) 2008 Free Software Foundation, Inc. diff --git a/deps/libffi/src/x86/ffiw64.c b/deps/libffi/src/x86/ffiw64.c index 37d9a7e9c036d9..f8db4e0d96236b 100644 --- a/deps/libffi/src/x86/ffiw64.c +++ b/deps/libffi/src/x86/ffiw64.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffiw64.c - Copyright (c) 2018 Anthony Green + ffiw64.c - Copyright (c) 2018, 2026 Anthony Green Copyright (c) 2014 Red Hat, Inc. x86 win64 Foreign Function Interface @@ -126,12 +126,15 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, size_t rsize; struct win64_call_frame *frame; ffi_type **arg_types = cif->arg_types; + void **avalue_copy = NULL; int nargs = cif->nargs; FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64); /* If we have any int128 or irregularly sized structure arguments, - make a copy so we are passing by value. */ + make a copy so we are passing by value. The pointer array is cloned + first: the caller owns avalue[] and may reuse it for another call, + so it must not be modified. */ for (i = 0; i < nargs; i++) { ffi_type *at = arg_types[i]; @@ -159,6 +162,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, if (needcopy) { char *argcopy = alloca (size); + if (avalue_copy == NULL) + { + avalue_copy = alloca (nargs * sizeof (void *)); + memcpy (avalue_copy, avalue, nargs * sizeof (void *)); + avalue = avalue_copy; + } memcpy (argcopy, avalue[i], size); avalue[i] = argcopy; } diff --git a/deps/libffi/src/x86/sysv.S b/deps/libffi/src/x86/sysv.S index b5969df1560143..dac841421d9b2b 100644 --- a/deps/libffi/src/x86/sysv.S +++ b/deps/libffi/src/x86/sysv.S @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2017 Anthony Green + sysv.S - Copyright (c) 2017, 2026 Anthony Green - Copyright (c) 2013 The Written Word, Inc. - Copyright (c) 1996,1998,2001-2003,2005,2008,2010 Red Hat, Inc. @@ -1269,6 +1269,6 @@ L(EFDE9): #endif /* ifdef __i386__ */ -#if defined __ELF__ && defined __linux__ +#if defined __ELF__ && (defined __linux__ || defined __FreeBSD__) .section .note.GNU-stack,"",@progbits #endif diff --git a/deps/libffi/src/x86/sysv_intel.S b/deps/libffi/src/x86/sysv_intel.S index efdde14ac20290..c7de159916ac9c 100644 --- a/deps/libffi/src/x86/sysv_intel.S +++ b/deps/libffi/src/x86/sysv_intel.S @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2017, 2022 Anthony Green + sysv.S - Copyright (c) 2017, 2022, 2026 Anthony Green - Copyright (c) 2013 The Written Word, Inc. - Copyright (c) 1996,1998,2001-2003,2005,2008,2010 Red Hat, Inc. @@ -992,7 +992,7 @@ L(EFDE9): #endif /* ifndef _MSC_VER */ #endif /* ifndef __x86_64__ */ -#if defined __ELF__ && defined __linux__ +#if defined __ELF__ && (defined __linux__ || defined __FreeBSD__) .section .note.GNU-stack,"",@progbits #endif #endif diff --git a/deps/libffi/src/x86/unix64.S b/deps/libffi/src/x86/unix64.S index da30ab7577a7c3..61983ef3bcf5ec 100644 --- a/deps/libffi/src/x86/unix64.S +++ b/deps/libffi/src/x86/unix64.S @@ -2,6 +2,7 @@ unix64.S - Copyright (c) 2013 The Written Word, Inc. - Copyright (c) 2008 Red Hat, Inc - Copyright (c) 2002 Bo Thorsen + - Copyright (c) 2026 Anthony Green x86-64 Foreign Function Interface @@ -242,6 +243,154 @@ L(load_sse): L(UW4): ENDF(C(ffi_call_unix64)) +/* Lean trampoline for the plan fast path: no stack args, simple return. + struct { UINT64 rax; double xmm0; } + ffi_plan_fast_call (struct register_args *img /rdi/, void (*fn)(void) /rsi/); + + Loads the argument registers from IMG, calls FN, and lets the callee's + rax/xmm0 flow straight out as this function's {UINT64,double} return -- so + the C caller recovers both with no return-dispatch table. Skips the frame + relocation that ffi_call_unix64 needs only for stack args and struct/x87 + returns. Caller guarantees img has no spilled stack arguments. */ + .balign 8 + .globl C(ffi_plan_fast_call) + FFI_HIDDEN(C(ffi_plan_fast_call)) +C(ffi_plan_fast_call): + .cfi_startproc + _CET_ENDBR + movq %rsi, %r11 /* fn */ + movq %rdi, %rax /* img */ + movl 0xb0(%rax), %r10d /* ssecount */ + testl %r10d, %r10d + jz 1f + movdqa 0x30(%rax), %xmm0 + movdqa 0x40(%rax), %xmm1 + movdqa 0x50(%rax), %xmm2 + movdqa 0x60(%rax), %xmm3 + movdqa 0x70(%rax), %xmm4 + movdqa 0x80(%rax), %xmm5 + movdqa 0x90(%rax), %xmm6 + movdqa 0xa0(%rax), %xmm7 +1: + movq 0x00(%rax), %rdi + movq 0x08(%rax), %rsi + movq 0x10(%rax), %rdx + movq 0x18(%rax), %rcx + movq 0x20(%rax), %r8 + movq 0x28(%rax), %r9 + movl %r10d, %eax /* %al = ssecount */ + subq $8, %rsp /* realign to 16 across the call */ + .cfi_adjust_cfa_offset 8 + call *%r11 + addq $8, %rsp + .cfi_adjust_cfa_offset -8 + ret /* rax + xmm0 carry the callee's return */ + .cfi_endproc + ENDF(C(ffi_plan_fast_call)) + +/* Count-based direct thunks for the pure-GP64 fast path: load avalue[0..N-1] + straight into the argument registers (no register_args image) and call. + struct { UINT64 rax; double xmm0; } + ffi_plan_gpN (void **avalue /rdi/, void (*fn)(void) /rsi/); + Eligible only when every arg is a single 64-bit GP value (no sign-extension, + no SSE, no stack spill, no sret) -- so a plain 8-byte load per arg is exact. + rax/xmm0 flow out as the {UINT64,double} return; C stores per return code. */ + +#define FFI_GP_HEAD \ + .cfi_startproc; \ + _CET_ENDBR; \ + movq %rsi, %r11; \ + movq %rdi, %rax +#define FFI_GP_LD(OFS, REG) \ + movq OFS(%rax), %r10; \ + movq (%r10), REG +#define FFI_GP_TAIL \ + xorl %eax, %eax; \ + subq $8, %rsp; \ + .cfi_adjust_cfa_offset 8; \ + call *%r11; \ + addq $8, %rsp; \ + .cfi_adjust_cfa_offset -8; \ + ret; \ + .cfi_endproc + + .balign 8 + .globl C(ffi_plan_gp0) + FFI_HIDDEN(C(ffi_plan_gp0)) +C(ffi_plan_gp0): + FFI_GP_HEAD + FFI_GP_TAIL + ENDF(C(ffi_plan_gp0)) + + .balign 8 + .globl C(ffi_plan_gp1) + FFI_HIDDEN(C(ffi_plan_gp1)) +C(ffi_plan_gp1): + FFI_GP_HEAD + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp1)) + + .balign 8 + .globl C(ffi_plan_gp2) + FFI_HIDDEN(C(ffi_plan_gp2)) +C(ffi_plan_gp2): + FFI_GP_HEAD + FFI_GP_LD(0x08, %rsi) + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp2)) + + .balign 8 + .globl C(ffi_plan_gp3) + FFI_HIDDEN(C(ffi_plan_gp3)) +C(ffi_plan_gp3): + FFI_GP_HEAD + FFI_GP_LD(0x08, %rsi) + FFI_GP_LD(0x10, %rdx) + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp3)) + + .balign 8 + .globl C(ffi_plan_gp4) + FFI_HIDDEN(C(ffi_plan_gp4)) +C(ffi_plan_gp4): + FFI_GP_HEAD + FFI_GP_LD(0x08, %rsi) + FFI_GP_LD(0x10, %rdx) + FFI_GP_LD(0x18, %rcx) + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp4)) + + .balign 8 + .globl C(ffi_plan_gp5) + FFI_HIDDEN(C(ffi_plan_gp5)) +C(ffi_plan_gp5): + FFI_GP_HEAD + FFI_GP_LD(0x08, %rsi) + FFI_GP_LD(0x10, %rdx) + FFI_GP_LD(0x18, %rcx) + FFI_GP_LD(0x20, %r8) + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp5)) + + .balign 8 + .globl C(ffi_plan_gp6) + FFI_HIDDEN(C(ffi_plan_gp6)) +C(ffi_plan_gp6): + FFI_GP_HEAD + FFI_GP_LD(0x08, %rsi) + FFI_GP_LD(0x10, %rdx) + FFI_GP_LD(0x18, %rcx) + FFI_GP_LD(0x20, %r8) + FFI_GP_LD(0x28, %r9) + FFI_GP_LD(0x00, %rdi) + FFI_GP_TAIL + ENDF(C(ffi_plan_gp6)) + /* 6 general registers, 8 vector registers, 32 bytes of rvalue, 8 bytes of alignment. */ #define ffi_closure_OFS_G 0 @@ -724,6 +873,6 @@ L(EFDE5): #endif #endif /* __x86_64__ */ -#if defined __ELF__ && defined __linux__ +#if defined __ELF__ && (defined __linux__ || defined __FreeBSD__) .section .note.GNU-stack,"",@progbits #endif diff --git a/deps/libffi/src/x86/win64.S b/deps/libffi/src/x86/win64.S index e994fa9e1eea62..185f0a3048fba7 100644 --- a/deps/libffi/src/x86/win64.S +++ b/deps/libffi/src/x86/win64.S @@ -255,6 +255,6 @@ C(ffi_closure_win64_alt): #endif #endif /* __x86_64__ */ -#if defined __ELF__ && defined __linux__ +#if defined __ELF__ && (defined __linux__ || defined __FreeBSD__) .section .note.GNU-stack,"",@progbits #endif diff --git a/deps/libffi/src/x86/win64_intel.S b/deps/libffi/src/x86/win64_intel.S index b278a7440040d4..e9eff00da3ce6d 100644 --- a/deps/libffi/src/x86/win64_intel.S +++ b/deps/libffi/src/x86/win64_intel.S @@ -237,7 +237,7 @@ ffi_closure_win64_2 LABEL near cfi_endproc C(ffi_closure_win64) endp -#if defined __ELF__ && defined __linux__ +#if defined __ELF__ && (defined __linux__ || defined __FreeBSD__) .section .note.GNU-stack,"",@progbits #endif _text ends diff --git a/deps/libffi/testsuite/Makefile.am b/deps/libffi/testsuite/Makefile.am index 2e422b9a44e8e0..c14a880959d835 100644 --- a/deps/libffi/testsuite/Makefile.am +++ b/deps/libffi/testsuite/Makefile.am @@ -15,9 +15,13 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/align_stdcall.c libffi.call/bpo_38748.c libffi.call/call.exp \ libffi.call/err_bad_typedef.c libffi.call/ffitest.h libffi.call/float.c \ libffi.call/float1.c libffi.call/float2.c libffi.call/float3.c \ - libffi.call/float4.c libffi.call/float_va.c libffi.call/many.c \ + libffi.call/float4.c libffi.call/float_va.c libffi.call/i128-1.c \ + libffi.call/large_struct_by_value.c libffi.call/many.c \ libffi.call/many2.c libffi.call/many_double.c libffi.call/many_mixed.c \ + libffi.call/many_small_structs.c \ libffi.call/negint.c libffi.call/offsets.c libffi.call/overread.c \ + libffi.call/plan.c libffi.call/plan_mixed.c libffi.call/plan_spill.c \ + libffi.call/plan_struct.c libffi.call/plan_var.c \ libffi.call/pr1172638.c libffi.call/promotion.c libffi.call/pyobjc_tc.c libffi.call/return_dbl.c \ libffi.call/return_dbl1.c libffi.call/return_dbl2.c libffi.call/return_fl.c \ libffi.call/return_fl1.c libffi.call/return_fl2.c libffi.call/return_fl3.c \ @@ -77,7 +81,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.complex/cls_complex_va_double.c libffi.complex/cls_complex_va_float.c libffi.complex/cls_complex_va_longdouble.c \ libffi.complex/complex.exp libffi.complex/complex.inc libffi.complex/complex_defs_double.inc \ libffi.complex/complex_defs_float.inc libffi.complex/complex_defs_longdouble.inc libffi.complex/complex_double.c \ - libffi.complex/complex_float.c libffi.complex/complex_int.c libffi.complex/complex_longdouble.c \ + libffi.complex/complex_float.c libffi.complex/complex_i128.c libffi.complex/complex_int.c libffi.complex/complex_longdouble.c \ libffi.complex/ffitest.h libffi.complex/many_complex.inc libffi.complex/many_complex_double.c \ libffi.complex/many_complex_float.c libffi.complex/many_complex_longdouble.c libffi.complex/return_complex.inc \ libffi.complex/return_complex1.inc libffi.complex/return_complex1_double.c libffi.complex/return_complex1_float.c \ diff --git a/deps/libffi/testsuite/Makefile.in b/deps/libffi/testsuite/Makefile.in index 04f864ca251555..1b29b90d363346 100644 --- a/deps/libffi/testsuite/Makefile.in +++ b/deps/libffi/testsuite/Makefile.in @@ -303,9 +303,13 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/align_stdcall.c libffi.call/bpo_38748.c libffi.call/call.exp \ libffi.call/err_bad_typedef.c libffi.call/ffitest.h libffi.call/float.c \ libffi.call/float1.c libffi.call/float2.c libffi.call/float3.c \ - libffi.call/float4.c libffi.call/float_va.c libffi.call/many.c \ + libffi.call/float4.c libffi.call/float_va.c libffi.call/i128-1.c \ + libffi.call/large_struct_by_value.c libffi.call/many.c \ libffi.call/many2.c libffi.call/many_double.c libffi.call/many_mixed.c \ + libffi.call/many_small_structs.c \ libffi.call/negint.c libffi.call/offsets.c libffi.call/overread.c \ + libffi.call/plan.c libffi.call/plan_mixed.c libffi.call/plan_spill.c \ + libffi.call/plan_struct.c libffi.call/plan_var.c \ libffi.call/pr1172638.c libffi.call/promotion.c libffi.call/pyobjc_tc.c libffi.call/return_dbl.c \ libffi.call/return_dbl1.c libffi.call/return_dbl2.c libffi.call/return_fl.c \ libffi.call/return_fl1.c libffi.call/return_fl2.c libffi.call/return_fl3.c \ @@ -365,7 +369,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.complex/cls_complex_va_double.c libffi.complex/cls_complex_va_float.c libffi.complex/cls_complex_va_longdouble.c \ libffi.complex/complex.exp libffi.complex/complex.inc libffi.complex/complex_defs_double.inc \ libffi.complex/complex_defs_float.inc libffi.complex/complex_defs_longdouble.inc libffi.complex/complex_double.c \ - libffi.complex/complex_float.c libffi.complex/complex_int.c libffi.complex/complex_longdouble.c \ + libffi.complex/complex_float.c libffi.complex/complex_i128.c libffi.complex/complex_int.c libffi.complex/complex_longdouble.c \ libffi.complex/ffitest.h libffi.complex/many_complex.inc libffi.complex/many_complex_double.c \ libffi.complex/many_complex_float.c libffi.complex/many_complex_longdouble.c libffi.complex/return_complex.inc \ libffi.complex/return_complex1.inc libffi.complex/return_complex1_double.c libffi.complex/return_complex1_float.c \ diff --git a/deps/libffi/testsuite/lib/libffi.exp b/deps/libffi/testsuite/lib/libffi.exp index 0a98a07daf6702..55afb8f094a026 100644 --- a/deps/libffi/testsuite/lib/libffi.exp +++ b/deps/libffi/testsuite/lib/libffi.exp @@ -411,6 +411,10 @@ proc libffi_target_compile { source dest type options } { lappend options "libs= -lpthread" } + if { [string match "*-*-netbsd*" $target_triplet] } { + lappend options "libs= -lpthread" + } + lappend options "libs= -lffi" if { [string match "aarch64*-*-linux*" $target_triplet] } { diff --git a/deps/libffi/testsuite/libffi.call/i128-1.c b/deps/libffi/testsuite/libffi.call/i128-1.c new file mode 100644 index 00000000000000..1395f5e9426026 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/i128-1.c @@ -0,0 +1,103 @@ +/* Area: ffi_call + Purpose: Check int128 call and return. + Limitations: none. + PR: none. */ + +/* { dg-do run } */ +#include "ffitest.h" + +#if defined(FFI_TARGET_HAS_INT128) && defined(__SIZEOF_INT128__) + +typedef __int128_t i128; + +static const i128 val = ((i128)0x01020304050607ull << 64) | 0x08090a0b0c0d0e0full; +static const int dummy = 0xdeadbeef; + +#define D(X) int X __attribute__((unused)) + +static i128 f0(i128 x) +{ + return x; +} + +static i128 f1(D(a), i128 x) +{ + return x; +} + +static i128 f2(D(a), D(b), i128 x) +{ + return x; +} + +static i128 f3(D(a), D(b), D(c), i128 x) +{ + return x; +} + +static i128 f4(D(a), D(b), D(c), D(d), i128 x) +{ + return x; +} + +static i128 f5(D(a), D(b), D(c), D(d), D(e), i128 x) +{ + return x; +} + +static i128 f6(D(a), D(b), D(c), D(d), D(e), D(f), i128 x) +{ + return x; +} + +static i128 f7(D(a), D(b), D(c), D(d), D(e), D(f), D(g), i128 x) +{ + return x; +} + +static i128 f8(D(a), D(b), D(c), D(d), D(e), D(f), D(g), D(h), i128 x) +{ + return x; +} + +#define N 9 + +static void * const funcs[N] = { + f0, f1, f2, f3, f4, f5, f6, f7, f8 +}; + +int main (void) +{ + int i; + + for (i = 0; i < N; i++) + { + ffi_cif cif; + ffi_status s; + ffi_type *args[N]; + void *values[N]; + i128 ret; + int j; + + for (j = 0; j < i; j++) + { + args[j] = &ffi_type_sint; + values[j] = (void *)&dummy; + } + args[i] = &ffi_type_sint128; + values[i] = (void *)&val; + + s = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, i + 1, + &ffi_type_sint128, args); + CHECK(s == FFI_OK); + + ffi_call(&cif, FFI_FN(funcs[i]), &ret, values); + CHECK(ret == val); + } + + return 0; +} + +#else +int main (void) { return 0; } +#endif diff --git a/deps/libffi/testsuite/libffi.call/large_struct_by_value.c b/deps/libffi/testsuite/libffi.call/large_struct_by_value.c new file mode 100644 index 00000000000000..016870dfe1096c --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/large_struct_by_value.c @@ -0,0 +1,63 @@ +/* Area: ffi_call + Purpose: Pass a large struct by value (more words than arg registers). + Limitations: none. + PR: none. + Originator: secscan regression (ARCompact used_stack overflow). + + Regression test: on ARCompact (ARC 32-bit), ffi_call_int sized the stack + argument area at two words per argument, but a by-value struct is marshalled + one word ("atom") at a time, and words beyond the argument registers were + written to that under-sized area without bound. Passing a 64-byte struct by + value (sixteen 32-bit words, eight more than the eight argument registers) + must marshal correctly and return the expected sum. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct { int v[8]; } big_struct; + +static int ABI_ATTR +sum_big (big_struct s) +{ + int i, sum = 0; + for (i = 0; i < 8; i++) + sum += s.v[i]; + return sum; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + ffi_type bs_type; + ffi_type *bs_elements[9]; + big_struct in; + ffi_arg result = 0; + int i, expected = 0; + + bs_type.size = 0; + bs_type.alignment = 0; + bs_type.type = FFI_TYPE_STRUCT; + for (i = 0; i < 8; i++) + bs_elements[i] = &ffi_type_sint; + bs_elements[8] = NULL; + bs_type.elements = bs_elements; + + for (i = 0; i < 8; i++) + { + in.v[i] = 0x1111 * (i + 1); + expected += in.v[i]; + } + + args[0] = &bs_type; + values[0] = ∈ + + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ffi_type_sint, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(sum_big), &result, values); + + CHECK((int) result == expected); + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/many_small_structs.c b/deps/libffi/testsuite/libffi.call/many_small_structs.c new file mode 100644 index 00000000000000..242c38cfc135bf --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/many_small_structs.c @@ -0,0 +1,92 @@ +/* Area: ffi_call + Purpose: Pass many small (8-byte) structs by value. + Limitations: none. + PR: none. + Originator: secscan regression (PA-RISC 32-bit slot under-count). + + Regression test: on PA-RISC 32-bit (FFI_PA32), ffi_size_stack_pa32 reserves + one stack slot per struct (pa/ffi.c: "z += 1"), but ffi_prep_args_pa32 + consumes two slots for a 5-8 byte struct passed inline. ffi_call_pa32 sets + the argument base to sp + cif->bytes and ffi_prep_args_pa32 writes each + argument at (base - slot*4), so once the marshaller's slot count exceeds + cif->bytes/4 the writes spill below sp -- first into the 64-byte register + save area, then over ffi_call_pa32's own saved return pointer. + + A few small structs only overflow into harmless scratch (the call still + returns correctly), so this uses enough 8-byte structs that the overflow + reaches the saved return pointer and corrupts the return path. On a correct + backend all arguments marshal within the allocated frame and the call simply + returns the expected sums; the test passes everywhere except an unfixed + FFI_PA32. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef struct { int a; int b; } small_struct; + +#define NARGS 40 + +static small_struct ABI_ATTR +many_small (small_struct s0, small_struct s1, small_struct s2, small_struct s3, + small_struct s4, small_struct s5, small_struct s6, small_struct s7, + small_struct s8, small_struct s9, small_struct s10, small_struct s11, + small_struct s12, small_struct s13, small_struct s14, small_struct s15, + small_struct s16, small_struct s17, small_struct s18, small_struct s19, + small_struct s20, small_struct s21, small_struct s22, small_struct s23, + small_struct s24, small_struct s25, small_struct s26, small_struct s27, + small_struct s28, small_struct s29, small_struct s30, small_struct s31, + small_struct s32, small_struct s33, small_struct s34, small_struct s35, + small_struct s36, small_struct s37, small_struct s38, small_struct s39) +{ + small_struct r; + r.a = s0.a + s1.a + s2.a + s3.a + s4.a + s5.a + s6.a + s7.a + + s8.a + s9.a + s10.a + s11.a + s12.a + s13.a + s14.a + s15.a + + s16.a + s17.a + s18.a + s19.a + s20.a + s21.a + s22.a + s23.a + + s24.a + s25.a + s26.a + s27.a + s28.a + s29.a + s30.a + s31.a + + s32.a + s33.a + s34.a + s35.a + s36.a + s37.a + s38.a + s39.a; + r.b = s0.b + s1.b + s2.b + s3.b + s4.b + s5.b + s6.b + s7.b + + s8.b + s9.b + s10.b + s11.b + s12.b + s13.b + s14.b + s15.b + + s16.b + s17.b + s18.b + s19.b + s20.b + s21.b + s22.b + s23.b + + s24.b + s25.b + s26.b + s27.b + s28.b + s29.b + s30.b + s31.b + + s32.b + s33.b + s34.b + s35.b + s36.b + s37.b + s38.b + s39.b; + return r; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[NARGS]; + void *values[NARGS]; + ffi_type ss_type; + ffi_type *ss_elements[3]; + small_struct in[NARGS]; + small_struct result = { 0, 0 }; + int i, expected_a = 0, expected_b = 0; + + ss_type.size = 0; + ss_type.alignment = 0; + ss_type.type = FFI_TYPE_STRUCT; + ss_type.elements = ss_elements; + ss_elements[0] = &ffi_type_sint; + ss_elements[1] = &ffi_type_sint; + ss_elements[2] = NULL; + + for (i = 0; i < NARGS; i++) + { + in[i].a = i + 1; + in[i].b = -(i + 1); + expected_a += in[i].a; + expected_b += in[i].b; + args[i] = &ss_type; + values[i] = &in[i]; + } + + CHECK(ffi_prep_cif(&cif, ABI_NUM, NARGS, &ss_type, args) == FFI_OK); + + ffi_call(&cif, FFI_FN(many_small), &result, values); + + CHECK(result.a == expected_a); + CHECK(result.b == expected_b); + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan.c b/deps/libffi/testsuite/libffi.call/plan.c new file mode 100644 index 00000000000000..afed0977e6b1cb --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan.c @@ -0,0 +1,127 @@ +/* Area: ffi_call_plan + Purpose: Check that a reusable call plan reproduces ffi_call for the + pure-GP64 fast path, pointer arguments and repeated reuse, + and that a signature with no fast path still yields a usable + plan that falls back to ffi_call. + Limitations: none. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include "ffitest.h" + +static uint64_t gp6(uint64_t a, uint64_t b, uint64_t c, + uint64_t d, uint64_t e, uint64_t f) +{ + return a + b * 2 + c * 3 + d * 4 + e * 5 + f * 6; +} + +static void *ptr_ident(void *p) +{ + return p; +} + +struct small_pair { long x; long y; }; + +static long ssum(struct small_pair s) +{ + return s.x - s.y; +} + +int main (void) +{ + ffi_cif cif; + ffi_type *args[6]; + void *values[6]; + ffi_call_plan *plan; + uint64_t a[6], r_call, r_plan; + int i, k; + + /* Pure GP64: every argument is one 64-bit integer, so build_plan + selects the ffi_plan_gpN direct thunk. Reuse the plan across many + invocations with changing values. */ + for (i = 0; i < 6; i++) + args[i] = &ffi_type_uint64; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 6, &ffi_type_uint64, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + for (k = 0; k < 100; k++) + { + for (i = 0; i < 6; i++) + { + a[i] = (uint64_t) (k * 7 + i + 1); + values[i] = &a[i]; + } + ffi_call(&cif, FFI_FN(gp6), &r_call, values); + ffi_call_plan_invoke(plan, FFI_FN(gp6), &r_plan, values); + CHECK(r_call == r_plan); + CHECK(r_plan == gp6(a[0], a[1], a[2], a[3], a[4], a[5])); + } + ffi_call_plan_free(plan); + + /* Pointer argument and pointer return. */ + { + ffi_cif cifp; + ffi_type *pargs[1]; + void *pvalues[1]; + void *in, *rc, *rp; + ffi_call_plan *planp; + + pargs[0] = &ffi_type_pointer; + CHECK(ffi_prep_cif(&cifp, FFI_DEFAULT_ABI, 1, &ffi_type_pointer, pargs) + == FFI_OK); + planp = ffi_call_plan_alloc(&cifp); + CHECK(planp != NULL); + + in = &cifp; + pvalues[0] = ∈ + ffi_call(&cifp, FFI_FN(ptr_ident), &rc, pvalues); + ffi_call_plan_invoke(planp, FFI_FN(ptr_ident), &rp, pvalues); + CHECK(rc == in); + CHECK(rp == in); + ffi_call_plan_free(planp); + } + + /* No fast path: a struct-by-value argument. build_plan returns NULL for + the fast plan, but ffi_call_plan_alloc must still hand back a valid plan + whose invoke falls back to ffi_call and produces the same result. */ + { + ffi_cif cifs; + ffi_type *sargs[1]; + ffi_type stype; + ffi_type *selements[3]; + void *svalues[1]; + struct small_pair s; + ffi_arg rc, rp; + ffi_call_plan *plans; + + selements[0] = &ffi_type_slong; + selements[1] = &ffi_type_slong; + selements[2] = NULL; + stype.size = stype.alignment = 0; + stype.type = FFI_TYPE_STRUCT; + stype.elements = selements; + + sargs[0] = &stype; + CHECK(ffi_prep_cif(&cifs, FFI_DEFAULT_ABI, 1, &ffi_type_slong, sargs) + == FFI_OK); + plans = ffi_call_plan_alloc(&cifs); + CHECK(plans != NULL); + + s.x = 123; + s.y = 45; + svalues[0] = &s; + ffi_call(&cifs, FFI_FN(ssum), &rc, svalues); + ffi_call_plan_invoke(plans, FFI_FN(ssum), &rp, svalues); + CHECK(rc == rp); + CHECK((long) rp == ssum(s)); + ffi_call_plan_free(plans); + } + + /* Freeing NULL is documented to be harmless. */ + ffi_call_plan_free(NULL); + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan_mixed.c b/deps/libffi/testsuite/libffi.call/plan_mixed.c new file mode 100644 index 00000000000000..54b1f6290c4422 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan_mixed.c @@ -0,0 +1,153 @@ +/* Area: ffi_call_plan + Purpose: Check that a reusable call plan reproduces ffi_call for + signatures that mix general-purpose and SSE registers, for + float and double returns, for signed narrow arguments, and + for integer returns narrower than a register (which the plan + must widen to ffi_arg exactly as ffi_call does). + Limitations: none. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include "ffitest.h" + +static double mixed(int a, double b, long c, float d, + long long e, double f) +{ + return (double) a + b + (double) c + (double) d + (double) e + f; +} + +static float faddf(float a, float b) +{ + return a + b; +} + +static signed char ret_sc(signed char x) +{ + return (signed char) (x + 1); +} + +static unsigned char ret_uc(unsigned char x) +{ + return (unsigned char) (x + 1); +} + +int main (void) +{ + /* Mixed GP + SSE arguments, double return: exercises the fast local-image + path with both integer and SSE moves and the ssecount (al) setup. */ + { + ffi_cif cif; + ffi_type *args[6]; + void *values[6]; + ffi_call_plan *plan; + int a = 3; + double b = 1.5, f = -2.25, rc, rp; + long c = 7; + float d = 0.5f; + long long e = -11; + + args[0] = &ffi_type_sint; + args[1] = &ffi_type_double; + args[2] = &ffi_type_slong; + args[3] = &ffi_type_float; + args[4] = &ffi_type_sint64; + args[5] = &ffi_type_double; + values[0] = &a; values[1] = &b; values[2] = &c; + values[3] = &d; values[4] = &e; values[5] = &f; + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 6, &ffi_type_double, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(mixed), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(mixed), &rp, values); + CHECK_DOUBLE_EQ(rc, rp); + CHECK_DOUBLE_EQ(rp, mixed(a, b, c, d, e, f)); + ffi_call_plan_free(plan); + } + + /* Float arguments and float return. */ + { + ffi_cif cif; + ffi_type *args[2]; + void *values[2]; + ffi_call_plan *plan; + float a = 1.25f, b = 2.5f, rc, rp; + + args[0] = &ffi_type_float; + args[1] = &ffi_type_float; + values[0] = &a; + values[1] = &b; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_float, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(faddf), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(faddf), &rp, values); + CHECK_FLOAT_EQ(rc, rp); + CHECK_FLOAT_EQ(rp, faddf(a, b)); + ffi_call_plan_free(plan); + } + + /* Signed narrow argument and signed narrow return: the plan sign-extends + the argument and widens the return to ffi_arg just as ffi_call does. */ + { + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + ffi_call_plan *plan; + signed char in; + ffi_arg rc, rp; + int v; + + args[0] = &ffi_type_schar; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_schar, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + for (v = -128; v < 128; v++) + { + in = (signed char) v; + values[0] = ∈ + ffi_call(&cif, FFI_FN(ret_sc), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(ret_sc), &rp, values); + CHECK(rc == rp); + CHECK((signed char) rp == ret_sc(in)); + } + ffi_call_plan_free(plan); + } + + /* Unsigned narrow argument and unsigned narrow return. */ + { + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + ffi_call_plan *plan; + unsigned char in; + ffi_arg rc, rp; + int v; + + args[0] = &ffi_type_uchar; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uchar, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + for (v = 0; v < 256; v++) + { + in = (unsigned char) v; + values[0] = ∈ + ffi_call(&cif, FFI_FN(ret_uc), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(ret_uc), &rp, values); + CHECK(rc == rp); + CHECK((unsigned char) rp == ret_uc(in)); + } + ffi_call_plan_free(plan); + } + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan_spill.c b/deps/libffi/testsuite/libffi.call/plan_spill.c new file mode 100644 index 00000000000000..c073c99142e423 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan_spill.c @@ -0,0 +1,142 @@ +/* Area: ffi_call_plan + Purpose: Check that a reusable call plan reproduces ffi_call when + arguments spill past the argument registers onto the stack. + This drives the non-fast plan path (a move list handed to + ffi_call_unix64) for GP spill, SSE spill, and a mix of both. + Limitations: none. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include "ffitest.h" + +/* 10 integers: 6 in registers, 4 spilled to the stack. */ +static long long gp10(long long a1, long long a2, long long a3, long long a4, + long long a5, long long a6, long long a7, long long a8, + long long a9, long long a10) +{ + return a1 + a2 * 2 + a3 * 3 + a4 * 4 + a5 * 5 + + a6 * 6 + a7 * 7 + a8 * 8 + a9 * 9 + a10 * 10; +} + +/* 12 doubles: 8 in SSE registers, 4 spilled to the stack. */ +static double sse12(double a1, double a2, double a3, double a4, + double a5, double a6, double a7, double a8, + double a9, double a10, double a11, double a12) +{ + return a1 + a2 * 2 + a3 * 3 + a4 * 4 + a5 * 5 + a6 * 6 + + a7 * 7 + a8 * 8 + a9 * 9 + a10 * 10 + a11 * 11 + a12 * 12; +} + +/* 8 ints + 8 doubles: both classes spill. */ +static double mix16(long i1, long i2, long i3, long i4, + long i5, long i6, long i7, long i8, + double d1, double d2, double d3, double d4, + double d5, double d6, double d7, double d8) +{ + double s = 0.0; + s += (double) (i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); + s += d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8; + return s; +} + +int main (void) +{ + /* GP spill. */ + { + ffi_cif cif; + ffi_type *args[10]; + void *values[10]; + long long a[10]; + long long rc, rp; + ffi_call_plan *plan; + int i; + + for (i = 0; i < 10; i++) + { + args[i] = &ffi_type_sint64; + a[i] = (long long) (i + 1) * 100 - 3; + values[i] = &a[i]; + } + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 10, &ffi_type_sint64, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(gp10), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(gp10), &rp, values); + CHECK(rc == rp); + CHECK(rp == gp10(a[0], a[1], a[2], a[3], a[4], + a[5], a[6], a[7], a[8], a[9])); + ffi_call_plan_free(plan); + } + + /* SSE spill. */ + { + ffi_cif cif; + ffi_type *args[12]; + void *values[12]; + double a[12]; + double rc, rp; + ffi_call_plan *plan; + int i; + + for (i = 0; i < 12; i++) + { + args[i] = &ffi_type_double; + a[i] = (double) i + 0.25; + values[i] = &a[i]; + } + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(sse12), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(sse12), &rp, values); + CHECK_DOUBLE_EQ(rc, rp); + CHECK_DOUBLE_EQ(rp, sse12(a[0], a[1], a[2], a[3], a[4], a[5], + a[6], a[7], a[8], a[9], a[10], a[11])); + ffi_call_plan_free(plan); + } + + /* Both classes spill. */ + { + ffi_cif cif; + ffi_type *args[16]; + void *values[16]; + long iv[8]; + double dv[8]; + double rc, rp; + ffi_call_plan *plan; + int i; + + for (i = 0; i < 8; i++) + { + args[i] = &ffi_type_slong; + iv[i] = (long) (i + 1); + values[i] = &iv[i]; + } + for (i = 0; i < 8; i++) + { + args[8 + i] = &ffi_type_double; + dv[i] = (double) (i + 1) * 0.5; + values[8 + i] = &dv[i]; + } + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, &ffi_type_double, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(mix16), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(mix16), &rp, values); + CHECK_DOUBLE_EQ(rc, rp); + CHECK_DOUBLE_EQ(rp, mix16(iv[0], iv[1], iv[2], iv[3], + iv[4], iv[5], iv[6], iv[7], + dv[0], dv[1], dv[2], dv[3], + dv[4], dv[5], dv[6], dv[7])); + ffi_call_plan_free(plan); + } + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan_struct.c b/deps/libffi/testsuite/libffi.call/plan_struct.c new file mode 100644 index 00000000000000..816296d77a8afa --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan_struct.c @@ -0,0 +1,163 @@ +/* Area: ffi_call_plan + Purpose: Check that a reusable call plan reproduces ffi_call for struct + returns. A struct return does not disable planning (only a + struct *argument* does), so this drives both the in-memory + return path (RET_IN_MEM, including a NULL rvalue) and the + register-pair struct return path, plus a large struct argument + that forces the ffi_call by-value copy fallback. + Limitations: none. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include "ffitest.h" + +static int call_count = 0; + +/* 24 bytes: returned in memory (a hidden pointer in the first argument). */ +struct big3 { double a, b, c; }; + +static struct big3 make_big3(double a, double b, double c) +{ + struct big3 r; + call_count++; + r.a = a + 1.0; + r.b = b + 2.0; + r.c = c + 3.0; + return r; +} + +/* A struct larger than 16 bytes passed by value forces ffi_call to make a + copy; build_plan has no fast path for a struct argument, so this exercises + the plan's fallback to ffi_call. */ +static double sum_big3(struct big3 s) +{ + return s.a + s.b + s.c; +} + +/* 16 bytes: returned in a register pair (RAX:RDX on x86-64). */ +struct pair2 { long x, y; }; + +static struct pair2 make_pair2(long x, long y) +{ + struct pair2 r; + r.x = x * 2; + r.y = y * 3; + return r; +} + +int main (void) +{ + ffi_type *big3_elements[4]; + ffi_type big3_t; + ffi_type *pair2_elements[3]; + ffi_type pair2_t; + + big3_elements[0] = &ffi_type_double; + big3_elements[1] = &ffi_type_double; + big3_elements[2] = &ffi_type_double; + big3_elements[3] = NULL; + big3_t.size = big3_t.alignment = 0; + big3_t.type = FFI_TYPE_STRUCT; + big3_t.elements = big3_elements; + + pair2_elements[0] = &ffi_type_slong; + pair2_elements[1] = &ffi_type_slong; + pair2_elements[2] = NULL; + pair2_t.size = pair2_t.alignment = 0; + pair2_t.type = FFI_TYPE_STRUCT; + pair2_t.elements = pair2_elements; + + /* In-memory struct return with scalar arguments. */ + { + ffi_cif cif; + ffi_type *args[3]; + void *values[3]; + ffi_call_plan *plan; + double a = 10.0, b = 20.0, c = 30.0; + struct big3 rc, rp; + int before; + + args[0] = &ffi_type_double; + args[1] = &ffi_type_double; + args[2] = &ffi_type_double; + values[0] = &a; + values[1] = &b; + values[2] = &c; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &big3_t, args) == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(make_big3), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(make_big3), &rp, values); + CHECK_DOUBLE_EQ(rc.a, rp.a); + CHECK_DOUBLE_EQ(rc.b, rp.b); + CHECK_DOUBLE_EQ(rc.c, rp.c); + CHECK_DOUBLE_EQ(rp.a, a + 1.0); + CHECK_DOUBLE_EQ(rp.b, b + 2.0); + CHECK_DOUBLE_EQ(rp.c, c + 3.0); + + /* A NULL rvalue for an in-memory struct return must not crash: libffi + supplies scratch space and discards the result, but the callee still + runs. Confirm the call actually happened. */ + before = call_count; + ffi_call_plan_invoke(plan, FFI_FN(make_big3), NULL, values); + CHECK(call_count == before + 1); + + ffi_call_plan_free(plan); + } + + /* Large struct argument: no fast path, falls back to ffi_call. */ + { + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + ffi_call_plan *plan; + struct big3 s; + double rc, rp; + + s.a = 1.5; + s.b = 2.5; + s.c = 3.5; + args[0] = &big3_t; + values[0] = &s; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_double, args) + == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(sum_big3), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(sum_big3), &rp, values); + CHECK_DOUBLE_EQ(rc, rp); + CHECK_DOUBLE_EQ(rp, sum_big3(s)); + ffi_call_plan_free(plan); + } + + /* Register-pair struct return. */ + { + ffi_cif cif; + ffi_type *args[2]; + void *values[2]; + ffi_call_plan *plan; + long x = 7, y = 11; + struct pair2 rc, rp; + + args[0] = &ffi_type_slong; + args[1] = &ffi_type_slong; + values[0] = &x; + values[1] = &y; + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &pair2_t, args) == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(make_pair2), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(make_pair2), &rp, values); + CHECK(rc.x == rp.x); + CHECK(rc.y == rp.y); + CHECK(rp.x == x * 2); + CHECK(rp.y == y * 3); + ffi_call_plan_free(plan); + } + + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.call/plan_var.c b/deps/libffi/testsuite/libffi.call/plan_var.c new file mode 100644 index 00000000000000..e630156b23f077 --- /dev/null +++ b/deps/libffi/testsuite/libffi.call/plan_var.c @@ -0,0 +1,73 @@ +/* Area: ffi_call_plan + Purpose: Check that a reusable call plan reproduces ffi_call for a + variadic signature prepared with ffi_prep_cif_var. The + variadic double arguments travel in SSE registers, so the + fast path must set the vector-register count (al) correctly. + Limitations: none. + PR: none. + Originator: ffi_call_plan tests */ + +/* { dg-do run } */ +#include +#include "ffitest.h" + +static double vsum(int n, ...) +{ + va_list ap; + double s = 0.0; + int i; + + va_start(ap, n); + for (i = 0; i < n; i++) + s += va_arg(ap, double); + va_end(ap); + return s; +} + +static void +run (int nvar) +{ + ffi_cif cif; + ffi_type *args[1 + 8]; + void *values[1 + 8]; + double d[8]; + int n = nvar; + double rc, rp, expect; + ffi_call_plan *plan; + int i; + + CHECK(nvar <= 8); + + args[0] = &ffi_type_sint; + values[0] = &n; + expect = 0.0; + for (i = 0; i < nvar; i++) + { + d[i] = (double) (i + 1) * 1.5; + args[1 + i] = &ffi_type_double; + values[1 + i] = &d[i]; + expect += d[i]; + } + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 1 + nvar, + &ffi_type_double, args) == FFI_OK); + plan = ffi_call_plan_alloc(&cif); + CHECK(plan != NULL); + + ffi_call(&cif, FFI_FN(vsum), &rc, values); + ffi_call_plan_invoke(plan, FFI_FN(vsum), &rp, values); + CHECK_DOUBLE_EQ(rc, rp); + CHECK_DOUBLE_EQ(rp, expect); + + ffi_call_plan_free(plan); +} + +int main (void) +{ + run (0); + run (1); + run (3); + run (5); + run (8); + exit(0); +} diff --git a/deps/libffi/testsuite/libffi.closures/closure.exp b/deps/libffi/testsuite/libffi.closures/closure.exp index ed4145ca843b4a..9d53294909ee73 100644 --- a/deps/libffi/testsuite/libffi.closures/closure.exp +++ b/deps/libffi/testsuite/libffi.closures/closure.exp @@ -36,7 +36,7 @@ if { [string match $compiler_vendor "microsoft"] } { set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]] if { [libffi_feature_test "#if FFI_CLOSURES"] } { - run-many-tests $tlist "" + run-many-tests $tlist $additional_options } else { foreach test $tlist { unsupported "$test" diff --git a/deps/libffi/testsuite/libffi.closures/closure_loc_fn0.c b/deps/libffi/testsuite/libffi.closures/closure_loc_fn0.c index f344a6074e1429..179485d9b57b87 100644 --- a/deps/libffi/testsuite/libffi.closures/closure_loc_fn0.c +++ b/deps/libffi/testsuite/libffi.closures/closure_loc_fn0.c @@ -6,6 +6,7 @@ PR: none. Originator: 20030828 */ +/* { dg-do run } */ #include "ffitest.h" @@ -80,8 +81,10 @@ int main (void) CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0, (void *) 3 /* userdata */, codeloc) == FFI_OK); -#if !defined(FFI_EXEC_STATIC_TRAMP) && !defined(__EMSCRIPTEN__) - /* With static trampolines, the codeloc does not point to closure */ +#if !defined(FFI_EXEC_STATIC_TRAMP) && !defined(__EMSCRIPTEN__) \ + && !(defined(FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE) + /* With static trampolines or a trampoline table (Apple aarch64), the + codeloc does not point to the closure */ CHECK(memcmp(pcl, FFI_CL(codeloc), sizeof(*pcl)) == 0); #endif diff --git a/deps/libffi/testsuite/libffi.complex/complex_i128.c b/deps/libffi/testsuite/libffi.complex/complex_i128.c new file mode 100644 index 00000000000000..a599d556e12083 --- /dev/null +++ b/deps/libffi/testsuite/libffi.complex/complex_i128.c @@ -0,0 +1,118 @@ +/* Area: ffi_call + Purpose: Check complex int128 call and return. + Limitations: none. + PR: none. */ + +/* { dg-do run } */ +#include "ffitest.h" + +/* clang defines __SIZEOF_INT128__ but does not support _Complex __int128, + so exclude it here and fall through to the trivial main() below. */ +#if defined(FFI_TARGET_HAS_INT128) && \ + defined(FFI_TARGET_HAS_COMPLEX_TYPE) && \ + defined(__SIZEOF_INT128__) && \ + !defined(__clang__) + +typedef __int128_t i128; +typedef _Complex __int128 ci128; + +static const ci128 val = + (((i128)0x01020304050607ull << 64) | 0x08090a0b0c0d0e0full) + + (((i128)0x10203040506070ull << 64) | 0x8090a0b0c0d0e0f0ull) * 1i; +static const int dummy = 0xdeadbeef; + +#define D(X) int X __attribute__((unused)) + +static ci128 f0(ci128 x) +{ + return x; +} + +static ci128 f1(D(a), ci128 x) +{ + return x; +} + +static ci128 f2(D(a), D(b), ci128 x) +{ + return x; +} + +static ci128 f3(D(a), D(b), D(c), ci128 x) +{ + return x; +} + +static ci128 f4(D(a), D(b), D(c), D(d), ci128 x) +{ + return x; +} + +static ci128 f5(D(a), D(b), D(c), D(d), D(e), ci128 x) +{ + return x; +} + +static ci128 f6(D(a), D(b), D(c), D(d), D(e), D(f), ci128 x) +{ + return x; +} + +static ci128 f7(D(a), D(b), D(c), D(d), D(e), D(f), D(g), ci128 x) +{ + return x; +} + +static ci128 f8(D(a), D(b), D(c), D(d), D(e), D(f), D(g), D(h), ci128 x) +{ + return x; +} + +#define N 9 + +static void * const funcs[N] = { + f0, f1, f2, f3, f4, f5, f6, f7, f8 +}; + +static ffi_type ffi_type_ci128 = { + sizeof(ci128), + _Alignof(ci128), + FFI_TYPE_COMPLEX, + (ffi_type *[2]){ &ffi_type_sint128, NULL }, +}; + +int main (void) +{ + int i; + + for (i = 0; i < N; i++) + { + ffi_cif cif; + ffi_status s; + ffi_type *args[N]; + void *values[N]; + ci128 ret; + int j; + + for (j = 0; j < i; j++) + { + args[j] = &ffi_type_sint; + values[j] = (void *)&dummy; + } + args[i] = &ffi_type_ci128; + values[i] = (void *)&val; + + s = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, i + 1, + &ffi_type_ci128, args); + CHECK(s == FFI_OK); + + ffi_call(&cif, FFI_FN(funcs[i]), &ret, values); + CHECK(ret == val); + } + + return 0; +} + +#else +int main (void) { return 0; } +#endif diff --git a/deps/libffi/testsuite/libffi.go/go.exp b/deps/libffi/testsuite/libffi.go/go.exp index 100c5e75b40915..f477e99ade6911 100644 --- a/deps/libffi/testsuite/libffi.go/go.exp +++ b/deps/libffi/testsuite/libffi.go/go.exp @@ -19,10 +19,23 @@ libffi-init global srcdir subdir +if { [string match $compiler_vendor "microsoft"] } { + # -wd4005 macro redefinition + # -wd4244 implicit conversion to type of smaller size + # -wd4305 truncation to smaller type + # -wd4477 printf %lu of uintptr_t + # -wd4312 implicit conversion to type of greater size + # -wd4311 pointer truncation to unsigned long + # -EHsc C++ Exception Handling (no SEH exceptions) + set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc"; +} else { + set additional_options ""; +} + set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } { - run-many-tests $tlist "" + run-many-tests $tlist $additional_options } else { foreach test $tlist { unsupported "$test" From 9449399b6942c25a3b3676a4bd0634d970375f63 Mon Sep 17 00:00:00 2001 From: Renegade334 Date: Sun, 12 Jul 2026 07:41:21 +0200 Subject: [PATCH 2/2] fixup! deps: update libffi to 3.7.1 --- deps/libffi/libffi.gyp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/deps/libffi/libffi.gyp b/deps/libffi/libffi.gyp index 2d43dcdb733c97..f3122a4e2a0041 100644 --- a/deps/libffi/libffi.gyp +++ b/deps/libffi/libffi.gyp @@ -204,13 +204,6 @@ }, ], 'conditions': [ - ['OS == "win" and clang == 1', { - 'msvs_settings': { - 'VCCLCompilerTool': { - 'AdditionalOptions': ['-Wno-incompatible-pointer-types'], - }, - }, - }], ['OS == "win" and (target_arch == "x64" or target_arch == "x86_64")', { 'actions': [ {