diff --git a/backport-Fix-check-for-invalid-varargs-arguments-707.patch b/backport-Fix-check-for-invalid-varargs-arguments-707.patch new file mode 100644 index 0000000000000000000000000000000000000000..56769dc38e5ee2c5e549d26c4e4b02d6308b58b1 --- /dev/null +++ b/backport-Fix-check-for-invalid-varargs-arguments-707.patch @@ -0,0 +1,197 @@ +From de95947ae5db07e4589bb16bab30b6c8ba2b3106 Mon Sep 17 00:00:00 2001 +From: Roland Schatz +Date: Tue, 24 May 2022 03:04:43 +0200 +Subject: [PATCH] Fix check for invalid varargs arguments. (#707) + +Conflict:NA +Reference:https://github.com/libffi/libffi/commit/de95947ae5db07e4589bb16bab30b6c8ba2b3106 +--- + src/prep_cif.c | 3 +- + testsuite/libffi.call/va_3.c | 154 +++++++++++++++++++++++++++++++++++ + 2 files changed, 156 insertions(+), 1 deletion(-) + create mode 100644 testsuite/libffi.call/va_3.c + +diff --git a/src/prep_cif.c b/src/prep_cif.c +index c1832b1..2d0f252 100644 +--- a/src/prep_cif.c ++++ b/src/prep_cif.c +@@ -1,6 +1,7 @@ + /* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 2011, 2012, 2021 Anthony Green + Copyright (c) 1996, 1998, 2007 Red Hat, Inc. ++ Copyright (c) 2022 Oracle and/or its affiliates. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the +@@ -240,7 +241,7 @@ ffi_status ffi_prep_cif_var(ffi_cif *cif, + if (rc != FFI_OK) + return rc; + +- for (i = 1; i < ntotalargs; i++) ++ for (i = nfixedargs; i < ntotalargs; i++) + { + ffi_type *arg_type = atypes[i]; + if (arg_type == &ffi_type_float +diff --git a/testsuite/libffi.call/va_3.c b/testsuite/libffi.call/va_3.c +new file mode 100644 +index 0000000..b3e73b5 +--- /dev/null ++++ b/testsuite/libffi.call/va_3.c +@@ -0,0 +1,154 @@ ++/* Area: ffi_call ++ Purpose: Test function with multiple fixed args and variable argument list. ++ Limitations: none. ++ PR: none. ++ Originator: ARM Ltd., Oracle */ ++ ++/* { dg-do run } */ ++/* { dg-output "" { xfail avr32*-*-* m68k-*-* } } */ ++ ++#include "ffitest.h" ++#include ++ ++/* ++ * This is a modified version of va_2.c that has fixed arguments with "small" types that ++ * are not allowed as variable arguments, but they should be still allowed as fixed args. ++ */ ++ ++static int ++test_fn (char a1, float a2, int n, ...) ++{ ++ va_list ap; ++ unsigned char uc; ++ signed char sc; ++ unsigned short us; ++ signed short ss; ++ unsigned int ui; ++ signed int si; ++ unsigned long ul; ++ signed long sl; ++ float f; ++ double d; ++ ++ va_start (ap, n); ++ ++ uc = va_arg (ap, unsigned); ++ sc = va_arg (ap, signed); ++ ++ us = va_arg (ap, unsigned); ++ ss = va_arg (ap, signed); ++ ++ ui = va_arg (ap, unsigned int); ++ si = va_arg (ap, signed int); ++ ++ ul = va_arg (ap, unsigned long); ++ sl = va_arg (ap, signed long); ++ ++ f = va_arg (ap, double); /* C standard promotes float->double ++ when anonymous */ ++ d = va_arg (ap, double); ++ ++ printf ("%d %f uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n", ++ a1, a2, ++ uc, sc, ++ us, ss, ++ ui, si, ++ ul, sl, ++ f, d); ++ ++ va_end (ap); ++ ++ CHECK(a1 == 1); ++ CHECK((int)a2 == 2); ++ CHECK(uc == 9); ++ CHECK(sc == 10); ++ CHECK(us == 11); ++ CHECK(ss == 12); ++ CHECK(ui == 13); ++ CHECK(si == 14); ++ CHECK(ul == 15); ++ CHECK(sl == 16); ++ CHECK((int)f == 2); ++ CHECK((int)d == 3); ++ ++ return n + 1; ++} ++ ++int ++main (void) ++{ ++ ffi_cif cif; ++ void* args[14]; ++ ffi_type* arg_types[14]; ++ ++ char a1; ++ float a2; ++ int n; ++ ffi_arg res; ++ ++ unsigned int uc; ++ signed int sc; ++ unsigned int us; ++ signed int ss; ++ unsigned int ui; ++ signed int si; ++ unsigned long ul; ++ signed long sl; ++ double d1; ++ double f1; ++ ++ arg_types[0] = &ffi_type_schar; ++ arg_types[1] = &ffi_type_float; ++ arg_types[2] = &ffi_type_sint; ++ arg_types[3] = &ffi_type_uint; ++ arg_types[4] = &ffi_type_sint; ++ arg_types[5] = &ffi_type_uint; ++ arg_types[6] = &ffi_type_sint; ++ arg_types[7] = &ffi_type_uint; ++ arg_types[8] = &ffi_type_sint; ++ arg_types[9] = &ffi_type_ulong; ++ arg_types[10] = &ffi_type_slong; ++ arg_types[11] = &ffi_type_double; ++ arg_types[12] = &ffi_type_double; ++ arg_types[13] = NULL; ++ ++ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 13, &ffi_type_sint, arg_types) == FFI_OK); ++ ++ a1 = 1; ++ a2 = 2.0f; ++ n = 41; ++ ++ uc = 9; ++ sc = 10; ++ us = 11; ++ ss = 12; ++ ui = 13; ++ si = 14; ++ ul = 15; ++ sl = 16; ++ f1 = 2.12; ++ d1 = 3.13; ++ ++ args[0] = &a1; ++ args[1] = &a2; ++ args[2] = &n; ++ args[3] = &uc; ++ args[4] = ≻ ++ args[5] = &us; ++ args[6] = &ss; ++ args[7] = &ui; ++ args[8] = &si; ++ args[9] = &ul; ++ args[10] = &sl; ++ args[11] = &f1; ++ args[12] = &d1; ++ args[13] = NULL; ++ ++ ffi_call(&cif, FFI_FN(test_fn), &res, args); ++ /* { dg-output "1 2.000000 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */ ++ printf("res: %d\n", (int) res); ++ /* { dg-output "\nres: 42" } */ ++ CHECK(res == 42); ++ ++ return 0; ++} +-- +2.23.0 + \ No newline at end of file diff --git a/backport-x86-64-Always-double-jump-table-slot-size-for-CET-71.patch b/backport-x86-64-Always-double-jump-table-slot-size-for-CET-71.patch new file mode 100644 index 0000000000000000000000000000000000000000..14b08cdf6186e322bc6909ecf4706b6202e19c1b --- /dev/null +++ b/backport-x86-64-Always-double-jump-table-slot-size-for-CET-71.patch @@ -0,0 +1,54 @@ +From 3ac265d5c0e038e324bae29131dbc4bacb4935ea Mon Sep 17 00:00:00 2001 +From: hjl-tools +Date: Sun, 15 May 2022 18:43:56 -0700 +Subject: [PATCH] x86-64: Always double jump table slot size for CET (#710) + (#711) + +When CET is enabled, double jump table slot size to add 4 bytes of ENDBR64 +for CET. Since CET enabled clang doesn't have the LLVM assembler bug: + +https://bugs.llvm.org/show_bug.cgi?id=21501 + +fixed by + +commit 04d39260d64e08b8bfb3844109ad43d4055b2e8d +Author: Rafael Espindola +Date: Wed Nov 4 23:50:29 2015 +0000 + + Simplify .org processing and make it a bit more powerful. + +we can use .org to allocate jump table slot size to 16 bytes. + +Conflict:NA +Reference:https://github.com/libffi/libffi/commit/3ac265d5c0e038e324bae29131dbc4bacb4935ea +--- + src/x86/unix64.S | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/x86/unix64.S b/src/x86/unix64.S +index 8cf3a23..d9c5bd4 100644 +--- a/src/x86/unix64.S ++++ b/src/x86/unix64.S +@@ -39,14 +39,13 @@ + actual table. The entry points into the table are all 8 bytes. + The use of ORG asserts that we're at the correct location. */ + /* ??? The clang assembler doesn't handle .org with symbolic expressions. */ +-#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) ++#ifdef __CET__ ++/* Double slot size to 16 byte to add 4 bytes of ENDBR64. */ ++# define E(BASE, X) .balign 8; .org BASE + X * 16 ++#elif defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__)) + # define E(BASE, X) .balign 8 + #else +-# ifdef __CET__ +-# define E(BASE, X) .balign 8; .org BASE + X * 16 +-# else +-# define E(BASE, X) .balign 8; .org BASE + X * 8 +-# endif ++# define E(BASE, X) .balign 8; .org BASE + X * 8 + #endif + + /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, +-- +2.23.0 + \ No newline at end of file diff --git a/libffi-3.4.2.tar.gz b/libffi-3.4.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6752a27688d5817706e3d3f369478975f8a179e6 Binary files /dev/null and b/libffi-3.4.2.tar.gz differ diff --git a/libffi-3.4.4.tar.gz b/libffi-3.4.4.tar.gz deleted file mode 100644 index 173ab92de0476b8d97418da1d04b8b1b46fb7875..0000000000000000000000000000000000000000 Binary files a/libffi-3.4.4.tar.gz and /dev/null differ diff --git a/libffi-Add-sw64-architecture.patch b/libffi-Add-sw64-architecture.patch new file mode 100644 index 0000000000000000000000000000000000000000..b1076ea92f820122584565298c16cf0413e6f8c1 --- /dev/null +++ b/libffi-Add-sw64-architecture.patch @@ -0,0 +1,1164 @@ +From 399558e5a99db58839e2a9a8802f743d9631466a Mon Sep 17 00:00:00 2001 +From: wuzx +Date: Fri, 18 Nov 2022 12:04:50 +0800 +Subject: [PATCH] Add sw64 architecture + +Add sw64 architecture in file Makefile.am Makefile.in config.guess config.sub configure configure.host m4/ax_gcc_archflag.m4 src/sw_64/ffi.c src/sw_64/ffitarget.h src/sw_64/internal.h src/sw_64/osf.S src/types.c and testsuite/libffi.go/static-chain.h to support sw64 architecture. + +Signed-off-by: wuzx +--- + Makefile.am | 2 + + Makefile.in | 24 ++ + config.guess | 9 + + config.sub | 1 + + configure | 2 +- + configure.host | 6 + + m4/ax_gcc_archflag.m4 | 2 +- + src/sw_64/ffi.c | 521 +++++++++++++++++++++++++++++ + src/sw_64/ffitarget.h | 57 ++++ + src/sw_64/internal.h | 23 ++ + src/sw_64/osf.S | 282 ++++++++++++++++ + src/types.c | 4 +- + testsuite/libffi.go/static-chain.h | 2 + + 13 files changed, 931 insertions(+), 4 deletions(-) + create mode 100644 src/sw_64/ffi.c + create mode 100644 src/sw_64/ffitarget.h + create mode 100644 src/sw_64/internal.h + create mode 100644 src/sw_64/osf.S + +diff --git a/Makefile.am b/Makefile.am +index 1b18198..e29722f 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -47,6 +47,7 @@ endif + + noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + src/alpha/ffitarget.h src/alpha/internal.h \ ++ src/sw_64/ffitarget.h src/sw_64/internal.h \ + src/arc/ffitarget.h src/arm/ffitarget.h src/arm/internal.h \ + src/avr32/ffitarget.h src/bfin/ffitarget.h \ + src/cris/ffitarget.h src/csky/ffitarget.h src/frv/ffitarget.h \ +@@ -67,6 +68,7 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + + EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ + src/aarch64/win64_armasm.S src/alpha/ffi.c src/alpha/osf.S \ ++ src/sw_64/ffi.c src/sw_64/osf.S + src/arc/ffi.c src/arc/arcompact.S src/arm/ffi.c \ + src/arm/sysv.S src/arm/ffi.c src/arm/sysv_msvc_arm32.S \ + src/avr32/ffi.c src/avr32/sysv.S src/bfin/ffi.c \ +diff --git a/Makefile.in b/Makefile.in +index a4b67a7..b4eddc2 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -202,6 +202,7 @@ am__depfiles_remade = src/$(DEPDIR)/closures.Plo \ + src/aarch64/$(DEPDIR)/ffi.Plo src/aarch64/$(DEPDIR)/sysv.Plo \ + src/aarch64/$(DEPDIR)/win64_armasm.Plo \ + src/alpha/$(DEPDIR)/ffi.Plo src/alpha/$(DEPDIR)/osf.Plo \ ++ src/sw_64/$(DEPDIR)/ffi.Plo src/sw_64/$(DEPDIR)/osf.Plo \ + src/arc/$(DEPDIR)/arcompact.Plo src/arc/$(DEPDIR)/ffi.Plo \ + src/arm/$(DEPDIR)/ffi.Plo src/arm/$(DEPDIR)/sysv.Plo \ + src/arm/$(DEPDIR)/sysv_msvc_arm32.Plo \ +@@ -548,6 +549,7 @@ libffi_la_SOURCES = src/prep_cif.c src/types.c src/raw_api.c \ + src/java_raw_api.c src/closures.c src/tramp.c $(am__append_2) + noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + src/alpha/ffitarget.h src/alpha/internal.h \ ++ src/sw_64/ffitarget.h src/sw_64/internal.h \ + src/arc/ffitarget.h src/arm/ffitarget.h src/arm/internal.h \ + src/avr32/ffitarget.h src/bfin/ffitarget.h \ + src/cris/ffitarget.h src/csky/ffitarget.h src/frv/ffitarget.h \ +@@ -568,6 +570,7 @@ noinst_HEADERS = src/aarch64/ffitarget.h src/aarch64/internal.h \ + + EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \ + src/aarch64/win64_armasm.S src/alpha/ffi.c src/alpha/osf.S \ ++ src/sw_64/ffi.c src/sw_64/osf.S \ + src/arc/ffi.c src/arc/arcompact.S src/arm/ffi.c \ + src/arm/sysv.S src/arm/ffi.c src/arm/sysv_msvc_arm32.S \ + src/avr32/ffi.c src/avr32/sysv.S src/bfin/ffi.c \ +@@ -751,6 +754,16 @@ src/alpha/ffi.lo: src/alpha/$(am__dirstamp) \ + src/alpha/$(DEPDIR)/$(am__dirstamp) + src/alpha/osf.lo: src/alpha/$(am__dirstamp) \ + src/alpha/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/$(am__dirstamp): ++ @$(MKDIR_P) src/sw_64 ++ @: > src/sw_64/$(am__dirstamp) ++src/sw_64/$(DEPDIR)/$(am__dirstamp): ++ @$(MKDIR_P) src/sw_64/$(DEPDIR) ++ @: > src/sw_64/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/ffi.lo: src/sw_64/$(am__dirstamp) \ ++ src/sw_64/$(DEPDIR)/$(am__dirstamp) ++src/sw_64/osf.lo: src/sw_64/$(am__dirstamp) \ ++ src/sw_64/$(DEPDIR)/$(am__dirstamp) + src/arc/$(am__dirstamp): + @$(MKDIR_P) src/arc + @: > src/arc/$(am__dirstamp) +@@ -1096,6 +1109,8 @@ mostlyclean-compile: + -rm -f src/aarch64/*.lo + -rm -f src/alpha/*.$(OBJEXT) + -rm -f src/alpha/*.lo ++ -rm -f src/sw_64/*.$(OBJEXT) ++ -rm -f src/sw_64/*.lo + -rm -f src/arc/*.$(OBJEXT) + -rm -f src/arc/*.lo + -rm -f src/arm/*.$(OBJEXT) +@@ -1168,6 +1183,8 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/ffi.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/sysv.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/win64_armasm.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@src/sw_64/$(DEPDIR)/ffi.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@src/sw_64/$(DEPDIR)/osf.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/ffi.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/osf.Plo@am__quote@ # am--include-marker + @AMDEP_TRUE@@am__include@ @am__quote@src/arc/$(DEPDIR)/arcompact.Plo@am__quote@ # am--include-marker +@@ -1311,6 +1328,7 @@ clean-libtool: + -rm -rf .libs _libs + -rm -rf src/.libs src/_libs + -rm -rf src/aarch64/.libs src/aarch64/_libs ++ -rm -rf src/sw_64/.libs src/sw_64/_libs + -rm -rf src/alpha/.libs src/alpha/_libs + -rm -rf src/arc/.libs src/arc/_libs + -rm -rf src/arm/.libs src/arm/_libs +@@ -1710,6 +1728,8 @@ distclean-generic: + -rm -f src/$(am__dirstamp) + -rm -f src/aarch64/$(DEPDIR)/$(am__dirstamp) + -rm -f src/aarch64/$(am__dirstamp) ++ -rm -f src/sw_64/$(DEPDIR)/$(am__dirstamp) ++ -rm -f src/sw_64/$(am__dirstamp) + -rm -f src/alpha/$(DEPDIR)/$(am__dirstamp) + -rm -f src/alpha/$(am__dirstamp) + -rm -f src/arc/$(DEPDIR)/$(am__dirstamp) +@@ -1792,6 +1812,8 @@ distclean: distclean-recursive + -rm -f src/aarch64/$(DEPDIR)/ffi.Plo + -rm -f src/aarch64/$(DEPDIR)/sysv.Plo + -rm -f src/aarch64/$(DEPDIR)/win64_armasm.Plo ++ -rm -f src/sw_64/$(DEPDIR)/ffi.Plo ++ -rm -f src/sw_64/$(DEPDIR)/osf.Plo + -rm -f src/alpha/$(DEPDIR)/ffi.Plo + -rm -f src/alpha/$(DEPDIR)/osf.Plo + -rm -f src/arc/$(DEPDIR)/arcompact.Plo +@@ -1930,6 +1952,8 @@ maintainer-clean: maintainer-clean-recursive + -rm -f src/aarch64/$(DEPDIR)/ffi.Plo + -rm -f src/aarch64/$(DEPDIR)/sysv.Plo + -rm -f src/aarch64/$(DEPDIR)/win64_armasm.Plo ++ -rm -f src/sw_64/$(DEPDIR)/ffi.Plo ++ -rm -f src/sw_64/$(DEPDIR)/osf.Plo + -rm -f src/alpha/$(DEPDIR)/ffi.Plo + -rm -f src/alpha/$(DEPDIR)/osf.Plo + -rm -f src/arc/$(DEPDIR)/arcompact.Plo +diff --git a/config.guess b/config.guess +index e94095c..01a1ef3 100644 +--- a/config.guess ++++ b/config.guess +@@ -925,6 +925,15 @@ EOF + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ sw) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo ${UNAME_MACHINE}-sunway-linux-${LIBC} ++ exit ;; ++ + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff --git a/config.sub b/config.sub +index 14b5150..bbb4efe 100644 +--- a/config.sub ++++ b/config.sub +@@ -1158,6 +1158,7 @@ case $cpu-$vendor in + case $cpu in + 1750a | 580 \ + | a29k \ ++ | sw_64 \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ +diff --git a/configure b/configure +index 94e149c..f911a05 100755 +--- a/configure ++++ b/configure +@@ -17216,7 +17216,7 @@ fi + *hypersparc*|*rt62[056]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; +- ++ sw_64*) ax_gcc_arch=sw6b ;; + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; +diff --git a/configure.host b/configure.host +index 2682671..372e20b 100644 +--- a/configure.host ++++ b/configure.host +@@ -24,6 +24,12 @@ case "${host}" in + HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' + SOURCES="ffi.c osf.S" + ;; ++ sw_64*-*-*) ++ TARGET=SW_64; TARGETDIR=sw_64; ++ # Support 128-bit long double, changeable via command-line switch. ++ HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' ++ SOURCES="ffi.c osf.S" ++ ;; + + arc*-*-*) + TARGET=ARC; TARGETDIR=arc +diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4 +index c52b9b2..de17232 100644 +--- a/m4/ax_gcc_archflag.m4 ++++ b/m4/ax_gcc_archflag.m4 +@@ -174,7 +174,7 @@ case $host_cpu in + *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;; + *cypress*) ax_gcc_arch=cypress ;; + esac ;; +- ++ sw_64*) ax_gcc_arch=sw6b ;; + alphaev5) ax_gcc_arch=ev5 ;; + alphaev56) ax_gcc_arch=ev56 ;; + alphapca56) ax_gcc_arch="pca56 ev56" ;; +diff --git a/src/sw_64/ffi.c b/src/sw_64/ffi.c +new file mode 100644 +index 0000000..d99668f +--- /dev/null ++++ b/src/sw_64/ffi.c +@@ -0,0 +1,521 @@ ++/* ----------------------------------------------------------------------- ++ ffi.c - Copyright (c) 2012 Anthony Green ++ Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc. ++ ++ Alpha Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++ ++#include ++#include ++#include ++#include "internal.h" ++ ++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE; ++ all further uses in this file will refer to the 128-bit type. */ ++#if defined(__LONG_DOUBLE_128__) ++# if FFI_TYPE_LONGDOUBLE != 4 ++# error FFI_TYPE_LONGDOUBLE out of date ++# endif ++#else ++# undef FFI_TYPE_LONGDOUBLE ++# define FFI_TYPE_LONGDOUBLE 4 ++#endif ++ ++extern void ffi_call_osf(void *stack, void *frame, unsigned flags, ++ void *raddr, void (*fn)(void), void *closure) ++ FFI_HIDDEN; ++extern void ffi_closure_osf(void) FFI_HIDDEN; ++extern void ffi_go_closure_osf(void) FFI_HIDDEN; ++ ++/* Promote a float value to its in-register double representation. ++ Unlike actually casting to double, this does not trap on NaN. */ ++static inline UINT64 lds(void *ptr) ++{ ++ UINT64 ret; ++ asm("flds %0,%1" : "=f"(ret) : "m"(*(UINT32 *)ptr)); ++ return ret; ++} ++ ++/* And the reverse. */ ++static inline void sts(void *ptr, UINT64 val) ++{ ++ asm("fsts %1,%0" : "=m"(*(UINT32 *)ptr) : "f"(val)); ++} ++ ++ffi_status FFI_HIDDEN ++ffi_prep_cif_machdep(ffi_cif *cif) ++{ ++ size_t bytes = 0; ++ int flags, i, avn; ++ ffi_type *rtype, *itype; ++ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ /* Compute the size of the argument area. */ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ itype = cif->arg_types[i]; ++ switch (itype->type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_FLOAT: ++ case FFI_TYPE_DOUBLE: ++ case FFI_TYPE_LONGDOUBLE: ++ /* All take one 8 byte slot. */ ++ bytes += 8; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ /* Passed by value in N slots. */ ++ bytes += FFI_ALIGN(itype->size, FFI_SIZEOF_ARG); ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ /* _Complex long double passed by reference; others in 2 slots. */ ++ if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE) ++ bytes += 8; ++ else ++ bytes += 16; ++ break; ++ ++ default: ++ abort(); ++ } ++ } ++ ++ /* Set the return type flag */ ++ rtype = cif->rtype; ++ switch (rtype->type) ++ { ++ case FFI_TYPE_VOID: ++ flags = SW_64_FLAGS(SW_64_ST_VOID, SW_64_LD_VOID); ++ break; ++ case FFI_TYPE_INT: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT32: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_INT32); ++ break; ++ case FFI_TYPE_FLOAT: ++ flags = SW_64_FLAGS(SW_64_ST_FLOAT, SW_64_LD_FLOAT); ++ break; ++ case FFI_TYPE_DOUBLE: ++ flags = SW_64_FLAGS(SW_64_ST_DOUBLE, SW_64_LD_DOUBLE); ++ break; ++ case FFI_TYPE_UINT8: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_UINT8); ++ break; ++ case FFI_TYPE_SINT8: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_SINT8); ++ break; ++ case FFI_TYPE_UINT16: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_UINT16); ++ break; ++ case FFI_TYPE_SINT16: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_SINT16); ++ break; ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_POINTER: ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_INT64); ++ break; ++ case FFI_TYPE_LONGDOUBLE: ++ case FFI_TYPE_STRUCT: ++ /* Passed in memory, with a hidden pointer. */ ++ flags = SW_64_RET_IN_MEM; ++ break; ++ case FFI_TYPE_COMPLEX: ++ itype = rtype->elements[0]; ++ switch (itype->type) ++ { ++ case FFI_TYPE_FLOAT: ++ flags = SW_64_FLAGS(SW_64_ST_CPLXF, SW_64_LD_CPLXF); ++ break; ++ case FFI_TYPE_DOUBLE: ++ flags = SW_64_FLAGS(SW_64_ST_CPLXD, SW_64_LD_CPLXD); ++ break; ++ default: ++ if (rtype->size <= 8) ++ flags = SW_64_FLAGS(SW_64_ST_INT, SW_64_LD_INT64); ++ else ++ flags = SW_64_RET_IN_MEM; ++ break; ++ } ++ break; ++ default: ++ abort(); ++ } ++ cif->flags = flags; ++ ++ /* Include the hidden structure pointer in args requirement. */ ++ if (flags == SW_64_RET_IN_MEM) ++ bytes += 8; ++ /* Minimum size is 6 slots, so that ffi_call_osf can pop them. */ ++ if (bytes < 6*8) ++ bytes = 6*8; ++ cif->bytes = bytes; ++ ++ return FFI_OK; ++} ++ ++static unsigned long ++extend_basic_type(void *valp, int type, int argn) ++{ ++ switch (type) ++ { ++ case FFI_TYPE_SINT8: ++ return *(SINT8 *)valp; ++ case FFI_TYPE_UINT8: ++ return *(UINT8 *)valp; ++ case FFI_TYPE_SINT16: ++ return *(SINT16 *)valp; ++ case FFI_TYPE_UINT16: ++ return *(UINT16 *)valp; ++ ++ case FFI_TYPE_FLOAT: ++ if (argn < 6) ++ return lds(valp); ++ /* FALLTHRU */ ++ ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ /* Note that unsigned 32-bit quantities are sign extended. */ ++ return *(SINT32 *)valp; ++ ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_DOUBLE: ++ return *(UINT64 *)valp; ++ ++ default: ++ abort(); ++ } ++} ++ ++static void ++ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, ++ void **avalue, void *closure) ++{ ++ unsigned long *argp; ++ long i, avn, argn, flags = cif->flags; ++ ffi_type **arg_types; ++ void *frame; ++ ++ /* If the return value is a struct and we don't have a return ++ value address then we need to make one. */ ++ if (rvalue == NULL && flags == SW_64_RET_IN_MEM) ++ rvalue = alloca(cif->rtype->size); ++ ++ /* Allocate the space for the arguments, plus 4 words of temp ++ space for ffi_call_osf. */ ++ argp = frame = alloca(cif->bytes + 4*FFI_SIZEOF_ARG); ++ frame += cif->bytes; ++ ++ argn = 0; ++ if (flags == SW_64_RET_IN_MEM) ++ argp[argn++] = (unsigned long)rvalue; ++ ++ avn = cif->nargs; ++ arg_types = cif->arg_types; ++ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ ffi_type *ty = arg_types[i]; ++ void *valp = avalue[i]; ++ int type = ty->type; ++ size_t size; ++ ++ switch (type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ case FFI_TYPE_FLOAT: ++ case FFI_TYPE_DOUBLE: ++ argp[argn] = extend_basic_type(valp, type, argn); ++ argn++; ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ by_reference: ++ /* Note that 128-bit long double is passed by reference. */ ++ argp[argn++] = (unsigned long)valp; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ size = ty->size; ++ memcpy(argp + argn, valp, size); ++ argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ type = ty->elements[0]->type; ++ if (type == FFI_TYPE_LONGDOUBLE) ++ goto by_reference; ++ ++ /* Most complex types passed as two separate arguments. */ ++ size = ty->elements[0]->size; ++ argp[argn] = extend_basic_type(valp, type, argn); ++ argp[argn + 1] = extend_basic_type(valp + size, type, argn + 1); ++ argn += 2; ++ break; ++ ++ default: ++ abort(); ++ } ++ } ++ ++ flags = (flags >> SW_64_ST_SHIFT) & 0xff; ++ ffi_call_osf(argp, frame, flags, rvalue, fn, closure); ++} ++ ++void ++ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ++{ ++ ffi_call_int(cif, fn, rvalue, avalue, NULL); ++} ++ ++void ++ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue, ++ void **avalue, void *closure) ++{ ++ ffi_call_int(cif, fn, rvalue, avalue, closure); ++} ++ ++ffi_status ++ffi_prep_closure_loc (ffi_closure* closure, ++ ffi_cif* cif, ++ void (*fun)(ffi_cif*, void*, void**, void*), ++ void *user_data, ++ void *codeloc) ++{ ++ unsigned int *tramp; ++ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ tramp = (unsigned int *) &closure->tramp[0]; ++ tramp[0] = 0x43fb0741; /* mov $27,$1 */ ++ tramp[1] = 0x8f7b0010; /* ldq $27,16($27) */ ++ tramp[2] = 0x0ffb0000; /* jmp $31,($27),0 */ ++ tramp[3] = 0x43ff075f; /* nop */ ++ *(void **) &tramp[4] = ffi_closure_osf; ++ ++ closure->cif = cif; ++ closure->fun = fun; ++ closure->user_data = user_data; ++ ++ /* Flush the Icache. ++ ++ Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal ++ instead, since both Compaq as and gas can handle it. ++ ++ 0x86 is PAL_imb in Tru64 UNIX . */ ++ asm volatile ("sys_call 0x86" : : : "memory"); ++ ++ return FFI_OK; ++} ++ ++ffi_status ++ffi_prep_go_closure (ffi_go_closure* closure, ++ ffi_cif* cif, ++ void (*fun)(ffi_cif*, void*, void**, void*)) ++{ ++ if (cif->abi != FFI_OSF) ++ return FFI_BAD_ABI; ++ ++ closure->tramp = (void *)ffi_go_closure_osf; ++ closure->cif = cif; ++ closure->fun = fun; ++ ++ return FFI_OK; ++} ++ ++long FFI_HIDDEN ++ffi_closure_osf_inner (ffi_cif *cif, ++ void (*fun)(ffi_cif*, void*, void**, void*), ++ void *user_data, ++ void *rvalue, unsigned long *argp) ++{ ++ void **avalue; ++ ffi_type **arg_types; ++ long i, avn, argn, flags; ++ ++ avalue = alloca(cif->nargs * sizeof(void *)); ++ flags = cif->flags; ++ argn = 0; ++ ++ /* Copy the caller's structure return address to that the closure ++ returns the data directly to the caller. */ ++ if (flags == SW_64_RET_IN_MEM) ++ { ++ rvalue = (void *) argp[0]; ++ argn = 1; ++ } ++ ++ arg_types = cif->arg_types; ++ ++ /* Grab the addresses of the arguments from the stack frame. */ ++ for (i = 0, avn = cif->nargs; i < avn; i++) ++ { ++ ffi_type *ty = arg_types[i]; ++ int type = ty->type; ++ void *valp = &argp[argn]; ++ size_t size; ++ ++ switch (type) ++ { ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ case FFI_TYPE_POINTER: ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_VOID: ++ case FFI_TYPE_STRUCT: ++ size = ty->size; ++ argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; ++ break; ++ ++ case FFI_TYPE_FLOAT: ++ /* Floats coming from registers need conversion from double ++ back to float format. */ ++ if (argn < 6) ++ { ++ valp = &argp[argn - 6]; ++ sts(valp, argp[argn - 6]); ++ } ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_DOUBLE: ++ if (argn < 6) ++ valp = &argp[argn - 6]; ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ by_reference: ++ /* 128-bit long double is passed by reference. */ ++ valp = (void *)argp[argn]; ++ argn += 1; ++ break; ++ ++ case FFI_TYPE_COMPLEX: ++ type = ty->elements[0]->type; ++ switch (type) ++ { ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ /* Passed as separate arguments, but they wind up sequential. */ ++ break; ++ ++ case FFI_TYPE_INT: ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_SINT32: ++ case FFI_TYPE_UINT32: ++ /* Passed as separate arguments. Disjoint, but there's room ++ enough in one slot to hold the pair. */ ++ size = ty->elements[0]->size; ++ memcpy(valp + size, valp + 8, size); ++ break; ++ ++ case FFI_TYPE_FLOAT: ++ /* Passed as separate arguments. Disjoint, and each piece ++ may need conversion back to float. */ ++ if (argn < 6) ++ { ++ valp = &argp[argn - 6]; ++ sts(valp, argp[argn - 6]); ++ } ++ if (argn + 1 < 6) ++ sts(valp + 4, argp[argn + 1 - 6]); ++ else ++ *(UINT32 *)(valp + 4) = argp[argn + 1]; ++ break; ++ ++ case FFI_TYPE_DOUBLE: ++ /* Passed as separate arguments. Only disjoint if one part ++ is in fp regs and the other is on the stack. */ ++ if (argn < 5) ++ valp = &argp[argn - 6]; ++ else if (argn == 5) ++ { ++ valp = alloca(16); ++ ((UINT64 *)valp)[0] = argp[5 - 6]; ++ ((UINT64 *)valp)[1] = argp[6]; ++ } ++ break; ++ ++ case FFI_TYPE_LONGDOUBLE: ++ goto by_reference; ++ ++ default: ++ abort(); ++ } ++ argn += 2; ++ break; ++ ++ default: ++ abort (); ++ } ++ ++ avalue[i] = valp; ++ } ++ ++ /* Invoke the closure. */ ++ fun (cif, rvalue, avalue, user_data); ++ ++ /* Tell ffi_closure_osf how to perform return type promotions. */ ++ return (flags >> SW_64_LD_SHIFT) & 0xff; ++} +diff --git a/src/sw_64/ffitarget.h b/src/sw_64/ffitarget.h +new file mode 100644 +index 0000000..a02dbd0 +--- /dev/null ++++ b/src/sw_64/ffitarget.h +@@ -0,0 +1,57 @@ ++/* -----------------------------------------------------------------*-C-*- ++ ffitarget.h - Copyright (c) 2012 Anthony Green ++ Copyright (c) 1996-2003 Red Hat, Inc. ++ Target configuration macros for Alpha. ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ++ ----------------------------------------------------------------------- */ ++ ++#ifndef LIBFFI_TARGET_H ++#define LIBFFI_TARGET_H ++ ++#ifndef LIBFFI_H ++#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." ++#endif ++ ++#ifndef LIBFFI_ASM ++typedef unsigned long ffi_arg; ++typedef signed long ffi_sarg; ++ ++typedef enum ffi_abi { ++ FFI_FIRST_ABI = 0, ++ FFI_OSF, ++ FFI_LAST_ABI, ++ FFI_DEFAULT_ABI = FFI_OSF ++} ffi_abi; ++#endif ++ ++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION ++#define FFI_TARGET_HAS_COMPLEX_TYPE ++ ++/* ---- Definitions for closures ----------------------------------------- */ ++ ++#define FFI_CLOSURES 1 ++#define FFI_GO_CLOSURES 1 ++#define FFI_TRAMPOLINE_SIZE 24 ++#define FFI_NATIVE_RAW_API 0 ++ ++#endif +diff --git a/src/sw_64/internal.h b/src/sw_64/internal.h +new file mode 100644 +index 0000000..1866a8c +--- /dev/null ++++ b/src/sw_64/internal.h +@@ -0,0 +1,23 @@ ++#define SW_64_ST_VOID 0 ++#define SW_64_ST_INT 1 ++#define SW_64_ST_FLOAT 2 ++#define SW_64_ST_DOUBLE 3 ++#define SW_64_ST_CPLXF 4 ++#define SW_64_ST_CPLXD 5 ++ ++#define SW_64_LD_VOID 0 ++#define SW_64_LD_INT64 1 ++#define SW_64_LD_INT32 2 ++#define SW_64_LD_UINT16 3 ++#define SW_64_LD_SINT16 4 ++#define SW_64_LD_UINT8 5 ++#define SW_64_LD_SINT8 6 ++#define SW_64_LD_FLOAT 7 ++#define SW_64_LD_DOUBLE 8 ++#define SW_64_LD_CPLXF 9 ++#define SW_64_LD_CPLXD 10 ++ ++#define SW_64_ST_SHIFT 0 ++#define SW_64_LD_SHIFT 8 ++#define SW_64_RET_IN_MEM 0x10000 ++#define SW_64_FLAGS(S, L) (((L) << SW_64_LD_SHIFT) | (S)) +diff --git a/src/sw_64/osf.S b/src/sw_64/osf.S +new file mode 100644 +index 0000000..b4b58e5 +--- /dev/null ++++ b/src/sw_64/osf.S +@@ -0,0 +1,282 @@ ++/* ----------------------------------------------------------------------- ++ osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat ++ ++ SW_64/OSF Foreign Function Interface ++ ++ Permission is hereby granted, free of charge, to any person obtaining ++ a copy of this software and associated documentation files (the ++ ``Software''), to deal in the Software without restriction, including ++ without limitation the rights to use, copy, modify, merge, publish, ++ distribute, sublicense, and/or sell copies of the Software, and to ++ permit persons to whom the Software is furnished to do so, subject to ++ the following conditions: ++ ++ The above copyright notice and this permission notice shall be included ++ in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++ ----------------------------------------------------------------------- */ ++ ++#define LIBFFI_ASM ++#include ++#include ++#include ++#include "internal.h" ++ ++ .arch sw6b ++ .text ++ ++/* Aid in building a direct addressed jump table, 4 insns per entry. */ ++.macro E index ++ .align 4 ++ .org 99b + \index * 16 ++.endm ++ ++/* ffi_call_osf (void *stack, void *frame, unsigned flags, ++ void *raddr, void (*fnaddr)(void), void *closure) ++ ++ Bit o trickiness here -- FRAME is the base of the stack frame ++ for this function. This has been allocated by ffi_call. We also ++ deallocate some of the stack that has been alloca'd. */ ++ ++ .align 4 ++ .globl ffi_call_osf ++ .ent ffi_call_osf ++ FFI_HIDDEN(ffi_call_osf) ++ ++ffi_call_osf: ++ cfi_startproc ++ cfi_def_cfa($17, 32) ++ mov $16, $30 ++ stl $26, 0($17) ++ stl $15, 8($17) ++ mov $17, $15 ++ .prologue 0 ++ cfi_def_cfa_register($15) ++ cfi_rel_offset($26, 0) ++ cfi_rel_offset($15, 8) ++ ++ stl $18, 16($17) # save flags into frame ++ stl $19, 24($17) # save rvalue into frame ++ mov $20, $27 # fn into place for call ++ mov $21, $1 # closure into static chain ++ ++ # Load up all of the (potential) argument registers. ++ ldl $16, 0($30) ++ fldd $f16, 0($30) ++ fldd $f17, 8($30) ++ ldl $17, 8($30) ++ fldd $f18, 16($30) ++ ldl $18, 16($30) ++ fldd $f19, 24($30) ++ ldl $19, 24($30) ++ fldd $f20, 32($30) ++ ldl $20, 32($30) ++ fldd $f21, 40($30) ++ ldl $21, 40($30) ++ ++ # Deallocate the register argument area. ++ ldi $30, 48($30) ++ ++ call $26, ($27), 0 ++0: ++ ldih $29, 0($26) !gpdisp!1 ++ ldl $2, 24($15) # reload rvalue ++ ldi $29, 0($29) !gpdisp!1 ++ ldl $3, 16($15) # reload flags ++ ldi $1, 99f-0b($26) ++ ldl $26, 0($15) ++ ldl $15, 8($15) ++ cfi_restore($26) ++ cfi_restore($15) ++ cfi_def_cfa($sp, 0) ++ seleq $2, SW_64_ST_VOID, $3 # mash null rvalue to void ++ addl $3, $3, $3 ++ s8addl $3, $1, $1 # 99f + stcode * 16 ++ jmp $31, ($1), $st_int ++ ++ .align 4 ++99: ++E SW_64_ST_VOID ++ ret ++E SW_64_ST_INT ++$st_int: ++ stl $0, 0($2) ++ ret ++E SW_64_ST_FLOAT ++ fsts $f0, 0($2) ++ ret ++E SW_64_ST_DOUBLE ++ fstd $f0, 0($2) ++ ret ++E SW_64_ST_CPLXF ++ fsts $f0, 0($2) ++ fsts $f1, 4($2) ++ ret ++E SW_64_ST_CPLXD ++ fstd $f0, 0($2) ++ fstd $f1, 8($2) ++ ret ++ ++ cfi_endproc ++ .end ffi_call_osf ++ ++/* ffi_closure_osf(...) ++ ++ Receives the closure argument in $1. */ ++ ++#define CLOSURE_FS (16*8) ++ ++ .align 4 ++ .globl ffi_go_closure_osf ++ .ent ffi_go_closure_osf ++ FFI_HIDDEN(ffi_go_closure_osf) ++ ++ffi_go_closure_osf: ++ cfi_startproc ++ ldgp $29, 0($27) ++ subl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++ stl $26, 0($30) ++ .prologue 1 ++ cfi_rel_offset($26, 0) ++ ++ stl $16, 10*8($30) ++ stl $17, 11*8($30) ++ stl $18, 12*8($30) ++ ++ ldl $16, 8($1) # load cif ++ ldl $17, 16($1) # load fun ++ mov $1, $18 # closure is user_data ++ br $do_closure ++ ++ cfi_endproc ++ .end ffi_go_closure_osf ++ ++ .align 4 ++ .globl ffi_closure_osf ++ .ent ffi_closure_osf ++ FFI_HIDDEN(ffi_closure_osf) ++ ++ffi_closure_osf: ++ cfi_startproc ++ ldgp $29, 0($27) ++ subl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++ stl $26, 0($30) ++ .prologue 1 ++ cfi_rel_offset($26, 0) ++ ++ # Store all of the potential argument registers in va_list format. ++ stl $16, 10*8($30) ++ stl $17, 11*8($30) ++ stl $18, 12*8($30) ++ ++ ldl $16, 24($1) # load cif ++ ldl $17, 32($1) # load fun ++ ldl $18, 40($1) # load user_data ++ ++$do_closure: ++ stl $19, 13*8($30) ++ stl $20, 14*8($30) ++ stl $21, 15*8($30) ++ fstd $f16, 4*8($30) ++ fstd $f17, 5*8($30) ++ fstd $f18, 6*8($30) ++ fstd $f19, 7*8($30) ++ fstd $f20, 8*8($30) ++ fstd $f21, 9*8($30) ++ ++ # Call ffi_closure_osf_inner to do the bulk of the work. ++ ldi $19, 2*8($30) ++ ldi $20, 10*8($30) ++ call $26, ffi_closure_osf_inner ++0: ++ ldih $29, 0($26) !gpdisp!2 ++ ldi $2, 99f-0b($26) ++ s4addl $0, 0, $1 # ldcode * 4 ++ ldl $0, 16($30) # preload return value ++ s4addl $1, $2, $1 # 99f + ldcode * 16 ++ ldi $29, 0($29) !gpdisp!2 ++ ldl $26, 0($30) ++ cfi_restore($26) ++ jmp $31, ($1), $load_32 ++ ++.macro epilogue ++ addl $30, CLOSURE_FS, $30 ++ cfi_adjust_cfa_offset(-CLOSURE_FS) ++ ret ++ .align 4 ++ cfi_adjust_cfa_offset(CLOSURE_FS) ++.endm ++ ++ .align 4 ++99: ++E SW_64_LD_VOID ++ epilogue ++ ++E SW_64_LD_INT64 ++ epilogue ++ ++E SW_64_LD_INT32 ++$load_32: ++ sextl $0, $0 ++ epilogue ++ ++E SW_64_LD_UINT16 ++ zapnot $0, 3, $0 ++ epilogue ++ ++E SW_64_LD_SINT16 ++#ifdef __sw_64_bwx__ ++ sexth $0, $0 ++#else ++ sll $0, 48, $0 ++ sra $0, 48, $0 ++#endif ++ epilogue ++ ++E SW_64_LD_UINT8 ++ and $0, 0xff, $0 ++ epilogue ++ ++E SW_64_LD_SINT8 ++#ifdef __sw_64_bwx__ ++ sextb $0, $0 ++#else ++ sll $0, 56, $0 ++ sra $0, 56, $0 ++#endif ++ epilogue ++ ++E SW_64_LD_FLOAT ++ flds $f0, 16($sp) ++ epilogue ++ ++E SW_64_LD_DOUBLE ++ fldd $f0, 16($sp) ++ epilogue ++ ++E SW_64_LD_CPLXF ++ flds $f0, 16($sp) ++ flds $f1, 20($sp) ++ epilogue ++ ++E SW_64_LD_CPLXD ++ fldd $f0, 16($sp) ++ fldd $f1, 24($sp) ++ epilogue ++ ++ cfi_endproc ++ .end ffi_closure_osf ++ ++#if defined __ELF__ && defined __linux__ ++ .section .note.GNU-stack,"",@progbits ++#endif +diff --git a/src/types.c b/src/types.c +index 9ec27f6..e5f666b 100644 +--- a/src/types.c ++++ b/src/types.c +@@ -80,13 +80,13 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const); + FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const); + FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const); + +-#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ ++#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__ || defined __sw_64__ + #define FFI_LDBL_CONST const + #else + #define FFI_LDBL_CONST + #endif + +-#ifdef __alpha__ ++#if defined __alpha__ || defined __sw_64__ + /* Even if we're not configured to default to 128-bit long double, + maintain binary compatibility, as -mlong-double-128 can be used + at any time. */ +diff --git a/testsuite/libffi.go/static-chain.h b/testsuite/libffi.go/static-chain.h +index 3675b40..25ef76e 100644 +--- a/testsuite/libffi.go/static-chain.h ++++ b/testsuite/libffi.go/static-chain.h +@@ -2,6 +2,8 @@ + # define STATIC_CHAIN_REG "x18" + #elif defined(__alpha__) + # define STATIC_CHAIN_REG "$1" ++#elif defined(__sw_64__) ++# define STATIC_CHAIN_REG "$1" + #elif defined(__arm__) + # define STATIC_CHAIN_REG "ip" + #elif defined(__sparc__) +-- +2.33.0 + diff --git a/libffi.spec b/libffi.spec index f4ff3a4349c0744c7481821b992b45f3ea43c72d..0bbe4404edfad8f4b76e430b58e4ec21b9a80f00 100644 --- a/libffi.spec +++ b/libffi.spec @@ -1,6 +1,6 @@ Name: libffi -Version: 3.4.4 -Release: 1 +Version: 3.4.2 +Release: 8 Summary: A Portable Foreign Function Interface Library License: MIT URL: http://sourceware.org/libffi @@ -8,8 +8,12 @@ Source0: https://github.com/libffi/libffi/releases/download/v%{version}/%{name}- Source1: ffi-multilib.h Source2: ffitarget-multilib.h -Patch0: backport-Fix-signed-vs-unsigned-comparison.patch -Patch1: fix-AARCH64EB-support.patch +Patch0: backport-x86-64-Always-double-jump-table-slot-size-for-CET-71.patch +Patch1: backport-Fix-check-for-invalid-varargs-arguments-707.patch +Patch2: libffi-Add-sw64-architecture.patch +Patch3: backport-Fix-signed-vs-unsigned-comparison.patch +Patch4: riscv-extend-return-types-smaller-than-ffi_arg-680.patch +Patch5: fix-AARCH64EB-support.patch BuildRequires: gcc gcc-c++ dejagnu BuildRequires: make @@ -53,9 +57,7 @@ BuildArch: noarch The help package contains man files. %prep -%setup -q -%patch0 -p1 -%patch1 -p1 +%autosetup -p1 -n %{name}-%{version} %build %configure \ @@ -99,6 +101,10 @@ fi %{_infodir}/libffi.info.gz %changelog +* Tue Nov 14 2023 zhangruifang - 3.4.2-8 +- revert version to 3.4.2-8 +- compatibility issues exist between versions + * Thu Oct 26 2023 zhangruifang - 3.4.4-1 - Type:enhancement - CVE:NA diff --git a/riscv-extend-return-types-smaller-than-ffi_arg-680.patch b/riscv-extend-return-types-smaller-than-ffi_arg-680.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa2526985c79e7b389cba7223e0c29c477aafbe7 --- /dev/null +++ b/riscv-extend-return-types-smaller-than-ffi_arg-680.patch @@ -0,0 +1,51 @@ +From aa3fce08ba620c50db17215a9f14dd0f1facf741 Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Sun, 13 Feb 2022 21:04:33 +0100 +Subject: [PATCH] riscv: extend return types smaller than ffi_arg (#680) + +Co-authored-by: Andreas Schwab +--- + src/riscv/ffi.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/src/riscv/ffi.c b/src/riscv/ffi.c +index c910858..ebd05ba 100644 +--- a/src/riscv/ffi.c ++++ b/src/riscv/ffi.c +@@ -373,7 +373,32 @@ ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue, + + cb.used_float = cb.used_integer = 0; + if (!return_by_ref && rvalue) +- unmarshal(&cb, cif->rtype, 0, rvalue); ++ { ++ if (IS_INT(cif->rtype->type) ++ && cif->rtype->size < sizeof (ffi_arg)) ++ { ++ /* Integer types smaller than ffi_arg need to be extended. */ ++ switch (cif->rtype->type) ++ { ++ case FFI_TYPE_SINT8: ++ case FFI_TYPE_SINT16: ++ case FFI_TYPE_SINT32: ++ unmarshal_atom (&cb, (sizeof (ffi_arg) > 4 ++ ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32), ++ rvalue); ++ break; ++ case FFI_TYPE_UINT8: ++ case FFI_TYPE_UINT16: ++ case FFI_TYPE_UINT32: ++ unmarshal_atom (&cb, (sizeof (ffi_arg) > 4 ++ ? FFI_TYPE_UINT64 : FFI_TYPE_UINT32), ++ rvalue); ++ break; ++ } ++ } ++ else ++ unmarshal(&cb, cif->rtype, 0, rvalue); ++ } + } + + void +-- +2.39.2 +