From 5ceddf4071e8bce3bdb20f8795d57d5ef0bc5503 Mon Sep 17 00:00:00 2001 From: Bill Roberts <152999275+billatarm@users.noreply.github.com> Date: Thu, 20 Feb 2025 04:25:21 -0600 Subject: [PATCH 01/87] aarch64: add PAC to GNU Notes (#882) While PAC was enabled, the bit to indicate support in the GNU Notes section of the ELF was missing. Before: readelf -n ./aarch64-unknown-linux-gnu/.libs/libffi.so Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI This was caused by this file not having PAC indicated in GNU Notes and the linker discarding it: File: ./aarch64-unknown-linux-gnu/src/aarch64/sysv.o Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI Now it has it: File: ./aarch64-unknown-linux-gnu/src/aarch64/sysv.o Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI, PAC As well as the output shared object: readelf -n ./aarch64-unknown-linux-gnu/.libs/libffi.so Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 Properties: AArch64 feature: BTI, PAC Fixes: #881 Signed-off-by: Bill Roberts --- src/aarch64/internal.h | 2 ++ src/aarch64/sysv.S | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h index 50fa5c139..591b9f5c0 100644 --- a/src/aarch64/internal.h +++ b/src/aarch64/internal.h @@ -91,6 +91,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define SIGN_LR_LINUX_ONLY #define BRANCH_TO_REG braaz #define PAC_CFI_WINDOW_SAVE + #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 /* Linux PAC Support */ #elif defined(__ARM_FEATURE_PAC_DEFAULT) #define GNU_PROPERTY_AARCH64_POINTER_AUTH (1 << 1) @@ -140,5 +141,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define SIGN_LR_LINUX_ONLY #define BRANCH_TO_REG br #define PAC_CFI_WINDOW_SAVE + #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 #endif /* HAVE_ARM64E_PTRAUTH */ #endif /* LIBFFI_ASM */ diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S index e83bc65de..81d33f2ef 100644 --- a/src/aarch64/sysv.S +++ b/src/aarch64/sysv.S @@ -692,7 +692,7 @@ CNAME(ffi_go_closure_SYSV): .asciz "GNU"; .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ .long 4; - .long GNU_PROPERTY_AARCH64_BTI; + .long GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_POINTER_AUTH; .long 0; .popsection; #endif From 89c99d738fd564da61b7ec70ab08fede475ba351 Mon Sep 17 00:00:00 2001 From: fossdd Date: Fri, 28 Feb 2025 22:10:10 +0100 Subject: [PATCH 02/87] MIPS: Dont import asm/sgidefs.h on linux (#885) Removed from Linux since Linux 3.7 Ref: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=61730c538f8281efa7ac12596da9f3f9a31b9272 --- src/mips/ffitarget.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mips/ffitarget.h b/src/mips/ffitarget.h index 294c3ba1a..cc7250cc1 100644 --- a/src/mips/ffitarget.h +++ b/src/mips/ffitarget.h @@ -32,16 +32,14 @@ #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." #endif -#ifdef __linux__ -# include -#elif defined(__rtems__) +#ifdef __rtems__ /* * Subprogram calling convention - copied from sgidefs.h */ #define _MIPS_SIM_ABI32 1 #define _MIPS_SIM_NABI32 2 #define _MIPS_SIM_ABI64 3 -#elif !defined(__OpenBSD__) && !defined(__FreeBSD__) +#elif !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__linux__) # include #endif From cf69efabcaefcb6803f6cefd970741d10c17cec1 Mon Sep 17 00:00:00 2001 From: Nikita Samusev <127026067+Nikitf777@users.noreply.github.com> Date: Sat, 8 Mar 2025 14:41:02 +0300 Subject: [PATCH 03/87] Update the Simple Example to fix a compile error (#886) Fixes the following error: candidate function not viable: no known conversion from 'int (const char *)' to 'void (*)()' for 2nd argument --- doc/libffi.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/libffi.texi b/doc/libffi.texi index e82f94402..5bf09eb49 100644 --- a/doc/libffi.texi +++ b/doc/libffi.texi @@ -263,14 +263,14 @@ int main() &ffi_type_sint, args) == FFI_OK) @{ s = "Hello World!"; - ffi_call(&cif, puts, &rc, values); + ffi_call(&cif, (void(*)())puts, &rc, values); /* rc now holds the result of the call to puts */ /* values holds a pointer to the function's arg, so to call puts() again all we need to do is change the value of s */ s = "This is cool!"; - ffi_call(&cif, puts, &rc, values); + ffi_call(&cif, (void(*)())puts, &rc, values); @} return 0; From fe203ffbb2bd7f93a86013d341aa767a406150bc Mon Sep 17 00:00:00 2001 From: mikulas-patocka <94898783+mikulas-patocka@users.noreply.github.com> Date: Thu, 27 Mar 2025 01:31:49 +0100 Subject: [PATCH 04/87] Fix bugs in the x86-64 and x32 target (#887) (#889) This commit fixes two bugs in ffi in the x86-64 target. The bugs were introduced by the commit d21881f55ed4a44d464c9091871e69b0bb47611a ("Fix x86/ffi64 calls with 6 gp and some sse registers"). The first bug is that when we pass an argument with less than 8 bytes, ffi will read memory beyond argument end, causing a crash if the argument is located just before the end of the mapped region. The second bug is in the x32 ABI - pointers in x32 are 4-byte, but GCC assumes that the pointer values in the registers are zero-extended. ffi doesn't respect this assumption, causing crashes in the called library. For example, when we compile this function for x32: int fn(int *a) { if (a) return *a; return -1; } we get this code: fn: testq %rdi, %rdi je .L3 movl (%edi), %eax ret .L3: movl $-1, %eax ret When we call this function using ffi with the argument NULL, the function crashes because top 4 bytes of the RDI register are not cleared. Fixes: d21881f55ed4 ("Fix x86/ffi64 calls with 6 gp and some sse registers (#848)") Signed-off-by: Mikulas Patocka --- src/x86/ffi64.c | 2 +- testsuite/libffi.call/overread.c | 54 ++++++++++++++++++++++++++++++++ testsuite/libffi.call/x32.c | 31 ++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 testsuite/libffi.call/overread.c create mode 100644 testsuite/libffi.call/x32.c diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c index 982b144cb..1d1b88e04 100644 --- a/src/x86/ffi64.c +++ b/src/x86/ffi64.c @@ -654,7 +654,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, break; default: reg_args->gpr[gprcount] = 0; - memcpy (®_args->gpr[gprcount], a, sizeof(UINT64)); + memcpy (®_args->gpr[gprcount], a, size <= 8 ? size : 8); } gprcount++; break; diff --git a/testsuite/libffi.call/overread.c b/testsuite/libffi.call/overread.c new file mode 100644 index 000000000..d9ae579bc --- /dev/null +++ b/testsuite/libffi.call/overread.c @@ -0,0 +1,54 @@ +/* Area: ffi_call + Purpose: Tests if ffi_call reads data beyond end. + Limitations: needs mmap. + PR: 887 + Originator: Mikulas Patocka */ + +/* { dg-do run } */ + +#include "ffitest.h" + +#ifdef __linux__ +#include +#include + +static int fn(unsigned char a, unsigned short b, unsigned int c, unsigned long d) +{ + return (int)(a + b + c + d); +} +#endif + +int main(void) +{ +#ifdef __linux__ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + ffi_arg rint; + char *m; + int ps; + args[0] = &ffi_type_uchar; + args[1] = &ffi_type_ushort; + args[2] = &ffi_type_uint; + args[3] = &ffi_type_ulong; + CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_sint, args) == FFI_OK); + ps = getpagesize(); + m = mmap(NULL, ps * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + CHECK(m != MAP_FAILED); + CHECK(mprotect(m, ps, PROT_NONE) == 0); + CHECK(mprotect(m + ps * 2, ps, PROT_NONE) == 0); + values[0] = m + ps * 2 - sizeof(unsigned char); + values[1] = m + ps * 2 - sizeof(unsigned short); + values[2] = m + ps * 2 - sizeof(unsigned int); + values[3] = m + ps * 2 - sizeof(unsigned long); + ffi_call(&cif, FFI_FN(fn), &rint, values); + CHECK((int)rint == 0); + values[0] = m + ps; + values[1] = m + ps; + values[2] = m + ps; + values[3] = m + ps; + ffi_call(&cif, FFI_FN(fn), &rint, values); + CHECK((int)rint == 0); +#endif + exit(0); +} diff --git a/testsuite/libffi.call/x32.c b/testsuite/libffi.call/x32.c new file mode 100644 index 000000000..f9ad82de9 --- /dev/null +++ b/testsuite/libffi.call/x32.c @@ -0,0 +1,31 @@ +/* Area: ffi_call + Purpose: Check zero-extension of pointers on x32. + Limitations: none. + PR: 887 + Originator: Mikulas Patocka */ + +/* { dg-do run } */ + +#include "ffitest.h" + +static int fn(int *a) +{ + if (a) + return *a; + return -1; +} + +int main(void) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + void *z[2] = { (void *)0, (void *)1 }; + ffi_arg rint; + args[0] = &ffi_type_pointer; + values[0] = z; + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ffi_type_sint, args) == FFI_OK); + ffi_call(&cif, FFI_FN(fn), &rint, values); + CHECK((int)rint == -1); + exit(0); +} From bb1a84ed9772ee65e00762dab1c4ae50100d5a27 Mon Sep 17 00:00:00 2001 From: mikulas-patocka <94898783+mikulas-patocka@users.noreply.github.com> Date: Sun, 30 Mar 2025 12:07:59 +0200 Subject: [PATCH 05/87] Add the "ABI_ATTR" attribute to called functions (#891) (#892) I accidentally omitted the "ABI_ATTR" attribute, so that the testsuite fails when testing the Microsoft ABI. Fixes: fe203ffbb2bd ("Fix bugs in the x86-64 and x32 target (#887) (#889)") Signed-off-by: Mikulas Patocka --- testsuite/libffi.call/overread.c | 2 +- testsuite/libffi.call/x32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/libffi.call/overread.c b/testsuite/libffi.call/overread.c index d9ae579bc..5ba10774c 100644 --- a/testsuite/libffi.call/overread.c +++ b/testsuite/libffi.call/overread.c @@ -12,7 +12,7 @@ #include #include -static int fn(unsigned char a, unsigned short b, unsigned int c, unsigned long d) +static int ABI_ATTR fn(unsigned char a, unsigned short b, unsigned int c, unsigned long d) { return (int)(a + b + c + d); } diff --git a/testsuite/libffi.call/x32.c b/testsuite/libffi.call/x32.c index f9ad82de9..9c380a529 100644 --- a/testsuite/libffi.call/x32.c +++ b/testsuite/libffi.call/x32.c @@ -8,7 +8,7 @@ #include "ffitest.h" -static int fn(int *a) +static int ABI_ATTR fn(int *a) { if (a) return *a; From 3429ed6b9414dfbe9d9da7609ab043291a01a148 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Tue, 8 Apr 2025 05:52:37 -0500 Subject: [PATCH 06/87] powerpc: Add static trampoline support (#894) (#895) Add static trampoline support to all three powerpc Linux ABIs, specifically powerpc-linux (32-bit SYSV BE), powerpc64-linux (64-bit ELFv1 BE) and powerpc64le-linux (64-bit ELFv2 LE). This follows the s390x implementation and does not introduce a ffi_closure_*_alt function, but rather jumps directly to the ffi_closure_* function itself. If compiling with --with-gcc-arch=power10 and pc-relative is enabled, we use a simpler and smaller trampoline that utilizes Power10's new pc-relative load instructions. --- Makefile.am | 3 ++- configure.ac | 3 ++- src/powerpc/ffi.c | 13 ++++++++++ src/powerpc/ffi_linux64.c | 45 +++++++++++++++++++-------------- src/powerpc/ffi_sysv.c | 42 +++++++++++++++++++------------ src/powerpc/internal.h | 10 ++++++++ src/powerpc/linux64_closure.S | 47 +++++++++++++++++++++++++++++++++++ src/powerpc/ppc_closure.S | 24 ++++++++++++++++++ 8 files changed, 150 insertions(+), 37 deletions(-) create mode 100644 src/powerpc/internal.h diff --git a/Makefile.am b/Makefile.am index 1f8aa9cce..ba3d16626 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,7 +58,8 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ src/moxie/ffitarget.h \ src/or1k/ffitarget.h src/pa/ffitarget.h \ src/powerpc/ffitarget.h src/powerpc/asm.h \ - src/powerpc/ffi_powerpc.h src/riscv/ffitarget.h \ + src/powerpc/ffi_powerpc.h src/powerpc/internal.h \ + src/riscv/ffitarget.h \ src/s390/ffitarget.h src/s390/internal.h src/sh/ffitarget.h \ src/sh64/ffitarget.h src/sparc/ffitarget.h \ src/sparc/internal.h src/tile/ffitarget.h src/vax/ffitarget.h \ diff --git a/configure.ac b/configure.ac index a1d02b803..a00342e6e 100644 --- a/configure.ac +++ b/configure.ac @@ -382,7 +382,8 @@ case "$target" in [Define this if you want statically defined trampolines]) fi ;; - *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* | loongarch*-*-linux-* | s390x*-linux-*) + *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* \ + | loongarch*-*-linux-* | s390x*-linux-* | powerpc*-linux-*) AC_DEFINE(FFI_EXEC_STATIC_TRAMP, 1, [Define this if you want statically defined trampolines]) ;; diff --git a/src/powerpc/ffi.c b/src/powerpc/ffi.c index a19bcbbfc..0a9774165 100644 --- a/src/powerpc/ffi.c +++ b/src/powerpc/ffi.c @@ -31,6 +31,8 @@ #include "ffi.h" #include "ffi_common.h" #include "ffi_powerpc.h" +#include "internal.h" +#include #if HAVE_LONG_DOUBLE_VARIANT /* Adjust ffi_type_longdouble. */ @@ -173,3 +175,14 @@ ffi_prep_go_closure (ffi_go_closure *closure, closure->fun = fun; return FFI_OK; } + +#ifdef FFI_EXEC_STATIC_TRAMP +void * +ffi_tramp_arch (size_t *tramp_size, size_t *map_size) +{ + extern void *trampoline_code_table; + *tramp_size = PPC_TRAMP_SIZE; + *map_size = PPC_TRAMP_MAP_SIZE; + return &trampoline_code_table; +} +#endif diff --git a/src/powerpc/ffi_linux64.c b/src/powerpc/ffi_linux64.c index 3454dacd3..90100a4d8 100644 --- a/src/powerpc/ffi_linux64.c +++ b/src/powerpc/ffi_linux64.c @@ -29,6 +29,7 @@ ----------------------------------------------------------------------- */ #include "ffi.h" +#include #ifdef POWERPC64 #include "ffi_common.h" @@ -820,32 +821,38 @@ ffi_prep_closure_loc_linux64 (ffi_closure *closure, void *user_data, void *codeloc) { -#if _CALL_ELF == 2 - unsigned int *tramp = (unsigned int *) &closure->tramp[0]; - if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) return FFI_BAD_ABI; - tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ - tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ - tramp[2] = 0x7d8903a6; /* mtctr 12 */ - tramp[3] = 0x4e800420; /* bctr */ +#ifdef FFI_EXEC_STATIC_TRAMP + if (ffi_tramp_is_present(closure)) + { + /* Initialize the static trampoline's parameters. */ + void (*dest)(void) = ffi_closure_LINUX64; + ffi_tramp_set_parms (closure->ftramp, dest, closure); + } + else +#endif + { +#if _CALL_ELF == 2 + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ + tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ + tramp[2] = 0x7d8903a6; /* mtctr 12 */ + tramp[3] = 0x4e800420; /* bctr */ /* 1: .quad function_addr */ /* 2: .quad context */ - *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; - *(void **) &tramp[6] = codeloc; - flush_icache ((char *) tramp, (char *) codeloc, 4 * 4); + *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; + *(void **) &tramp[6] = codeloc; + flush_icache ((char *) tramp, (char *) codeloc, 4 * 4); #else - void **tramp = (void **) &closure->tramp[0]; - - if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) - return FFI_BAD_ABI; - - /* Copy function address and TOC from ffi_closure_LINUX64 OPD. */ - memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *)); - tramp[1] = codeloc; - memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *)); + /* Copy function address and TOC from ffi_closure_LINUX64 OPD. */ + void **tramp = (void **) &closure->tramp[0]; + memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *)); + tramp[1] = codeloc; + memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *)); #endif + } closure->cif = cif; closure->fun = fun; diff --git a/src/powerpc/ffi_sysv.c b/src/powerpc/ffi_sysv.c index 4078e7511..5d7c5c823 100644 --- a/src/powerpc/ffi_sysv.c +++ b/src/powerpc/ffi_sysv.c @@ -29,6 +29,7 @@ ----------------------------------------------------------------------- */ #include "ffi.h" +#include #ifndef POWERPC64 #include "ffi_common.h" @@ -636,25 +637,34 @@ ffi_prep_closure_loc_sysv (ffi_closure *closure, void *user_data, void *codeloc) { - unsigned int *tramp; - if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI) return FFI_BAD_ABI; - tramp = (unsigned int *) &closure->tramp[0]; - tramp[0] = 0x7c0802a6; /* mflr r0 */ - tramp[1] = 0x429f0005; /* bcl 20,31,.+4 */ - tramp[2] = 0x7d6802a6; /* mflr r11 */ - tramp[3] = 0x7c0803a6; /* mtlr r0 */ - tramp[4] = 0x800b0018; /* lwz r0,24(r11) */ - tramp[5] = 0x816b001c; /* lwz r11,28(r11) */ - tramp[6] = 0x7c0903a6; /* mtctr r0 */ - tramp[7] = 0x4e800420; /* bctr */ - *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */ - *(void **) &tramp[9] = codeloc; /* context */ - - /* Flush the icache. */ - flush_icache ((char *)tramp, (char *)codeloc, 8 * 4); +#ifdef FFI_EXEC_STATIC_TRAMP + if (ffi_tramp_is_present(closure)) + { + /* Initialize the static trampoline's parameters. */ + void (*dest)(void) = ffi_closure_SYSV; + ffi_tramp_set_parms (closure->ftramp, dest, closure); + } + else +#endif + { + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x429f0005; /* bcl 20,31,.+4 */ + tramp[2] = 0x7d6802a6; /* mflr r11 */ + tramp[3] = 0x7c0803a6; /* mtlr r0 */ + tramp[4] = 0x800b0018; /* lwz r0,24(r11) */ + tramp[5] = 0x816b001c; /* lwz r11,28(r11) */ + tramp[6] = 0x7c0903a6; /* mtctr r0 */ + tramp[7] = 0x4e800420; /* bctr */ + *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[9] = codeloc; /* context */ + + /* Flush the icache. */ + flush_icache ((char *)tramp, (char *)codeloc, 8 * 4); + } closure->cif = cif; closure->fun = fun; diff --git a/src/powerpc/internal.h b/src/powerpc/internal.h new file mode 100644 index 000000000..b3db5f014 --- /dev/null +++ b/src/powerpc/internal.h @@ -0,0 +1,10 @@ +#ifdef FFI_EXEC_STATIC_TRAMP +/* For the trampoline code table mapping, a mapping size of 64K is chosen. */ +#define PPC_TRAMP_MAP_SHIFT 16 +#define PPC_TRAMP_MAP_SIZE (1 << PPC_TRAMP_MAP_SHIFT) +# ifdef __PCREL__ +# define PPC_TRAMP_SIZE 24 +# else +# define PPC_TRAMP_SIZE 40 +# endif /* __PCREL__ */ +#endif /* FFI_EXEC_STATIC_TRAMP */ diff --git a/src/powerpc/linux64_closure.S b/src/powerpc/linux64_closure.S index 199981db3..d9e5cff64 100644 --- a/src/powerpc/linux64_closure.S +++ b/src/powerpc/linux64_closure.S @@ -27,6 +27,7 @@ #define LIBFFI_ASM #include #include +#include "internal.h" .file "linux64_closure.S" @@ -559,7 +560,53 @@ ffi_go_closure_linux64: .size .ffi_go_closure_linux64,.-.ffi_go_closure_linux64 # endif # endif + +#ifdef FFI_EXEC_STATIC_TRAMP + .text + .align PPC_TRAMP_MAP_SHIFT + FFI_HIDDEN (trampoline_code_table) + .globl trampoline_code_table +# if _CALL_ELF == 2 + .type trampoline_code_table,@function +trampoline_code_table: + .localentry trampoline_code_table,.-trampoline_code_table +# else + .section ".opd","aw" + .align 3 +trampoline_code_table: + .quad .L.trampoline_code_table,.TOC.@tocbase,0 + .type trampoline_code_table,@function + .text +.L.trampoline_code_table: +# endif + .rept PPC_TRAMP_MAP_SIZE / PPC_TRAMP_SIZE +#ifdef __PCREL__ + pla %r2,PPC_TRAMP_MAP_SIZE + ld %r11,0(%r2) + ld %r12,8(%r2) + mtctr %r12 + bctr +#else + mflr %r0 + bcl 20,31,$+4 + mflr %r11 + addis %r11,%r11,PPC_TRAMP_MAP_SIZE@ha + mtlr %r0 + ld %r12,(PPC_TRAMP_MAP_SIZE+0)@l(%r11) + mtctr %r12 + ld %r11,(PPC_TRAMP_MAP_SIZE-8)@l(%r11) + bctr + nop +#endif + .endr + .align PPC_TRAMP_MAP_SHIFT +#if _CALL_ELF == 2 + .size trampoline_code_table,.-trampoline_code_table +#else + .size trampoline_code_table,.-.L.trampoline_code_table #endif +#endif /* FFI_EXEC_STATIC_TRAMP */ +#endif /* POWERPC64 */ #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 .section .note.GNU-stack,"",@progbits diff --git a/src/powerpc/ppc_closure.S b/src/powerpc/ppc_closure.S index b6d209de8..d3556ebad 100644 --- a/src/powerpc/ppc_closure.S +++ b/src/powerpc/ppc_closure.S @@ -27,6 +27,7 @@ #define LIBFFI_ASM #include #include +#include "internal.h" #include .file "ppc_closure.S" @@ -391,6 +392,29 @@ ENTRY(ffi_go_closure_sysv) .cfi_endproc END(ffi_go_closure_sysv) +#ifdef FFI_EXEC_STATIC_TRAMP + .text + .align PPC_TRAMP_MAP_SHIFT + FFI_HIDDEN (trampoline_code_table) + .globl trampoline_code_table + .type trampoline_code_table,@function +trampoline_code_table: + .rept PPC_TRAMP_MAP_SIZE / PPC_TRAMP_SIZE + mflr %r0 + bcl 20,31,$+4 + mflr %r11 + addis %r11,%r11,PPC_TRAMP_MAP_SIZE@ha + mtlr %r0 + lwz %r0,(PPC_TRAMP_MAP_SIZE-4)@l(%r11) + mtctr %r0 + lwz %r11,(PPC_TRAMP_MAP_SIZE-8)@l(%r11) + bctr + nop + .endr + .size trampoline_code_table,.-trampoline_code_table + .align PPC_TRAMP_MAP_SHIFT +#endif /* FFI_EXEC_STATIC_TRAMP */ + #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif From bfb5b005a08239c751db667f68a67aeb72a9b9ff Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 9 Apr 2025 10:32:42 -0400 Subject: [PATCH 07/87] feat: Update version of libffi to 3.4.8 with various fixes and enhancements --- README.md | 12 ++++++++++-- configure.ac | 2 +- doc/version.texi | 8 ++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0d4c24243..6f47c255e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.4.7 was released on February 8, 2025. Check the libffi web +libffi-3.4.8 was released on April 9, 2025. Check the libffi web page for updates: . @@ -200,7 +200,15 @@ History See the git log for details at http://github.com/libffi/libffi. - 3.4.7 Feb-8-2024 + 3.4.8 Apr-9-2025 + Add static trampoline support for powerpc-linux (32-bit SYSV BE), + powerpc64-linux (64-bit ELFv1 BE) and + powerpc64le-linux (64-bit ELFv2 LE) + Various x86-64 bug fixes (x32 ABI and improper memory access for + small argument calls). + Fix to enable pointer authentication for aarch64. + + 3.4.7 Feb-8-2025 Add static trampoline support for Linux on s390x. Fix BTI support for ARM64. Support pointer authentication for ARM64. diff --git a/configure.ac b/configure.ac index a00342e6e..f04789556 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.71]) -AC_INIT([libffi],[3.4.7],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.4.8],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) AC_CANONICAL_TARGET diff --git a/doc/version.texi b/doc/version.texi index 73e9e6f4c..711d9567a 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 1 June 2024 -@set UPDATED-MONTH June 2024 -@set EDITION 3.4.7 -@set VERSION 3.4.7 +@set UPDATED 27 March 2025 +@set UPDATED-MONTH March 2025 +@set EDITION 3.4.8 +@set VERSION 3.4.8 From 6a99edb8082f75e523e0d6ebaba42218b80e10c8 Mon Sep 17 00:00:00 2001 From: Sam James Date: Thu, 10 Apr 2025 03:44:45 +0100 Subject: [PATCH 08/87] testsuite: add two tests to Makefile.am (#893) * Add libffi.call/overread.c and libffi.call/x32.c to Makefile.am so they're included in dist tarballs * Fix indentation and rewrap --- testsuite/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 92ae1aaa2..12d128900 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -17,8 +17,8 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ 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/many2.c libffi.call/many_double.c libffi.call/many_mixed.c \ - libffi.call/negint.c libffi.call/offsets.c libffi.call/pr1172638.c \ - libffi.call/promotion.c libffi.call/pyobjc_tc.c libffi.call/return_dbl.c \ + libffi.call/negint.c libffi.call/offsets.c libffi.call/overread.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 \ libffi.call/return_ldl.c libffi.call/return_ll.c libffi.call/return_ll1.c \ @@ -31,11 +31,11 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \ libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \ libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \ - libffi.call/struct_int_float.c \ + libffi.call/struct_int_float.c \ libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \ libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \ libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \ - libffi.call/callback2.c libffi.call/callback3.c libffi.call/callback4.c \ + libffi.call/callback2.c libffi.call/callback3.c libffi.call/callback4.c libffi.call/x32.c \ libffi.closures/closure.exp libffi.closures/closure_fn0.c libffi.closures/closure_fn1.c \ libffi.closures/closure_fn2.c libffi.closures/closure_fn3.c libffi.closures/closure_fn4.c \ libffi.closures/closure_fn5.c libffi.closures/closure_fn6.c libffi.closures/closure_loc_fn0.c \ From a431b47822f06e3f16b2e16f3163fd209ac56b5f Mon Sep 17 00:00:00 2001 From: Sam James Date: Tue, 15 Apr 2025 10:30:27 +0100 Subject: [PATCH 09/87] pa: add .note.GNU-stack marker to linux.S (#899) Similarly to f515eac04cf8e5f594d5d9dee5fb7dfc3a186a4c, add a .note.GNU-stack marker to pa/linux.S as it doesn't need an executable stack. Absence of the note means that GNU Binutils will consider it as needing an executable stack and mark it as such automatically. When building libffi on HPPA with `-Wl,--warn-warn-execstack`, we get: ``` ld: warning: src/pa/.libs/linux.o: missing .note.GNU-stack section implies executable stack ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker ``` That becomes more problematic with glibc-2.41 which forbids dlopen() of a library with an executable stack, and libffi is commonly dlopen()'d, especially by Python. I suspect the reason it didn't show up on Debian is that since February, Debian has been building Binutils with --disable-default-execstack. Bug: https://bugs.gentoo.org/953805 Bug: https://github.com/libffi/libffi/issues/898 --- src/pa/linux.S | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pa/linux.S b/src/pa/linux.S index 2d3b03604..fdd433247 100644 --- a/src/pa/linux.S +++ b/src/pa/linux.S @@ -425,3 +425,7 @@ ffi_closure_pa32: .align 4 .LEFDE2: + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",%progbits +#endif From aea22de28ec92a69cab9198de479263fe8b1a637 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 18 Apr 2025 10:09:45 -0500 Subject: [PATCH 10/87] powerpc: Fix closures on powerpc64-linux when statically linking (#900) (#902) Closures on powerpc64-linux using static trampolines do not work when statically linking libffi. The problem is the usage of tramp_globals.text in libffi assumes it contains the entry point address of the first trampoline. Powerpc's ffi_tramp_arch code returns &trampoline_code_table which for ABIs that use function descriptors, ends up returning trampoline_code_table's function descriptor address instead of its entry point address. Update the code to always return the entry point address for all ABIs. --- src/powerpc/ffi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/powerpc/ffi.c b/src/powerpc/ffi.c index 0a9774165..3601cc4ab 100644 --- a/src/powerpc/ffi.c +++ b/src/powerpc/ffi.c @@ -183,6 +183,12 @@ ffi_tramp_arch (size_t *tramp_size, size_t *map_size) extern void *trampoline_code_table; *tramp_size = PPC_TRAMP_SIZE; *map_size = PPC_TRAMP_MAP_SIZE; +#if defined (_CALL_AIX) || _CALL_ELF == 1 + /* The caller wants the entry point address of the trampoline code, + not the address of the function descriptor. */ + return *(void **)trampoline_code_table; +#else return &trampoline_code_table; +#endif } #endif From 562cb53b5ddc97020291927d47823f210c5f3486 Mon Sep 17 00:00:00 2001 From: David Tenty Date: Fri, 25 Apr 2025 05:07:57 -0400 Subject: [PATCH 11/87] Add initializer (#904) --- testsuite/libffi.bhaible/testcases.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/libffi.bhaible/testcases.c b/testsuite/libffi.bhaible/testcases.c index 23a6f4660..22cf1ebb5 100644 --- a/testsuite/libffi.bhaible/testcases.c +++ b/testsuite/libffi.bhaible/testcases.c @@ -21,7 +21,7 @@ #include -FILE* out; +FILE* out = NULL; #define uchar unsigned char #define ushort unsigned short From 571177adcb2b604739a0432b7392f1b83294decf Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 27 Apr 2025 08:30:35 -0400 Subject: [PATCH 12/87] feat(testsuite): add longjmp test to Makefile and implement longjmp test code --- testsuite/Makefile.am | 2 +- testsuite/libffi.call/longjmp.c | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 testsuite/libffi.call/longjmp.c diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 12d128900..fa9134f44 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -31,7 +31,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \ libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \ libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \ - libffi.call/struct_int_float.c \ + libffi.call/struct_int_float.c libffi.call/longjmp.c \ libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \ libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \ libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \ diff --git a/testsuite/libffi.call/longjmp.c b/testsuite/libffi.call/longjmp.c new file mode 100644 index 000000000..fc0c7ffd9 --- /dev/null +++ b/testsuite/libffi.call/longjmp.c @@ -0,0 +1,60 @@ +/* Area: ffi_call + Purpose: Test longjmp over ffi_call frames */ + +/* Test code adapted from Lars Kanis' bug report: + https://github.com/libffi/libffi/issues/905 */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "ffi_common.h" + +#include + +static jmp_buf buf; + +static void ABI_ATTR lev2(const char *str) { + printf("lev2 %s\n", str); + // jumps back to where setjmp was called - making setjmp now return 1 + longjmp(buf, 1); +} + +static void ABI_ATTR lev1(const char *str) { + lev2(str); + + // will not be reached + printf("lev1 %s\n", str); +} + +int main() +{ + ffi_cif cif; + ffi_type *args[1]; + void *values[1]; + char *s; + ffi_arg rc; + /* Initialize the argument info vectors */ + args[0] = &ffi_type_pointer; + values[0] = &s; + /* Initialize the cif */ + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) == FFI_OK) + { + s = "direct call"; + if (!setjmp(buf)){ + // works on x64 and arm64 + lev1(s); + } else { + printf("back to main\n"); + } + + s = "through libffi"; + if (!setjmp(buf)){ + // works on x64 but segfaults on arm64 + ffi_call(&cif, (void (*)(void))lev1, &rc, values); + } else { + printf("back to main\n"); + } + } + return 0; +} From c6f1610509d3d146017d6cc30020ce334bde8425 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 27 Apr 2025 08:59:12 -0400 Subject: [PATCH 13/87] feat(testsuite): add mingw64-align.c to test alignment in structs --- testsuite/Makefile.am | 2 +- testsuite/libffi.call/mingw64-align.c | 52 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 testsuite/libffi.call/mingw64-align.c diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index fa9134f44..8f8821d69 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -31,7 +31,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \ libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \ libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \ - libffi.call/struct_int_float.c libffi.call/longjmp.c \ + libffi.call/struct_int_float.c libffi.call/longjmp.c libffi.call/mingw64-align.c \ libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \ libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \ libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \ diff --git a/testsuite/libffi.call/mingw64-align.c b/testsuite/libffi.call/mingw64-align.c new file mode 100644 index 000000000..74677c8e8 --- /dev/null +++ b/testsuite/libffi.call/mingw64-align.c @@ -0,0 +1,52 @@ +/* Test code adapted from Emil Taylor Bye's bug report: + https://github.com/libffi/libffi/issues/897 */ + +/* { dg-do run } */ + +#include "ffitest.h" +#include "ffi_common.h" + +typedef struct u64struct { + uint64_t a; + uint64_t b; +} u64struct_t; + +typedef u64struct_t (*callback_t) (u64struct_t); + +void ABI_ATTR callback(ffi_cif *cif, void *ret, void *args[], void *dontcare __UNUSED__) { + ffi_type *argty = *(cif->arg_types); + + // This fails as the argument is not properly aligned + CHECK(((size_t) *args) % (argty->alignment) == 0); + + *((u64struct_t *) ret) = *((u64struct_t *) *args); +} + +int main() { + ffi_cif cif; + ffi_type *args[1]; + ffi_closure *closure; + void *code_ptr; + ffi_type struct_type; + ffi_type *struct_type_elements[3]; + + struct_type.size = struct_type.alignment = 0; + struct_type.type = FFI_TYPE_STRUCT; + struct_type.elements = struct_type_elements; + struct_type_elements[0] = &ffi_type_uint64; + struct_type_elements[1] = &ffi_type_uint64; + struct_type_elements[2] = NULL; + + args[0] = &struct_type; + + closure = ffi_closure_alloc(sizeof(ffi_closure), &code_ptr); + + if (closure) { + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &struct_type, args) == FFI_OK) { + if (ffi_prep_closure_loc(closure, &cif, callback, NULL, code_ptr) == FFI_OK) { + u64struct_t in_arg = { a:0x123456789ABCDEF0, b:0x123456789ABCDEF0 }; + ((callback_t)code_ptr)(in_arg); + } + } + } +} From f9c60855da770a8465ad0fe7149ad86d1a6f900b Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 24 May 2025 08:11:37 -0400 Subject: [PATCH 14/87] Add custom github issue labels for gail --- .gail-labels | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .gail-labels diff --git a/.gail-labels b/.gail-labels new file mode 100644 index 000000000..446914469 --- /dev/null +++ b/.gail-labels @@ -0,0 +1,43 @@ +# This is a list of labels to be used for automatic tagging +# of github issues using gail: https://github.com/atgreen/gail + +# Main categories +BUILD-ERROR +RUNTIME-ERROR +FEATURE-REQUEST + +# Operating systems +ANDROID +IOS +LINUX +MACOS +SOLARIS +WINDOWS + +# Processor families +AARCH64 +ALPHA +ARC +ARM +AVR32 +BLACKFIN +CSKY +HPPA +IA-64 +KVX +LOONGARCH64 +M68K +M88K +MICROBLAZE +MIPS +MOXIE +OPENRISC +POWERPC +RISC-V +S390 +SPARC +TILE +VAX +WASM +X86 +XTENSA From 5b253476d10e12291e96671ff5bf275737928ffd Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 25 May 2025 13:33:51 -0400 Subject: [PATCH 15/87] chore(testsuite): remove mingw64-align.c from Makefile and delete file --- testsuite/Makefile.am | 2 +- testsuite/libffi.call/mingw64-align.c | 52 --------------------------- 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 testsuite/libffi.call/mingw64-align.c diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 8f8821d69..fa9134f44 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -31,7 +31,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \ libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \ libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \ - libffi.call/struct_int_float.c libffi.call/longjmp.c libffi.call/mingw64-align.c \ + libffi.call/struct_int_float.c libffi.call/longjmp.c \ libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \ libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \ libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \ diff --git a/testsuite/libffi.call/mingw64-align.c b/testsuite/libffi.call/mingw64-align.c deleted file mode 100644 index 74677c8e8..000000000 --- a/testsuite/libffi.call/mingw64-align.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Test code adapted from Emil Taylor Bye's bug report: - https://github.com/libffi/libffi/issues/897 */ - -/* { dg-do run } */ - -#include "ffitest.h" -#include "ffi_common.h" - -typedef struct u64struct { - uint64_t a; - uint64_t b; -} u64struct_t; - -typedef u64struct_t (*callback_t) (u64struct_t); - -void ABI_ATTR callback(ffi_cif *cif, void *ret, void *args[], void *dontcare __UNUSED__) { - ffi_type *argty = *(cif->arg_types); - - // This fails as the argument is not properly aligned - CHECK(((size_t) *args) % (argty->alignment) == 0); - - *((u64struct_t *) ret) = *((u64struct_t *) *args); -} - -int main() { - ffi_cif cif; - ffi_type *args[1]; - ffi_closure *closure; - void *code_ptr; - ffi_type struct_type; - ffi_type *struct_type_elements[3]; - - struct_type.size = struct_type.alignment = 0; - struct_type.type = FFI_TYPE_STRUCT; - struct_type.elements = struct_type_elements; - struct_type_elements[0] = &ffi_type_uint64; - struct_type_elements[1] = &ffi_type_uint64; - struct_type_elements[2] = NULL; - - args[0] = &struct_type; - - closure = ffi_closure_alloc(sizeof(ffi_closure), &code_ptr); - - if (closure) { - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &struct_type, args) == FFI_OK) { - if (ffi_prep_closure_loc(closure, &cif, callback, NULL, code_ptr) == FFI_OK) { - u64struct_t in_arg = { a:0x123456789ABCDEF0, b:0x123456789ABCDEF0 }; - ((callback_t)code_ptr)(in_arg); - } - } - } -} From 64d5e122f747c9b761b311f85cfc5d99c02fe959 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 25 May 2025 16:09:59 -0400 Subject: [PATCH 16/87] docs: update required installations in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f47c255e..2da805b93 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ compiler. If you're building libffi directly from git hosted sources, configure won't exist yet; run ./autogen.sh first. This will require that you -install autoconf, automake and libtool. +install autoconf, automake, libtool and texinfo. You may want to tell configure where to install the libffi library and header files. To do that, use the ``--prefix`` configure switch. Libffi From c9a3a06f9be8f32da3eac132ff6754ec74feb42a Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 26 May 2025 08:18:13 -0400 Subject: [PATCH 17/87] feat(libffi): upgrade to version 3.5.0 and add version API --- configure.ac | 9 +++++++-- doc/libffi.texi | 15 ++++++++++++++- include/ffi.h.in | 15 ++++++++++++++- libffi.map.in | 3 +++ src/types.c | 12 ++++++++++++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index f04789556..69ed04360 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,15 @@ dnl Process this with autoconf to create configure -AC_PREREQ([2.71]) +AC_PREREQ([2.72]) -AC_INIT([libffi],[3.4.8],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) +FFI_VERSION_STRING="3.5.0" +FFI_VERSION_NUMBER=30500 +AC_SUBST(FFI_VERSION_STRING) +AC_SUBST(FFI_VERSION_NUMBER) + AC_CANONICAL_TARGET target_alias=${target_alias-$host_alias} diff --git a/doc/libffi.texi b/doc/libffi.texi index 5bf09eb49..1ae2e24a9 100644 --- a/doc/libffi.texi +++ b/doc/libffi.texi @@ -18,7 +18,7 @@ This manual is for libffi, a portable foreign function interface library. -Copyright @copyright{} 2008--2024 Anthony Green and Red Hat, Inc. +Copyright @copyright{} 2008--2025 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 @@ -236,6 +236,19 @@ object declared as @code{short}; but if the return type is a larger type -- usually @code{ffi_arg}. @end defun +@findex ffi_get_version +@defun {const char *} ffi_get_version (void) +Returns the library version as a string. This string is also +available at build time as the macro @code{FFI_VERSION_STRING}. +@end defun + +@findex ffi_get_version_number +@defun {unsigned long} ffi_get_version_number (void) +Returns the library version as an unsigned long value where +version ``x.y.z'' is represented as the number x*y*z. +This number is also available at build time as the macro +@code{FFI_VERSION_NUMBER}. +@end defun @node Simple Example @section Simple Example diff --git a/include/ffi.h.in b/include/ffi.h.in index e5c1daef3..c97d7e0c6 100644 --- a/include/ffi.h.in +++ b/include/ffi.h.in @@ -1,6 +1,6 @@ /* -----------------------------------------------------------------*-C-*- libffi @VERSION@ - - Copyright (c) 2011, 2014, 2019, 2021, 2022, 2024 Anthony Green + - Copyright (c) 2011, 2014, 2019, 2021, 2022, 2024, 2025 Anthony Green - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. Permission is hereby granted, free of charge, to any person @@ -54,6 +54,19 @@ extern "C" { #define @TARGET@ #endif +/* ---- Version API ------------------------------------------------------ */ + +#define FFI_VERSION_STRING "@FFI_VERSION_STRING@" +#define FFI_VERSION_NUMBER @FFI_VERSION_NUMBER@ + +#ifndef LIBFFI_ASM +/* Return a version string. */ +const char *ffi_get_version (void); + +/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ +unsigned long ffi_get_version_number (void); +#endif + /* ---- System configuration information --------------------------------- */ /* If these change, update src/mips/ffitarget.h. */ diff --git a/libffi.map.in b/libffi.map.in index 08c50b22d..c5e0c5124 100644 --- a/libffi.map.in +++ b/libffi.map.in @@ -24,6 +24,9 @@ LIBFFI_BASE_8.0 { ffi_type_pointer; /* Exported functions. */ + ffi_get_version; + ffi_get_version_number; + ffi_call; ffi_prep_cif; ffi_prep_cif_var; diff --git a/src/types.c b/src/types.c index c1c27f38d..28d7a1ed0 100644 --- a/src/types.c +++ b/src/types.c @@ -31,6 +31,18 @@ #include #include +/* Return a version string. */ +const char *ffi_get_version (void) +{ + return FFI_VERSION_STRING; +} + +/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ +unsigned long ffi_get_version_number (void) +{ + return FFI_VERSION_NUMBER; +} + /* Type definitions */ #define FFI_TYPEDEF(name, type, id, maybe_const)\ From dc9b1332f7b74513a24c87051fa8334e7b461074 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 26 May 2025 08:18:40 -0400 Subject: [PATCH 18/87] chore: update Makefile.am configurations --- Makefile.am | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Makefile.am b/Makefile.am index ba3d16626..cffcb9f6f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,6 +4,10 @@ AUTOMAKE_OPTIONS = foreign subdir-objects ACLOCAL_AMFLAGS = -I m4 +# Alias required by AX_ENABLE_BUILDDIR / config-ml +.PHONY: all-configured +all-configured: all + SUBDIRS = include testsuite man if BUILD_DOCS ## This hack is needed because it doesn't seem possible to make a @@ -14,15 +18,15 @@ if BUILD_DOCS SUBDIRS += doc endif -EXTRA_DIST = LICENSE ChangeLog.old \ - m4/libtool.m4 m4/lt~obsolete.m4 \ - m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ - m4/ltversion.m4 src/debug.c msvcc.sh \ - generate-darwin-source-and-headers.py \ - libffi.xcodeproj/project.pbxproj \ - src/powerpc/t-aix \ - libtool-ldflags libtool-version configure.host README.md \ - libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl +EXTRA_DIST = LICENSE ChangeLog.old \ + m4/libtool.m4 m4/lt~obsolete.m4 \ + m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ + m4/ltversion.m4 src/debug.c msvcc.sh \ + generate-darwin-source-and-headers.py \ + libffi.xcodeproj/project.pbxproj \ + src/powerpc/t-aix \ + libtool-ldflags libtool-version configure.host README.md \ + libffi.map.in LICENSE-BUILDTOOLS msvc_build make_sunver.pl # local.exp is generated by configure DISTCLEANFILES = local.exp @@ -147,7 +151,7 @@ libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src -AM_CCASFLAGS = $(AM_CPPFLAGS) +AM_CCASFLAGS = '$(AM_CPPFLAGS)' dist-hook: d=`(cd $(distdir); pwd)`; (cd doc; make pdf; cp *.pdf $$d/doc) From be4e59e3990142905bb55ffe94950f0f2201cde5 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 26 May 2025 08:19:00 -0400 Subject: [PATCH 19/87] chore: update version to 3.5.0 and libtool version to 10:0:2 --- doc/version.texi | 8 ++++---- libtool-version | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/version.texi b/doc/version.texi index 711d9567a..aaa50629a 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 27 March 2025 -@set UPDATED-MONTH March 2025 -@set EDITION 3.4.8 -@set VERSION 3.4.8 +@set UPDATED 26 May 2025 +@set UPDATED-MONTH May 2025 +@set EDITION 3.5.0 +@set VERSION 3.5.0 diff --git a/libtool-version b/libtool-version index 3b32cb76a..37c2bc903 100644 --- a/libtool-version +++ b/libtool-version @@ -26,4 +26,4 @@ # release, then set age to 0. # # CURRENT:REVISION:AGE -9:4:1 +10:0:2 From 4094362f545cdfe07f65b00c8c0db82b9b96b34b Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 26 May 2025 08:19:15 -0400 Subject: [PATCH 20/87] refactor: enhance assembler pseudo-ops and compiler flag checking --- m4/asmcfi.m4 | 38 ++++++++++++++++++++++++++----------- m4/ax_check_compile_flag.m4 | 16 +++++++++++++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/m4/asmcfi.m4 b/m4/asmcfi.m4 index 3e2860227..bf427a5aa 100644 --- a/m4/asmcfi.m4 +++ b/m4/asmcfi.m4 @@ -1,13 +1,29 @@ +dnl ------------------------------------------------------------------ +dnl Check whether the assembler understands .cfi_* pseudo-ops. +dnl ------------------------------------------------------------------ AC_DEFUN([GCC_AS_CFI_PSEUDO_OP], -[AC_CACHE_CHECK([assembler .cfi pseudo-op support], - gcc_cv_as_cfi_pseudo_op, [ - gcc_cv_as_cfi_pseudo_op=unknown - AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],, - [gcc_cv_as_cfi_pseudo_op=yes], - [gcc_cv_as_cfi_pseudo_op=no]) - ]) - if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then - AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1, - [Define if your assembler supports .cfi_* directives.]) - fi +[ + AC_CACHE_CHECK([assembler .cfi pseudo-op support], + [gcc_cv_as_cfi_pseudo_op], + [ AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ + int foo (void) + { + __asm__ ( + ".cfi_sections\n\t" + ".cfi_startproc\n\t" + ".cfi_endproc"); + return 0; + } + ]])], + [gcc_cv_as_cfi_pseudo_op=yes], + [gcc_cv_as_cfi_pseudo_op=no]) + AC_LANG_POP([C]) + ]) + + if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then + AC_DEFINE([HAVE_AS_CFI_PSEUDO_OP], [1], + [Define if your assembler supports .cfi_* directives.]) + fi ]) diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 index bd753b34d..54191c553 100644 --- a/m4/ax_check_compile_flag.m4 +++ b/m4/ax_check_compile_flag.m4 @@ -34,14 +34,24 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 6 +#serial 11 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ +AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + if test x"m4_case(_AC_LANG, + [C], [$GCC], + [C++], [$GXX], + [Fortran], [$GFC], + [Fortran 77], [$G77], + [Objective C], [$GOBJC], + [Objective C++], [$GOBJCXX], + [no])" = xyes ; then + add_gnu_werror="-Werror" + fi + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 $add_gnu_werror" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) From 9ee7341dbaec04d8c79685fb55703fc9453d0e55 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 26 May 2025 08:19:32 -0400 Subject: [PATCH 21/87] feat(README): add details for next version release in history section --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 2da805b93..c04a1b871 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,12 @@ History See the git log for details at http://github.com/libffi/libffi. + Next Version TBD + Add FFI_VERSION_STRING and FFI_VERSION_NUMBER macros, as well + as ffi_get_version() and ffi_get_version_number() functions. + Fix closures on powerpc64-linux when statically linking. + Mark the PA stack as non-executable. + 3.4.8 Apr-9-2025 Add static trampoline support for powerpc-linux (32-bit SYSV BE), powerpc64-linux (64-bit ELFv1 BE) and From dcc9e93b8ab1990ae0b598d083e19b6c47eb89cc Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 28 May 2025 14:32:02 -0400 Subject: [PATCH 22/87] Add Issue labeler Action --- .github/workflows/label-new-issue.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/label-new-issue.yaml diff --git a/.github/workflows/label-new-issue.yaml b/.github/workflows/label-new-issue.yaml new file mode 100644 index 000000000..9a73973f0 --- /dev/null +++ b/.github/workflows/label-new-issue.yaml @@ -0,0 +1,15 @@ +on: + issues: + types: [opened] + +jobs: + label_issue_job: + permissions: write-all + runs-on: ubuntu-latest + name: Label new issue + steps: + - id: label-new-issue + uses: atgreen/gail-issue-labeler-action@master + with: + llm_api_key: ${{ secrets.OPENAI_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} From 022929b1fc06082389862816f08308f222de9389 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:30:51 +0200 Subject: [PATCH 23/87] doc now shows the correct calculation for version number (#911) --- doc/libffi.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/libffi.texi b/doc/libffi.texi index 1ae2e24a9..6111d2c60 100644 --- a/doc/libffi.texi +++ b/doc/libffi.texi @@ -245,7 +245,7 @@ available at build time as the macro @code{FFI_VERSION_STRING}. @findex ffi_get_version_number @defun {unsigned long} ffi_get_version_number (void) Returns the library version as an unsigned long value where -version ``x.y.z'' is represented as the number x*y*z. +version ``x.y.z'' is represented as the number x*10000+y*100+z. This number is also available at build time as the macro @code{FFI_VERSION_NUMBER}. @end defun From 854ce7be85da6ab571b2f73390be20f57c5afc9b Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 2 Jun 2025 20:18:46 -0400 Subject: [PATCH 24/87] Make 3.5.0-pre0 release. Build and publish Windows binaries. Clean up testing. (#912) This commit removes many platforms from the testing workflow. They will be added back in future commits. --- .ci/install.sh | 93 +++--- .github/workflows/build.yml | 474 +++++------------------------ configure.ac | 4 +- m4/asmcfi.m4 | 9 +- testsuite/emscripten/build.sh | 7 + testsuite/emscripten/node-tests.sh | 7 + 6 files changed, 148 insertions(+), 446 deletions(-) diff --git a/.ci/install.sh b/.ci/install.sh index 446fed0ab..0bc53b7c3 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -10,69 +10,70 @@ if [[ $RUNNER_OS != 'Linux' ]]; then # Download and extract the rlgl client wget -qO - https://rl.gl/cli/rlgl-darwin-amd64.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; + tar --strip-components=2 -xvzf - ./rlgl/rlgl; else # Download and extract the rlgl client case $HOST in - aarch64-linux-gnu) - wget -qO - https://rl.gl/cli/rlgl-linux-arm.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; - ;; - ppc64le-linux-gnu) - wget -qO - https://rl.gl/cli/rlgl-linux-ppc64le.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; - ;; - s390x-linux-gnu) - wget -qO - https://rl.gl/cli/rlgl-linux-s390x.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; - ;; - *) - wget -qO - https://rl.gl/cli/rlgl-linux-amd64.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; - ;; + aarch64-*linux-gnu) + wget -qO - https://rl.gl/cli/rlgl-linux-arm.tgz | \ + tar --strip-components=2 -xvzf - ./rlgl/rlgl; + ;; + ppc64le-linux-gnu) + wget -qO - https://rl.gl/cli/rlgl-linux-ppc64le.tgz | \ + tar --strip-components=2 -xvzf - ./rlgl/rlgl; + ;; + s390x-linux-gnu) + wget -qO - https://rl.gl/cli/rlgl-linux-s390x.tgz | \ + tar --strip-components=2 -xvzf - ./rlgl/rlgl; + ;; + *) + wget -qO - https://rl.gl/cli/rlgl-linux-amd64.tgz | \ + tar --strip-components=2 -xvzf - ./rlgl/rlgl; + ;; esac sudo apt-get clean # clear the cache sudo apt-get update + sudo apt install libltdl-dev zip set -x - wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.71.tar.gz | tar -xvzf - + wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - mkdir -p ~/i - (cd autoconf-2.71; ./configure --prefix=$HOME/i; make; make install) + (cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) case $HOST in - mips64el-linux-gnu | sparc64-linux-gnu) + mips64el-linux-gnu | sparc64-linux-gnu) ;; - alpha-linux-gnu | arm32v7-linux-gnu | m68k-linux-gnu | sh4-linux-gnu) - sudo apt-get install qemu-user-static - ;; - hppa-linux-gnu ) - sudo apt-get install -y qemu-user-static g++-5-hppa-linux-gnu - ;; - i386-pc-linux-gnu) - sudo apt-get install gcc-multilib g++-multilib; - ;; - moxie-elf) - echo 'deb [trusted=yes] https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list - sudo apt-get clean # clear the cache - sudo apt-get update ## -qq - sudo apt-get update - sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim texinfo sharutils texlive dejagnu - ;; - x86_64-w64-mingw32) - sudo apt-get install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 wine; - ;; - i686-w32-mingw32) - sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 wine; - ;; + alpha-linux-gnu | arm32v7-linux-gnu | m68k-linux-gnu | sh4-linux-gnu) + sudo apt-get install qemu-user-static + ;; + hppa-linux-gnu ) + sudo apt-get install -y qemu-user-static g++-5-hppa-linux-gnu + ;; + i386-pc-linux-gnu) + sudo apt-get install gcc-multilib g++-multilib; + ;; + moxie-elf) + echo 'deb [trusted=yes] https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list + sudo apt-get clean # clear the cache + sudo apt-get update ## -qq + sudo apt-get update + sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim texinfo sharutils texlive dejagnu + ;; + x86_64-w64-mingw32) + sudo apt-get install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 wine; + ;; + i686-w32-mingw32) + sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 wine; + ;; esac case $HOST in - arm32v7-linux-gnu) + arm32v7-linux-gnu) # don't install host tools ;; - *) - sudo apt-get install dejagnu texinfo sharutils - ;; + *) + sudo apt-get install dejagnu texinfo sharutils + ;; esac fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59c3a8425..5e50bd7f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,84 +13,40 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: + build-sim: + name: ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} \ + ${{ matrix.MEVAL }} ${{ matrix.LIBFFI_TEST_OPTIMIZATION }} - build-warp: - name: ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} ${{ matrix.MEVAL }} ${{ matrix.LIBFFI_TEST_OPTIMIZATION }} - runs-on: warp-ubuntu-latest-arm64-2x + runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - include: - - HOST: "aarch64-linux-gnu" + include: + # ---------- existing x86-64 variants ---------- + - runner: ubuntu-latest + HOST: x86_64-pc-linux-gnu + MEVAL: 'export CC=clang CXX=clang' - steps: - - uses: actions/checkout@v3 + - runner: ubuntu-latest + HOST: i386-pc-linux-gnu + MEVAL: 'export CC="gcc -m32" CXX="g++ -m32"' - - env: - MEVAL: ${{ matrix.MEVAL }} - HOST: ${{ matrix.HOST }} - LDFLAGS: ${{ matrix.LDFLAGS }} - RUNTESTFLAGS: ${{ matrix.RUNTESTFLAGS }} - CONFIGURE_OPTIONS: ${{ matrix.CONFIGURE_OPTIONS }} - run: | - if test x"$MEVAL" != x; then eval ${MEVAL}; fi - ./.ci/install.sh - ./.ci/build.sh + - runner: ubuntu-latest + HOST: x86_64-pc-linux-gnu + CONFIGURE_OPTIONS: "--disable-shared" - build-sim: - name: ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} ${{ matrix.MEVAL }} ${{ matrix.LIBFFI_TEST_OPTIMIZATION }} - runs-on: ubuntu-latest + - runner: ubuntu-latest + HOST: x86_64-pc-linux-gnu + CONFIGURE_OPTIONS: "--enable-shared" - strategy: - fail-fast: false - matrix: - include: - - HOST: "x86_64-pc-linux-gnu" - MEVAL: "export CC=clang CXX=clang" - - HOST: "i386-pc-linux-gnu" - MEVAL: 'export CC="gcc -m32" CXX="g++ -m32"' - - HOST: "x86_64-pc-linux-gnu" - CONFIGURE_OPTIONS: "--disable-shared" - - HOST: "x86_64-pc-linux-gnu" - CONFIGURE_OPTIONS: "--enable-shared" - - HOST: "m68k-linux-gnu" - MEVAL: 'export CC="m68k-linux-gnu-gcc-8 -mcpu=547x" CXX="m68k-linux-gnu-g++-8 -mcpu=547x"' - CONFIGURE_OPTIONS: '--disable-shared' - QEMU_LD_PREFIX: '/usr/m68k-linux-gnu' - QEMU_CPU: 'cfv4e' - - HOST: "sh4-linux-gnu" - CONFIGURE_OPTIONS: "--disable-shared" - QEMU_LD_PREFIX: "/usr/sh4-linux-gnu" - QEMU_CPU: 'sh7785' - - HOST: "alpha-linux-gnu" - CONFIGURE_OPTIONS: "--disable-shared" - QEMU_LD_PREFIX: "/usr/alpha-linux-gnu" - QEMU_CPU: 'ev4-alpha-cpu' - - HOST: "arm32v7-linux-gnu" - LIBFFI_TEST_OPTIMIZATION: "-O0" - QEMU_CPU: 'any' - - HOST: "arm32v7-linux-gnu" - LIBFFI_TEST_OPTIMIZATION: "-O2" - QEMU_CPU: 'any' - - HOST: "arm32v7-linux-gnu" - LIBFFI_TEST_OPTIMIZATION: "-O2 -fomit-frame-pointer" - QEMU_CPU: 'any' - - HOST: "powerpc-eabisim" - RUNTESTFLAGS: "--target_board powerpc-eabisim" - - HOST: "or1k-elf" - RUNTESTFLAGS: "--target_board or1k-sim" - - HOST: "m32r-elf" - RUNTESTFLAGS: "--target_board m32r-sim" - - HOST: "bfin-elf" - RUNTESTFLAGS: "--target_board bfin-sim" - - MEVAL: "export PATH=/opt/moxielogic/bin:$PATH CC=moxie-elf-gcc CXX=moxie-elf-g++" - HOST: "moxie-elf" - LDFLAGS: "-Tsim.ld" - RUNTESTFLAGS: "--target_board moxie-sim" + # ---------- new native arm64 build ---------- + - runner: ubuntu-22.04-arm # or ubuntu-24.04-arm + HOST: aarch64-unknown-linux-gnu + MEVAL: 'export CC=clang CXX=clang' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - env: MEVAL: ${{ matrix.MEVAL }} @@ -105,298 +61,6 @@ jobs: ./.ci/install.sh ./.ci/build.sh - build-cfarm: - name: ${{ matrix.CFARM_TRIPLE }} ${{ matrix.CFARM_CC }} - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - CFARM_HOST: cfarm185.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: aarch64-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm185.fsffrance.org - CFARM_PORT: 22 - CFARM_TRIPLE: aarch64-lto-linux-gnu - CFARM_CC: "gcc -flto" - CFARM_CXX: "g++ -flto" - - CFARM_HOST: cfarm400.cfarm.net - CFARM_PORT: 25465 - CFARM_TRIPLE: loongarch64-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm230.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: mips-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm211.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: sparc64-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm211.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: sparc64-linux-gnu - CFARM_CC: "gcc -m32" - CFARM_CXX: "g++ -m32" - - CFARM_HOST: cfarm91.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: riscv64-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm103.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: aarch64-m1-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm112.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: powerpc64le-linux-gnu - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - CFARM_HOST: cfarm111.cfarm.net - CFARM_PORT: 22 - CFARM_TRIPLE: powerpc-ibm-aix7.1.5.0 - CFARM_CC: "gcc" - CFARM_CXX: "g++" - - steps: - - - uses: actions/checkout@v3 - - - name: Run autogen - run: | - wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.71.tar.gz | tar -xvzf - - mkdir -p ~/i - (cd autoconf-2.71; ./configure --prefix=$HOME/i; make; make install) - rm -rf autoconf-2.71 - PATH=$HOME/i/bin:$PATH ./autogen.sh - echo "${{ secrets.CFARM_KEY }}" > /tmp/cfk - chmod go-rw /tmp/cfk - - - name: Generate build dir name - run: | - echo BUILD_DIR=t/$GITHUB_RUN_NUMBER-$RANDOM >> $GITHUB_ENV - - - name: Check for host availability - id: check-host - run: | - set +e - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "mkdir -p ${{ env.BUILD_DIR }}" - if test $? -ne 0; then - echo "Remote host is unavailable." - echo "HOST_OK=NO" >> $GITHUB_OUTPUT - else - echo "Remote host is available." - echo "HOST_OK=YES" >> $GITHUB_OUTPUT - fi - set -e - - - name: Show host availability - run: | - echo ${{ steps.check-host.outputs.HOST_OK }} - - - name: Copy source to remote host - if: ${{ steps.check-host.outputs.HOST_OK == 'YES' }} - run: | - echo ${{ steps.check-host.outputs.HOST_OK }} - scp -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -P ${{ matrix.CFARM_PORT }} -r * ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }}:${{ env.BUILD_DIR }} - - - name: Run configure and make - if: ${{ steps.check-host.outputs.HOST_OK == 'YES' }} - run: | - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "${{ matrix.CFARM_CC }} --version" - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "(cd ${{ env.BUILD_DIR }}; if test -f ~/.profile; then source ~/.profile; fi; CC='${{ matrix.CFARM_CC }}' CXX='${{ matrix.CFARM_CXX }}' ./configure --host=${{ matrix.CFARM_TRIPLE }}) || true; exit 0" - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "(cd ${{ env.BUILD_DIR }}; if test -f ~/.profile; then source ~/.profile; fi; make;) || true; exit 0" - - - name: Run tests - if: ${{ steps.check-host.outputs.HOST_OK == 'YES' }} - run: | - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "(cd ${{ env.BUILD_DIR }}; if test -f ~/.profile; then source ~/.profile; fi; GCC_COLORS= make check & CHECKPID=\$!; while kill -0 \$CHECKPID 2>/dev/null; do echo 'Waiting for tests to finish'; sleep 5; done;)" - - - name: Copy results and clean up - if: ${{ steps.check-host.outputs.HOST_OK == 'YES' }} - run: | - scp -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -P ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }}:${{ env.BUILD_DIR }}/*/testsuite/*.log . - ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3 -i /tmp/cfk -p ${{ matrix.CFARM_PORT }} ${{ secrets.CFARM_USERNAME }}@${{ matrix.CFARM_HOST }} "rm -rf ${{ env.BUILD_DIR }}" - - - name: Install rlgl and run - if: ${{ steps.check-host.outputs.HOST_OK == 'YES' }} - run: | - wget -qO - https://rl.gl/cli/rlgl-linux-amd64.tgz | \ - tar --strip-components=2 -xvzf - ./rlgl/rlgl; - ./rlgl l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl - ./rlgl e -l project=libffi -l sha=${GITHUB_SHA:0:7} -l CC='${{ matrix.CFARM_CC }}' -l build-host=${{ matrix.CFARM_TRIPLE }} --policy=https://github.com/libffi/rlgl-policy.git libffi.log - exit $? - - build: - name: Cygwin ${{ matrix.arch }} - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - include: - - host: i686-pc-cygwin - arch: x86 - - host: x86_64-pc-cygwin - arch: x64 - - steps: - - run: git config --global core.autocrlf input - - - uses: actions/checkout@v3 - - - name: Set up Cygwin - uses: egor-tensin/setup-cygwin@v3 - with: - platform: ${{ matrix.arch }} - packages: wget gcc-core make dejagnu automake autoconf libtool texinfo dos2unix unzip - - - run: | - set -x - cd $(cygpath $RUNNER_WORKSPACE)/libffi - wget https://rl.gl/cli/rlgl-windows-amd64.zip - unzip rlgl-windows-amd64.zip - autoreconf -f -v -i - ./configure - make -j 4 - TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true - ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl - ./rlgl/rlgl.exe e \ - -l project=libffi \ - -l sha=${GITHUB_SHA:0:7} \ - -l CC=gcc \ - -l host=${{ matrix.host }} \ - --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) - shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - - build-msys2: - - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - include: - - MSYSTEM: MINGW32 - MSYS2_ARCH: i686 - - MSYSTEM: MINGW64 - MSYS2_ARCH: x86_64 - name: ${{ matrix.MSYSTEM }} - - steps: - - run: git config --global core.autocrlf input - - uses: actions/checkout@v3 - - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.MSYSTEM }} - update: true - install: >- - base-devel - autoconf-wrapper - autoconf - automake - libtool - make - dejagnu - mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc - mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs - unzip - - - run: | - set -x - cd $(cygpath $RUNNER_WORKSPACE)/libffi - wget https://rl.gl/cli/rlgl-windows-amd64.zip - unzip rlgl-windows-amd64.zip - autoreconf -f -v -i - CC=${{ matrix.MSYS2_ARCH }}-w64-mingw32-gcc CXX=${{ matrix.MSYS2_ARCH }}-w64-mingw32-g++ ./configure - make - TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true - ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl - ./rlgl/rlgl.exe e \ - -l project=libffi \ - -l sha=${GITHUB_SHA:0:7} \ - -l CC=${{ matrix.MSYS2_ARCH }}-w64-mingw32-gcc \ - -l host=x86_64-pc-cygwin \ - --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) - shell: msys2 {0} - - build-msys2-clang: - - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - include: - - MSYSTEM: MINGW32 - MSYS2_ARCH: i686 - - MSYSTEM: MINGW64 - MSYS2_ARCH: x86_64 - name: ${{ matrix.MSYSTEM }} - - steps: - - run: git config --global core.autocrlf input - - uses: actions/checkout@v3 - - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.MSYSTEM }} - update: true - install: >- - base-devel - autoconf-wrapper - autoconf - automake - libtool - make - dejagnu - clang - mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc - mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs - unzip - - - run: | - set -x - cd $(cygpath $RUNNER_WORKSPACE)/libffi - wget https://rl.gl/cli/rlgl-windows-amd64.zip - unzip rlgl-windows-amd64.zip - autoreconf -f -v -i - CC=clang CXX=clang ./configure - make - TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci make check || true - ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl - ./rlgl/rlgl.exe e \ - -l project=libffi \ - -l sha=${GITHUB_SHA:0:7} \ - -l CC=clang \ - -l host=x86_64-pc-cygwin \ - --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) - shell: msys2 {0} - - build-macos: - runs-on: ${{ matrix.platform }} - - strategy: - fail-fast: false - matrix: - platform: [macos-11, macos-12] - compilers: [CC=gcc CXX=g++, CC=clang CXX=clang] - - name: ${{ matrix.platform }} ${{ matrix.compilers }} - - steps: - - run: git config --global core.autocrlf input - - uses: actions/checkout@v3 - - run: ./.ci/install.sh - - run: ${{ matrix.compilers }} ./.ci/build.sh - build-msvc: name: Windows ${{ matrix.width }}-bit Visual C++ runs-on: windows-latest @@ -409,7 +73,7 @@ jobs: width: 32 arch: x86 tools: amd64_x86 - - host: x86_64-pc-cygwin + - host: x86_64-w64-mingw32 width: 64 arch: x64 tools: amd64 @@ -417,23 +81,51 @@ jobs: steps: - run: git config --global core.autocrlf input - uses: actions/checkout@v3 - - uses: egor-tensin/setup-cygwin@v3 + - uses: egor-tensin/setup-cygwin@v4 with: platform: x64 packages: wget make dejagnu automake autoconf libtool texinfo unzip dos2unix - - uses: ilammy/msvc-dev-cmd@v1.12.0 + - uses: ilammy/msvc-dev-cmd@v1.13.0 with: arch: ${{ matrix.tools }} + - name: Read libffi version from configure.ac + id: ver + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + run: | + cd $(cygpath $RUNNER_WORKSPACE)/libffi + # Pull the second bracketed field from the AC_INIT line. + # Example line: AC_INIT([libffi],[3.5.0],[http://…]) + ls -l + grep AC_INIT configure.ac + ver=$(sed -nE 's/^AC_INIT\(\[libffi\],[[:space:]]*\[([^]]+)\].*/\1/p' configure.ac) + [[ -n "$ver" ]] || { echo "Could not parse version!"; exit 1; } + echo "version=$ver" >> "$GITHUB_OUTPUT" + - name: Build and test run: | - # export PATH=$PATH:"/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.16.27023/bin/HostX64/x64" cd $(cygpath $RUNNER_WORKSPACE)/libffi wget https://rl.gl/cli/rlgl-windows-amd64.zip unzip rlgl-windows-amd64.zip autoreconf -f -v -i - ./configure --host=${{ matrix.host }} CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='$(pwd)/.ci/ar-lib lib' NM='dumpbin -symbols' STRIP=':' $DEBUG_ARG $SHARED_ARG || cat */config.log + ./configure \ + --enable-shared \ + --build="${{ matrix.host }}" --host="${{ matrix.host }}" \ + --disable-docs \ + CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ + CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ + LD="link" \ + LDFLAGS="-no-undefined " \ + CPP="cl -nologo -EP" \ + CXXCPP="cl -nologo -EP" \ + CPPFLAGS="-DFFI_BUILDING_DLL" \ + CFLAGS="-DFFI_BUILDING_DLL" \ + AR='$(pwd)/.ci/ar-lib lib' \ + NM='dumpbin -symbols' STRIP=':' \ + $DEBUG_ARG || cat */config.log make + find ./ -type f -name 'libffi*' + ls -l */.libs cp $(find . -name 'libffi-?.dll') ${{ matrix.host }}/testsuite/ TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl @@ -445,35 +137,29 @@ jobs: --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' - build-android: - name: Android ${{ matrix.host }} - runs-on: ubuntu-latest + - name: Create binary distribution + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + run: | + cd $(cygpath $RUNNER_WORKSPACE)/libffi + set -euxo pipefail - strategy: - fail-fast: false - matrix: - host: [armv7a-linux-androideabi, aarch64-linux-android, i686-linux-android, x86_64-linux-android] + pkgdir="libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries" + mkdir -p "$pkgdir" - steps: - - run: git config --global core.autocrlf input - - uses: actions/checkout@v3 - - run: ./.ci/install.sh - - env: - HOST: ${{ matrix.HOST }} - ANDROID_API_LEVEL: 23 - CONFIGURE_OPTIONS: "--disable-shared --disable-multi-os-directory" # fixes warning about unsupported -print-multi-os-directory with clang - run: | - # Relevant documentation: - # https://developer.android.com/ndk/guides/other_build_systems - # https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md - export TOOLCHAIN="${ANDROID_NDK_ROOT}"/toolchains/llvm/prebuilt/linux-x86_64 - export CC="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang - export CXX="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang++ - export LD="${TOOLCHAIN}"/bin/ld.lld - export AR="${TOOLCHAIN}"/bin/llvm-ar - export AS="${CC}" - export RANLIB="${TOOLCHAIN}"/bin/llvm-ranlib - export STRIP="${TOOLCHAIN}"/bin/llvm-strip - export NM="${TOOLCHAIN}"/bin/llvm-nm - export OBJDUMP="${TOOLCHAIN}"/bin/llvm-objdump - ./.ci/build.sh + # Copy libraries, headers, and licence into the *same* directory + cp "${{ matrix.host }}"/.libs/libffi-8.* "$pkgdir/" + cp "${{ matrix.host }}"/include/*.h "$pkgdir/" + cp LICENSE "$pkgdir/" + + - name: Upload artefact + uses: actions/upload-artifact@v4 + with: + name: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries + path: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries + if-no-files-found: error + + - name: Upload to GitHub Release + if: github.ref_type == 'tag' + uses: softprops/action-gh-release@v2 + with: + files: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries.zip diff --git a/configure.ac b/configure.ac index 69ed04360..d1a8c697c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.72]) -AC_INIT([libffi],[3.5.0],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.0-pre0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.0" +FFI_VERSION_STRING="3.5.0-dev" FFI_VERSION_NUMBER=30500 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) diff --git a/m4/asmcfi.m4 b/m4/asmcfi.m4 index bf427a5aa..6be634b44 100644 --- a/m4/asmcfi.m4 +++ b/m4/asmcfi.m4 @@ -8,12 +8,13 @@ AC_DEFUN([GCC_AS_CFI_PSEUDO_OP], [ AC_LANG_PUSH([C]) AC_COMPILE_IFELSE( [AC_LANG_SOURCE([[ + #ifdef _MSC_VER + Nope. + #endif int foo (void) { - __asm__ ( - ".cfi_sections\n\t" - ".cfi_startproc\n\t" - ".cfi_endproc"); + __asm__ (".cfi_remember_state\n\t" + ".cfi_restore_state\n\t"); return 0; } ]])], diff --git a/testsuite/emscripten/build.sh b/testsuite/emscripten/build.sh index 83ece7bcf..0b36df532 100755 --- a/testsuite/emscripten/build.sh +++ b/testsuite/emscripten/build.sh @@ -38,6 +38,13 @@ export EM_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" # Specific variables for cross-compilation export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten +wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - +mkdir -p ~/i +(cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) + +# Special build tools are here... +export PATH=$HOME/i/bin:$PATH + autoreconf -fiv emconfigure ./configure --host=$CHOST --prefix="$TARGET" --enable-static --disable-shared --disable-dependency-tracking \ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs diff --git a/testsuite/emscripten/node-tests.sh b/testsuite/emscripten/node-tests.sh index 016e99c4b..bc4ea601f 100755 --- a/testsuite/emscripten/node-tests.sh +++ b/testsuite/emscripten/node-tests.sh @@ -13,6 +13,13 @@ export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -s # Specific variables for cross-compilation export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten +wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - +mkdir -p ~/i +(cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) + +# Special build tools are here... +export PATH=$HOME/i/bin:$PATH + autoreconf -fiv emconfigure ./configure --prefix="$(pwd)/target" --host=$CHOST --enable-static --disable-shared \ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs || From 55d84b0cb9e2561bfbbb4c8a7d3e731a45543c76 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 2 Jun 2025 20:40:44 -0400 Subject: [PATCH 25/87] docs: update README with new libffi release information --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c04a1b871..45cae743b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.4.8 was released on April 9, 2025. Check the libffi web +libffi-3.5.0-pre0 was released on June 2, 2025. Check the libffi web page for updates: . From 3ee0dc41b681814e3789867d7d4ff31b6fd9ab99 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 2 Jun 2025 20:41:27 -0400 Subject: [PATCH 26/87] chore: update version to 3.5.0-pre0 in version.texi --- doc/version.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/version.texi b/doc/version.texi index aaa50629a..3974ec30e 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ @set UPDATED 26 May 2025 @set UPDATED-MONTH May 2025 -@set EDITION 3.5.0 -@set VERSION 3.5.0 +@set EDITION 3.5.0-pre0 +@set VERSION 3.5.0-pre0 From 2529b40dbd9b5d1c5bff8123dfc7568635f5c900 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 2 Jun 2025 20:42:47 -0400 Subject: [PATCH 27/87] chore: update version to 3.5.0-rc0 in documentation and configuration files --- README.md | 2 +- configure.ac | 2 +- doc/version.texi | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 45cae743b..cc706c3ee 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.5.0-pre0 was released on June 2, 2025. Check the libffi web +libffi-3.5.0-rc0 was released on June 2, 2025. Check the libffi web page for updates: . diff --git a/configure.ac b/configure.ac index d1a8c697c..55adb14b5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.72]) -AC_INIT([libffi],[3.5.0-pre0],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.0-rc0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) FFI_VERSION_STRING="3.5.0-dev" diff --git a/doc/version.texi b/doc/version.texi index 3974ec30e..ba42140af 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ @set UPDATED 26 May 2025 @set UPDATED-MONTH May 2025 -@set EDITION 3.5.0-pre0 -@set VERSION 3.5.0-pre0 +@set EDITION 3.5.0-rc0 +@set VERSION 3.5.0-rc0 From 5ad529fb0dabeec863bec8d6c5f6b3502b45d6c1 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Tue, 3 Jun 2025 19:12:49 -0400 Subject: [PATCH 28/87] Many CI testing fixes and improvements. (#913) --- .ci/build.sh | 69 +-- .github/workflows/build.yml | 61 ++- testsuite/lib/libffi.exp | 514 +++++++++--------- testsuite/libffi.closures/unwindtest.cc | 1 - .../libffi.closures/unwindtest_ffi_call.cc | 1 - 5 files changed, 353 insertions(+), 293 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index b27f49e3d..cd9dca771 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -17,9 +17,14 @@ fi export DOCKER=docker +if ! command -v makeinfo >/dev/null 2>&1; then + CONFIGURE_OPTIONS="--disable-docs ${CONFIGURE_OPTIONS}" +fi + function build_linux() { ./autogen.sh + ./configure ${HOST+--host=$HOST} ${CONFIGURE_OPTIONS} || cat */config.log make make dist @@ -27,7 +32,7 @@ function build_linux() DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci make check RUNTESTFLAGS="-a $RUNTESTFLAGS" ./rlgl l --key=${RLGL_KEY} https://rl.gl - ./rlgl e -l project=libffi -l sha=${GITHUB_SHA:0:7} -l CC='$CC' ${HOST+-l host=$HOST} --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log + ./rlgl e -l project=libffi -l sha=${GITHUB_SHA:0:7} -l CC='${CC}' ${HOST+-l host=$HOST} --policy=https://github.com/libffi/rlgl-policy.git */testsuite/libffi.log exit $? } @@ -62,7 +67,7 @@ function build_cross() function build_ios() { which python -# export PYTHON_BIN=/usr/local/bin/python + # export PYTHON_BIN=/usr/local/bin/python ./generate-darwin-source-and-headers.py --only-ios xcodebuild -showsdks xcodebuild -project libffi.xcodeproj -target "libffi-iOS" -configuration Release -sdk iphoneos11.4 @@ -72,7 +77,7 @@ function build_ios() function build_macosx() { which python -# export PYTHON_BIN=/usr/local/bin/python + # export PYTHON_BIN=/usr/local/bin/python ./generate-darwin-source-and-headers.py --only-osx xcodebuild -showsdks xcodebuild -project libffi.xcodeproj -target "libffi-Mac" -configuration Release -sdk macosx10.13 @@ -82,43 +87,43 @@ function build_macosx() case "$HOST" in arm-apple-darwin*) - ./autogen.sh - build_ios - ;; + ./autogen.sh + build_ios + ;; x86_64-apple-darwin*) - ./autogen.sh - build_macosx - ;; + ./autogen.sh + build_macosx + ;; arm32v7-linux-gnu) - ./autogen.sh + ./autogen.sh build_foreign_linux arm quay.io/moxielogic/arm32v7-ci-build-container:latest - ;; + ;; bfin-elf ) - ./autogen.sh - GCC_OPTIONS=-msim build_cross - ;; + ./autogen.sh + GCC_OPTIONS=-msim build_cross + ;; m32r-elf ) - ./autogen.sh - build_cross - ;; + ./autogen.sh + build_cross + ;; or1k-elf ) - ./autogen.sh - build_cross - ;; + ./autogen.sh + build_cross + ;; powerpc-eabisim ) - ./autogen.sh - build_cross - ;; + ./autogen.sh + build_cross + ;; m68k-linux-gnu ) - ./autogen.sh - GCC_OPTIONS=-mcpu=547x build_cross_linux - ;; + ./autogen.sh + GCC_OPTIONS=-mcpu=547x build_cross_linux + ;; alpha-linux-gnu | sh4-linux-gnu ) - ./autogen.sh - build_cross_linux - ;; + ./autogen.sh + build_cross_linux + ;; *) - ./autogen.sh - build_linux - ;; + ./autogen.sh + build_linux + ;; esac diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e50bd7f1..663d6d903 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,8 +13,8 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - build-sim: - name: ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} \ + build-linux: + name: Linux ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} \ ${{ matrix.MEVAL }} ${{ matrix.LIBFFI_TEST_OPTIMIZATION }} runs-on: ${{ matrix.runner }} @@ -26,7 +26,7 @@ jobs: # ---------- existing x86-64 variants ---------- - runner: ubuntu-latest HOST: x86_64-pc-linux-gnu - MEVAL: 'export CC=clang CXX=clang' + MEVAL: 'export CC=clang CXX=clang++' - runner: ubuntu-latest HOST: i386-pc-linux-gnu @@ -43,7 +43,7 @@ jobs: # ---------- new native arm64 build ---------- - runner: ubuntu-22.04-arm # or ubuntu-24.04-arm HOST: aarch64-unknown-linux-gnu - MEVAL: 'export CC=clang CXX=clang' + MEVAL: 'export CC=clang CXX=clang++' steps: - uses: actions/checkout@v4 @@ -61,6 +61,22 @@ jobs: ./.ci/install.sh ./.ci/build.sh + build-macos: + name: MacOS ${{ matrix.platform }} ${{ matrix.compilers }} + runs-on: ${{ matrix.platform }} + + strategy: + fail-fast: false + matrix: + platform: [macos-13, macos-14, macos-15] + compilers: [CC=gcc CXX=g++, CC=clang CXX=clang++] + + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v4 + - run: ./.ci/install.sh + - run: ${{ matrix.compilers }} ./.ci/build.sh + build-msvc: name: Windows ${{ matrix.width }}-bit Visual C++ runs-on: windows-latest @@ -80,7 +96,7 @@ jobs: steps: - run: git config --global core.autocrlf input - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: egor-tensin/setup-cygwin@v4 with: platform: x64 @@ -163,3 +179,38 @@ jobs: uses: softprops/action-gh-release@v2 with: files: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries.zip + + build-android: + name: Android ${{ matrix.host }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + host: [armv7a-linux-androideabi, aarch64-linux-android, i686-linux-android, x86_64-linux-android] + + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v4 + - run: ./.ci/install.sh + - env: + HOST: ${{ matrix.HOST }} + ANDROID_API_LEVEL: 23 + CONFIGURE_OPTIONS: "--disable-shared --disable-multi-os-directory" # fixes warning about unsupported -print-multi-os-directory with clang + run: | + # Relevant documentation: + # https://developer.android.com/ndk/guides/other_build_systems + # https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md + export TOOLCHAIN="${ANDROID_NDK_ROOT}"/toolchains/llvm/prebuilt/linux-x86_64 + export CC="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang + export CXX="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang++ + export CC_FOR_TARGET="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang + export CXX_FOR_TARGET="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang++ + export LD="${TOOLCHAIN}"/bin/ld.lld + export AR="${TOOLCHAIN}"/bin/llvm-ar + export AS="${CC}" + export RANLIB="${TOOLCHAIN}"/bin/llvm-ranlib + export STRIP="${TOOLCHAIN}"/bin/llvm-strip + export NM="${TOOLCHAIN}"/bin/llvm-nm + export OBJDUMP="${TOOLCHAIN}"/bin/llvm-objdump + ./.ci/build.sh diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp index b5731dbc9..c542912bf 100644 --- a/testsuite/lib/libffi.exp +++ b/testsuite/lib/libffi.exp @@ -1,4 +1,4 @@ -# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014, 2019, 2022 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014, 2019, 2022, 2025 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -38,14 +38,14 @@ proc is-effective-target { arg } { global et_index set selected 0 if { ![info exists et_index] } { - # Initialize the effective target index that is used in some - # check_effective_target_* procs. - set et_index 0 + # Initialize the effective target index that is used in some + # check_effective_target_* procs. + set et_index 0 } if { [info procs check_effective_target_${arg}] != [list] } { - set selected [check_effective_target_${arg}] + set selected [check_effective_target_${arg}] } else { - error "unknown effective target keyword `$arg'" + error "unknown effective target keyword `$arg'" } verbose "is-effective-target: $arg $selected" 2 return $selected @@ -53,9 +53,9 @@ proc is-effective-target { arg } { proc is-effective-target-keyword { arg } { if { [info procs check_effective_target_${arg}] != [list] } { - return 1 + return 1 } else { - return 0 + return 0 } } @@ -87,93 +87,93 @@ if { [info procs saved-dg-process-target] == [list] } { # Evaluate an operand within a selector expression. proc selector_opd { op } { - set selector "target" - lappend selector $op - set answer [ expr { [dg-process-target $selector] == "S" } ] - verbose "selector_opd: `$op' $answer" 2 - return $answer + set selector "target" + lappend selector $op + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_opd: `$op' $answer" 2 + return $answer } # Evaluate a target triplet list within a selector expression. # Unlike other operands, this needs to be expanded from a list to # the same string as "target". proc selector_list { op } { - set selector "target [join $op]" - set answer [ expr { [dg-process-target $selector] == "S" } ] - verbose "selector_list: `$op' $answer" 2 - return $answer + set selector "target [join $op]" + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_list: `$op' $answer" 2 + return $answer } # Evaluate a selector expression. proc selector_expression { exp } { - if { [llength $exp] == 2 } { - if [string match "!" [lindex $exp 0]] { - set op1 [lindex $exp 1] - set answer [expr { ! [selector_opd $op1] }] - } else { - # Assume it's a list of target triplets. - set answer [selector_list $exp] - } - } elseif { [llength $exp] == 3 } { - set op1 [lindex $exp 0] - set opr [lindex $exp 1] - set op2 [lindex $exp 2] - if [string match "&&" $opr] { - set answer [expr { [selector_opd $op1] && [selector_opd $op2] }] - } elseif [string match "||" $opr] { - set answer [expr { [selector_opd $op1] || [selector_opd $op2] }] - } else { - # Assume it's a list of target triplets. - set answer [selector_list $exp] - } - } else { - # Assume it's a list of target triplets. - set answer [selector_list $exp] - } - - verbose "selector_expression: `$exp' $answer" 2 - return $answer + if { [llength $exp] == 2 } { + if [string match "!" [lindex $exp 0]] { + set op1 [lindex $exp 1] + set answer [expr { ! [selector_opd $op1] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } elseif { [llength $exp] == 3 } { + set op1 [lindex $exp 0] + set opr [lindex $exp 1] + set op2 [lindex $exp 2] + if [string match "&&" $opr] { + set answer [expr { [selector_opd $op1] && [selector_opd $op2] }] + } elseif [string match "||" $opr] { + set answer [expr { [selector_opd $op1] || [selector_opd $op2] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + + verbose "selector_expression: `$exp' $answer" 2 + return $answer } # Evaluate "target selector" or "xfail selector". proc dg-process-target-1 { args } { - verbose "dg-process-target-1: `$args'" 2 - - # Extract the 'what' keyword from the argument list. - set selector [string trim [lindex $args 0]] - if [regexp "^xfail " $selector] { - set what "xfail" - } elseif [regexp "^target " $selector] { - set what "target" - } else { - error "syntax error in target selector \"$selector\"" - } - - # Extract the rest of the list, which might be a keyword. - regsub "^${what}" $selector "" rest - set rest [string trim $rest] - - if [is-effective-target-keyword $rest] { - # The selector is an effective target keyword. - if [is-effective-target $rest] { - return [expr { $what == "xfail" ? "F" : "S" }] - } else { - return [expr { $what == "xfail" ? "P" : "N" }] - } - } - - if [string match "{*}" $rest] { - if [selector_expression [lindex $rest 0]] { - return [expr { $what == "xfail" ? "F" : "S" }] - } else { - return [expr { $what == "xfail" ? "P" : "N" }] - } - } - - # The selector is not an effective-target keyword, so process - # the list of target triplets. - return [saved-dg-process-target $selector] + verbose "dg-process-target-1: `$args'" 2 + + # Extract the 'what' keyword from the argument list. + set selector [string trim [lindex $args 0]] + if [regexp "^xfail " $selector] { + set what "xfail" + } elseif [regexp "^target " $selector] { + set what "target" + } else { + error "syntax error in target selector \"$selector\"" + } + + # Extract the rest of the list, which might be a keyword. + regsub "^${what}" $selector "" rest + set rest [string trim $rest] + + if [is-effective-target-keyword $rest] { + # The selector is an effective target keyword. + if [is-effective-target $rest] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + if [string match "{*}" $rest] { + if [selector_expression [lindex $rest 0]] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + # The selector is not an effective-target keyword, so process + # the list of target triplets. + return [saved-dg-process-target $selector] } # Intercept calls to the DejaGnu function. In addition to @@ -181,24 +181,24 @@ if { [info procs saved-dg-process-target] == [list] } { # "target selector1 xfail selector2". proc dg-process-target { args } { - verbose "replacement dg-process-target: `$args'" 2 - - set selector [string trim [lindex $args 0]] - - # If the argument list contains both 'target' and 'xfail', - # process 'target' and, if that succeeds, process 'xfail'. - if [regexp "^target .* xfail .*" $selector] { - set xfail_index [string first "xfail" $selector] - set xfail_selector [string range $selector $xfail_index end] - set target_selector [string range $selector 0 [expr $xfail_index-1]] - set target_selector [string trim $target_selector] - if { [dg-process-target-1 $target_selector] == "N" } { - return "N" - } - return [dg-process-target-1 $xfail_selector] + verbose "replacement dg-process-target: `$args'" 2 + + set selector [string trim [lindex $args 0]] + + # If the argument list contains both 'target' and 'xfail', + # process 'target' and, if that succeeds, process 'xfail'. + if [regexp "^target .* xfail .*" $selector] { + set xfail_index [string first "xfail" $selector] + set xfail_selector [string range $selector $xfail_index end] + set target_selector [string range $selector 0 [expr $xfail_index-1]] + set target_selector [string trim $target_selector] + if { [dg-process-target-1 $target_selector] == "N" } { + return "N" + } + return [dg-process-target-1 $xfail_selector] - } - return [dg-process-target-1 $selector] + } + return [dg-process-target-1 $selector] } } @@ -217,8 +217,8 @@ proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } { upvar 2 dg-output-text output_match if { [llength $output_match] > 1 } { - regsub -all "\n" [lindex $output_match 1] "\r?\n" x - set output_match [lreplace $output_match 1 1 $x] + regsub -all "\n" [lindex $output_match 1] "\r?\n" x + set output_match [lreplace $output_match 1 1 $x] } if { [ istarget "wasm32-*-*" ] } { @@ -232,34 +232,34 @@ proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } { set options [list] switch $do_what { - "compile" { - set compile_type "assembly" - set output_file "[file rootname [file tail $prog]].s" - } - "link" { - set compile_type "executable" - set output_file "[file rootname [file tail $prog]]$exec_suffix" - # The following line is needed for targets like the i960 where - # the default output file is b.out. Sigh. - } - "run" { - set compile_type "executable" - # FIXME: "./" is to cope with "." not being in $PATH. - # Should this be handled elsewhere? - # YES. - set output_file "./[file rootname [file tail $prog]]$exec_suffix" - # This is the only place where we care if an executable was - # created or not. If it was, dg.exp will try to run it. - remote_file build delete $output_file; - } - default { - perror "$do_what: not a valid dg-do keyword" - return "" - } + "compile" { + set compile_type "assembly" + set output_file "[file rootname [file tail $prog]].s" + } + "link" { + set compile_type "executable" + set output_file "[file rootname [file tail $prog]]$exec_suffix" + # The following line is needed for targets like the i960 where + # the default output file is b.out. Sigh. + } + "run" { + set compile_type "executable" + # FIXME: "./" is to cope with "." not being in $PATH. + # Should this be handled elsewhere? + # YES. + set output_file "./[file rootname [file tail $prog]]$exec_suffix" + # This is the only place where we care if an executable was + # created or not. If it was, dg.exp will try to run it. + remote_file build delete $output_file; + } + default { + perror "$do_what: not a valid dg-do keyword" + return "" + } } if { $extra_tool_flags != "" } { - lappend options "additional_flags=$extra_tool_flags" + lappend options "additional_flags=$extra_tool_flags" } set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options]; @@ -297,7 +297,7 @@ proc libffi-init { args } { global compiler_vendor if ![info exists blddirffi] { - set blddirffi [pwd]/.. + set blddirffi [pwd]/.. } verbose "libffi $blddirffi" @@ -306,7 +306,7 @@ proc libffi-init { args } { if { [string match $compiler_vendor "gnu"] } { set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] if {$gccdir != ""} { - set gccdir [file dirname $gccdir] + set gccdir [file dirname $gccdir] } verbose "gccdir $gccdir" @@ -315,17 +315,17 @@ proc libffi-init { args } { set compiler "${gccdir}/xgcc" if { [is_remote host] == 0 && [which $compiler] != 0 } { - foreach i "[exec $compiler --print-multi-lib]" { - set mldir "" - regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir - set mldir [string trimright $mldir "\;@"] - if { "$mldir" == "." } { - continue - } - if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { - append ld_library_path ":${gccdir}/${mldir}" - } - } + foreach i "[exec $compiler --print-multi-lib]" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "." } { + continue + } + if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { + append ld_library_path ":${gccdir}/${mldir}" + } + } } } @@ -341,8 +341,8 @@ proc libffi-init { args } { set libffi_dir "${blddirffi}/.libs" verbose "libffi_dir $libffi_dir" if { $libffi_dir != "" } { - set libffi_dir [file dirname ${libffi_dir}] - set libffi_link_flags "-L${libffi_dir}/.libs" + set libffi_dir [file dirname ${libffi_dir}] + set libffi_link_flags "-L${libffi_dir}/.libs" } set_ld_library_path_env_vars @@ -353,8 +353,8 @@ proc libffi_exit { } { global gluefile; if [info exists gluefile] { - file_on_build delete $gluefile; - unset gluefile; + file_on_build delete $gluefile; + unset gluefile; } } @@ -369,54 +369,59 @@ proc libffi_target_compile { source dest type options } { global compiler_vendor if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { - lappend options "libs=${gluefile}" - lappend options "ldflags=$wrap_flags" + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" } # TOOL_OPTIONS must come first, so that it doesn't override testcase # specific options. if [info exists TOOL_OPTIONS] { - lappend options "additional_flags=$TOOL_OPTIONS" + lappend options "additional_flags=$TOOL_OPTIONS" } # search for ffi_mips.h in srcdir, too lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.." - lappend options "additional_flags=${libffi_link_flags}" - - # Darwin needs a stack execution allowed flag. + if { [string match $type "executable"] } { - if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] - || [istarget "*-*-darwin2*"] } { - # lappend options "additional_flags=-Wl,-allow_stack_execute" - lappend options "additional_flags=-Wno-unused-command-line-argument" - lappend options "additional_flags=-Wl,-search_paths_first" - } + lappend options "additional_flags=${libffi_link_flags}" - # If you're building the compiler with --prefix set to a place - # where it's not yet installed, then the linker won't be able to - # find the libgcc used by libffi.dylib. We could pass the - # -dylib_file option, but that's complicated, and it's much easier - # to just make the linker find libgcc using -L options. - if { [string match "*-*-darwin*" $target_triplet] } { - lappend options "libs= -shared-libgcc" - } + # Darwin needs a stack execution allowed flag. + if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] + || [istarget "*-*-darwin2*"] } { + # lappend options "additional_flags=-Wl,-allow_stack_execute" + lappend options "additional_flags=-Wno-unused-command-line-argument" + lappend options "additional_flags=-Wl,-search_paths_first" + } - if { [string match "*-*-openbsd*" $target_triplet] } { - lappend options "libs= -lpthread" - } + # If you're building the compiler with --prefix set to a place + # where it's not yet installed, then the linker won't be able to + # find the libgcc used by libffi.dylib. We could pass the + # -dylib_file option, but that's complicated, and it's much easier + # to just make the linker find libgcc using -L options. + if { [string match "*-*-darwin*" $target_triplet] } { + lappend options "libs= -shared-libgcc" + } - lappend options "libs= -lffi" + if { [string match "*-*-openbsd*" $target_triplet] } { + lappend options "libs= -lpthread" + } - if { ![string match "*android*" $target_triplet] } { + lappend options "libs= -lffi" if { [string match "aarch64*-*-linux*" $target_triplet] } { - lappend options "libs= -lpthread" + if { ! [string match "*android*" $target_triplet] } { + lappend options "libs= -lpthread" + } } # this may be required for g++, but just confused clang. if { [string match "*.cc" $source] } { lappend options "c++" if { [string match "*-*-darwin*" $target_triplet] } { + if { [string match $compiler_vendor "gnu"] } { + lappend options "libs= -lc++" + } + } elseif { [string match "*android*" $target_triplet] } { lappend options "libs= -lc++" } } @@ -447,9 +452,10 @@ proc libffi_feature_test { test } { puts $f "#else" puts $f "# error Failed $test" puts $f "#endif" + puts $f "int main() {return 0;}" close $f - set lines [libffi_target_compile $src /dev/null assembly ""] + set lines [libffi_target_compile $src /dev/null assemble ""] file delete $src return [string match "" $lines] @@ -463,10 +469,10 @@ proc libffi_feature_test { test } { proc search_for { file pattern } { set fd [open $file r] while { [gets $fd cur_line]>=0 } { - if [string match "*$pattern*" $cur_line] then { - close $fd - return 1 - } + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } } close $fd return 0 @@ -478,27 +484,27 @@ proc libffi-dg-runtest { testcases default-extra-flags } { global runtests foreach test $testcases { - # If we're only testing specific files and this isn't one of - # them, skip it. - if ![runtest_file_p $runtests $test] { - continue - } - - # Look for a loop within the source code - if we don't find one, - # don't pass -funroll[-all]-loops. - global torture_with_loops torture_without_loops - if [expr [search_for $test "for*("]+[search_for $test "while*("]] { - set option_list $torture_with_loops - } else { - set option_list $torture_without_loops - } - - set nshort [file tail [file dirname $test]]/[file tail $test] - - foreach flags $option_list { - verbose "Testing $nshort, $flags" 1 - dg-test $test $flags ${default-extra-flags} - } + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags $option_list { + verbose "Testing $nshort, $flags" 1 + dg-test $test $flags ${default-extra-flags} + } } } @@ -507,31 +513,31 @@ proc run-many-tests { testcases extra_flags } { global has_gccbug global env switch $compiler_vendor { - "clang" { - set common "-W -Wall" - if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { - set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] - } else { - set optimizations { "-O0" "-O2" } + "clang" { + set common "-W -Wall" + if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { + set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] + } else { + set optimizations { "-O0" "-O2" } + } } - } - "gnu" { - set common "-W -Wall -Wno-psabi" - if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { - set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] - } else { - set optimizations { "-O0" "-O2" } + "gnu" { + set common "-W -Wall -Wno-psabi" + if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { + set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] + } else { + set optimizations { "-O0" "-O2" } + } } - } - default { - # Assume we are using the vendor compiler. - set common "" - if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { - set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] - } else { - set optimizations { "" } + default { + # Assume we are using the vendor compiler. + set common "" + if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { + set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] + } else { + set optimizations { "" } + } } - } } info exists env(LD_LIBRARY_PATH) @@ -546,7 +552,7 @@ proc run-many-tests { testcases extra_flags } { "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" } } elseif { [istarget "x86_64-*-*"] \ - && [libffi_feature_test "#if !defined __ILP32__ \ + && [libffi_feature_test "#if !defined __ILP32__ \ && !defined __i386__"] } { set targetabis { "" @@ -566,22 +572,22 @@ proc run-many-tests { testcases extra_flags } { foreach opt $optimizations { foreach abi $abis { set options [concat $common $opt $abi] - set has_gccbug false; - if { [string match $compiler_vendor "gnu"] \ - && [string match "*MSABI*" $abi] \ - && ( ( [string match "*DGTEST=57 *" $common] \ - && [string match "*call.c*" $testname] ) \ - || ( [string match "*DGTEST=54 *" $common] \ - && [string match "*callback*" $testname] ) \ - || [string match "*DGTEST=55 *" $common] \ - || [string match "*DGTEST=56 *" $common] ) } then { - if [libffi_feature_test "#if (__GNUC__ < 9) || ((__GNUC__ == 9) && (__GNUC_MINOR__ < 3))"] { - set has_gccbug true; - } - } - verbose "Testing $testname, $options" 1 - verbose "has_gccbug = $has_gccbug" 1 - dg-test $test $options "" + set has_gccbug false; + if { [string match $compiler_vendor "gnu"] \ + && [string match "*MSABI*" $abi] \ + && ( ( [string match "*DGTEST=57 *" $common] \ + && [string match "*call.c*" $testname] ) \ + || ( [string match "*DGTEST=54 *" $common] \ + && [string match "*callback*" $testname] ) \ + || [string match "*DGTEST=55 *" $common] \ + || [string match "*DGTEST=56 *" $common] ) } then { + if [libffi_feature_test "#if (__GNUC__ < 9) || ((__GNUC__ == 9) && (__GNUC_MINOR__ < 3))"] { + set has_gccbug true; + } + } + verbose "Testing $testname, $options" 1 + verbose "has_gccbug = $has_gccbug" 1 + dg-test $test $options "" } } } @@ -593,8 +599,8 @@ proc dg-xfail-if { args } { set args [lreplace $args 0 0] set selector "target [join [lindex $args 1]]" if { [dg-process-target $selector] == "S" } { - global compiler_conditional_xfail_data - set compiler_conditional_xfail_data $args + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data $args } } @@ -606,22 +612,22 @@ proc check-flags { args } { # The next two arguments are optional. If they were not specified, # use the defaults. if { [llength $args] == 2 } { - lappend $args [list "*"] + lappend $args [list "*"] } if { [llength $args] == 3 } { - lappend $args [list ""] + lappend $args [list ""] } # If the option strings are the defaults, or the same as the # defaults, there is no need to call check_conditional_xfail to # compare them to the actual options. if { [string compare [lindex $args 2] "*"] == 0 - && [string compare [lindex $args 3] "" ] == 0 } { - set result 1 + && [string compare [lindex $args 3] "" ] == 0 } { + set result 1 } else { - # The target list might be an effective-target keyword, so replace - # the original list with "*-*-*", since we already know it matches. - set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] + # The target list might be an effective-target keyword, so replace + # the original list with "*-*-*", since we already know it matches. + set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] } return $result @@ -637,7 +643,7 @@ proc dg-skip-if { args } { # Don't bother if we're already skipping the test. upvar dg-do-what dg-do-what if { [lindex ${dg-do-what} 1] == "N" } { - return + return } set selector [list target [lindex $args 1]] @@ -662,18 +668,18 @@ if { [info procs saved-dg-test] == [list] } { rename dg-test saved-dg-test proc dg-test { args } { - global additional_files - global additional_sources - global errorInfo - - if { [ catch { eval saved-dg-test $args } errmsg ] } { - set saved_info $errorInfo - set additional_files "" - set additional_sources "" - error $errmsg $saved_info - } - set additional_files "" - set additional_sources "" + global additional_files + global additional_sources + global errorInfo + + if { [ catch { eval saved-dg-test $args } errmsg ] } { + set saved_info $errorInfo + set additional_files "" + set additional_sources "" + error $errmsg $saved_info + } + set additional_files "" + set additional_sources "" } } diff --git a/testsuite/libffi.closures/unwindtest.cc b/testsuite/libffi.closures/unwindtest.cc index b643c48e4..6c97c61e8 100644 --- a/testsuite/libffi.closures/unwindtest.cc +++ b/testsuite/libffi.closures/unwindtest.cc @@ -48,7 +48,6 @@ typedef int (*closure_test_type1)(float, float, float, float, signed short, float, float, int, double, int, int, float, int, int, int, int); -extern "C" int main (void) { ffi_cif cif; diff --git a/testsuite/libffi.closures/unwindtest_ffi_call.cc b/testsuite/libffi.closures/unwindtest_ffi_call.cc index 6feaa5752..153d24094 100644 --- a/testsuite/libffi.closures/unwindtest_ffi_call.cc +++ b/testsuite/libffi.closures/unwindtest_ffi_call.cc @@ -14,7 +14,6 @@ static int checking(int a __UNUSED__, short b __UNUSED__, throw 9; } -extern "C" int main (void) { ffi_cif cif; From 2d8868ace7419b377587adf6b63fb276411931dd Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 4 Jun 2025 07:04:53 -0400 Subject: [PATCH 29/87] Update generate-darwin-source-and-headers.py (#914) --- generate-darwin-source-and-headers.py | 29 +-------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/generate-darwin-source-and-headers.py b/generate-darwin-source-and-headers.py index c801dc065..f6e915284 100755 --- a/generate-darwin-source-and-headers.py +++ b/generate-darwin-source-and-headers.py @@ -11,15 +11,6 @@ class Platform(object): pass -class i386_platform(Platform): - arch = 'i386' - - prefix = "#ifdef __i386__\n\n" - suffix = "\n\n#endif" - src_dir = 'x86' - src_files = ['sysv.S', 'ffi.c', 'internal.h'] - - class x86_64_platform(Platform): arch = 'x86_64' @@ -47,13 +38,6 @@ class armv7_platform(Platform): src_files = ['sysv.S', 'ffi.c', 'internal.h'] -class ios_simulator_i386_platform(i386_platform): - target = 'i386-apple-ios-simulator' - directory = 'darwin_ios' - sdk = 'iphonesimulator' - version_min = '-miphoneos-version-min=7.0' - - class ios_simulator_x86_64_platform(x86_64_platform): target = 'x86_64-apple-ios-simulator' directory = 'darwin_ios' @@ -117,13 +101,6 @@ class tvos_device_arm64_platform(arm64_platform): version_min = '-mtvos-version-min=9.0' -class watchos_simulator_i386_platform(i386_platform): - target = 'i386-apple-watchos-simulator' - directory = 'darwin_watchos' - sdk = 'watchsimulator' - version_min = '-mwatchos-version-min=4.0' - - class watchos_simulator_x86_64_platform(x86_64_platform): target = 'x86_64-apple-watchos-simulator' directory = 'darwin_watchos' @@ -210,7 +187,7 @@ def xcrun_cmd(cmd): mkdir_p(build_dir) env = dict(CC=xcrun_cmd('clang'), LD=xcrun_cmd('ld'), - CFLAGS='%s -fembed-bitcode' % (platform.version_min)) + CFLAGS='%s' % (platform.version_min)) working_dir = os.getcwd() try: os.chdir(build_dir) @@ -248,7 +225,6 @@ def generate_source_and_headers( copy_files('include', 'darwin_common/include', pattern='*.h') if generate_ios: - copy_src_platform_files(ios_simulator_i386_platform) copy_src_platform_files(ios_simulator_x86_64_platform) copy_src_platform_files(ios_simulator_arm64_platform) copy_src_platform_files(ios_device_armv7_platform) @@ -261,7 +237,6 @@ def generate_source_and_headers( copy_src_platform_files(tvos_simulator_arm64_platform) copy_src_platform_files(tvos_device_arm64_platform) if generate_watchos: - copy_src_platform_files(watchos_simulator_i386_platform) copy_src_platform_files(watchos_simulator_x86_64_platform) copy_src_platform_files(watchos_simulator_arm64_platform) copy_src_platform_files(watchos_device_armv7k_platform) @@ -270,7 +245,6 @@ def generate_source_and_headers( platform_headers = collections.defaultdict(set) if generate_ios: - build_target(ios_simulator_i386_platform, platform_headers) build_target(ios_simulator_x86_64_platform, platform_headers) build_target(ios_simulator_arm64_platform, platform_headers) build_target(ios_device_armv7_platform, platform_headers) @@ -283,7 +257,6 @@ def generate_source_and_headers( build_target(tvos_simulator_arm64_platform, platform_headers) build_target(tvos_device_arm64_platform, platform_headers) if generate_watchos: - build_target(watchos_simulator_i386_platform, platform_headers) build_target(watchos_simulator_x86_64_platform, platform_headers) build_target(watchos_simulator_arm64_platform, platform_headers) build_target(watchos_device_armv7k_platform, platform_headers) From d38abaf9db7cb4f9ddd8a18083f0d1f86a8c3312 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 4 Jun 2025 07:57:21 -0400 Subject: [PATCH 30/87] feat(testsuite): add Emscripten support to libffi.closures tests --- testsuite/libffi.closures/unwindtest.cc | 3 +++ testsuite/libffi.closures/unwindtest_ffi_call.cc | 3 +++ 2 files changed, 6 insertions(+) diff --git a/testsuite/libffi.closures/unwindtest.cc b/testsuite/libffi.closures/unwindtest.cc index 6c97c61e8..634fb716b 100644 --- a/testsuite/libffi.closures/unwindtest.cc +++ b/testsuite/libffi.closures/unwindtest.cc @@ -48,6 +48,9 @@ typedef int (*closure_test_type1)(float, float, float, float, signed short, float, float, int, double, int, int, float, int, int, int, int); +#ifdef __EMSCRIPTEN__ +extern "C" +#endif int main (void) { ffi_cif cif; diff --git a/testsuite/libffi.closures/unwindtest_ffi_call.cc b/testsuite/libffi.closures/unwindtest_ffi_call.cc index 153d24094..1b86cc071 100644 --- a/testsuite/libffi.closures/unwindtest_ffi_call.cc +++ b/testsuite/libffi.closures/unwindtest_ffi_call.cc @@ -14,6 +14,9 @@ static int checking(int a __UNUSED__, short b __UNUSED__, throw 9; } +#ifdef __EMSCRIPTEN__ +extern "C" +#endif int main (void) { ffi_cif cif; From d6b1f3423278f52cf01f4ddc24b432a0875fbb00 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 4 Jun 2025 11:24:11 -0400 Subject: [PATCH 31/87] refactor: move and modify unix-noexec.exp and site.exp files --- .appveyor.yml | 84 ------------------------------ .appveyor/site.exp | 16 ------ .ci/site.exp | 6 +++ {.appveyor => .ci}/unix-noexec.exp | 0 4 files changed, 6 insertions(+), 100 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .appveyor/site.exp rename {.appveyor => .ci}/unix-noexec.exp (100%) diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 48fbb4df2..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,84 +0,0 @@ -shallow_clone: true - -# We're currently only testing libffi built with Microsoft's -# tools. -# This matrix should be expanded to include at least: -# 32- and 64-bit gcc/cygwin -# 32- and 64-bit gcc/mingw -# 32- and 64-bit clang/mingw -# and perhaps more. - -image: Visual Studio 2017 -platform: - - x64 - - x86 - - arm - - arm64 - -configuration: - - Debug - - Release - -environment: - global: - CYG_ROOT: C:/cygwin64 - CYG_CACHE: C:/cygwin64/var/cache/setup - CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/ - VSVER: 15 - matrix: - - SHARED_ARG: "--enable-shared --disable-static" - - SHARED_ARG: "--enable-static --disable-shared" - -install: - - ps: >- - If ($env:Platform -Match "x86") { - $env:VCVARS_PLATFORM="x86" - $env:BUILD="i686-pc-cygwin" - $env:HOST="i686-pc-cygwin" - $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh" - $env:SRC_ARCHITECTURE="x86" - } ElseIf ($env:Platform -Match "arm64") { - $env:VCVARS_PLATFORM="x86_arm64" - $env:BUILD="i686-pc-cygwin" - $env:HOST="aarch64-w64-cygwin" - $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm64" - $env:SRC_ARCHITECTURE="aarch64" - } ElseIf ($env:Platform -Match "arm") { - $env:VCVARS_PLATFORM="x86_arm" - $env:BUILD="i686-pc-cygwin" - $env:HOST="arm-w32-cygwin" - $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm" - $env:SRC_ARCHITECTURE="arm" - } Else { - $env:VCVARS_PLATFORM="amd64" - $env:BUILD="x86_64-w64-cygwin" - $env:HOST="x86_64-w64-cygwin" - $env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -m64" - $env:SRC_ARCHITECTURE="x86" - } - If ($env:Configuration -Match "Debug") { - $env:DEBUG_ARG="--enable-debug" - } Else { - $env:DEBUG_ARG="--disable-debug" - } - - 'appveyor DownloadFile https://cygwin.com/setup-x86_64.exe -FileName setup.exe' - - 'setup.exe -qgnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu -P autoconf -P automake -P libtool' - - '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"' - - echo call VsDevCmd to set VS150COMNTOOLS - - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" - - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - - call "%VSCOMNTOOLS%..\..\vc\Auxiliary\Build\vcvarsall.bat" %VCVARS_PLATFORM% - -build_script: - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; ./autogen.sh)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; ./configure CC='%MSVCC%' CXX='%MSVCC%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST $DEBUG_ARG $SHARED_ARG)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; cp src/%SRC_ARCHITECTURE%/ffitarget.h include)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; make)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; cp $HOST/.libs/libffi.lib $HOST/testsuite/libffi-8.lib || true)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/ || true)" - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; TERM=none make check RUNTESTFLAGS='-v -v -v -v --target '$HOST DEJAGNU=$PWD/.appveyor/site.exp SITEDIR=$PWD/.appveyor)" - - -on_finish: - - c:\cygwin64\bin\sh -lc "(cd $OLDPWD; cat `find ./ -name libffi.log`)" diff --git a/.appveyor/site.exp b/.appveyor/site.exp deleted file mode 100644 index 93f47731f..000000000 --- a/.appveyor/site.exp +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2021 Anthony Green - -lappend boards_dir $::env(SITEDIR) - -verbose "Global Config File: target_triplet is $target_triplet" 1 -global target_list - -case "$target_triplet" in { - { "aarch*cygwin*" } { - set target_list "unix-noexec" - } - { "arm*cygwin*" } { - set target_list "unix-noexec" - } -} - diff --git a/.ci/site.exp b/.ci/site.exp index 96c013e08..8b1d92b48 100644 --- a/.ci/site.exp +++ b/.ci/site.exp @@ -26,4 +26,10 @@ case "$target_triplet" in { { "powerpc-eabisim" } { set target_list "powerpc-eabisim" } + { "aarch*cygwin*" } { + set target_list "unix-noexec" + } + { "arm*cygwin*" } { + set target_list "unix-noexec" + } } diff --git a/.appveyor/unix-noexec.exp b/.ci/unix-noexec.exp similarity index 100% rename from .appveyor/unix-noexec.exp rename to .ci/unix-noexec.exp From 3c54639eb81b68115f6ff3dcc562857d67d4136d Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 4 Jun 2025 19:20:37 -0400 Subject: [PATCH 32/87] refactor(ci): improve wget retry logic in .ci/install.sh (#915) --- .ci/install.sh | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/.ci/install.sh b/.ci/install.sh index 0bc53b7c3..59f8463e6 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -37,8 +37,36 @@ else sudo apt-get update sudo apt install libltdl-dev zip - set -x - wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - + shopt -s inherit_errexit # propagate failure out of subshells (bash >= 4.4) + + URL=https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz + MAX_TRIES=5 + BACKOFF=2 # seconds; will double every attempt + + attempt=1 + while (( attempt <= MAX_TRIES )); do + echo "➡️ Attempt ${attempt}/${MAX_TRIES}" + if wget --retry-connrefused \ + --waitretry=1 \ + --read-timeout=20 \ + --timeout=15 \ + -qO- "$URL" \ + | tar -xzv; then + echo "✅ Success on attempt ${attempt}" + break + fi + + echo "⚠️ Download or extract failed, retrying in ${BACKOFF}s…" + sleep "$BACKOFF" + BACKOFF=$(( BACKOFF * 2 )) + (( attempt++ )) + done + + if (( attempt > MAX_TRIES )); then + echo "❌ Exhausted retries ($MAX_TRIES) – aborting." >&2 + exit 1 + fi + mkdir -p ~/i (cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) From bac99f2f3f3c7b368cd304d14188e473975e129f Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 06:12:10 -0400 Subject: [PATCH 33/87] Release candidate 1 for 3.5.0. Windows build fixes. (#916) * refactor(ci): improve wget retry logic in .ci/install.sh * build(github-actions): use static runtime library in build * refactor(ffi.h.in): export version API * chore: update libffi version to 3.5.0-rc1 --- .github/workflows/build.yml | 4 ++-- README.md | 2 +- configure.ac | 4 ++-- include/ffi.h.in | 26 +++++++++++++------------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 663d6d903..c24d786f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,8 +134,8 @@ jobs: LDFLAGS="-no-undefined " \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ - CPPFLAGS="-DFFI_BUILDING_DLL" \ - CFLAGS="-DFFI_BUILDING_DLL" \ + CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ + CFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ AR='$(pwd)/.ci/ar-lib lib' \ NM='dumpbin -symbols' STRIP=':' \ $DEBUG_ARG || cat */config.log diff --git a/README.md b/README.md index cc706c3ee..044afd83e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.5.0-rc0 was released on June 2, 2025. Check the libffi web +libffi-3.5.0-rc1 was released on June 5, 2025. Check the libffi web page for updates: . diff --git a/configure.ac b/configure.ac index 55adb14b5..5b36c4696 100644 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.72]) -AC_INIT([libffi],[3.5.0-rc0],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.0-rc1],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.0-dev" +FFI_VERSION_STRING="3.5.0-rc1" FFI_VERSION_NUMBER=30500 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) diff --git a/include/ffi.h.in b/include/ffi.h.in index c97d7e0c6..ba91c6695 100644 --- a/include/ffi.h.in +++ b/include/ffi.h.in @@ -54,19 +54,6 @@ extern "C" { #define @TARGET@ #endif -/* ---- Version API ------------------------------------------------------ */ - -#define FFI_VERSION_STRING "@FFI_VERSION_STRING@" -#define FFI_VERSION_NUMBER @FFI_VERSION_NUMBER@ - -#ifndef LIBFFI_ASM -/* Return a version string. */ -const char *ffi_get_version (void); - -/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ -unsigned long ffi_get_version_number (void); -#endif - /* ---- System configuration information --------------------------------- */ /* If these change, update src/mips/ffitarget.h. */ @@ -327,6 +314,19 @@ void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __a FFI_API size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated)); +/* ---- Version API ------------------------------------------------------ */ + +#define FFI_VERSION_STRING "@FFI_VERSION_STRING@" +#define FFI_VERSION_NUMBER @FFI_VERSION_NUMBER@ + +#ifndef LIBFFI_ASM +/* Return a version string. */ +FFI_API const char *ffi_get_version (void); + +/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ +FFI_API unsigned long ffi_get_version_number (void); +#endif + /* ---- Definitions for closures ----------------------------------------- */ #if FFI_CLOSURES From 1b6b176a289d923e7cf4c19f17eeadac67c5bd02 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 06:17:56 -0400 Subject: [PATCH 34/87] Update README.md to mention SH targets --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 044afd83e..e2e9d242c 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,9 @@ tested: | RISC-V 64-bit | Linux | GCC | | S390 | Linux | GCC | | S390X | Linux | GCC | +| SH3 | Linux | GCC | +| SH4 | Linux | GCC | +| SH5/SH64 | Linux | GCC | | SPARC | Linux | GCC | | SPARC | Solaris | GCC | | SPARC | Solaris | Oracle Solaris Studio C | From 27f93a7038925797eaca6dea34375fd1b9909307 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 06:50:12 -0400 Subject: [PATCH 35/87] feat(build): add version information resource to build script and update documentation version --- .github/workflows/build.yml | 31 ++++++++++++++++++++++++++++++- doc/version.texi | 8 ++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c24d786f7..f530692f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,6 +123,35 @@ jobs: cd $(cygpath $RUNNER_WORKSPACE)/libffi wget https://rl.gl/cli/rlgl-windows-amd64.zip unzip rlgl-windows-amd64.zip + # ---------- add VERSIONINFO resource -------------------------- + cat > version.rc <<'EOF' + #include + #include + VS_VERSION_INFO VERSIONINFO + FILEVERSION ${FFI_MAJOR},${FFI_MINOR},${FFI_MICRO},0 + PRODUCTVERSION ${FFI_MAJOR},${FFI_MINOR},${FFI_MICRO},0 + FILEFLAGSMASK VS_FFI_FILEFLAGMASK + FILEFLAGS 0 + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 + BEGIN BLOCK "StringFileInfo" + BEGIN BLOCK "040904B0" // US-English, UTF-16 + BEGIN + VALUE "CompanyName", "https://github.com/libffi/libffi\0" + VALUE "FileDescription", "Portable Foreign Function Interface library\0" + VALUE "ProductName", "libffi\0" + VALUE "FileVersion", "${{ steps.ver.outputs.version }}\0" + VALUE "LegalCopyright", "Copyright © 1996-2025 Anthony Green and others\0" + END + END + END + EOF + rc /nologo /DFFI_MAJOR=$(cut -d. -f1 <<<"${{ steps.ver.outputs.version }}") \ + /DFFI_MINOR=$(cut -d. -f2 <<<"${{ steps.ver.outputs.version }}") \ + /DFFI_MICRO=$(cut -d. -f3 <<<"${{ steps.ver.outputs.version }}") \ + -fo version.res version.rc + # ---------------------------------------------------------------- autoreconf -f -v -i ./configure \ --enable-shared \ @@ -131,7 +160,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined " \ + LDFLAGS="-no-undefined version.res" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ diff --git a/doc/version.texi b/doc/version.texi index ba42140af..e82174ff7 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 26 May 2025 -@set UPDATED-MONTH May 2025 -@set EDITION 3.5.0-rc0 -@set VERSION 3.5.0-rc0 +@set UPDATED 5 June 2025 +@set UPDATED-MONTH June 2025 +@set EDITION 3.5.0-rc1 +@set VERSION 3.5.0-rc1 From 49c70cab94981600b471a480048f497fccf03239 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 06:57:20 -0400 Subject: [PATCH 36/87] fix(build): correct variables for FILEVERSION and PRODUCTVERSION --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f530692f4..9850aeb40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -128,8 +128,8 @@ jobs: #include #include VS_VERSION_INFO VERSIONINFO - FILEVERSION ${FFI_MAJOR},${FFI_MINOR},${FFI_MICRO},0 - PRODUCTVERSION ${FFI_MAJOR},${FFI_MINOR},${FFI_MICRO},0 + FILEVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 + PRODUCTVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 FILEFLAGSMASK VS_FFI_FILEFLAGMASK FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 From d6029210d795258c99e0606753556060d233109e Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 07:11:43 -0400 Subject: [PATCH 37/87] ci: refactor version retrieval in build workflow --- .github/workflows/build.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9850aeb40..23dcd5260 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -130,7 +130,7 @@ jobs: VS_VERSION_INFO VERSIONINFO FILEVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 PRODUCTVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 - FILEFLAGSMASK VS_FFI_FILEFLAGMASK + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -147,9 +147,10 @@ jobs: END END EOF - rc /nologo /DFFI_MAJOR=$(cut -d. -f1 <<<"${{ steps.ver.outputs.version }}") \ - /DFFI_MINOR=$(cut -d. -f2 <<<"${{ steps.ver.outputs.version }}") \ - /DFFI_MICRO=$(cut -d. -f3 <<<"${{ steps.ver.outputs.version }}") \ + ver=${{ steps.ver.outputs.version }} + rc /nologo /dFFI_MAJOR=$(cut -d. -f1 <<<"$ver") \ + /dFFI_MINOR=$(cut -d. -f2 <<<"$ver") \ + /dFFI_MICRO=$(cut -d. -f3 <<<"$ver") \ -fo version.res version.rc # ---------------------------------------------------------------- autoreconf -f -v -i From c8d929fc45bae3192666c06b1c83e53afe7e639d Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 07:33:57 -0400 Subject: [PATCH 38/87] ci: add version logging in build workflow --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 23dcd5260..62f62bf6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -147,6 +147,10 @@ jobs: END END EOF + echo "$ver" + echo $(cut -d. -f1 <<<"$ver") + echo $(cut -d. -f2 <<<"$ver") + echo $(cut -d. -f3 <<<"$ver") ver=${{ steps.ver.outputs.version }} rc /nologo /dFFI_MAJOR=$(cut -d. -f1 <<<"$ver") \ /dFFI_MINOR=$(cut -d. -f2 <<<"$ver") \ From e133ee847de50b710072aae1a478208c0a56c8f9 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 07:42:52 -0400 Subject: [PATCH 39/87] chore(build): add command to log version information in build script --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62f62bf6d..ebe32aa32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -147,6 +147,7 @@ jobs: END END EOF + cat version.rc echo "$ver" echo $(cut -d. -f1 <<<"$ver") echo $(cut -d. -f2 <<<"$ver") From ec22d0fe7bd9db7629a7540a7ba12a2ec6a28889 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 08:44:36 -0400 Subject: [PATCH 40/87] build(.github/workflows): include build number in version info --- .github/workflows/build.yml | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ebe32aa32..a5b69b0f2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -128,8 +128,8 @@ jobs: #include #include VS_VERSION_INFO VERSIONINFO - FILEVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 - PRODUCTVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,0 + FILEVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,FFI_BUILD + PRODUCTVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,FFI_BUILD FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 @@ -148,14 +148,28 @@ jobs: END EOF cat version.rc - echo "$ver" - echo $(cut -d. -f1 <<<"$ver") - echo $(cut -d. -f2 <<<"$ver") - echo $(cut -d. -f3 <<<"$ver") ver=${{ steps.ver.outputs.version }} - rc /nologo /dFFI_MAJOR=$(cut -d. -f1 <<<"$ver") \ - /dFFI_MINOR=$(cut -d. -f2 <<<"$ver") \ - /dFFI_MICRO=$(cut -d. -f3 <<<"$ver") \ + echo "$ver" + + base=${ver%%-*} + rc=${ver#*-} + [[ $rc == "$ver" ]] && rc="" # no rc? rc="" + + maj=$(cut -d. -f1 <<<"$base") + min=$(cut -d. -f2 <<<"$base") + pat=$(cut -d. -f3 <<<"$base") + + # Decide on build number + if [[ $rc =~ ^rc([0-9]+)$ ]]; then + build=${BASH_REMATCH[1]} # rc1 → 1 + else + build=0 + fi + + rc /nologo /dFFI_MAJOR=$maj \ + /dFFI_MINOR=$min \ + /dFFI_MICRO=$pat \ + /dFFI_BUILD=$build \ -fo version.res version.rc # ---------------------------------------------------------------- autoreconf -f -v -i From c07b0c4ddc99d6be9d3d4fbe2c39ca86e9af4dc4 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 08:52:41 -0400 Subject: [PATCH 41/87] fix(github workflows): correct LDFLAGS path in build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a5b69b0f2..93e5b602a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -180,7 +180,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined version.res" \ + LDFLAGS="-no-undefined $(pwd)/version.res" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ From d241e510196393c4ec8a7a8f1e456d2695802ff6 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 09:22:10 -0400 Subject: [PATCH 42/87] chore(build): update build script to use object file for versioning --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 93e5b602a..3db36603e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -171,6 +171,7 @@ jobs: /dFFI_MICRO=$pat \ /dFFI_BUILD=$build \ -fo version.res version.rc + windres -O coff -F pe-${{ matrix.arch == 'x64' && 'x86-64' || 'i386' }} version.rc version.o # ---------------------------------------------------------------- autoreconf -f -v -i ./configure \ @@ -180,7 +181,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined $(pwd)/version.res" \ + LDFLAGS="-no-undefined $(pwd)/version.o" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ From d326a4c025a379ea590a9926a55bd39dcc8d9ae3 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 5 Jun 2025 09:35:47 -0400 Subject: [PATCH 43/87] refactor: simplify versioning in .github/workflows/build.yml --- .github/workflows/build.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3db36603e..f1e78d3a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -166,12 +166,10 @@ jobs: build=0 fi - rc /nologo /dFFI_MAJOR=$maj \ - /dFFI_MINOR=$min \ - /dFFI_MICRO=$pat \ - /dFFI_BUILD=$build \ - -fo version.res version.rc - windres -O coff -F pe-${{ matrix.arch == 'x64' && 'x86-64' || 'i386' }} version.rc version.o + windres -O coff -F pe-${{ matrix.arch == 'x64' && 'x86-64' || 'i386' }} \ + -DFFI_MAJOR=$maj -DFFI_MINOR=$min -DFFI_MICRO=$pat -DFFI_BUILD=$build \ + -DFFI_VERSION_STR="\"$ver\"" \ + version.rc version.o # ---------------------------------------------------------------- autoreconf -f -v -i ./configure \ From c2ae66fc45dbfc18afe1244663bb5d97937c7976 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Fri, 6 Jun 2025 13:41:56 -0400 Subject: [PATCH 44/87] fix(build): change version.o to version.obj in build.yml --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1e78d3a5..06902928c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -169,7 +169,7 @@ jobs: windres -O coff -F pe-${{ matrix.arch == 'x64' && 'x86-64' || 'i386' }} \ -DFFI_MAJOR=$maj -DFFI_MINOR=$min -DFFI_MICRO=$pat -DFFI_BUILD=$build \ -DFFI_VERSION_STR="\"$ver\"" \ - version.rc version.o + version.rc version.obj # ---------------------------------------------------------------- autoreconf -f -v -i ./configure \ @@ -179,7 +179,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined $(pwd)/version.o" \ + LDFLAGS="-no-undefined $(cygpath -w $(pwd)/version.obj)" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ From 9bb21f1d291235c7aa2627b1175b4a085858396c Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Fri, 6 Jun 2025 13:48:25 -0400 Subject: [PATCH 45/87] fix: correct path in LDFLAGS line of build.yml workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06902928c..9191a9315 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -179,7 +179,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined $(cygpath -w $(pwd)/version.obj)" \ + LDFLAGS="-no-undefined $(pwd)/version.obj" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ From e3cbebffcc397ce2121a32887ffbc06070a3c024 Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Fri, 6 Jun 2025 22:40:40 +0200 Subject: [PATCH 46/87] use rcedit to add metainfo to DLL (#918) * use rcedit to add metainfo to DLL * remove trailing backslash in build.yml * build.yml: add rcedit execute permission * build.yml: cd to the right directory --- .github/workflows/build.yml | 87 ++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9191a9315..002c35b48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,54 +123,6 @@ jobs: cd $(cygpath $RUNNER_WORKSPACE)/libffi wget https://rl.gl/cli/rlgl-windows-amd64.zip unzip rlgl-windows-amd64.zip - # ---------- add VERSIONINFO resource -------------------------- - cat > version.rc <<'EOF' - #include - #include - VS_VERSION_INFO VERSIONINFO - FILEVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,FFI_BUILD - PRODUCTVERSION FFI_MAJOR,FFI_MINOR,FFI_MICRO,FFI_BUILD - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS 0 - FILEOS VOS_NT_WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0 - BEGIN BLOCK "StringFileInfo" - BEGIN BLOCK "040904B0" // US-English, UTF-16 - BEGIN - VALUE "CompanyName", "https://github.com/libffi/libffi\0" - VALUE "FileDescription", "Portable Foreign Function Interface library\0" - VALUE "ProductName", "libffi\0" - VALUE "FileVersion", "${{ steps.ver.outputs.version }}\0" - VALUE "LegalCopyright", "Copyright © 1996-2025 Anthony Green and others\0" - END - END - END - EOF - cat version.rc - ver=${{ steps.ver.outputs.version }} - echo "$ver" - - base=${ver%%-*} - rc=${ver#*-} - [[ $rc == "$ver" ]] && rc="" # no rc? rc="" - - maj=$(cut -d. -f1 <<<"$base") - min=$(cut -d. -f2 <<<"$base") - pat=$(cut -d. -f3 <<<"$base") - - # Decide on build number - if [[ $rc =~ ^rc([0-9]+)$ ]]; then - build=${BASH_REMATCH[1]} # rc1 → 1 - else - build=0 - fi - - windres -O coff -F pe-${{ matrix.arch == 'x64' && 'x86-64' || 'i386' }} \ - -DFFI_MAJOR=$maj -DFFI_MINOR=$min -DFFI_MICRO=$pat -DFFI_BUILD=$build \ - -DFFI_VERSION_STR="\"$ver\"" \ - version.rc version.obj - # ---------------------------------------------------------------- autoreconf -f -v -i ./configure \ --enable-shared \ @@ -179,7 +131,7 @@ jobs: CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \ LD="link" \ - LDFLAGS="-no-undefined $(pwd)/version.obj" \ + LDFLAGS="-no-undefined" \ CPP="cl -nologo -EP" \ CXXCPP="cl -nologo -EP" \ CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ @@ -201,6 +153,43 @@ jobs: --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + - name: Add meta information to DLL + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + run: | + cd $(cygpath $RUNNER_WORKSPACE)/libffi + + # Deconstruct the libffi version + ver=${{ steps.ver.outputs.version }} + echo "$ver" + + base=${ver%%-*} + rc=${ver#*-} + [[ $rc == "$ver" ]] && rc="" # no rc? rc="" + + maj=$(cut -d. -f1 <<<"$base") + min=$(cut -d. -f2 <<<"$base") + pat=$(cut -d. -f3 <<<"$base") + + # Decide on build number + if [[ $rc =~ ^rc([0-9]+)$ ]]; then + build=${BASH_REMATCH[1]} # rc1 → 1 + else + build=0 + fi + + # Use rcedit to edit the DLLs resources + wget -O rcedit.exe https://github.com/electron/rcedit/releases/download/v2.0.0/rcedit-${{ matrix.arch }}.exe + chmod +x ./rcedit.exe + + ./rcedit.exe "${{ matrix.host }}"/.libs/libffi-8.dll \ + --set-file-version "$maj.$min.$pat.$build" \ + --set-product-version "$maj.$min.$pat.$build" \ + --set-version-string "CompanyName" "https://github.com/libffi/libffi" \ + --set-version-string "FileDescription" "Portable foreign function interface library" \ + --set-version-string "ProductName" "libffi" \ + --set-version-string "FileVersion" "${{ steps.ver.outputs.version }}" \ + --set-version-string "LegalCopyright" "Copyright (c) 1996-2025 Anthony Green and others" + - name: Create binary distribution shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' run: | From 024cbc252c534419573ea775706c8b272e7159ef Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 7 Jun 2025 08:35:15 -0400 Subject: [PATCH 47/87] feat(.ci): add Containerfile for ppc64le architecture --- .ci/Containerfile.ppc64le | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .ci/Containerfile.ppc64le diff --git a/.ci/Containerfile.ppc64le b/.ci/Containerfile.ppc64le new file mode 100644 index 000000000..ec283dc55 --- /dev/null +++ b/.ci/Containerfile.ppc64le @@ -0,0 +1,3 @@ +FROM ppc64le/fedora + +RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc From d796b1ba066358f57e02a2337e3c1451ba900016 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 7 Jun 2025 08:47:04 -0400 Subject: [PATCH 48/87] feat(.ci): add libtool to ppc64le container setup --- .ci/Containerfile.ppc64le | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Containerfile.ppc64le b/.ci/Containerfile.ppc64le index ec283dc55..c4071cf15 100644 --- a/.ci/Containerfile.ppc64le +++ b/.ci/Containerfile.ppc64le @@ -1,3 +1,3 @@ FROM ppc64le/fedora -RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc +RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc libtool From 58f9179009b61ff563279fcd6ea489eda94b5260 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 7 Jun 2025 08:48:41 -0400 Subject: [PATCH 49/87] ci: add diffutils and gawk to ppc64le container dependencies --- .ci/Containerfile.ppc64le | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Containerfile.ppc64le b/.ci/Containerfile.ppc64le index c4071cf15..f9e3a56ab 100644 --- a/.ci/Containerfile.ppc64le +++ b/.ci/Containerfile.ppc64le @@ -1,3 +1,3 @@ FROM ppc64le/fedora -RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc libtool +RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc libtool diffutils gawk From 8b30fe51d46ad29608d928c9920ca69f93394092 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 7 Jun 2025 08:51:52 -0400 Subject: [PATCH 50/87] ci: add user configuration for DejaGNU tests in ppc64le container --- .ci/Containerfile.ppc64le | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.ci/Containerfile.ppc64le b/.ci/Containerfile.ppc64le index f9e3a56ab..d771f7bbe 100644 --- a/.ci/Containerfile.ppc64le +++ b/.ci/Containerfile.ppc64le @@ -1,3 +1,12 @@ FROM ppc64le/fedora RUN dnf install -y dejagnu automake autoconf dejagnu texinfo gcc libtool diffutils gawk + +# ----------------------------------------------------------------------------- +# Give UID 10000 a name so ‘whoami’ works during DejaGNU tests +# ----------------------------------------------------------------------------- +RUN groupadd -g 10000 builder \ + && useradd -u 10000 -g 10000 -d /home/builder -s /sbin/nologin builder \ + && mkdir -p /home/builder \ + && chown 10000:10000 /home/builder +USER 10000 From 8b0eab28cb45c6862b30f5cadfc1a7fe996b072c Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Sun, 8 Jun 2025 12:16:38 +0200 Subject: [PATCH 51/87] Update License date and improve rcedit DLL metadata (#919) * rcedit add architecture and original filename * Update LICENSE to 2025 --- .github/workflows/build.yml | 8 +++++--- LICENSE | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 002c35b48..453260d83 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,14 +181,16 @@ jobs: wget -O rcedit.exe https://github.com/electron/rcedit/releases/download/v2.0.0/rcedit-${{ matrix.arch }}.exe chmod +x ./rcedit.exe - ./rcedit.exe "${{ matrix.host }}"/.libs/libffi-8.dll \ + dll_filename=libffi-8.dll + ./rcedit.exe "${{ matrix.host }}"/.libs/$dll_filename \ --set-file-version "$maj.$min.$pat.$build" \ --set-product-version "$maj.$min.$pat.$build" \ --set-version-string "CompanyName" "https://github.com/libffi/libffi" \ - --set-version-string "FileDescription" "Portable foreign function interface library" \ + --set-version-string "FileDescription" "Portable foreign function interface library (${{ matrix.arch }})" \ --set-version-string "ProductName" "libffi" \ --set-version-string "FileVersion" "${{ steps.ver.outputs.version }}" \ - --set-version-string "LegalCopyright" "Copyright (c) 1996-2025 Anthony Green and others" + --set-version-string "LegalCopyright" "Copyright (c) 1996-2025 Anthony Green and others" \ + --set-version-string "OriginalFilename" "$dll_filename" - name: Create binary distribution shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' diff --git a/LICENSE b/LICENSE index 7282e798c..12b4970e0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -libffi - Copyright (c) 1996-2024 Anthony Green, Red Hat, Inc and others. +libffi - Copyright (c) 1996-2025 Anthony Green, Red Hat, Inc and others. See source files for details. Permission is hereby granted, free of charge, to any person obtaining From cb424c6d41401bb93c59a553849d32c34bfff765 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 06:50:47 -0400 Subject: [PATCH 52/87] docs: Update README with release details for version 3.5.0 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2e9d242c..f345319c3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.5.0-rc1 was released on June 5, 2025. Check the libffi web +libffi-3.5.0 was released on June 8, 2025. Check the libffi web page for updates: . @@ -203,7 +203,7 @@ History See the git log for details at http://github.com/libffi/libffi. - Next Version TBD + 3.5.0 Jun-8-2025 Add FFI_VERSION_STRING and FFI_VERSION_NUMBER macros, as well as ffi_get_version() and ffi_get_version_number() functions. Fix closures on powerpc64-linux when statically linking. From c8225fb03db49dfa04403a28091ab99b0998fffe Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 06:51:58 -0400 Subject: [PATCH 53/87] chore: update libffi version to 3.5.0 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 5b36c4696..69ed04360 100644 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.72]) -AC_INIT([libffi],[3.5.0-rc1],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.0-rc1" +FFI_VERSION_STRING="3.5.0" FFI_VERSION_NUMBER=30500 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) From b14d43793a83aabe79cae4ac6a39b6183f25c8aa Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 06:53:12 -0400 Subject: [PATCH 54/87] Update version --- doc/version.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/version.texi b/doc/version.texi index e82174ff7..5fff7763b 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 5 June 2025 +@set UPDATED 7 June 2025 @set UPDATED-MONTH June 2025 -@set EDITION 3.5.0-rc1 -@set VERSION 3.5.0-rc1 +@set EDITION 3.5.0 +@set VERSION 3.5.0 From 074c423f86b30fa895f391230bdbedf076053fa3 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:30:54 -0400 Subject: [PATCH 55/87] feat: Add ffi_get_default_abi and ffi_get_closure_size functions --- README.md | 1 + doc/libffi.texi | 10 ++++++++++ include/ffi.h.in | 5 +++++ libffi.map.in | 3 +++ src/types.c | 12 +++++++++++- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f345319c3..e86401436 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ See the git log for details at http://github.com/libffi/libffi. 3.5.0 Jun-8-2025 Add FFI_VERSION_STRING and FFI_VERSION_NUMBER macros, as well as ffi_get_version() and ffi_get_version_number() functions. + Add ffi_get_default_abi() and ffi_get_closure_size() functions. Fix closures on powerpc64-linux when statically linking. Mark the PA stack as non-executable. diff --git a/doc/libffi.texi b/doc/libffi.texi index 6111d2c60..165c2fb1f 100644 --- a/doc/libffi.texi +++ b/doc/libffi.texi @@ -250,6 +250,16 @@ This number is also available at build time as the macro @code{FFI_VERSION_NUMBER}. @end defun +@findex ffi_get_default_abi +@defun {unsigned int} ffi_get_default_abi (void) +Return the value of @code{FFI_DEFAULT_ABI}. +@end defun + +@findex ffi_get_closure_size +@defun {size_t} ffi_get_closure_size (void) +Return @code{sizeof(ffi_closure)}. +@end defun + @node Simple Example @section Simple Example diff --git a/include/ffi.h.in b/include/ffi.h.in index ba91c6695..6ce7ac55e 100644 --- a/include/ffi.h.in +++ b/include/ffi.h.in @@ -327,6 +327,11 @@ FFI_API const char *ffi_get_version (void); FFI_API unsigned long ffi_get_version_number (void); #endif +/* ---- Internals API ---------------------------------------------------- */ + +FFI_API unsigned int ffi_get_default_abi (void); +FFI_API size_t ffi_get_closure_size (void); + /* ---- Definitions for closures ----------------------------------------- */ #if FFI_CLOSURES diff --git a/libffi.map.in b/libffi.map.in index c5e0c5124..a12ac0200 100644 --- a/libffi.map.in +++ b/libffi.map.in @@ -27,6 +27,9 @@ LIBFFI_BASE_8.0 { ffi_get_version; ffi_get_version_number; + ffi_get_default_abi; + ffi_get_closure_size; + ffi_call; ffi_prep_cif; ffi_prep_cif_var; diff --git a/src/types.c b/src/types.c index 28d7a1ed0..8b2dec98e 100644 --- a/src/types.c +++ b/src/types.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998, 2024 Red Hat, Inc. + types.c - Copyright (c) 1996, 1998, 2024, 2025 Red Hat, Inc. Predefined ffi_types needed by libffi. @@ -43,6 +43,16 @@ unsigned long ffi_get_version_number (void) return FFI_VERSION_NUMBER; } +unsigned int ffi_get_default_abi (void) +{ + return FFI_DEFAULT_ABI; +} + +size_t ffi_get_closure_size (void) +{ + return sizeof(ffi_closure); +} + /* Type definitions */ #define FFI_TYPEDEF(name, type, id, maybe_const)\ From a5d465029ce1ffce4860c75c2aa3fa0d1a8e18be Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:40:39 -0400 Subject: [PATCH 56/87] feat(testsuite): add new threading tests to libffi test suite --- testsuite/libffi.threads/ffitest.h | 163 +++++++++++++++++++++++++++ testsuite/libffi.threads/threads.exp | 54 +++++++++ testsuite/libffi.threads/tsan.c | 66 +++++++++++ 3 files changed, 283 insertions(+) create mode 100644 testsuite/libffi.threads/ffitest.h create mode 100644 testsuite/libffi.threads/threads.exp create mode 100644 testsuite/libffi.threads/tsan.c diff --git a/testsuite/libffi.threads/ffitest.h b/testsuite/libffi.threads/ffitest.h new file mode 100644 index 000000000..8bd8a3cb6 --- /dev/null +++ b/testsuite/libffi.threads/ffitest.h @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include "fficonfig.h" + +#include +#include + +#if defined HAVE_STDINT_H +#include +#endif + +#if defined HAVE_INTTYPES_H +#include +#endif + +#define MAX_ARGS 256 + +#define CHECK(x) \ + do { \ + if(!(x)){ \ + printf("Check failed:\n%s\n", #x); \ + abort(); \ + } \ + } while(0) + +#define CHECK_FLOAT_EQ(x, y) \ + do { \ + if(fabs((x) - (y)) > FLT_EPSILON){ \ + printf("Check failed CHECK_FLOAT_EQ(%s, %s)\n", #x, #y); \ + abort(); \ + } \ + } while(0) + +#define CHECK_DOUBLE_EQ(x, y) \ + do { \ + if(fabs((x) - (y)) > DBL_EPSILON){ \ + printf("Check failed CHECK_FLOAT_EQ(%s, %s)\n", #x, #y); \ + abort(); \ + } \ + } while(0) + +/* Define macros so that compilers other than gcc can run the tests. */ +#undef __UNUSED__ +#if defined(__GNUC__) +#define __UNUSED__ __attribute__((__unused__)) +#define __STDCALL__ __attribute__((stdcall)) +#define __THISCALL__ __attribute__((thiscall)) +#define __FASTCALL__ __attribute__((fastcall)) +#define __MSABI__ __attribute__((ms_abi)) +#else +#define __UNUSED__ +#define __STDCALL__ __stdcall +#define __THISCALL__ __thiscall +#define __FASTCALL__ __fastcall +#endif + +#ifndef ABI_NUM +#define ABI_NUM FFI_DEFAULT_ABI +#define ABI_ATTR +#endif + +/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a + file open. */ +#ifdef HAVE_MMAP_ANON +# undef HAVE_MMAP_DEV_ZERO + +# include +# ifndef MAP_FAILED +# define MAP_FAILED -1 +# endif +# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif +# define USING_MMAP + +#endif + +#ifdef HAVE_MMAP_DEV_ZERO + +# include +# ifndef MAP_FAILED +# define MAP_FAILED -1 +# endif +# define USING_MMAP + +#endif + +/* msvc kludge. */ +#if defined(_MSC_VER) +#define PRIdLL "I64d" +#define PRIuLL "I64u" +#else +#define PRIdLL "lld" +#define PRIuLL "llu" +#endif + +/* Tru64 UNIX kludge. */ +#if defined(__alpha__) && defined(__osf__) +/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */ +#undef PRIdLL +#define PRIdLL "ld" +#undef PRIuLL +#define PRIuLL "lu" +#define PRId8 "hd" +#define PRIu8 "hu" +#define PRId64 "ld" +#define PRIu64 "lu" +#define PRIuPTR "lu" +#endif + +/* PA HP-UX kludge. */ +#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR) +#define PRIuPTR "lu" +#endif + +/* IRIX kludge. */ +#if defined(__sgi) +/* IRIX 6.5 provides all definitions, but only for C99 + compilations. */ +#define PRId8 "hhd" +#define PRIu8 "hhu" +#if (_MIPS_SZLONG == 32) +#define PRId64 "lld" +#define PRIu64 "llu" +#endif +/* This doesn't match , which always has "lld" here, but the + arguments are uint64_t, int64_t, which are unsigned long, long for + 64-bit in . */ +#if (_MIPS_SZLONG == 64) +#define PRId64 "ld" +#define PRIu64 "lu" +#endif +/* This doesn't match , which has "u" here, but the arguments + are uintptr_t, which is always unsigned long. */ +#define PRIuPTR "lu" +#endif + +/* Solaris < 10 kludge. */ +#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR) +#if defined(__arch64__) || defined (__x86_64__) +#define PRIuPTR "lu" +#else +#define PRIuPTR "u" +#endif +#endif + +/* MSVC kludge. */ +#if defined _MSC_VER +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) +#define PRIuPTR "lu" +#define PRIu8 "u" +#define PRId8 "d" +#define PRIu64 "I64u" +#define PRId64 "I64d" +#endif +#endif + +#ifndef PRIuPTR +#define PRIuPTR "u" +#endif diff --git a/testsuite/libffi.threads/threads.exp b/testsuite/libffi.threads/threads.exp new file mode 100644 index 000000000..13ba2bdcd --- /dev/null +++ b/testsuite/libffi.threads/threads.exp @@ -0,0 +1,54 @@ +# Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# . + +dg-init +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]] + +run-many-tests $tlist $additional_options + +set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]] + +# No C++ for or1k +if { [istarget "or1k-*-*"] } { + foreach test $tlist { + unsupported "$test" + } +} else { + run-many-tests $tlist $additional_options +} + +dg-finish + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testsuite/libffi.threads/tsan.c b/testsuite/libffi.threads/tsan.c new file mode 100644 index 000000000..d6134f85d --- /dev/null +++ b/testsuite/libffi.threads/tsan.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ + +#include "ffitest.h" + +#include +#include +#include + +#define NUM_THREADS 20 + +pthread_barrier_t barrier; + +typedef float (*callback_fn)(float, float); + +void callback(ffi_cif *cif __UNUSED__, void *ret, void **args, void *userdata __UNUSED__) { + float a = *(float *)args[0]; + float b = *(float *)args[1]; + *(float *)ret = a / 2 + b / 2; +} + +void *thread_func(void *arg) { + pthread_barrier_wait(&barrier); + + ffi_cif cif; + ffi_type *args[2] = { &ffi_type_float, &ffi_type_float }; + + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_float, args) != FFI_OK) { + fprintf(stderr, "ffi_prep_cif failed\n"); + return NULL; + } + + ffi_closure *closure = ffi_closure_alloc(sizeof(ffi_closure), (void **)&arg); + + if (ffi_prep_closure_loc(closure, &cif, callback, NULL, arg) != FFI_OK) { + fprintf(stderr, "ffi_prep_closure_loc failed\n"); + return NULL; + } + + callback_fn fn = (callback_fn)arg; + (void) fn(4.0f, 6.0f); + + ffi_closure_free(closure); + return NULL; +} + +int main() { + pthread_t threads[NUM_THREADS]; + + pthread_barrier_init(&barrier, NULL, NUM_THREADS); + + for (int i = 0; i < NUM_THREADS; ++i) { + if (pthread_create(&threads[i], NULL, thread_func, NULL) != 0) { + perror("pthread_create"); + exit(EXIT_FAILURE); + } + } + + for (int i = 0; i < NUM_THREADS; ++i) { + pthread_join(threads[i], NULL); + } + + pthread_barrier_destroy(&barrier); + + printf("Completed\n"); + return 0; +} From 5fd812149e4740346341c1c9a8c355cc05f411c3 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:47:04 -0400 Subject: [PATCH 57/87] chore: update documentation date and add test files to Makefile --- doc/version.texi | 2 +- testsuite/Makefile.am | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/version.texi b/doc/version.texi index 5fff7763b..5d61d6f71 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 7 June 2025 +@set UPDATED 8 June 2025 @set UPDATED-MONTH June 2025 @set EDITION 3.5.0 @set VERSION 3.5.0 diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index fa9134f44..2e422b9a4 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -85,4 +85,5 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \ libffi.complex/return_complex2_float.c libffi.complex/return_complex2_longdouble.c libffi.complex/return_complex_double.c \ libffi.complex/return_complex_float.c libffi.complex/return_complex_longdouble.c libffi.go/aa-direct.c \ libffi.go/closure1.c libffi.go/ffitest.h libffi.go/go.exp \ - libffi.go/static-chain.h Makefile.am Makefile.in + libffi.go/static-chain.h Makefile.am Makefile.in \ + libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c From f530522ce48922178b25af9b5467cacc41c21de6 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:52:25 -0400 Subject: [PATCH 58/87] chore: disable color diagnostics in libffi tests --- testsuite/lib/libffi.exp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp index c542912bf..719411f7c 100644 --- a/testsuite/lib/libffi.exp +++ b/testsuite/lib/libffi.exp @@ -522,7 +522,7 @@ proc run-many-tests { testcases extra_flags } { } } "gnu" { - set common "-W -Wall -Wno-psabi" + set common "-W -Wall -Wno-psabi -fno-diagnostics-color" if [info exists env(LIBFFI_TEST_OPTIMIZATION)] { set optimizations [ list $env(LIBFFI_TEST_OPTIMIZATION) ] } else { From 70b34efece027faa843520709b300242e0526154 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:53:00 -0400 Subject: [PATCH 59/87] feat(testsuite): add -lpthread flag for wasm32 targets --- testsuite/lib/libffi.exp | 1 + 1 file changed, 1 insertion(+) diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp index 719411f7c..104196480 100644 --- a/testsuite/lib/libffi.exp +++ b/testsuite/lib/libffi.exp @@ -435,6 +435,7 @@ proc libffi_target_compile { source dest type options } { # which causes it to be seen as unsupported. if { [string match "wasm32-*" $target_triplet] } { lappend options "additional_flags=-Wno-unused-command-line-argument" + lappend options "libs= -lpthread" } verbose "options: $options" From 5be311bed5e93305ed3f31bd29bcdcfe4baaa00c Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 07:56:37 -0400 Subject: [PATCH 60/87] refactor: add POSIX barriers to libffi.threads testsuite --- testsuite/libffi.threads/tsan.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/testsuite/libffi.threads/tsan.c b/testsuite/libffi.threads/tsan.c index d6134f85d..aeff60c1f 100644 --- a/testsuite/libffi.threads/tsan.c +++ b/testsuite/libffi.threads/tsan.c @@ -8,7 +8,9 @@ #define NUM_THREADS 20 +#ifdef _POSIX_BARRIERS pthread_barrier_t barrier; +#endif typedef float (*callback_fn)(float, float); @@ -19,7 +21,9 @@ void callback(ffi_cif *cif __UNUSED__, void *ret, void **args, void *userdata __ } void *thread_func(void *arg) { +#ifdef _POSIX_BARRIERS pthread_barrier_wait(&barrier); +#endif ffi_cif cif; ffi_type *args[2] = { &ffi_type_float, &ffi_type_float }; @@ -46,7 +50,9 @@ void *thread_func(void *arg) { int main() { pthread_t threads[NUM_THREADS]; +#ifdef _POSIX_BARRIERS pthread_barrier_init(&barrier, NULL, NUM_THREADS); +#endif for (int i = 0; i < NUM_THREADS; ++i) { if (pthread_create(&threads[i], NULL, thread_func, NULL) != 0) { @@ -59,7 +65,9 @@ int main() { pthread_join(threads[i], NULL); } +#ifdef _POSIX_BARRIERS pthread_barrier_destroy(&barrier); +#endif printf("Completed\n"); return 0; From 668e2162e8185c007c3876c0de6723fb56aee0a1 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 08:00:36 -0400 Subject: [PATCH 61/87] refactor(threads): don't run tests on windows --- testsuite/libffi.threads/threads.exp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/testsuite/libffi.threads/threads.exp b/testsuite/libffi.threads/threads.exp index 13ba2bdcd..feb5f8c0d 100644 --- a/testsuite/libffi.threads/threads.exp +++ b/testsuite/libffi.threads/threads.exp @@ -34,12 +34,8 @@ if { [string match $compiler_vendor "microsoft"] } { set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]] -run-many-tests $tlist $additional_options - -set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]] - -# No C++ for or1k -if { [istarget "or1k-*-*"] } { +# No pthreads for windows +if { [string match $compiler_vendor "microsoft"] } { foreach test $tlist { unsupported "$test" } From d2c78d2ebbd9e65401095c6a2f281fe5132f028b Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 08:16:42 -0400 Subject: [PATCH 62/87] feat(testsuite): exclude wasm from pthreads testing in libffi --- testsuite/libffi.threads/threads.exp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/libffi.threads/threads.exp b/testsuite/libffi.threads/threads.exp index feb5f8c0d..ca0375091 100644 --- a/testsuite/libffi.threads/threads.exp +++ b/testsuite/libffi.threads/threads.exp @@ -34,8 +34,8 @@ if { [string match $compiler_vendor "microsoft"] } { set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]] -# No pthreads for windows -if { [string match $compiler_vendor "microsoft"] } { +# No pthreads for windows or wasm +if { [string match $compiler_vendor "microsoft"] || [istarget "wasm*-*-*"] } { foreach test $tlist { unsupported "$test" } From 64a42f618dcd555920756e84b0c8bfcec358c32e Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 8 Jun 2025 16:59:58 -0400 Subject: [PATCH 63/87] More CI testing (#921) * ci: add new build configuration in GitHub Actions * ci: add Windows clang build workflow * ci: add additional packages to GitHub workflows build * ci: optimize build workflow and improve commenting * ci: remove unused MSVC dev command from build workflow * ci: modify build workflow to support multiple compilers * build(github-actions): use matrix.compiler for CC and CXX variables --- .github/workflows/build.yml | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 453260d83..9d13b28e4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,6 +40,10 @@ jobs: HOST: x86_64-pc-linux-gnu CONFIGURE_OPTIONS: "--enable-shared" + - runner: ubuntu-latest + HOST: x86_64-pc-linux-gnu + CONFIGURE_OPTIONS: "--disable-exec-static-tramp" + # ---------- new native arm64 build ---------- - runner: ubuntu-22.04-arm # or ubuntu-24.04-arm HOST: aarch64-unknown-linux-gnu @@ -77,6 +81,96 @@ jobs: - run: ./.ci/install.sh - run: ${{ matrix.compilers }} ./.ci/build.sh + build-non-msvc: + name: Windows ${{ matrix.width }}-bit ${{ matrix.compiler }} + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + include: + # Cygwin 32-bit + - host: i686-pc-cygwin + width: 32 + arch: x86 + target: i686-pc-cygwin + gcc_prefix: /usr/i686-pc-cygwin + compiler: gcc + - host: i686-pc-cygwin + width: 32 + arch: x86 + target: i686-pc-cygwin + gcc_prefix: /usr/i686-pc-cygwin + compiler: clang + # MinGW-w64 64-bit + - host: x86_64-w64-mingw32 + width: 64 + arch: x64 + target: x86_64-w64-mingw32 + gcc_prefix: /usr/${{ github.workspace }}/mingw64 # unused but keeps the table homogeneous + compiler: clang + - host: x86_64-w64-mingw32 + width: 64 + arch: x64 + target: x86_64-w64-mingw32 + gcc_prefix: /usr/${{ github.workspace }}/mingw64 # unused but keeps the table homogeneous + compiler: gcc + + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v4 + + # ──────────────────────────────── Cygwin & tool-chains ──────────────────────────────── + - uses: egor-tensin/setup-cygwin@v4 + with: + # gcc / g++ are needed so Clang can reuse their start-files & libraries + packages: > + wget make dejagnu automake autoconf libtool texinfo unzip dos2unix + clang gcc-core gcc-g++ + cygwin32-gcc-core cygwin32-gcc-g++ cygwin32-runtime cygwin32-libgcc1 + + # ──────────────────────────────── Common environment ──────────────────────────────── + - name: Export build env + shell: bash + run: | + echo "GCC_PREFIX=${{ matrix.gcc_prefix }}" >> $GITHUB_ENV + echo "CC=${{ matrix.compiler }} --target=${{ matrix.target }} -B${{ matrix.gcc_prefix }}/bin \ + -L${{ matrix.gcc_prefix }}/lib -I${{ matrix.gcc_prefix }}/include" >> $GITHUB_ENV + echo "CXX=${{ matrix.compiler }} --target=${{ matrix.target }} -B${{ matrix.gcc_prefix }}/bin \ + -L${{ matrix.gcc_prefix }}/lib -I${{ matrix.gcc_prefix }}/include" >> $GITHUB_ENV + # make sure the cross-gcc bin dir is found *before* /usr/bin (64-bit) + echo "${{ matrix.gcc_prefix }}/bin" >> $GITHUB_PATH + + # ──────────────────────────────── Pick version from configure.ac ───────────────────── + - id: ver + name: Read libffi version + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + run: | + cd "$(cygpath $RUNNER_WORKSPACE)/libffi" + version=$(sed -nE 's/^AC_INIT\(\[libffi\],[[:space:]]*\[([^]]+)\].*/\1/p' configure.ac) + [[ $version ]] || { echo "Could not parse version"; exit 1; } + echo "version=$version" >> "$GITHUB_OUTPUT" + + # ──────────────────────────────── Build & test ─────────────────────────────────────── + - name: Build and test + shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}' + run: | + set -euo pipefail + cd "$(cygpath $RUNNER_WORKSPACE)/libffi" + + autoreconf -fvi + ./configure \ + --enable-shared \ + --build=${{ matrix.host }} --host=${{ matrix.host }} \ + CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ + CFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" + + make -j$(nproc) + file ./.libs/libffi-*.dll # sanity-check: should say PE32 or PE32+ as expected + + # quick self-tests (dejagnu, etc.) + make -k check || true + build-msvc: name: Windows ${{ matrix.width }}-bit Visual C++ runs-on: windows-latest From 40a76827051bde95e20cc4edeba31a353c074321 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 09:49:00 -0400 Subject: [PATCH 64/87] Improve CI test coverage (#923) Add CI testing on Windows with both gcc and clang. --- .github/workflows/build.yml | 19 +++- testsuite/lib/libffi.exp | 8 +- testsuite/libffi.call/ffitest.h | 3 + testsuite/libffi.threads/ffitest.h | 164 +---------------------------- 4 files changed, 23 insertions(+), 171 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d13b28e4..ff4958eff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -157,7 +157,8 @@ jobs: run: | set -euo pipefail cd "$(cygpath $RUNNER_WORKSPACE)/libffi" - + wget https://rl.gl/cli/rlgl-windows-amd64.zip + unzip rlgl-windows-amd64.zip autoreconf -fvi ./configure \ --enable-shared \ @@ -165,11 +166,18 @@ jobs: CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \ CFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" - make -j$(nproc) - file ./.libs/libffi-*.dll # sanity-check: should say PE32 or PE32+ as expected + make + # sanity-check + file */.libs/*ffi-*.dll - # quick self-tests (dejagnu, etc.) - make -k check || true + TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true + ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl + ./rlgl/rlgl.exe e \ + -l project=libffi \ + -l sha=${GITHUB_SHA:0:7} \ + -l CC=${{ matrix.compiler }} \ + -l host=${{ matrix.host }} \ + --policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log) build-msvc: name: Windows ${{ matrix.width }}-bit Visual C++ @@ -237,6 +245,7 @@ jobs: find ./ -type f -name 'libffi*' ls -l */.libs cp $(find . -name 'libffi-?.dll') ${{ matrix.host }}/testsuite/ + find ./ -name ffi.h TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true ./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl ./rlgl/rlgl.exe e \ diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp index 104196480..81eff7752 100644 --- a/testsuite/lib/libffi.exp +++ b/testsuite/lib/libffi.exp @@ -342,7 +342,7 @@ proc libffi-init { args } { verbose "libffi_dir $libffi_dir" if { $libffi_dir != "" } { set libffi_dir [file dirname ${libffi_dir}] - set libffi_link_flags "-L${libffi_dir}/.libs" + set libffi_link_flags "-L ../.libs" } set_ld_library_path_env_vars @@ -380,7 +380,8 @@ proc libffi_target_compile { source dest type options } { } # search for ffi_mips.h in srcdir, too - lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.." + # lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.." + lappend options "additional_flags=-I ../include -I ${srcdir}/../include -I .." if { [string match $type "executable"] } { lappend options "additional_flags=${libffi_link_flags}" @@ -456,8 +457,9 @@ proc libffi_feature_test { test } { puts $f "int main() {return 0;}" close $f - set lines [libffi_target_compile $src /dev/null assemble ""] + set lines [libffi_target_compile $src $src.i preprocess ""] file delete $src + file delete $src.i return [string match "" $lines] } diff --git a/testsuite/libffi.call/ffitest.h b/testsuite/libffi.call/ffitest.h index 8bd8a3cb6..a7c634b4c 100644 --- a/testsuite/libffi.call/ffitest.h +++ b/testsuite/libffi.call/ffitest.h @@ -1,3 +1,6 @@ +#undef __USE_MINGW_ANSI_STDIO +#define __USE_MINGW_ANSI_STDIO 1 + #include #include #include diff --git a/testsuite/libffi.threads/ffitest.h b/testsuite/libffi.threads/ffitest.h index 8bd8a3cb6..d27d362d6 100644 --- a/testsuite/libffi.threads/ffitest.h +++ b/testsuite/libffi.threads/ffitest.h @@ -1,163 +1 @@ -#include -#include -#include -#include -#include -#include "fficonfig.h" - -#include -#include - -#if defined HAVE_STDINT_H -#include -#endif - -#if defined HAVE_INTTYPES_H -#include -#endif - -#define MAX_ARGS 256 - -#define CHECK(x) \ - do { \ - if(!(x)){ \ - printf("Check failed:\n%s\n", #x); \ - abort(); \ - } \ - } while(0) - -#define CHECK_FLOAT_EQ(x, y) \ - do { \ - if(fabs((x) - (y)) > FLT_EPSILON){ \ - printf("Check failed CHECK_FLOAT_EQ(%s, %s)\n", #x, #y); \ - abort(); \ - } \ - } while(0) - -#define CHECK_DOUBLE_EQ(x, y) \ - do { \ - if(fabs((x) - (y)) > DBL_EPSILON){ \ - printf("Check failed CHECK_FLOAT_EQ(%s, %s)\n", #x, #y); \ - abort(); \ - } \ - } while(0) - -/* Define macros so that compilers other than gcc can run the tests. */ -#undef __UNUSED__ -#if defined(__GNUC__) -#define __UNUSED__ __attribute__((__unused__)) -#define __STDCALL__ __attribute__((stdcall)) -#define __THISCALL__ __attribute__((thiscall)) -#define __FASTCALL__ __attribute__((fastcall)) -#define __MSABI__ __attribute__((ms_abi)) -#else -#define __UNUSED__ -#define __STDCALL__ __stdcall -#define __THISCALL__ __thiscall -#define __FASTCALL__ __fastcall -#endif - -#ifndef ABI_NUM -#define ABI_NUM FFI_DEFAULT_ABI -#define ABI_ATTR -#endif - -/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a - file open. */ -#ifdef HAVE_MMAP_ANON -# undef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -# endif -# define USING_MMAP - -#endif - -#ifdef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# define USING_MMAP - -#endif - -/* msvc kludge. */ -#if defined(_MSC_VER) -#define PRIdLL "I64d" -#define PRIuLL "I64u" -#else -#define PRIdLL "lld" -#define PRIuLL "llu" -#endif - -/* Tru64 UNIX kludge. */ -#if defined(__alpha__) && defined(__osf__) -/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */ -#undef PRIdLL -#define PRIdLL "ld" -#undef PRIuLL -#define PRIuLL "lu" -#define PRId8 "hd" -#define PRIu8 "hu" -#define PRId64 "ld" -#define PRIu64 "lu" -#define PRIuPTR "lu" -#endif - -/* PA HP-UX kludge. */ -#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR) -#define PRIuPTR "lu" -#endif - -/* IRIX kludge. */ -#if defined(__sgi) -/* IRIX 6.5 provides all definitions, but only for C99 - compilations. */ -#define PRId8 "hhd" -#define PRIu8 "hhu" -#if (_MIPS_SZLONG == 32) -#define PRId64 "lld" -#define PRIu64 "llu" -#endif -/* This doesn't match , which always has "lld" here, but the - arguments are uint64_t, int64_t, which are unsigned long, long for - 64-bit in . */ -#if (_MIPS_SZLONG == 64) -#define PRId64 "ld" -#define PRIu64 "lu" -#endif -/* This doesn't match , which has "u" here, but the arguments - are uintptr_t, which is always unsigned long. */ -#define PRIuPTR "lu" -#endif - -/* Solaris < 10 kludge. */ -#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR) -#if defined(__arch64__) || defined (__x86_64__) -#define PRIuPTR "lu" -#else -#define PRIuPTR "u" -#endif -#endif - -/* MSVC kludge. */ -#if defined _MSC_VER -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) -#define PRIuPTR "lu" -#define PRIu8 "u" -#define PRId8 "d" -#define PRIu64 "I64u" -#define PRId64 "I64d" -#endif -#endif - -#ifndef PRIuPTR -#define PRIuPTR "u" -#endif +#include "../libffi.call/ffitest.h" From a46977da5056cc7f23eee6db544d88cd5a88b9f4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 9 Jun 2025 15:55:02 +0200 Subject: [PATCH 65/87] Downgrade Autoconf requirement to version 2.68 (#922) * Downgrade Autoconf requirement to version 2.68 * CI: remove redundant Autoconf install scripts --- .ci/install.sh | 33 ------------------------------ configure.ac | 6 +----- testsuite/emscripten/build.sh | 7 ------- testsuite/emscripten/node-tests.sh | 7 ------- 4 files changed, 1 insertion(+), 52 deletions(-) diff --git a/.ci/install.sh b/.ci/install.sh index 59f8463e6..34871d26c 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -37,39 +37,6 @@ else sudo apt-get update sudo apt install libltdl-dev zip - shopt -s inherit_errexit # propagate failure out of subshells (bash >= 4.4) - - URL=https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz - MAX_TRIES=5 - BACKOFF=2 # seconds; will double every attempt - - attempt=1 - while (( attempt <= MAX_TRIES )); do - echo "➡️ Attempt ${attempt}/${MAX_TRIES}" - if wget --retry-connrefused \ - --waitretry=1 \ - --read-timeout=20 \ - --timeout=15 \ - -qO- "$URL" \ - | tar -xzv; then - echo "✅ Success on attempt ${attempt}" - break - fi - - echo "⚠️ Download or extract failed, retrying in ${BACKOFF}s…" - sleep "$BACKOFF" - BACKOFF=$(( BACKOFF * 2 )) - (( attempt++ )) - done - - if (( attempt > MAX_TRIES )); then - echo "❌ Exhausted retries ($MAX_TRIES) – aborting." >&2 - exit 1 - fi - - mkdir -p ~/i - (cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) - case $HOST in mips64el-linux-gnu | sparc64-linux-gnu) ;; diff --git a/configure.ac b/configure.ac index 69ed04360..d8110716c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this with autoconf to create configure -AC_PREREQ([2.72]) +AC_PREREQ([2.68]) AC_INIT([libffi],[3.5.0],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) @@ -94,10 +94,6 @@ m4_warn([obsolete], [The preprocessor macro `STDC_HEADERS' is obsolete. Except in unusual embedded environments, you can safely include all ISO C90 headers unconditionally.])dnl -# Autoupdate added the next two lines to ensure that your configure -# script's behavior did not change. They are probably safe to remove. -AC_CHECK_INCLUDES_DEFAULT -AC_PROG_EGREP AC_CHECK_FUNCS(memcpy) AC_CHECK_HEADERS(alloca.h) diff --git a/testsuite/emscripten/build.sh b/testsuite/emscripten/build.sh index 0b36df532..83ece7bcf 100755 --- a/testsuite/emscripten/build.sh +++ b/testsuite/emscripten/build.sh @@ -38,13 +38,6 @@ export EM_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" # Specific variables for cross-compilation export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten -wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - -mkdir -p ~/i -(cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) - -# Special build tools are here... -export PATH=$HOME/i/bin:$PATH - autoreconf -fiv emconfigure ./configure --host=$CHOST --prefix="$TARGET" --enable-static --disable-shared --disable-dependency-tracking \ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs diff --git a/testsuite/emscripten/node-tests.sh b/testsuite/emscripten/node-tests.sh index bc4ea601f..016e99c4b 100755 --- a/testsuite/emscripten/node-tests.sh +++ b/testsuite/emscripten/node-tests.sh @@ -13,13 +13,6 @@ export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -s # Specific variables for cross-compilation export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten -wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 -qO - https://ftpmirror.gnu.org/autoconf/autoconf-2.72.tar.gz | tar -xvzf - -mkdir -p ~/i -(cd autoconf-2.72; ./configure --prefix=$HOME/i; make; make install) - -# Special build tools are here... -export PATH=$HOME/i/bin:$PATH - autoreconf -fiv emconfigure ./configure --prefix="$(pwd)/target" --host=$CHOST --enable-static --disable-shared \ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs || From 0947743f691bbd9d034a8ebe178ca8cb81e7fcd7 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 11:53:15 -0400 Subject: [PATCH 66/87] Make tarballs (#924) * Create tarballs in CI --- .github/workflows/tarball.yml | 43 +++++++++++++++++++++++++++++++++++ configure.ac | 6 ++--- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/tarball.yml diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml new file mode 100644 index 000000000..08e9ebefc --- /dev/null +++ b/.github/workflows/tarball.yml @@ -0,0 +1,43 @@ +name: snapshot-dist-tarball +on: + push: + branches: [ master ] + workflow_dispatch: + +jobs: + dist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # git describe needs full history + + - name: Install autotools + run: sudo apt-get update && sudo apt-get -y install autoconf automake libtool texinfo libltdl-dev texlive + + - name: Stamp snapshot version into configure.ac + run: | + VERSION="$(git describe --match 'v[0-9]*' --long --always | sed -e 's/^v//' -e 's/-/.dev./' -e 's/-/+g/')" + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + + # 1) AC_INIT second argument + # AC_INIT([libffi],[],[bug-address]) + sed -E -i "s/^(AC_INIT\(\[libffi\],\s*\[)[^]]+/\1$VERSION/" configure.ac + + # 2) FFI_VERSION_STRING="..." + sed -E -i "s/^(FFI_VERSION_STRING=\")[^\"]+/\1$VERSION/" configure.ac + + - name: autogen + run: ./autogen.sh + + - name: Configure + run: ./configure + + - name: Build dist tarball + run: make dist + + - name: Upload artefact + uses: actions/upload-artifact@v4 + with: + name: "libffi-${{ env.VERSION }}" + path: "libffi-${{ env.VERSION }}.tar.*" diff --git a/configure.ac b/configure.ac index d8110716c..ea1fab0c1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,11 +2,11 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.68]) -AC_INIT([libffi],[3.5.0],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.1-dev],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.0" -FFI_VERSION_NUMBER=30500 +FFI_VERSION_STRING="3.5.1-dev" +FFI_VERSION_NUMBER=30501 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) From 172bfb41f4f27cac939537e907106ef37abae701 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 12:22:35 -0400 Subject: [PATCH 67/87] chore(.github/workflows): update tarball workflow to use softprops/action-gh-release --- .github/workflows/tarball.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 08e9ebefc..b6e6e949c 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -17,7 +17,7 @@ jobs: - name: Stamp snapshot version into configure.ac run: | - VERSION="$(git describe --match 'v[0-9]*' --long --always | sed -e 's/^v//' -e 's/-/.dev./' -e 's/-/+g/')" + VERSION="$(git describe --tags --long --match 'v[0-9]*' | sed -e 's/^v//' -e 's/-/.dev./' -e 's/-/+g/')" echo "VERSION=$VERSION" >> "$GITHUB_ENV" # 1) AC_INIT second argument @@ -36,8 +36,10 @@ jobs: - name: Build dist tarball run: make dist - - name: Upload artefact - uses: actions/upload-artifact@v4 + - name: Create (or update) “snapshots” release + uses: softprops/action-gh-release@v2 with: - name: "libffi-${{ env.VERSION }}" - path: "libffi-${{ env.VERSION }}.tar.*" + tag_name: snapshots + prerelease: true + body: "Snapshot built from ${{ github.sha }}" + files: libffi-${{ env.VERSION }}.tar.* From 2f535b8f747eea5c3336ecf20a3ecc9c0d523f62 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 12:52:43 -0400 Subject: [PATCH 68/87] chore(ci): update tarball workflow in GitHub Actions --- .github/workflows/tarball.yml | 61 +++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index b6e6e949c..91597f3b0 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -8,38 +8,43 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # git describe needs full history +name: snapshot-dist-tarball +on: + push: + branches: [ master ] + workflow_dispatch: - - name: Install autotools - run: sudo apt-get update && sudo apt-get -y install autoconf automake libtool texinfo libltdl-dev texlive +jobs: + dist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: {fetch-depth: 0} - - name: Stamp snapshot version into configure.ac + - name: Compute snapshot VERSION + id: ver run: | - VERSION="$(git describe --tags --long --match 'v[0-9]*' | sed -e 's/^v//' -e 's/-/.dev./' -e 's/-/+g/')" - echo "VERSION=$VERSION" >> "$GITHUB_ENV" - - # 1) AC_INIT second argument - # AC_INIT([libffi],[],[bug-address]) - sed -E -i "s/^(AC_INIT\(\[libffi\],\s*\[)[^]]+/\1$VERSION/" configure.ac - - # 2) FFI_VERSION_STRING="..." - sed -E -i "s/^(FFI_VERSION_STRING=\")[^\"]+/\1$VERSION/" configure.ac - - - name: autogen - run: ./autogen.sh - - - name: Configure - run: ./configure + DESC=$(git describe --long --tags --match 'v[0-9]*' 2>/dev/null || echo "") + VERSION=$(echo "$DESC" | sed -E 's/^v//; s/-([0-9]+)-g/\.dev.\1+g/') + if [[ -z "$VERSION" || "$VERSION" == "$DESC" ]]; then + VERSION="3.5.1-dev.0+g$(git rev-parse --short HEAD)" + fi + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Patch configure.ac + run: | + sed -Ei "s/^(AC_INIT\(\[libffi\],\s*\[)[^]]+/\1${VERSION}/" configure.ac + sed -Ei "s/^(FFI_VERSION_STRING=\")[^\"]+/\1${VERSION}/" configure.ac - - name: Build dist tarball - run: make dist + - run: autoreconf -fi + - run: ./configure + - run: make dist # produces libffi-${VERSION}.tar.gz - name: Create (or update) “snapshots” release uses: softprops/action-gh-release@v2 - with: - tag_name: snapshots - prerelease: true - body: "Snapshot built from ${{ github.sha }}" - files: libffi-${{ env.VERSION }}.tar.* + with: + tag_name: snapshots + prerelease: true + body: "Nightly snapshot built from ${{ github.sha }}" + files: libffi-${{ env.VERSION }}.tar.* From 2a5195bb2a633f7c9cc3b787d16ddb940c2a719d Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 12:54:55 -0400 Subject: [PATCH 69/87] chore(.github/workflows): update tarball.yml indentation --- .github/workflows/tarball.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 91597f3b0..f18044e5f 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -43,8 +43,8 @@ jobs: - name: Create (or update) “snapshots” release uses: softprops/action-gh-release@v2 - with: - tag_name: snapshots - prerelease: true - body: "Nightly snapshot built from ${{ github.sha }}" - files: libffi-${{ env.VERSION }}.tar.* + with: + tag_name: snapshots + prerelease: true + body: "Nightly snapshot built from ${{ github.sha }}" + files: libffi-${{ env.VERSION }}.tar.* From 7f5375d7c75805d02f95516875107e9eb345ae8c Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 12:55:09 -0400 Subject: [PATCH 70/87] chore(workflows): update snapshot release description in tarball.yml --- .github/workflows/tarball.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index f18044e5f..2918680d9 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -46,5 +46,5 @@ jobs: with: tag_name: snapshots prerelease: true - body: "Nightly snapshot built from ${{ github.sha }}" + body: "Snapshot built from ${{ github.sha }}" files: libffi-${{ env.VERSION }}.tar.* From 1f73aa507ed8e8bc49864c99ff21d82dd454cb55 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 12:56:19 -0400 Subject: [PATCH 71/87] refactor(.github/workflows/tarball): remove repeated job blocks --- .github/workflows/tarball.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 2918680d9..d8bd982d5 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -4,16 +4,6 @@ on: branches: [ master ] workflow_dispatch: -jobs: - dist: - runs-on: ubuntu-latest - steps: -name: snapshot-dist-tarball -on: - push: - branches: [ master ] - workflow_dispatch: - jobs: dist: runs-on: ubuntu-latest From ceab352dfa55745ab058a289e59faee925508d10 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 13:01:50 -0400 Subject: [PATCH 72/87] ci: add installation of necessary tools to tarball workflow --- .github/workflows/tarball.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index d8bd982d5..0ce10653f 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -8,6 +8,11 @@ jobs: dist: runs-on: ubuntu-latest steps: + - name: Install tools + run: | + sudo apt update + sudo apt install texlive makeinfo autoconf automake libtool libltdl-dev + - uses: actions/checkout@v4 with: {fetch-depth: 0} From 7ac6f14591d174a314bf45a8b02d136525cd86f9 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 13:08:02 -0400 Subject: [PATCH 73/87] ci: change packages installed during workflow --- .github/workflows/tarball.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 0ce10653f..d89562b4f 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -11,7 +11,7 @@ jobs: - name: Install tools run: | sudo apt update - sudo apt install texlive makeinfo autoconf automake libtool libltdl-dev + sudo apt install texlive texinfo autoconf automake libtool libltdl-dev - uses: actions/checkout@v4 with: {fetch-depth: 0} From b9b837855666636645bd3e00ce60d082ad8cc713 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 13:29:03 -0400 Subject: [PATCH 74/87] fix(github-actions): correct regex in version extraction --- .github/workflows/tarball.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index d89562b4f..9465bb5cd 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -20,7 +20,7 @@ jobs: id: ver run: | DESC=$(git describe --long --tags --match 'v[0-9]*' 2>/dev/null || echo "") - VERSION=$(echo "$DESC" | sed -E 's/^v//; s/-([0-9]+)-g/\.dev.\1+g/') + VERSION=$(echo "$DESC" | sed -E 's/^v//; s/-([0-9]+)-g/\.\1+g/') if [[ -z "$VERSION" || "$VERSION" == "$DESC" ]]; then VERSION="3.5.1-dev.0+g$(git rev-parse --short HEAD)" fi From a18d4e95d39d4b2b155abdea4ff1ac0006c12a6f Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 13:35:29 -0400 Subject: [PATCH 75/87] feat(.github/workflows): add step to wipe old snapshot assets in tarball.yml --- .github/workflows/tarball.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 9465bb5cd..617c14664 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -36,6 +36,15 @@ jobs: - run: ./configure - run: make dist # produces libffi-${VERSION}.tar.gz + - name: Wipe old snapshot assets + uses: mknejp/delete-release-assets@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tag: snapshots # ← whatever tag your nightly release uses + assets: | + libffi-*.tar.* + libffi-*.zip + - name: Create (or update) “snapshots” release uses: softprops/action-gh-release@v2 with: From 26d7be77cc151acb458ef84f66859ef5300ce432 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 18:23:15 -0400 Subject: [PATCH 76/87] ci: update build.sh for Linux build process --- .ci/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index cd9dca771..4eabf568a 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -23,9 +23,9 @@ fi function build_linux() { - ./autogen.sh - ./configure ${HOST+--host=$HOST} ${CONFIGURE_OPTIONS} || cat */config.log + ls -l */config.log + cat */config.log make make dist DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci runtest --version From d994395ce74026f67b50957e6ce899e8ddbe5028 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 18:43:40 -0400 Subject: [PATCH 77/87] ci: update gcc version to 15 in build process --- .ci/install.sh | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/install.sh b/.ci/install.sh index 34871d26c..9fa4c4099 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -6,7 +6,7 @@ if [[ $RUNNER_OS != 'Linux' ]]; then # brew update > brew-update.log 2>&1 # fix an issue with libtool on travis by reinstalling it brew uninstall libtool; - brew install automake libtool dejagnu; + brew install automake libtool dejagnu gcc@15; # Download and extract the rlgl client wget -qO - https://rl.gl/cli/rlgl-darwin-amd64.tgz | \ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff4958eff..e112ab465 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,7 +73,7 @@ jobs: fail-fast: false matrix: platform: [macos-13, macos-14, macos-15] - compilers: [CC=gcc CXX=g++, CC=clang CXX=clang++] + compilers: [CC=gcc-15 CXX=g++, CC=clang CXX=clang++] steps: - run: git config --global core.autocrlf input From 517310ddbf7046a743af035ce61f2b304802bd00 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Mon, 9 Jun 2025 19:03:49 -0400 Subject: [PATCH 78/87] ci: update compiler versions in github workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e112ab465..38d2db98e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,7 +73,7 @@ jobs: fail-fast: false matrix: platform: [macos-13, macos-14, macos-15] - compilers: [CC=gcc-15 CXX=g++, CC=clang CXX=clang++] + compilers: [CC=gcc-15 CXX=g++-15, CC=clang CXX=g++-15] steps: - run: git config --global core.autocrlf input From 330467d55c5f983d16cb2b03703a149db21d07ce Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Tue, 10 Jun 2025 16:01:56 -0400 Subject: [PATCH 79/87] Move new symbols to new symbol versioning. --- libffi.map.in | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libffi.map.in b/libffi.map.in index a12ac0200..cc135ba8e 100644 --- a/libffi.map.in +++ b/libffi.map.in @@ -23,13 +23,6 @@ LIBFFI_BASE_8.0 { ffi_type_longdouble; ffi_type_pointer; - /* Exported functions. */ - ffi_get_version; - ffi_get_version_number; - - ffi_get_default_abi; - ffi_get_closure_size; - ffi_call; ffi_prep_cif; ffi_prep_cif_var; @@ -52,6 +45,19 @@ LIBFFI_BASE_8.0 { *; }; +/* ---------------------------------------------------------------------- + Symbols **added in libffi 3.5.0**. + Give them a fresh namespace so that package managers notice when + code requires a newer libffi than 3.4.x. + -------------------------------------------------------------------- */ +LIBFFI_BASE_8.1 { + global: + ffi_get_version; + ffi_get_version_number; + ffi_get_default_abi; + ffi_get_closure_size; +} LIBFFI_BASE_8.0; + #ifdef FFI_TARGET_HAS_COMPLEX_TYPE LIBFFI_COMPLEX_8.0 { global: From 90220e51bcb2040d24b1f06581f0805a3091acda Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Tue, 10 Jun 2025 16:03:47 -0400 Subject: [PATCH 80/87] Update version. --- README.md | 5 ++++- configure.ac | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e86401436..01ed28f28 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Status ====== -libffi-3.5.0 was released on June 8, 2025. Check the libffi web +libffi-3.5.1 was released on June 10, 2025. Check the libffi web page for updates: . @@ -203,6 +203,9 @@ History See the git log for details at http://github.com/libffi/libffi. + 3.5.1 Jun-10-2025 + Fix symbol versioning error. + 3.5.0 Jun-8-2025 Add FFI_VERSION_STRING and FFI_VERSION_NUMBER macros, as well as ffi_get_version() and ffi_get_version_number() functions. diff --git a/configure.ac b/configure.ac index ea1fab0c1..258107d70 100644 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.68]) -AC_INIT([libffi],[3.5.1-dev],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.1],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.1-dev" +FFI_VERSION_STRING="3.5.1" FFI_VERSION_NUMBER=30501 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) From e28a0d5b0708ade04979e2a1d5c2a2d3acc749ec Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Tue, 10 Jun 2025 16:17:58 -0400 Subject: [PATCH 81/87] ci: add fail-if-no-assets option in tarball workflow --- .github/workflows/tarball.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 617c14664..c83222e7c 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -41,6 +41,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} tag: snapshots # ← whatever tag your nightly release uses + fail-if-no-assets: false assets: | libffi-*.tar.* libffi-*.zip From d0f831bca60ea74b55a3155b929f195a971a3cac Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 21 Jun 2025 16:05:31 -0400 Subject: [PATCH 82/87] feat: add QUESTION to .gail-labels --- .gail-labels | 1 + 1 file changed, 1 insertion(+) diff --git a/.gail-labels b/.gail-labels index 446914469..2090d9fe6 100644 --- a/.gail-labels +++ b/.gail-labels @@ -5,6 +5,7 @@ BUILD-ERROR RUNTIME-ERROR FEATURE-REQUEST +QUESTION # Operating systems ANDROID From 60671187688ae3b295ab0e1dd77a8d6dd7a805a2 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Fri, 11 Jul 2025 03:17:18 -0400 Subject: [PATCH 83/87] fix(tramp): ensure file descriptor is closed on exec. Thanks to Florian Weimer. c# Please enter the commit message for your changes. Lines starting --- src/tramp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tramp.c b/src/tramp.c index 8ec084868..31180efb6 100644 --- a/src/tramp.c +++ b/src/tramp.c @@ -236,7 +236,7 @@ ffi_tramp_get_libffi (void) if (!found) return 0; - tramp_globals.fd = open (file, O_RDONLY); + tramp_globals.fd = open (file, O_RDONLY | O_CLOEXEC); if (tramp_globals.fd == -1) return 0; From b7885ace59999564aec38c812156093cf0bfac02 Mon Sep 17 00:00:00 2001 From: Weitian LI Date: Sat, 2 Aug 2025 14:27:51 +0800 Subject: [PATCH 84/87] fix: enable FFI_MMAP_EXEC_WRIT for DragonFly BSD (#930) Similar to PR #265 [1], we need to enable FFI_MMAP_EXEC_WRIT to use explicit write+exec mapping on DragonFly BSD. Without this fix, we were having segfaults with Meld [2]; it would crash with SIGSEGV after 5 diff operations. The crash was caused by it attempting to execute code from non-execute memory region. Moreover, if we set the `machdep.pmap_nx_enable=2` tunable (i.e., strict NX mode), Meld would crash upon the first diff operation. Fix the `configure.ac` script to enable `FFI_MMAP_EXEC_WRIT` for DragonFly BSD. In addition, add it to the supported platforms table. [1] https://github.com/libffi/libffi/pull/265 [2] https://meldmerge.org/ --- README.md | 1 + configure.ac | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01ed28f28..33d2f66c9 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ tested: | X86 | Solaris | Oracle Solaris Studio C | | X86 | Windows/Cygwin | GCC | | X86 | Windows/MinGW | GCC | +| X86-64 | DragonFly BSD | GCC | | X86-64 | FreeBSD | GCC | | X86-64 | Linux | GCC | | X86-64 | Linux/x32 | GCC | diff --git a/configure.ac b/configure.ac index 258107d70..a04f2f821 100644 --- a/configure.ac +++ b/configure.ac @@ -230,7 +230,7 @@ case "$target" in [Cannot use PROT_EXEC on this target, so, we revert to alternative means]) ;; - *-apple-* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*) + *-apple-* | *-*-dragonfly* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*) AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1, [Cannot use malloc on this target, so, we revert to alternative means]) From 20eacb22e9e9cdd6402cb75278dede2b36051e53 Mon Sep 17 00:00:00 2001 From: Kohei Tokunaga <43872416+ktock@users.noreply.github.com> Date: Sat, 2 Aug 2025 15:28:46 +0900 Subject: [PATCH 85/87] Emscripten: Add wasm64 target (#927) * src/wasm32: Allow building with Emscripten with 64bit support MEMORY64 enables 64bit pointers so this commit updates the accessors for the libffi data structures accordingly. Each JS functions in ffi.c receives pointers as BigInt (i64) values and with casts them to Numer (i53) using bigintToI53Checked. While memory64 supports 64bit addressing, the maximum memory size is currently limited to 16GiB [1]. Therefore, we can assume that the passed pointers are within the Number's range. [1] https://webassembly.github.io/memory64/js-api/#limits Signed-off-by: Kohei Tokunaga * Add wasm64 target to the build scripts This commit adds support for the wasm64 target via the configure script. Emscripten supports two modes of the -sMEMORY64 flag[1] so the script allows users specifying the value through a configuration variable. Additionally, "src/wasm32" directory has been renamed to the more generic "src/wasm" because it's now shared between both 32bit and 64bit builds. [1] https://emscripten.org/docs/tools_reference/settings_reference.html#memory64 Signed-off-by: Kohei Tokunaga * GitHub Actions: Add wasm64 tests This commit adds a test matrix for wasm32, wasm64 and wasm64 with the -sMEMORY64=2 flag, using the latest version of Emscripten. -Wno-main is added to suppress the following warning in unwindtest.cc and unwindtest_ffi_call.cc. > FAIL: libffi.closures/unwindtest_ffi_call.cc -W -Wall -O2 (test for excess errors) > Excess errors: > ./libffi.closures/unwindtest_ffi_call.cc:20:5: warning: 'main' should not be 'extern "C"' [-Wmain] > 20 | int main (void) > | ^ > 1 warning generated. Signed-off-by: Kohei Tokunaga * testsuite: Fix types of main function test_libffi.py calls each test's main function without arguments, but some tests define the main function with parameters. This signature mismatch causes a runtime error with the recent version of Emscripten. This commit resolves this issue by updating the function signatures to match the way they are called. Signed-off-by: Kohei Tokunaga * README: Add document about WASM64 Signed-off-by: Kohei Tokunaga --------- Signed-off-by: Kohei Tokunaga --- .github/workflows/emscripten.yml | 61 +++++- Makefile.am | 4 +- README.md | 1 + configure.ac | 8 + configure.host | 7 +- src/{wasm32 => wasm}/ffi.c | 211 +++++++++++++++----- src/{wasm32 => wasm}/ffitarget.h | 17 ++ testsuite/emscripten/build.sh | 4 +- testsuite/emscripten/node-tests.sh | 8 +- testsuite/libffi.closures/cls_dbls_struct.c | 2 +- testsuite/libffi.closures/huge_struct.c | 3 +- 11 files changed, 257 insertions(+), 69 deletions(-) rename src/{wasm32 => wasm}/ffi.c (79%) rename src/{wasm32 => wasm}/ffitarget.h (86%) diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 2be8df404..a8c0a1001 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -19,7 +19,7 @@ env: # "info" field, or in Makefile.envs: # https://github.com/pyodide/pyodide/blob/main/Makefile.envs#L2 PYTHON_VERSION: 3.12.7 - EMSCRIPTEN_VERSION: 3.1.58 + EMSCRIPTEN_VERSION: 4.0.10 EM_CACHE_FOLDER: emsdk-cache jobs: @@ -39,6 +39,21 @@ jobs: actions-cache-folder: ${{ env.EM_CACHE_FOLDER }} test-dejagnu: + strategy: + matrix: + target: + - name: wasm32 + host: wasm32 + configureflags: + testflags: + - name: wasm64 + host: wasm64 + configureflags: + testflags: -sMEMORY64=1 + - name: wasm64-2 + host: wasm64 + configureflags: WASM64_MEMORY64=2 + testflags: -sMEMORY64=2 runs-on: ubuntu-24.04 needs: [setup-emsdk-cache] steps: @@ -62,11 +77,26 @@ jobs: version: ${{ env.EMSCRIPTEN_VERSION }} actions-cache-folder: ${{ env.EM_CACHE_FOLDER }} + - name: Setup node.js + uses: actions/setup-node@v4 + with: + node-version: 24 + + # This step updates emsdk's configuration file ".emscripten" to point to + # nodejs installed in the previous step. + - name: Configure emsdk to use the installed node.js + run: sed -i -E 's|NODE_JS = .*|NODE_JS = '"'$(which node)'"'|g' ${EMSDK}/.emscripten + - name: Install dependencies run: sudo apt-get install dejagnu libltdl-dev - name: Run tests run: testsuite/emscripten/node-tests.sh + env: + TARGET_HOST: ${{ matrix.target.host }} + EXTRA_CONFIGURE_FLAGS: ${{ matrix.target.configureflags }} + EXTRA_CFLAGS: ${{ matrix.target.testflags }} + EXTRA_TEST_LDFLAGS: ${{ matrix.target.testflags }} - name: Install rlgl and run run: | @@ -77,6 +107,21 @@ jobs: exit $? build: + strategy: + matrix: + target: + - name: wasm32 + host: wasm32 + configureflags: + testflags: + - name: wasm64 + host: wasm64 + configureflags: + testflags: -sMEMORY64=1 + - name: wasm64-2 + host: wasm64 + configureflags: WASM64_MEMORY64=2 + testflags: -sMEMORY64=2 runs-on: ubuntu-24.04 needs: [setup-emsdk-cache] steps: @@ -100,6 +145,9 @@ jobs: - name: Build run: ./testsuite/emscripten/build.sh + env: + TARGET_HOST: ${{ matrix.target.host }} + EXTRA_CONFIGURE_FLAGS: ${{ matrix.target.configureflags }} - name: Build tests run: | @@ -107,16 +155,23 @@ jobs: cp -r testsuite/libffi.closures testsuite/libffi.closures.test ./testsuite/emscripten/build-tests.sh testsuite/libffi.call.test ./testsuite/emscripten/build-tests.sh testsuite/libffi.closures.test + env: + EXTRA_CFLAGS: ${{ matrix.target.testflags }} + EXTRA_LD_FLAGS: ${{ matrix.target.testflags }} - name: Store artifacts uses: actions/upload-artifact@v4 with: - name: built-tests + name: built-tests-${{ matrix.target.name }} path: ./testsuite/libffi.c*/ test: strategy: matrix: + target: + - name: wasm32 + - name: wasm64 + - name: wasm64-2 browser: ["chrome"] # FIXME: selenium can't find gecko driver for "firefox" runs-on: ubuntu-24.04 @@ -128,7 +183,7 @@ jobs: - name: Download build artifact uses: actions/download-artifact@v4 with: - name: built-tests + name: built-tests-${{ matrix.target.name }} path: ./testsuite/ - uses: conda-incubator/setup-miniconda@v3 diff --git a/Makefile.am b/Makefile.am index cffcb9f6f..c3bcf00b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,7 +67,7 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ src/s390/ffitarget.h src/s390/internal.h src/sh/ffitarget.h \ src/sh64/ffitarget.h src/sparc/ffitarget.h \ src/sparc/internal.h src/tile/ffitarget.h src/vax/ffitarget.h \ - src/wasm32/ffitarget.h \ + src/wasm/ffitarget.h \ src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h \ src/x86/asmnames.h src/xtensa/ffitarget.h src/dlmalloc.c \ src/kvx/ffitarget.h src/kvx/asm.h \ @@ -98,7 +98,7 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \ src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \ src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \ - src/wasm32/ffi.c \ + src/wasm/ffi.c \ src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \ src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \ src/xtensa/ffi.c src/xtensa/sysv.S src/kvx/ffi.c \ diff --git a/README.md b/README.md index 33d2f66c9..02910aa43 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ tested: | TILE-Gx/TILEPro | Linux | GCC | | VAX | OpenBSD/vax | GCC | | WASM32 | Emscripten | EMCC | +| WASM64 | Emscripten | EMCC | | X86 | FreeBSD | GCC | | X86 | GNU HURD | GCC | | X86 | Interix | GCC | diff --git a/configure.ac b/configure.ac index a04f2f821..3ca84e25a 100644 --- a/configure.ac +++ b/configure.ac @@ -123,6 +123,8 @@ AC_C_BIGENDIAN GCC_AS_CFI_PSEUDO_OP +AC_ARG_VAR([WASM64_MEMORY64], [Used only for the wasm64 target. Set to 1 (default) or 2 for Emscripten's -sMEMORY64 mode]) + case "$TARGET" in SPARC) AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs], @@ -182,6 +184,12 @@ case "$TARGET" in [Define if the compiler uses zarch features.]) fi ;; + wasm64) + if test -z "$WASM64_MEMORY64"; then + WASM64_MEMORY64=1 + fi + CFLAGS="$CFLAGS -sMEMORY64=$WASM64_MEMORY64" + ;; esac AC_CACHE_CHECK([whether compiler supports pointer authentication], diff --git a/configure.host b/configure.host index c69a49cef..4e10c3edb 100644 --- a/configure.host +++ b/configure.host @@ -261,7 +261,12 @@ case "${host}" in ;; wasm32-*-*) - TARGET=wasm32; TARGETDIR=wasm32 + TARGET=wasm32; TARGETDIR=wasm + SOURCES="ffi.c" + ;; + + wasm64-*-*) + TARGET=wasm64; TARGETDIR=wasm SOURCES="ffi.c" ;; diff --git a/src/wasm32/ffi.c b/src/wasm/ffi.c similarity index 79% rename from src/wasm32/ffi.c rename to src/wasm/ffi.c index 632848712..486ffa785 100644 --- a/src/wasm32/ffi.c +++ b/src/wasm/ffi.c @@ -59,16 +59,29 @@ EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$co offsetof(struct, field) == offset, \ "Memory layout of '" #struct "' has changed: '" #field "' is in an unexpected location"); +#if __SIZEOF_POINTER__ == 4 + +#define FFI_EMSCRIPTEN_ABI FFI_WASM32_EMSCRIPTEN +#define PTR_SIG 'i' + +#define DEC_PTR(p) p +#define ENC_PTR(p) p + +#define DEREF_PTR(addr, offset) DEREF_U32(addr, offset) +#define DEREF_PTR_NUMBER(addr, offset) DEREF_PTR(addr, offset) + 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); CHECK_FIELD_OFFSET(ffi_cif, rtype, 4*3); +CHECK_FIELD_OFFSET(ffi_cif, flags, 4*5); CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 4*6); #define CIF__ABI(addr) DEREF_U32(addr, 0) #define CIF__NARGS(addr) DEREF_U32(addr, 1) #define CIF__ARGTYPES(addr) DEREF_U32(addr, 2) #define CIF__RTYPE(addr) DEREF_U32(addr, 3) +#define CIF__FLAGS(addr) DEREF_U32(addr, 5) #define CIF__NFIXEDARGS(addr) DEREF_U32(addr, 6) CHECK_FIELD_OFFSET(ffi_type, size, 0); @@ -81,6 +94,49 @@ CHECK_FIELD_OFFSET(ffi_type, elements, 8); #define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 6, 0) #define FFI_TYPE__ELEMENTS(addr) DEREF_U32(addr + 8, 0) +#elif __SIZEOF_POINTER__ == 8 + +#define FFI_EMSCRIPTEN_ABI FFI_WASM64_EMSCRIPTEN +#define PTR_SIG 'j' + +// DEC_PTR casts a pointer value (comming from Wasm) represented as BigInt (i64) to Number (i53). +// This should be used for a pointer that is expected to be within the i53 range. If the pointer +// value is outside the Number's range, the value will become NaN. +#define DEC_PTR(p) bigintToI53Checked(p) +// ENC_PTR casts a pointer value represented as Number to BigInt (i64) +#define ENC_PTR(p) BigInt(p) + +#define DEREF_PTR(addr, offset) DEREF_U64(addr, offset) +#define DEREF_PTR_NUMBER(addr, offset) DEC_PTR(DEREF_PTR(addr, offset)) + +CHECK_FIELD_OFFSET(ffi_cif, abi, 0); +CHECK_FIELD_OFFSET(ffi_cif, nargs, 4); +CHECK_FIELD_OFFSET(ffi_cif, arg_types, 8); +CHECK_FIELD_OFFSET(ffi_cif, rtype, 16); +CHECK_FIELD_OFFSET(ffi_cif, flags, 28); +CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 32); + +#define CIF__ABI(addr) DEREF_U32(addr, 0) +#define CIF__NARGS(addr) DEREF_U32(addr + 4, 0) +#define CIF__ARGTYPES(addr) DEREF_U64(addr + 8, 0) +#define CIF__RTYPE(addr) DEREF_U64(addr + 16, 0) +#define CIF__FLAGS(addr) DEREF_U32(addr + 28, 0) +#define CIF__NFIXEDARGS(addr) DEREF_U32(addr + 32, 0) + +CHECK_FIELD_OFFSET(ffi_type, size, 0); +CHECK_FIELD_OFFSET(ffi_type, alignment, 8); +CHECK_FIELD_OFFSET(ffi_type, type, 10); +CHECK_FIELD_OFFSET(ffi_type, elements, 16); + +#define FFI_TYPE__SIZE(addr) DEREF_U64(addr, 0) +#define FFI_TYPE__ALIGN(addr) DEREF_U16(addr + 8, 0) +#define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 10, 0) +#define FFI_TYPE__ELEMENTS(addr) DEREF_U64(addr + 16, 0) + +#else +#error "Unknown pointer size" +#endif + #define ALIGN_ADDRESS(addr, align) (addr &= (~((align) - 1))) #define STACK_ALLOC(stack, size, align) ((stack -= (size)), ALIGN_ADDRESS(stack, align)) @@ -100,7 +156,7 @@ _Static_assert(FFI_BAD_TYPEDEF_MACRO == FFI_BAD_TYPEDEF, "FFI_BAD_TYPEDEF must b ffi_status FFI_HIDDEN ffi_prep_cif_machdep(ffi_cif *cif) { - if (cif->abi != FFI_WASM32_EMSCRIPTEN) + if (cif->abi != FFI_EMSCRIPTEN_ABI) return FFI_BAD_ABI; // This is called after ffi_prep_cif_machdep_var so we need to avoid // overwriting cif->nfixedargs. @@ -144,6 +200,7 @@ ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs) EM_JS_MACROS( void, unbox_small_structs, (ffi_type type_ptr), { + type_ptr = DEC_PTR(type_ptr); var type_id = FFI_TYPE__TYPEID(type_ptr); while (type_id === FFI_TYPE_STRUCT) { // Don't unbox single element structs if they are bigger than 16 bytes. This @@ -156,15 +213,15 @@ unbox_small_structs, (ffi_type type_ptr), { // // See the Python comment here: // https://github.com/python/cpython/blob/a16a9f978f42b8a09297c1efbf33877f6388c403/Modules/_ctypes/stgdict.c#L718-L779 - if (FFI_TYPE__SIZE(type_ptr) > 16) { + if (DEC_PTR(FFI_TYPE__SIZE(type_ptr)) > 16) { break; } - var elements = FFI_TYPE__ELEMENTS(type_ptr); - var first_element = DEREF_U32(elements, 0); + var elements = DEC_PTR(FFI_TYPE__ELEMENTS(type_ptr)); + var first_element = DEREF_PTR_NUMBER(elements, 0); if (first_element === 0) { type_id = FFI_TYPE_VOID; break; - } else if (DEREF_U32(elements, 1) === 0) { + } else if (DEREF_PTR_NUMBER(elements, 1) === 0) { type_ptr = first_element; type_id = FFI_TYPE__TYPEID(first_element); } else { @@ -178,10 +235,15 @@ EM_JS_MACROS( void, ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), { + cif = DEC_PTR(cif); + fn = DEC_PTR(fn); + rvalue = DEC_PTR(rvalue); + avalue = DEC_PTR(avalue); var abi = CIF__ABI(cif); var nargs = CIF__NARGS(cif); var nfixedargs = CIF__NFIXEDARGS(cif); - var arg_types_ptr = CIF__ARGTYPES(cif); + var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif)); + var flags = CIF__FLAGS(cif); var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif)); var rtype_ptr = rtype_unboxed[0]; var rtype_id = rtype_unboxed[1]; @@ -205,7 +267,7 @@ 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) { - args.push(rvalue); + args.push(ENC_PTR(rvalue)); ret_by_arg = true; } @@ -214,8 +276,8 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), // Javascript to C automatically, here we manually do the inverse conversion // from C to Javascript. for (var i = 0; i < nfixedargs; i++) { - var arg_ptr = DEREF_U32(avalue, i); - var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i)); + var arg_ptr = DEREF_PTR_NUMBER(avalue, i); + var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i)); var arg_type_ptr = arg_unboxed[0]; var arg_type_id = arg_unboxed[1]; @@ -226,7 +288,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), case FFI_TYPE_INT: case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: args.push(DEREF_U32(arg_ptr, 0)); break; case FFI_TYPE_FLOAT: @@ -260,11 +321,14 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), // Nontrivial structs are passed by pointer. // Have to copy the struct onto the stack though because C ABI says it's // call by value. - var size = FFI_TYPE__SIZE(arg_type_ptr); + var size = DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)); var align = FFI_TYPE__ALIGN(arg_type_ptr); STACK_ALLOC(cur_stack_ptr, size, align); HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size)); - args.push(cur_stack_ptr); + args.push(ENC_PTR(cur_stack_ptr)); + break; + case FFI_TYPE_POINTER: + args.push(DEREF_PTR(arg_ptr, 0)); break; case FFI_TYPE_COMPLEX: throw new Error('complex marshalling nyi'); @@ -282,11 +346,11 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), // We don't have any way of knowing how many args were actually passed, so we // just always copy extra nonsense past the end. The ownwards call will know // not to look at it. - if (nfixedargs != nargs) { + if (flags & VARARGS_FLAG) { var struct_arg_info = []; for (var i = nargs - 1; i >= nfixedargs; i--) { - var arg_ptr = DEREF_U32(avalue, i); - var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i)); + var arg_ptr = DEREF_PTR_NUMBER(avalue, i); + var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i)); var arg_type_ptr = arg_unboxed[0]; var arg_type_id = arg_unboxed[1]; switch (arg_type_id) { @@ -303,7 +367,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), case FFI_TYPE_INT: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: case FFI_TYPE_FLOAT: STACK_ALLOC(cur_stack_ptr, 4, 4); DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0); @@ -326,8 +389,12 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), // Again, struct must be passed by pointer. // But ABI is by value, so have to copy struct onto stack. // Currently arguments are going onto stack so we can't put it there now. Come back for this. - STACK_ALLOC(cur_stack_ptr, 4, 4); - struct_arg_info.push([cur_stack_ptr, arg_ptr, FFI_TYPE__SIZE(arg_type_ptr), FFI_TYPE__ALIGN(arg_type_ptr)]); + STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__); + struct_arg_info.push([cur_stack_ptr, arg_ptr, DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]); + break; + case FFI_TYPE_POINTER: + STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__); + DEREF_PTR(cur_stack_ptr, 0) = DEREF_PTR(arg_ptr, 0); break; case FFI_TYPE_COMPLEX: throw new Error('complex arg marshalling nyi'); @@ -336,7 +403,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), } } // extra normal argument which is the pointer to the varargs. - args.push(cur_stack_ptr); + args.push(ENC_PTR(cur_stack_ptr)); // Now allocate variable struct args on stack too. for (var i = 0; i < struct_arg_info.length; i++) { var struct_info = struct_arg_info[i]; @@ -346,7 +413,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), var align = struct_info[3]; STACK_ALLOC(cur_stack_ptr, size, align); HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size)); - DEREF_U32(arg_target, 0) = cur_stack_ptr; + DEREF_PTR(arg_target, 0) = ENC_PTR(cur_stack_ptr); } } stackRestore(cur_stack_ptr); @@ -371,7 +438,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), case FFI_TYPE_INT: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: DEREF_U32(rvalue, 0) = result; break; case FFI_TYPE_FLOAT: @@ -392,6 +458,9 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), case FFI_TYPE_SINT64: DEREF_U64(rvalue, 0) = result; break; + case FFI_TYPE_POINTER: + DEREF_PTR(rvalue, 0) = result; + break; case FFI_TYPE_COMPLEX: throw new Error('complex ret marshalling nyi'); default: @@ -403,6 +472,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { ffi_call_js(cif, fn, rvalue, avalue); } +#if __SIZEOF_POINTER__ == 4 + CHECK_FIELD_OFFSET(ffi_closure, ftramp, 4*0); CHECK_FIELD_OFFSET(ffi_closure, cif, 4*1); CHECK_FIELD_OFFSET(ffi_closure, fun, 4*2); @@ -413,12 +484,30 @@ CHECK_FIELD_OFFSET(ffi_closure, user_data, 4*3); #define CLOSURE__fun(addr) DEREF_U32(addr, 2) #define CLOSURE__user_data(addr) DEREF_U32(addr, 3) +#elif __SIZEOF_POINTER__ == 8 + +CHECK_FIELD_OFFSET(ffi_closure, ftramp, 0); +CHECK_FIELD_OFFSET(ffi_closure, cif, 8); +CHECK_FIELD_OFFSET(ffi_closure, fun, 16); +CHECK_FIELD_OFFSET(ffi_closure, user_data, 24); + +#define CLOSURE__wrapper(addr) DEREF_U64(addr, 0) +#define CLOSURE__cif(addr) DEREF_U64(addr, 1) +#define CLOSURE__fun(addr) DEREF_U64(addr, 2) +#define CLOSURE__user_data(addr) DEREF_U64(addr, 3) + +#else +#error "Unknown pointer size" +#endif + EM_JS_MACROS(void *, ffi_closure_alloc_js, (size_t size, void **code), { + size = DEC_PTR(size); + code = DEC_PTR(code); var closure = _malloc(size); var index = getEmptyTableSlot(); - DEREF_U32(code, 0) = index; - CLOSURE__wrapper(closure) = index; - return closure; + DEREF_PTR(code, 0) = ENC_PTR(index); + CLOSURE__wrapper(closure) = ENC_PTR(index); + return ENC_PTR(closure); }) void * __attribute__ ((visibility ("default"))) @@ -427,7 +516,8 @@ ffi_closure_alloc(size_t size, void **code) { } EM_JS_MACROS(void, ffi_closure_free_js, (void *closure), { - var index = CLOSURE__wrapper(closure); + closure = DEC_PTR(closure); + var index = DEC_PTR(CLOSURE__wrapper(closure)); freeTableIndexes.push(index); _free(closure); }) @@ -442,10 +532,15 @@ ffi_status, ffi_prep_closure_loc_js, (ffi_closure *closure, ffi_cif *cif, void *fun, void *user_data, void *codeloc), { + closure = DEC_PTR(closure); + cif = DEC_PTR(cif); + fun = DEC_PTR(fun); + user_data = DEC_PTR(user_data); + codeloc = DEC_PTR(codeloc); var abi = CIF__ABI(cif); var nargs = CIF__NARGS(cif); var nfixedargs = CIF__NFIXEDARGS(cif); - var arg_types_ptr = CIF__ARGTYPES(cif); + var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif)); var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif)); var rtype_ptr = rtype_unboxed[0]; var rtype_id = rtype_unboxed[1]; @@ -461,7 +556,7 @@ ffi_prep_closure_loc_js, case FFI_TYPE_STRUCT: case FFI_TYPE_LONGDOUBLE: // Return via a first pointer argument. - sig = 'vi'; + sig = 'v' + PTR_SIG; ret_by_arg = true; break; case FFI_TYPE_INT: @@ -471,7 +566,6 @@ ffi_prep_closure_loc_js, case FFI_TYPE_SINT16: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: sig = 'i'; break; case FFI_TYPE_FLOAT: @@ -484,6 +578,9 @@ ffi_prep_closure_loc_js, case FFI_TYPE_SINT64: sig = 'j'; break; + case FFI_TYPE_POINTER: + sig = PTR_SIG; + break; case FFI_TYPE_COMPLEX: throw new Error('complex ret marshalling nyi'); default: @@ -492,11 +589,11 @@ ffi_prep_closure_loc_js, var unboxed_arg_type_id_list = []; var unboxed_arg_type_info_list = []; for (var i = 0; i < nargs; i++) { - var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i)); + var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i)); var arg_type_ptr = arg_unboxed[0]; var arg_type_id = arg_unboxed[1]; unboxed_arg_type_id_list.push(arg_type_id); - unboxed_arg_type_info_list.push([FFI_TYPE__SIZE(arg_type_ptr), FFI_TYPE__ALIGN(arg_type_ptr)]); + unboxed_arg_type_info_list.push([DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]); } for (var i = 0; i < nfixedargs; i++) { switch (unboxed_arg_type_id_list[i]) { @@ -507,8 +604,6 @@ ffi_prep_closure_loc_js, case FFI_TYPE_SINT16: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - case FFI_TYPE_STRUCT: sig += 'i'; break; case FFI_TYPE_FLOAT: @@ -524,6 +619,10 @@ ffi_prep_closure_loc_js, case FFI_TYPE_SINT64: sig += 'j'; break; + case FFI_TYPE_STRUCT: + case FFI_TYPE_POINTER: + sig += PTR_SIG; + break; case FFI_TYPE_COMPLEX: throw new Error('complex marshalling nyi'); default: @@ -532,7 +631,7 @@ ffi_prep_closure_loc_js, } if (nfixedargs < nargs) { // extra pointer to varargs stack - sig += 'i'; + sig += PTR_SIG; } LOG_DEBUG("CREATE_CLOSURE", "sig:", sig); function trampoline() { @@ -551,7 +650,7 @@ ffi_prep_closure_loc_js, STACK_ALLOC(cur_ptr, 8, 8); ret_ptr = cur_ptr; } - cur_ptr -= 4 * nargs; + cur_ptr -= __SIZEOF_POINTER__ * nargs; var args_ptr = cur_ptr; var carg_idx = 0; // Here we either have the actual argument, or a pair of BigInts for long @@ -572,58 +671,62 @@ ffi_prep_closure_loc_js, case FFI_TYPE_SINT8: // Bad things happen if we don't align to 4 here STACK_ALLOC(cur_ptr, 1, 4); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_U8(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_UINT16: case FFI_TYPE_SINT16: // Bad things happen if we don't align to 4 here STACK_ALLOC(cur_ptr, 2, 4); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_U16(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_INT: case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: STACK_ALLOC(cur_ptr, 4, 4); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_U32(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_STRUCT: // cur_arg is already a pointer to struct // copy it onto stack to pass by value STACK_ALLOC(cur_ptr, arg_size, arg_align); - HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(cur_arg, cur_arg + arg_size)); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(DEC_PTR(cur_arg), DEC_PTR(cur_arg) + arg_size)); + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); break; case FFI_TYPE_FLOAT: STACK_ALLOC(cur_ptr, 4, 4); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_F32(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_DOUBLE: STACK_ALLOC(cur_ptr, 8, 8); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_F64(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: STACK_ALLOC(cur_ptr, 8, 8); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_U64(cur_ptr, 0) = cur_arg; break; case FFI_TYPE_LONGDOUBLE: STACK_ALLOC(cur_ptr, 16, 8); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); DEREF_U64(cur_ptr, 0) = cur_arg; cur_arg = args[jsarg_idx++]; DEREF_U64(cur_ptr, 1) = cur_arg; break; + case FFI_TYPE_POINTER: + STACK_ALLOC(cur_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__); + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); + DEREF_PTR(cur_ptr, 0) = cur_arg; + break; } } // If its a varargs call, last js argument is a pointer to the varargs. - var varargs = args[args.length - 1]; + var varargs = DEC_PTR(args[args.length - 1]); // We have no way of knowing how many varargs were actually provided, this // fills the rest of the stack space allocated with nonsense. The onward // call will know to ignore the nonsense. @@ -639,20 +742,20 @@ ffi_prep_closure_loc_js, if (arg_type_id === FFI_TYPE_STRUCT) { // In this case varargs is a pointer to pointer to struct so we need to // deref once - var struct_ptr = DEREF_U32(varargs, 0); + var struct_ptr = DEREF_PTR_NUMBER(varargs, 0); STACK_ALLOC(cur_ptr, arg_size, arg_align); HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(struct_ptr, struct_ptr + arg_size)); - DEREF_U32(args_ptr, carg_idx) = cur_ptr; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr); } else { - DEREF_U32(args_ptr, carg_idx) = varargs; + DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(varargs); } - varargs += 4; + varargs += __SIZEOF_POINTER__; } stackRestore(cur_ptr); stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure)); getWasmTableEntry(CLOSURE__fun(closure))( - CLOSURE__cif(closure), ret_ptr, args_ptr, + CLOSURE__cif(closure), ENC_PTR(ret_ptr), ENC_PTR(args_ptr), CLOSURE__user_data(closure) ); stackRestore(orig_stack_ptr); @@ -677,9 +780,9 @@ ffi_prep_closure_loc_js, return FFI_BAD_TYPEDEF_MACRO; } setWasmTableEntry(codeloc, wasm_trampoline); - CLOSURE__cif(closure) = cif; - CLOSURE__fun(closure) = fun; - CLOSURE__user_data(closure) = user_data; + CLOSURE__cif(closure) = ENC_PTR(cif); + CLOSURE__fun(closure) = ENC_PTR(fun); + CLOSURE__user_data(closure) = ENC_PTR(user_data); return FFI_OK_MACRO; }) @@ -688,7 +791,7 @@ ffi_prep_closure_loc_js, ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc) { - if (cif->abi != FFI_WASM32_EMSCRIPTEN) + if (cif->abi != FFI_EMSCRIPTEN_ABI) return FFI_BAD_ABI; return ffi_prep_closure_loc_js(closure, cif, (void *)fun, user_data, codeloc); diff --git a/src/wasm32/ffitarget.h b/src/wasm/ffitarget.h similarity index 86% rename from src/wasm32/ffitarget.h rename to src/wasm/ffitarget.h index ac78b7433..10041c00d 100644 --- a/src/wasm32/ffitarget.h +++ b/src/wasm/ffitarget.h @@ -42,14 +42,31 @@ typedef void (*ffi_fp)(void); typedef enum ffi_abi { FFI_FIRST_ABI = 0, +#if __SIZEOF_POINTER__ == 4 FFI_WASM32, // "raw", no structures, varargs, or closures (not implemented!) FFI_WASM32_EMSCRIPTEN, // structures, varargs, and split 64-bit params +#elif __SIZEOF_POINTER__ == 8 + FFI_WASM64, + FFI_WASM64_EMSCRIPTEN, +#else +#error "Unknown pointer size" +#endif FFI_LAST_ABI, +#if __SIZEOF_POINTER__ == 4 #ifdef __EMSCRIPTEN__ FFI_DEFAULT_ABI = FFI_WASM32_EMSCRIPTEN #else FFI_DEFAULT_ABI = FFI_WASM32 #endif +#elif __SIZEOF_POINTER__ == 8 +#ifdef __EMSCRIPTEN__ + FFI_DEFAULT_ABI = FFI_WASM64_EMSCRIPTEN +#else + FFI_DEFAULT_ABI = FFI_WASM64 +#endif +#else +#error "Unknown pointer size" +#endif } ffi_abi; #define FFI_CLOSURES 1 diff --git a/testsuite/emscripten/build.sh b/testsuite/emscripten/build.sh index 83ece7bcf..a332c1d53 100755 --- a/testsuite/emscripten/build.sh +++ b/testsuite/emscripten/build.sh @@ -36,11 +36,11 @@ export PKG_CONFIG_PATH="$TARGET/lib/pkgconfig" export EM_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" # Specific variables for cross-compilation -export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten +export CHOST="${TARGET_HOST}-unknown-linux" # wasm32-unknown-emscripten autoreconf -fiv emconfigure ./configure --host=$CHOST --prefix="$TARGET" --enable-static --disable-shared --disable-dependency-tracking \ - --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs + --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs ${EXTRA_CONFIGURE_FLAGS} make install cp fficonfig.h target/include/ cp include/ffi_common.h target/include/ diff --git a/testsuite/emscripten/node-tests.sh b/testsuite/emscripten/node-tests.sh index 016e99c4b..2710947c0 100755 --- a/testsuite/emscripten/node-tests.sh +++ b/testsuite/emscripten/node-tests.sh @@ -8,16 +8,16 @@ fi # Common compiler flags export CFLAGS="-fPIC $EXTRA_CFLAGS" export CXXFLAGS="$CFLAGS -sNO_DISABLE_EXCEPTION_CATCHING $EXTRA_CXXFLAGS" -export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT" +export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT -Wno-main" # Specific variables for cross-compilation -export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten +export CHOST="${TARGET_HOST}-unknown-linux" # wasm32-unknown-emscripten autoreconf -fiv emconfigure ./configure --prefix="$(pwd)/target" --host=$CHOST --enable-static --disable-shared \ - --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs || + --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs ${EXTRA_CONFIGURE_FLAGS} || (cat config.log && exit 1) make EMMAKEN_JUST_CONFIGURE=1 emmake make check \ - RUNTESTFLAGS="LDFLAGS_FOR_TARGET='$LDFLAGS'" || (cat testsuite/libffi.log && exit 1) + RUNTESTFLAGS="LDFLAGS_FOR_TARGET='$LDFLAGS $EXTRA_TEST_LDFLAGS'" || (cat testsuite/libffi.log && exit 1) diff --git a/testsuite/libffi.closures/cls_dbls_struct.c b/testsuite/libffi.closures/cls_dbls_struct.c index 00e247e7e..d0c206c04 100644 --- a/testsuite/libffi.closures/cls_dbls_struct.c +++ b/testsuite/libffi.closures/cls_dbls_struct.c @@ -28,7 +28,7 @@ closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, closure_test_fn(*(Dbls*)args[0]); } -int main(int argc __UNUSED__, char** argv __UNUSED__) +int main(void) { ffi_cif cif; diff --git a/testsuite/libffi.closures/huge_struct.c b/testsuite/libffi.closures/huge_struct.c index 572a0c8fb..b3488304c 100644 --- a/testsuite/libffi.closures/huge_struct.c +++ b/testsuite/libffi.closures/huge_struct.c @@ -216,8 +216,7 @@ cls_large_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __ ui8_5, si8_5); } -int -main(int argc __UNUSED__, const char** argv __UNUSED__) +int main (void) { void *code; ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); From b53b0042c2637162ba8ea55f382264a0841359a7 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 2 Aug 2025 08:52:25 +0200 Subject: [PATCH 86/87] Fix for systems without O_CLOEXEC --- src/tramp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tramp.c b/src/tramp.c index 31180efb6..76a9dfe75 100644 --- a/src/tramp.c +++ b/src/tramp.c @@ -209,6 +209,11 @@ ffi_tramp_get_libffi (void) unsigned long start, end, offset, inode; uintptr_t addr = (uintptr_t) tramp_globals.text; int nfields, found; + int open_flags = O_RDONLY; + +#ifdef O_CLOEXEC + open_flags |= O_CLOEXEC; +#endif snprintf (file, PATH_MAX, "/proc/%d/maps", getpid()); fp = fopen (file, "r"); @@ -236,7 +241,7 @@ ffi_tramp_get_libffi (void) if (!found) return 0; - tramp_globals.fd = open (file, O_RDONLY | O_CLOEXEC); + tramp_globals.fd = open (file, open_flags); if (tramp_globals.fd == -1) return 0; From e2eda0cf72a0598b44278cc91860ea402273fa29 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sat, 2 Aug 2025 08:56:01 +0200 Subject: [PATCH 87/87] feat: Update libffi version to 3.5.2 with wasm64 and DragonFly BSD support --- README.md | 8 ++++++-- configure.ac | 6 +++--- doc/version.texi | 8 ++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 02910aa43..f093c324f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ Status ====== -libffi-3.5.1 was released on June 10, 2025. Check the libffi web -page for updates: . +libffi-3.5.2 was released on August 2, 2025. What is libffi? @@ -205,6 +204,11 @@ History See the git log for details at http://github.com/libffi/libffi. + 3.5.2 Aug-2-2025 + Add wasm64 support. + Add DragonFly BSD support. + Ensure trampoline file descriptors are closed on exec. + 3.5.1 Jun-10-2025 Fix symbol versioning error. diff --git a/configure.ac b/configure.ac index 3ca84e25a..dcfc7b242 100644 --- a/configure.ac +++ b/configure.ac @@ -2,11 +2,11 @@ dnl Process this with autoconf to create configure AC_PREREQ([2.68]) -AC_INIT([libffi],[3.5.1],[http://github.com/libffi/libffi/issues]) +AC_INIT([libffi],[3.5.2],[http://github.com/libffi/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) -FFI_VERSION_STRING="3.5.1" -FFI_VERSION_NUMBER=30501 +FFI_VERSION_STRING="3.5.2" +FFI_VERSION_NUMBER=30502 AC_SUBST(FFI_VERSION_STRING) AC_SUBST(FFI_VERSION_NUMBER) diff --git a/doc/version.texi b/doc/version.texi index 5d61d6f71..fc180c12d 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 8 June 2025 -@set UPDATED-MONTH June 2025 -@set EDITION 3.5.0 -@set VERSION 3.5.0 +@set UPDATED 2 August 2025 +@set UPDATED-MONTH August 2025 +@set EDITION 3.5.2 +@set VERSION 3.5.2