commit de7afe7aa9e8ab7ac36429428a7222caae1e7988
Merge: 63cfe02c 8d6f5bf5
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 08:15:07 2026 -0500

    Merge pull request #1082 from libffi/release/3.8.1
    
    Release 3.8.1

commit 8d6f5bf587f642c53b62bde916d7ec60da925cf3
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 08:10:58 2026 -0500

    Release 3.8.1
    
    Bump the version from 3.8.0 to 3.8.1 and finalize the changelog:
    
      * configure.ac: AC_INIT 3.8.0 -> 3.8.1 (propagates to FFI_VERSION,
        libffi.pc, and the manual's @value{VERSION}).
      * libtool-version: 13:0:5 -> 13:1:5.  The source changed but no exported
        interface was added, removed, or changed since 3.8.0, so only revision
        is incremented.
      * doc/version.texi, README.md: set the version and the release date.
    
    Also fix three latent release-tooling bugs that "make distcheck" exposes
    (plain "make dist" hides them because it does not make the source tree
    read-only or verify a clean distclean):
    
      * Makefile.am dist-hook rewrote $(distdir)/README.md, which automake had
        already copied read-only, so the redirect failed with "Permission
        denied".  Remove it first.
      * configure.ac: the X86_64 unwind-section test linked conftest without
        -o, leaving an a.out that distcleancheck flagged.  Link to a conftest
        file and clean up.
      * Makefile.am: add the generated libffi.map (and libffi.map-sun) to
        DISTCLEANFILES so distclean removes them.
    
    make distcheck now passes end to end: builds from the tarball, runs the
    full testsuite, installs, uninstalls, and distcleans with nothing left.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 63cfe02cc95a0ad97a38586bb5aaf87fcc7e69b4
Merge: fd2cdac5 f3dd79a0
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 07:34:25 2026 -0500

    Merge pull request #1081 from libffi/testsuite/dist-missing-tests
    
    testsuite: add new tests to EXTRA_DIST so they ship in the release

commit f3dd79a0662142fca361835ebabea06727c634eb
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 07:22:22 2026 -0500

    testsuite: add the new tests to EXTRA_DIST so they ship in the release
    
    The dejagnu .exp drivers glob *.c at run time, so these tests ran in-tree,
    but testsuite/Makefile.am's EXTRA_DIST is a hand-maintained list and `make
    dist` ships only what it names.  The tests added this cycle were missing, so
    a `make check` from the release tarball would silently skip them -- dropping
    the regression coverage for several of the security fixes:
    
      libffi.call/closure_raw.c                 (GHSA-w6j9-w53f-2857)
      libffi.closures/closure_int128.c          (GHSA-wf8m-qr3x-cch4)
      libffi.closures/closure_mmap_failure.c    (#1055)
      libffi.closures/closure_trampoline_table.c (GHSA-23hx-9rxv-9qfp)
      libffi.vector/vector_unsupported_abi.c    (GHSA-5pc3-hr6f-q3mm)
    
    Also add libffi.configure/libdir.sh (the --libdir test run from CI) so it
    ships too.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit fd2cdac5e82b6c357775ff968ff58149f8f44245
Merge: 297a80c4 852244d3
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 07:19:30 2026 -0500

    Merge pull request #1080 from libffi/readme/tighten-tbd
    
    README: tighten the TBD changelog and fold in the security fixes

commit 852244d378e908d846439a7a02d2b33c8b00a965
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 07:18:18 2026 -0500

    README: tighten the TBD changelog and fold in the security fixes
    
    Group the pending changes by architecture and theme instead of a flat
    list plus a separate "Security fixes" block, so related entries (including
    the six advisories) sit together.  Drop the CWE codes and the long
    mechanism descriptions -- the referenced issues and advisories carry that
    detail -- while keeping every #issue and GHSA reference.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 297a80c4b02ef00010e985675c4c34dbc7bb2181
Merge: 21a49087 46203c53
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 07:12:43 2026 -0500

    Merge pull request #1079 from libffi/ci/green-emscripten-pytest
    
    ci(emscripten): get the browser test job green (pytest 9.x + closure_mmap_failure)

commit 46203c534e0a5d57729d838cc59d42103dd7cf62
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 06:21:33 2026 -0500

    testsuite: guard closure_mmap_failure for non-glibc harnesses
    
    The Emscripten browser harness (testsuite/emscripten/build-tests.sh) compiles
    every testcase and ignores the dg-do "target x86_64-*-linux-gnu*" directive.
    closure_mmap_failure interposes mmap via dlsym(RTLD_NEXT, "mmap"), which aborts
    on wasm:
    
      Aborted(Assertion failed: Tried to dlsym() from an unopened handle: -1)
    
    (188 passed, 1 failed in the browser run.)  Guard the body on __GLIBC__ so it
    is a no-op wherever the RTLD_NEXT mmap-interposition technique isn't available;
    ffitest.h pulls in <stdlib.h>, so __GLIBC__ is defined on the x86_64-linux-gnu
    dejagnu runs that actually exercise this test, leaving them unchanged.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 4abb340542b4a7f6af328bf5e8c16d2bd631b30e
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 06:08:19 2026 -0500

    ci(emscripten): bump pytest-pyodide 0.59.2 -> 0.59.4 for pytest 9.x
    
    The browser `test` job crashed during pytest collection:
    
      INTERNALERROR> AttributeError: 'FixtureManager' object has no
      attribute '_arg2fixturedefs'
    
    pytest-pyodide 0.59.2's set_runtime_fixture_params() reads the private
    pytest internal `_fixturemanager._arg2fixturedefs`, which pytest removed.
    The workflow installs an unpinned pytest (currently 9.2.0), so collection
    aborted before any test ran.  (It was masked until now because the build
    job failed first; fixing closure_raw.c let the test job finally run.)
    
    0.59.4 handles this with a version shim (uses getfixturedefs() on
    pytest >= 9.2), so just bump the pin.  Pinning pytest down instead is a
    dead end: pytest-asyncio 1.5.0 (a pytest-pyodide dep) requires pytest>=8.4,
    which already lacks _arg2fixturedefs.
    
    Verified locally that collection of testsuite/emscripten/test_libffi.py
    succeeds with pytest 9.2.0 + pytest-pyodide 0.59.4 (the crash is gone);
    the browser run itself is validated by CI.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 21a490876ea8046f544fbbf93a594ccf63685e9a
Merge: 997aee20 6aff44d2
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 05:41:38 2026 -0500

    Merge pull request #1078 from libffi/ci/green-emscripten-raw
    
    testsuite: guard closure_raw on !FFI_NO_RAW_API (fix Emscripten CI)

commit 6aff44d25cc7ba8ed4d3a1f64a7e931544545a41
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 05:18:38 2026 -0500

    testsuite: guard closure_raw on !FFI_NO_RAW_API (fix Emscripten CI)
    
    The Emscripten build configures libffi with --disable-raw-api, which sets
    FFI_NO_RAW_API and compiles raw_api.c (and the native raw entries) to
    nothing -- so ffi_prep_raw_closure_loc is absent from the wasm library.
    closure_raw.c referenced it unconditionally under only #if FFI_CLOSURES, so
    every wasm target failed to link:
    
      wasm-ld: error: undefined symbol: ffi_prep_raw_closure_loc
    
    Match raw_api.c's own guard: compile the raw-closure test only when
    FFI_CLOSURES && !FFI_NO_RAW_API, falling back to the no-op main otherwise.
    ffitest.h already includes fficonfig.h, so FFI_NO_RAW_API is visible to the
    test.  No change on targets where the raw API is enabled.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 997aee20b30d93c4526473d66fec6a37168f550a
Merge: 4098fd38 7632e27b
Author: Anthony Green <green@moxielogic.com>
Date:   Sat Nov 14 00:41:50 2026 -0500

    Merge pull request #1077 from libffi/ci/green-android-macos
    
    ci: xfail x86_64 Android ld-struct return; drop dead macos-14 runner

commit 7632e27b5894c78b0511a4aef8ef0cf0c325880c
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 22:06:45 2026 -0500

    ci: xfail x86_64 Android ld-struct return; drop dead macos-14 runner
    
    Two independent CI-green fixes:
    
    testsuite: cls_struct_ld_return.c fails only on x86_64-pc-linux-android
    (NDK clang, static, run natively), while x86_64-pc-linux-gnu passes the
    identical test.  The generic x86-64 struct-return path is therefore sound;
    the Android-specific divergence (possibly a binary128 vs 80-bit long double
    difference feeding classify_argument) is unconfirmed and can't be reproduced
    without the NDK.  xfail it on x86_64-*-linux-android* and track the real fix
    in libffi #1076 rather than guess at ffi64.c and risk the cases that pass.
    
    build.yml: the macos-14 runners (both compiler jobs and the Rosetta job that
    pins macos-14) have been lost on every recent run -- scheduled, then killed
    ~2 min in with no steps, conclusion "cancelled" -- while macos-15 runs fine.
    Drop macos-14 from the matrix and move the Rosetta x86_64 job to macos-15,
    which is also Apple Silicon and supports Rosetta 2, so x86_64 macOS coverage
    is preserved.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 4098fd38a167f492e0f9c774298f6754c8ec20d1
Merge: 89a976d5 24c817af
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 19:38:54 2026 -0500

    Merge pull request #1075 from libffi/ci/green-android-win32
    
    CI: make dist PDF best-effort (Android) and xfail closure_raw on i686 MSVC

commit 24c817af9aac5e1fb286ce7219d2e08ffd38c113
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 19:38:36 2026 -0500

    testsuite: xfail closure_raw on i686 MSVC (libffi #1074)
    
    The raw-API closure test passes everywhere except 32-bit MSVC
    (i686-pc-cygwin), where it compiles but fails at execution in the i386
    native raw-closure path.  It passes on Windows 64-bit gcc/clang and all
    Linux/macOS targets, and the GHSA-w6j9 change there is static-trampoline
    gated (off on Windows), so this is a pre-existing gap the new test
    exposed.  xfail it on i686-pc-cygwin, tracked by issue #1074.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 9967918609a581dad639b388e03b6d5679e7340b
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 19:38:36 2026 -0500

    build: make the dist-hook PDF manual truly best-effort
    
    The previous guard checked for texi2pdf, but texi2pdf ships with texinfo
    even when no TeX engine is installed (e.g. the Android CI container), so
    'make pdf' still ran texi2dvi --pdf and failed 'make dist'.  Attempt the
    PDF build and copy, and if any part fails, skip it with a message; the
    .info manual is still shipped and release builds (with texlive) still get
    the PDF.  Verified: 'make dist' with the TeX engine forced to fail still
    succeeds.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 89a976d5b37fb16fc7881d5a0b9d4138418bd221
Merge: 48d7a47e d9208dee
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 19:06:30 2026 -0500

    Merge pull request #1073 from libffi/ci/fix-ci-regressions
    
    CI: fix regressions from new tests + complete the dist-hook docs guard

commit d9208dee3bd27888e23512327820c1e869413cb4
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 18:19:50 2026 -0500

    testsuite: xfail more mips N64 complex/fp-return tests (libffi #1071)
    
    The full matrix surfaced two more failures in the same mips N64 ABI
    cluster: complex_regs_double fails on little-endian (it passes on
    big-endian hardware), and cls_struct_ld_return (long-double struct return)
    fails at -O2.  xfail both on mips64*-*-* alongside the others, tracked by
    issue #1071.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit ecb977826207ce0ebf99272c2be2d34da8216dfd
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 18:19:50 2026 -0500

    build: only build the PDF manual in dist-hook when texi2pdf is present
    
    The dist-hook BUILD_DOCS guard still ran 'make pdf' whenever makeinfo was
    available, so environments with texinfo but no TeX (e.g. the Android CI
    container) failed 'make dist' at the PDF step.  Build and copy the PDF
    only when texi2pdf exists; the .info manual is still shipped, and release
    builds (which install texlive) still get the PDF.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit b81760d079fb5ba84c70965eaf6b82de2d8a4fe4
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 18:19:50 2026 -0500

    testsuite: fix closure_raw user_data cast for LLP64 (Windows)
    
    closure_raw.c read its void* user_data back as (long), which truncates a
    64-bit pointer on LLP64 (Windows x64), tripping -Wall as an excess error
    and failing the test's compile on the mingw/MSVC CI jobs.  Use intptr_t.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 48d7a47ef94a9b229f7591b6aadd31542556b3f5
Merge: 693dcbac e431830b
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 16:15:36 2026 -0500

    Merge pull request #1072 from libffi/readme-changelog-consolidate
    
    README: complete and consolidate the TBD changelog

commit 693dcbac9f1eb63c68e13fbdec767201b8ec1ff5
Merge: af169894 1436c4a9
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 16:15:31 2026 -0500

    Merge pull request #1070 from libffi/ci/dist-docs-and-test-portability
    
    CI: fix make dist doc build and closure_mmap_failure on Android

commit e431830b996633d67f41dd43db448fa5f364e789
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 16:14:00 2026 -0500

    README: complete and consolidate the TBD changelog for the release
    
    Add user-facing changes that had landed since 3.8.0 but were missing from
    the notes: the x86-64 single-long-double struct return (#1058), the x86-64
    16-byte vector call-plan upper-half fix, the RISC-V void-call return-buffer
    fix, the wasm >=2 GiB heap and stack-switching-closure fixes (#1062), the
    bounded executable-mmap retry (#1055), keeping bundled dlmalloc symbols
    static, the mips N32/N64 CFI unwinding (#1063), and the build/packaging
    fixes (--enable-docs, --libdir, CCASFLAGS; #1060).
    
    Consolidate the six security fixes under one Security fixes heading with a
    concise entry each (keeping the GHSA/CWE ids), fold GHSA-vg77 into the
    aarch64 entry it duplicates, and merge the NetBSD closure-allocation
    fallback into the page-size-lookup entry.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 1436c4a967441a4fb10be43d98d0fb9dfce60743
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 16:09:31 2026 -0500

    testsuite: xfail mips N64 complex/fp-return tests (libffi #1071)
    
    complex_regs_float, complex_regs_longdouble and cls_struct_fp_return fail
    on mips64 N64 due to real, pre-existing ABI bugs in libffi's N64
    complex-float/longdouble argument passing and fp-struct returns (confirmed
    on real mips64 hardware, not a QEMU artifact).  Mark them xfail on
    mips64*-*-* with a pointer to the tracking issue so CI reflects the known
    limitation while the ABI fix is developed; they are not whitelisted in
    rlgl-policy, since the sim is not at fault.
    
    See https://github.com/libffi/libffi/issues/1071.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit a5cf1f76582fc8d669c6e8ed5415571068099017
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 15:12:26 2026 -0500

    testsuite: restrict closure_mmap_failure to glibc Linux
    
    The test interposes mmap with a defined symbol plus dlsym(RTLD_NEXT,
    "mmap") and -Wl,--export-dynamic, which is a glibc technique.  Its
    target guard was x86_64-*-linux*, which also matches x86_64-linux-android,
    so the Android x86_64 CI job tried to build it and failed to compile
    ("test for excess errors").  Tighten the guard to x86_64-*-linux-gnu* so
    it runs on glibc Linux (where it is designed to work and still passes) and
    is skipped on Android and musl.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 591109062b61d5f8b8bc45253d288ab3445e4280
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 15:09:49 2026 -0500

    build: only build docs in dist-hook when docs are enabled
    
    The dist-hook unconditionally ran "cd doc; make pdf", so "make dist"
    tried to build the PDF (and the .info it depends on) even when configured
    --disable-docs or when makeinfo/TeX is absent.  That failed the dist step
    on runners without texinfo/texlive (e.g. the macOS and Android CI jobs:
    libffi.info Error 127, libffi.pdf Error 1).
    
    Guard the doc-building line of dist-hook with the BUILD_DOCS automake
    conditional, leaving the ChangeLog and README generation unconditional.
    Verified: with --disable-docs the generated rule comments out the pdf
    build and "make dist" completes (produces the tarball); with
    --enable-docs the pdf build still runs.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit af169894df2091141cbf3c2c562f1802decd2b14
Merge: c19aeb48 2cb14fc0
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:45:49 2026 -0500

    Merge pull request #1060 from 7thplanetyt/codex/fix-890-ccasflags
    
    configure: keep assembler defaults in sync with final CFLAGS

commit c19aeb480f8fe4c7f0bf1bfcf9d2d6b7bee4e4b9
Merge: 113cdf63 1c7d90af
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:45:44 2026 -0500

    Merge pull request #1063 from vhankala/mips-n32-cfi
    
    mips: Use CFI directives in N32/N64 assembly

commit 113cdf6313bce9a1cdb8ed7e8c96e6c60cc169a2
Merge: f64ed0fa 6a1bdb5d
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:45:40 2026 -0500

    Merge pull request #1062 from agriyakhetarpal/wasm-unsigned-heap-index
    
    Fix WASM heap view indexing at 2 GiB and above

commit f64ed0faee0fe947c8e47012ec088d3617da072a
Merge: 5b8dbbd8 a80fe939
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:45:35 2026 -0500

    Merge pull request #1058 from shalseth/x86-64-struct-ld-return
    
    x86-64: return a struct with one long double member in %st0

commit 5b8dbbd85f5cdaf296ceb1226c9533f51a5e0a22
Merge: 8da7a153 12e1b740
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:30:20 2026 -0500

    Merge pull request #1069 from libffi/fix/ghsa-w6j9-raw-closure
    
    Fix raw-API closures under static trampolines (GHSA-w6j9-w53f-2857)

commit 12e1b740ebe7861a9d0a7dc23003e3498645e8f2
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:28:11 2026 -0500

    x86: support static trampolines in the i386 native raw closure path
    
    ffi_prep_raw_closure_loc for the i386 native raw API wrote a dynamic
    trampoline straight into closure->tramp with no ffi_tramp_is_present()
    guard, unlike ffi_prep_closure_loc.  With FFI_EXEC_STATIC_TRAMP (the
    default) that write lands on the ftramp pointer ffi_closure_alloc stored
    at offset 0, so ffi_closure_free later calls ffi_tramp_free() on a
    corrupted pointer; and the static trampoline returned in *code was never
    given its parameters, so invoking the closure jumped through an unset
    (NULL or stale) slot.  The documented ffi_closure_alloc +
    ffi_prep_raw_closure_loc pattern therefore crashed (GHSA-w6j9-w53f-2857
    part B).
    
    Mirror ffi_prep_closure_loc: when a static trampoline is present, set its
    parameters (via the closure's ftramp, read through ffi_closure as
    ffi_closure_alloc does) and point it at new _alt entry points instead of
    writing the dynamic trampoline.  Add ffi_closure_raw_SYSV_alt and
    ffi_closure_raw_THISCALL_alt, which load the closure pointer the static
    trampoline passes into %eax and fall through to the normal bodies, just
    like ffi_closure_i386_alt.  No struct layout changes.
    
    Verified on real i386 (GCC compile farm, cfarm26, native i686): the
    raw-closure test crashed before and passes after, and the call and
    closure suites pass (1472).  This completes GHSA-w6j9-w53f-2857 together
    with the generic-path fix; the closure_raw.c test now exercises both the
    generic (x86-64) and native (i386) raw closure paths.
    
    Advisory: GHSA-w6j9-w53f-2857
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 8f13de89965408bd1186c873ec87ad8f0a9170af
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:11:13 2026 -0500

    raw API: pass the closure, not codeloc, as the translate-args user_data
    
    ffi_prep_raw_closure_loc and ffi_prep_java_raw_closure_loc installed their
    generic trampoline handler (ffi_translate_args / ffi_java_translate_args)
    with codeloc as both the user_data and the code location. The handler then
    cast that user_data back to the ffi_raw_closure and read cl->fun and
    cl->user_data from it.
    
    That worked only because, before static trampolines, codeloc aliased the
    closure's own data. With FFI_EXEC_STATIC_TRAMP (the default on Linux)
    codeloc points into the read-only trampoline code table instead, so the
    handler read cl->fun from unrelated memory and made a wild indirect call.
    The documented ffi_closure_alloc + ffi_prep_raw_closure_loc pattern
    therefore crashed.
    
    Pass the closure itself as the user_data so the handler always reads the
    real cl->fun/cl->user_data, regardless of where the code lives.
    
    Add testsuite/libffi.call/closure_raw.c, the first test to exercise
    ffi_prep_raw_closure_loc; verified on x86-64 (static trampolines on) that
    the documented pattern crashed before and returns the correct value after.
    
    This is part A of GHSA-w6j9-w53f-2857. Part B (the i386 native raw API not
    checking ffi_tramp_is_present) is handled separately where it can be run on
    a 32-bit target.
    
    Reported-by: karimabisaad (https://github.com/karimabisaad)
    Advisory: GHSA-w6j9-w53f-2857
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 8da7a153ff8e5a10b9c1e57b186fd31ae8c01c51
Merge: 748934db d544f904
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:07:10 2026 -0500

    Merge pull request #1068 from libffi/fix/ghsa-wf8m-s390x-int128
    
    s390x: pass 128-bit integer arguments to closures by reference (GHSA-wf8m-qr3x-cch4)

commit d544f90452eac771560e6c1032acd25f586e216a
Merge: cdc4a549 748934db
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:07:03 2026 -0500

    Merge remote-tracking branch 'origin/master' into wf8m-merge
    
    # Conflicts:
    #       README.md

commit 748934dbfa1c99da2f1d1839c97cf22f05ebafab
Merge: 39fd231e 6383099a
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:06:38 2026 -0500

    Merge pull request #1067 from libffi/fix/ghsa-h52h-aarch64-abi
    
    aarch64: fix large-struct pointer offset and HFA/HVA detection (GHSA-h52h-3759-xqm4)

commit 6383099aae8ed4cfc314430a22315e261acafd5c
Merge: fa9a7093 39fd231e
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:06:32 2026 -0500

    Merge remote-tracking branch 'origin/master' into h52h-merge
    
    # Conflicts:
    #       README.md

commit 39fd231e4b54d1519143da4eadbf33ff786ddaa9
Merge: 70a894ae ee3d6126
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 14:04:39 2026 -0500

    Merge pull request #1066 from libffi/fix/ghsa-fq46-69xf-x5gf-tramp-path
    
    Harden static-trampoline code-table lookup against path attacks (GHSA-fq46-69xf-x5gf)

commit cdc4a549fe7305cb6956f17b7f57db3dc7c8e2f5
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 13:56:36 2026 -0500

    s390x: pass 128-bit integer arguments to closures by reference
    
    The s390x call path passes __int128 (and complex and long double) by
    reference: one GPR slot holds a pointer to the value.  The closure helper
    ffi_closure_helper_SYSV handled complex and long double this way but had
    no SINT128/UINT128 case, so those fell into the switch default
    (FFI_ASSERT(0), a no-op in release builds).  The avalue[] entry for the
    argument was left uninitialised, so the handler received a stale stack
    pointer and dereferenced it (a 16-byte out-of-bounds read); and because
    no GPR slot was consumed, every following argument was decoded from a
    shifted slot.
    
    Group SINT128/UINT128 with COMPLEX in the by-reference handling, so one
    GPR slot is consumed and the pointer is dereferenced into avalue[],
    mirroring the call side.
    
    Add a closures regression test (closure_int128.c) that passes a 128-bit
    integer, and an argument after it, through a closure.  Verified on s390x
    (GCC compile farm): before the fix the handler returned a garbage value,
    after it returns the correct one, and the call/closure/complex suites
    pass (1088).
    
    Reported-by: zerovulnlabs (https://github.com/zerovulnlabs)
    Advisory: GHSA-wf8m-qr3x-cch4
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit fa9a709309d8961b43dea0bdb3bb144ff9428ca5
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 13:39:00 2026 -0500

    aarch64: fix homogeneous-aggregate detection (HFA/HVA)
    
    is_vfp_type decided whether an aggregate is a homogeneous floating-point
    or vector aggregate using helpers that were too strict in one way and
    not recursive enough in another:
    
      * It required every vector lane in an HVA to have the same scalar type.
        AAPCS64 (and GCC and Clang) treat two short vectors as the same
        fundamental type when they are the same size; the lane type does not
        matter.  So { float32x4_t, int32x4_t } was rejected and sent down the
        >16-byte memory path, while a native callee passed/returned it in
        q0/q1.  As a closure return that meant the handler wrote through a
        stale x8; as an argument it shifted every later argument by a
        register.
    
      * The vector-width and lane checks ran only on the outermost members
        and is_simd() looked only at the first nested aggregate, so a nested
        aggregate that mixes a vector with scalars (e.g.
        struct { struct { float32x4_t v; float a,b,c,d; }; }) was wrongly
        accepted as a two-register HVA and passed in v0/v1, where both
        compilers pass it by reference in x0.
    
    Replace is_hfa0/is_simd/is_hfa1 with a single recursive hfa_flatten()
    that flattens the aggregate and requires every leaf to share one
    fundamental type -- a floating-point scalar, or a short vector matched by
    size (lane type ignored) -- with 1 to 4 leaves.  The AARCH64_RET_*
    encoding is unchanged.
    
    Verified on aarch64 (cfarm185) against native GCC callees: the two
    mismatching cases now agree with the native ABI, and the full testsuite
    passes (1788).
    
    Reported-by: karimabisaad (https://github.com/karimabisaad)
    Advisory: GHSA-h52h-3759-xqm4
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit da4db395c00c77e3615f44554fb44bb986dbc592
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 13:25:15 2026 -0500

    aarch64: place spilled large-struct pointer at an 8-byte-aligned slot
    
    When ffi_call passes a non-HFA composite larger than 16 bytes by value,
    AAPCS64 B.4 replaces it with a pointer that occupies a plain 8-byte,
    8-aligned stack slot.  ffi_call_int copied the payload and jumped to
    do_pointer with the pointer in hand, but left `ty' pointing at the
    composite, so allocate_to_stack used the composite's alignment (16, or 4
    on Darwin) for the pointer slot instead of 8.
    
    With the x registers exhausted and NSAA not 16-aligned (for example nine
    sint64 arguments followed by a 32-byte, 16-aligned struct), the pointer
    was written 8 bytes higher than where the callee reads it.  libffi's own
    closure path uses sizeof(void*) for the same slot, so ffi_call and
    closures disagreed even without any compiler involved; the callee
    dereferenced uninitialised stack as the struct address.
    
    Re-point `ty' at ffi_type_pointer before the jump so the slot is aligned
    by 8.  Confirmed on aarch64 (cfarm185): a native GCC callee taking nine
    int64s and a 32-byte struct crashed before and returns the correct value
    after; the call and closure suites pass (954).
    
    Reported-by: karimabisaad (https://github.com/karimabisaad)
    Advisory: GHSA-h52h-3759-xqm4
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit ee3d61264a180953293914aedb37c520f1253a1f
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 13:11:24 2026 -0500

    Harden static-trampoline code-table lookup against path attacks
    
    On Linux, ffi_tramp_get_libffi() located the file backing the static
    trampoline code table by parsing /proc/self/maps, then reopened the path
    it read and mapped it PROT_READ | PROT_EXEC.  Two problems let that file
    be attacker-controlled:
    
      1. The path was read with sscanf("%s"), which stops at the first
         whitespace.  /proc/self/maps does not escape spaces in the name
         field, so a libffi or executable path containing a space was
         truncated and libffi opened the truncated path.
      2. The parsed device and inode were never used, so nothing checked
         that the reopened file was the one the mapping was backed by.  The
         path could be replaced or symlinked between the read and the open.
    
    Either way the bytes of an attacker-supplied file could become the
    executable trampoline code table, and every closure allocated from it
    would run attacker code (GHSA-fq46-69xf-x5gf, CWE-59/CWE-367/CWE-706).
    
    Read the whole path (the rest of the maps line, which keeps embedded
    spaces) rather than a whitespace-delimited token, and after opening it
    fstat the descriptor and require its inode to match the mapping's inode,
    falling back to the temp-file trampoline otherwise.  Only the inode is
    compared: the /proc/self/maps device field does not equal stat(2)'s
    st_dev on btrfs, overlayfs and some other filesystems, so comparing
    st_dev would reject the real file there (and /proc/self/map_files, which
    would avoid the path entirely, is capability-gated and returns EPERM for
    a process's own mappings on common kernels).
    
    Verified on x86-64: a closure built under a path containing a space now
    opens the full path and runs correctly while ignoring a file planted at
    the truncated path; the libffi.closures suite still passes (610).
    
    Reported-by: zerovulnlabs (https://github.com/zerovulnlabs)
    Advisory: GHSA-fq46-69xf-x5gf
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 70a894ae395756653d08f65e411220fd3ee61efc
Merge: dc84815c 7b13cee9
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 12:33:12 2026 -0500

    Merge pull request #1065 from libffi/fix/ghsa-23hx-9rxv-9qfp-trampoline-uaf
    
    Fix heap use-after-free in Darwin trampoline-table closure allocator (GHSA-23hx-9rxv-9qfp)

commit 7b13cee9c321d58d1f2226c49190c04eec4c7aac
Merge: 13888a72 dc84815c
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 12:33:00 2026 -0500

    Merge remote-tracking branch 'origin/master' into fix/ghsa-23hx-9rxv-9qfp-trampoline-uaf
    
    # Conflicts:
    #       README.md

commit dc84815c9177de730d27d7ed87486cc42566859d
Merge: d02afc25 d06f515a
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 12:32:27 2026 -0500

    Merge pull request #1064 from libffi/fix/ghsa-5pc3-hr6f-q3mm-vector-abi
    
    Reject x86-64 vector types with an undefined calling convention (GHSA-5pc3-hr6f-q3mm)

commit d06f515abea2964969d720ac7ded3eb475bc4476
Author: Anthony Green <green@moxielogic.com>
Date:   Fri Nov 13 12:15:49 2026 -0500

    Reject x86-64 vector types with an undefined calling convention
    
    On x86-64 System V the psABI only defines how 8- and 16-byte vectors
    (the __m64/__m128 shapes) are passed and returned.  Narrower vectors and
    the single-element <1 x double> are unspecified, and GCC and Clang
    disagree on them: for <1 x double> GCC uses memory/sret while Clang uses
    %xmm0, and for <1 x float> GCC uses memory while Clang returns it in an
    integer register.
    
    ffi_prep_cif_machdep classified every 8-byte vector as SSE, so for
    <1 x double> f(long x) against a GCC-built target libffi passed no sret
    pointer and left x in %rdi; the callee then stored its result through
    %rdi -- i.e. through the caller's integer argument, an attacker-
    influenced out-of-bounds write (CWE-843 type confusion -> CWE-787).
    
    libffi cannot tell which compiler built the target, and the two
    conventions genuinely diverge, so there is no classification that is
    correct for both.  Reject the undefined shapes instead: a type that is,
    or recursively contains, a vector is now FFI_BAD_TYPEDEF unless the
    vector is 16 bytes, or 8 bytes and not <1 x double> -- the shapes both
    compilers agree on and this port implements.  Multi-lane 8- and 16-byte
    vectors keep working.
    
    Add a vector regression test asserting FFI_BAD_TYPEDEF for the undefined
    shapes (including a struct that contains one) and FFI_OK for the agreed
    ones, and note the change in the README history.
    
    Reported-by: karimabisaad (https://github.com/karimabisaad)
    Advisory: GHSA-5pc3-hr6f-q3mm
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 13888a72978e222cfedcaa376c0bdd5ad88365c4
Author: Anthony Green <green@moxielogic.com>
Date:   Thu Nov 12 08:46:02 2026 -0500

    Fix heap use-after-free in Darwin trampoline-table closure allocator
    
    ffi_closure_free() bumped a non-head trampoline table to the front of
    ffi_trampoline_tables without first unlinking it from its old position.
    The old neighbours kept pointing at the moved table, turning the
    doubly-linked list into a cycle with stale prev/next links.  A later
    ffi_trampoline_table_free() then unlinked through those stale links,
    writing a pointer into freed heap memory (CWE-416), and called
    vm_deallocate() from inside a corrupted list.
    
    This affects only the FFI_EXEC_TRAMPOLINE_TABLE + __MACH__ allocator
    (aarch64-apple-* and *arm*-apple-*, where it is the default) once a
    process spans more than one trampoline table, i.e. more than 1024 live
    closures.  The trigger is an ordinary sequence of ffi_closure_alloc and
    ffi_closure_free calls, so script-driven FFI runtimes that create
    callbacks dynamically can reach it.
    
    Fix it by unlinking the table from its current position before pushing
    it to the head of the list.  Add a closures regression test that churns
    many live closures across several trampoline tables, and note the fix
    in the README history.
    
    Reported-by: karimabisaad (https://github.com/karimabisaad)
    Advisory: GHSA-23hx-9rxv-9qfp
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

commit 6a1bdb5d0ad16dc66169b23cf94ef1c4458650f5
Author: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com>
Date:   Thu Nov 12 14:31:08 2026 +0530

    Fix WASM heap view indexing at 2 GiB and above

commit 1c7d90afa7524085764ab5177f1f5cff0befdbb8
Author: Visa Hankala <visa@hankala.org>
Date:   Tue Nov 10 15:23:41 2026 +0000

    mips: Use CFI directives in N32/N64 assembly
    
    Use CFI directives in N32/N64 assembly when the assembler
    supports them.
    
    This fixes build on OpenBSD/mips64 with LLVM LLD. The manually
    constructed .eh_frame generates R_MIPS_64 relocations against local
    symbols that LLD does not handle. With CFI directives the assembler
    produces PC-relative relocations that LLD accepts.

commit 2cb14fc08a7c74ec4114ef5d0086c0862f495d47
Author: 7thplanetyt <221369153+7thplanetyt@users.noreply.github.com>
Date:   Fri Nov 6 21:33:18 2026 -0600

    configure: keep assembler defaults in sync with final CFLAGS
    
    Supply a make-time CFLAGS default before AM_PROG_AS when CCASFLAGS is unset.
    Preserve explicit environment and configure-argument values, including empty
    ones. Add six configure regression cases and one native Linux CI step.
    
    Implements Peter Bergner's late-bound default suggestion from issue #890.
    Prepared and independently reviewed with Codex AI assistance.

commit a80fe93964cc67bdcf1cd7b82ce6205d44fb6311
Author: Stian Halseth <stian@itx.no>
Date:   Fri Nov 6 12:14:36 2026 +0100

    x86-64: return a struct with one long double member in %st0
    
    The psABI classifies a struct whose only member is an x87 long double
    as X87/X87UP, and returns it in %st0 like a plain long double.
    ffi_prep_cif_machdep() sent it down the RAX/RDX struct path instead.
    ffi_call() then stores garbage, and leaves the callee's value on the
    x87 register stack, so after a few calls later long double arithmetic
    in the caller gives NaN. A closure returning such a struct leaves %st0
    empty, and its caller reads NaN.
    
    Add cls_struct_ld_return to check the return through ffi_call and a
    closure.
    
    Signed-off-by: Stian Halseth <stian@itx.no>

commit d02afc25e8ea3aac9e78e227748e1fd7c9f14c82
Merge: 5f667d18 e71a504b
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 14:49:52 2026 -0400

    Merge pull request #1055 from libffi/fix/issue-1032-bounded-dlmmap
    
    Fix unbounded executable mmap retries

commit e71a504b6448b32e0afeff75126a6f26407f3811
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 12:52:02 2026 -0400

    Fix unbounded executable mmap retries

commit 5f667d1863b3b4473972b8c75dfcf8abc1c200a6
Merge: eb894dff a5ddf9f8
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 10:27:06 2026 -0400

    Merge pull request #1054 from libffi/codex/pr-1028-rebased
    
    configure: honor explicit --enable-docs

commit a5ddf9f8e3583eb60a54bebae42b3b758e130ab9
Author: fhgffy <102001626+fhgffy@users.noreply.github.com>
Date:   Tue Oct 6 07:12:33 2026 +0800

    configure: honor explicit --enable-docs
    
    Preserve Autoconf's parsed docs value instead of unconditionally disabling
    documentation whenever either option polarity is supplied. Add a five-case
    configuration regression and run it in the native Linux CI job.

commit eb894dff6927f92cd47011c9a18326745ec86b94
Merge: 595c3930 fc0cd5d2
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 09:55:18 2026 -0400

    Merge pull request #1031 from dannf/dlmalloc-static-decls
    
    closures: keep the dlmalloc 2.8.6 additions static

commit 595c3930a3d6f72d4d5ae2ed85390dab17e7f1d1
Merge: a8c5a70e 1ae71737
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 09:49:28 2026 -0400

    Merge pull request #1027 from NotAFlightRisk/plan-vector-upper-half
    
    x86-64: copy the upper half of 16-byte vector arguments in call plans

commit a8c5a70e18288a36a9119b74f59456fcf86c6bca
Merge: daec8db4 5fdd801e
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 08:59:44 2026 -0400

    Merge pull request #1026 from HNO3Miracle/fix/riscv-void-return
    
    riscv: ignore return buffer for void calls

commit daec8db406d7dec17b72008f7450a88d8109afe5
Merge: c38051bf e1aac2a7
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 07:54:08 2026 -0400

    Merge pull request #1045 from mohd-akram/fix-x64-cfi
    
    x86-64: fix build with missing CFI

commit c38051bf796c1ad7948db75dd2a55f3a78b78a8c
Merge: a6d36760 d8127bda
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 07:41:37 2026 -0400

    Merge pull request #1044 from libffi/fix-pr1022-complete
    
    configure: respect every explicit libdir spelling

commit a6d367602ad2552ac58f4a840932ebbd8c76f151
Merge: 61a20c6c 0762e0da
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 07:17:07 2026 -0400

    Merge pull request #1053 from libffi/fix-mips64-complex-abi
    
    mips: bound small complex return stores

commit 0762e0daeea915d1890c93c2dde69efc85ee2c2f
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 07:14:59 2026 -0400

    mips: bound small complex return stores
    
    The N32/N64 assembly writes complex GPR returns in 8-byte chunks. Bounce values smaller than 16 bytes through an aligned temporary buffer so callers' result objects are not overrun, and account for big-endian right justification. Do the matching right justification for closure returns smaller than one register.\n\nReported-by: Daniel Golle <daniel@makrotopia.org>

commit 61a20c6c9ad62a3650921b811e82ac87e3652340
Merge: 871815cb 8a1db735
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 06:43:31 2026 -0400

    Merge pull request #1052 from libffi/fix-mips-o32-complex-reg-exhaustion
    
    mips: fix O32 complex call and closure returns

commit 8a1db7350d1037671747fbf135204c8976fb60fd
Author: Anthony Green <green@moxielogic.com>
Date:   Wed Oct 28 06:23:32 2026 -0400

    mips: fix O32 complex call and closure returns
    
    Handle all integer-complex sizes in the O32 call path and return soft-float complex values through the ABI-defined GPR set. Restore hard-float closure results from the FP save area, preserve the argument flags, and pass the complex result size back to assembly explicitly.
    
    Reported-by: Daniel Golle <daniel@makrotopia.org>

commit 871815cbc2553e6871a1d51b2e8abebf2f75cd9a
Merge: 83944b00 94eb0e5b
Author: Anthony Green <green@moxielogic.com>
Date:   Tue Oct 27 21:45:43 2026 -0400

    Merge pull request #1051 from libffi/fix-qemu-binfmt-comment
    
    ci: name the QEMU binfmt package correctly

commit 94eb0e5b8cf5d7671e31391fb32cd227e67cab97
Author: Anthony Green <green@moxielogic.com>
Date:   Tue Oct 27 21:42:01 2026 -0400

    ci: name the QEMU binfmt package correctly

commit 83944b006a6bda260bbe24e4013851168aba5b2b
Merge: fc345b31 3365ad8b
Author: Anthony Green <green@moxielogic.com>
Date:   Tue Oct 27 21:20:00 2026 -0400

    Merge pull request #1050 from libffi/fix-aarch64-darwin-stack-slots
    
    aarch64: fix small composite stack slots on Darwin

commit 3365ad8b968a9b742922b6f1188462fe6ce142ec
Author: Anthony Green <green@moxielogic.com>
Date:   Tue Oct 27 20:44:21 2026 -0400

    aarch64: match Darwin stack slots to compiler ABI

commit 8c8b07941c73f23eb2c87023d9b9add2ec174708
Author: Daniel Golle <daniel@makrotopia.org>
