libffi-3.2.1 fixes
#1
libffi-3.2.1 fixes
At the moment i'm preparing dual neko packages for the "Big" Python 2.7.16 build and one of the dependencies is libffi.

Libffi is a library which is an interface between function objects and the operating system's calling convention. For programs who want to call a function but do not know the function arguments at runtime and /or the return type, they can use the libffi API to infer the number and types of arguments and return types before a call to that function. It is used in many code generating programs, like the gcc compiler and pseudocode interpreters like Python, but also Glib has a libffi dependency.

While revisiting my work on libffi since 2009 (see the Changelog and holy crap, that's ten years ago) i noticed that it still builds fine with MIPSPro and absolves most unittests, except for a few double/float/ulong tests and four unwind cc exception handling test:
Code:
Running ../../testsuite/libffi.call/call.exp ...
XPASS: libffi.call/cls_double_va.c output pattern test
FAIL: libffi.call/cls_ulong_va.c output pattern test
FAIL: libffi.call/float.c execution test
FAIL: libffi.call/huge_struct.c output pattern test
FAIL: libffi.call/unwindtest.cc (test for excess errors)
FAIL: libffi.call/unwindtest.cc execution test
FAIL: libffi.call/unwindtest_ffi_call.cc (test for excess errors)
FAIL: libffi.call/unwindtest_ffi_call.cc execution test

                === libffi Summary ===

# of expected passes            363
# of unexpected failures        7
# of unexpected successes       1
# of expected failures          1

So i went in fixing stuff again and then i found this patch from Anthony Green in Feb 9 2011:
Code:
@@ -278,6 +278,9 @@ typedef struct {
} ffi_closure __attribute__((aligned (8)));
#else
} ffi_closure;
+# ifdef __sgi
+#  pragma pack 0
+# endif
#endif

void *ffi_closure_alloc (size_t size, void **code);
@@ -296,6 +299,9 @@ ffi_prep_closure_loc (ffi_closure*,
              void *user_data,
              void*codeloc);

+#ifdef __sgi
+# pragma pack 8
+#endif
typedef struct {
   char tramp[FFI_TRAMPOLINE_SIZE];

This looks to be another alignment patch, except that it is backwards: #pragma pack (n) always precedes and never follows #pagma pack (0), since the scope of the pragma ends with the #pragma pack (0) statement.
Fixing that file with some more pragma packs and a missing LONGLONG_MAX plus a fix to cls_ulong_va.c i now get this:
Code:
Running ../../testsuite/libffi.call/call.exp ...
XPASS: libffi.call/cls_double_va.c output pattern test
XPASS: libffi.call/cls_longdouble_va.c output pattern test
FAIL: libffi.call/unwindtest_ffi_call.cc execution test

                === libffi Summary ===

# of expected passes            370
# of unexpected failures        1
# of unexpected successes       2

So my patch actually fixes one extra test result which was flagged as an expected failure on mips-sgi-irix6* , very cool.

This leaves us with only one test to fix, and that is a unittest in which the ffi function causes a 'throw' in C++ which is 'caught' in the main test-program.
To fix this test requires an exception handling frame in the n32.S machinecode. It is present for GAS as .eh_frame but there is nothing for the MIPSPro's AS so this test should for now fail only on MIPSPro compile, until i know enough assembly to add an .eh_handle equivalent for MIPSPro assembler (which should be _MIPS_eh_region BTW).
Practically this means that the libffi-3.2.1 + my patch can be used with MIPSPro C and C++ provided that you compile C++ programs with -LANG:exceptions=OFF or that you do not use exceptions in C++ code which uses ffi_call's.

I'll leave you with the libffi-3.2.1 IRIX patch and my environment settings for now so you can try it for your Python and GCC compiles and see if it fixes unittests for you.
Code:
setenv CC 'c99 -woff 1185,1552,3968,3970'
setenv CFLAGS '-O2 -mips3 -n32 -diag_error 1035'
setenv CXX 'CC -woff 3970'
setenv CXXFLAGS '-O2 -mips3 -n32 -diag_error 1035'
setenv CPPFLAGS -I/usr/nekoware/include
setenv LDFLAGS -L/usr/nekoware/lib

libffi-3.2.1_irix.patch:
--- ./testsuite/libffi.call/ffitest.h   Sun Jul 14 03:03:59 2019
+++ ./testsuite/libffi.call/ffitest.h   Sun Jul 14 23:01:21 2019
@@ -6,7 +6,9 @@
#include "fficonfig.h"

#if defined HAVE_STDINT_H
-#include <stdint.h>
+# if !(defined(__cplusplus) && defined(__sgi) && !defined(__GNUC__) )
+#  include <stdint.h>
+# endif
#endif

#if defined HAVE_INTTYPES_H
@@ -109,6 +111,7 @@
#endif
/* This doesn't match <inttypes.h>, which has "u" here, but the arguments
    are uintptr_t, which is always unsigned long.  */
+#undef PRIuPTR
#define PRIuPTR "lu"
#endif

--- ./testsuite/libffi.call/cls_ulong_va.c      Thu Jul 18 01:54:09 2019
+++ ./testsuite/libffi.call/cls_ulong_va.c      Thu Jul 18 01:56:15 2019
@@ -13,9 +13,9 @@
static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
                         void* userdata __UNUSED__)
  {
-   *(T *)resp = *(T *)args[0];
+   *(ffi_arg *)resp = *(T *)args[0];

-   printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+   printf("%ld: %ld %ld\n", (long)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
  }

typedef T (*cls_ret_T)(T, ...);
--- include/ffi.h.in.orig       Sat Nov  8 13:47:24 2014
+++ include/ffi.h.in    Sat Jul 20 23:18:59 2019
@@ -103,6 +103,11 @@
#   undef  FFI_64_BIT_MAX
#   define FFI_64_BIT_MAX 9223372036854775807LL
#  endif
+#  ifdef  __sgi /* IRIX has LONGLONG_MAX */
+#   define FFI_LONG_LONG_MAX LONGLONG_MAX
+#   undef  FFI_64_BIT_MAX
+#   define FFI_64_BIT_MAX 9223372036854775807LL
+#  endif
# endif
#endif

@@ -311,6 +316,9 @@
#ifdef _MSC_VER
__declspec(align(8))
#endif
+# ifdef __sgi
+#  pragma pack (8)
+# endif
typedef struct {
#if @FFI_EXEC_TRAMPOLINE_TABLE@
   void *trampoline_table;
@@ -326,7 +334,7 @@
#else
} ffi_closure;
# ifdef __sgi
-#  pragma pack 0
+#  pragma pack (0)
# endif
#endif

@@ -347,7 +355,7 @@
                      void*codeloc);

#ifdef __sgi
-# pragma pack 8
+# pragma pack (8)
#endif
typedef struct {
#if @FFI_EXEC_TRAMPOLINE_TABLE@
@@ -373,6 +381,9 @@
   void      *user_data;

} ffi_raw_closure;
+# ifdef __sgi
+#  pragma pack (0)
+# endif

typedef struct {
#if @FFI_EXEC_TRAMPOLINE_TABLE@
(This post was last modified: 07-25-2019, 12:57 AM by dexter1.)
dexter1
Administrator

Trade Count: (1)
Posts: 297
Threads: 17
Joined: May 2018
Location: The Netherlands
Find Reply
07-25-2019, 12:39 AM
#2
RE: libffi-3.2.1 fixes
Oh, wow. Thanks! That's great news. I'll have to dig out my old notes about building stuff on IRIX for full details, but I know I've run into issues due to the lack of libffi in the past. I'm sure I'll be able to put that patch to good use sometime.

SGI:  Indigo, Indigo2, Octane, Origin 300
Sun:  SPARCstation 20 (x4), Ultra 2, Blade 2500, T5240
HP:  9000/380, 425e, C8000
Digital: DECstation 5000/125, PWS 600au
jpstewart
Developer

Trade Count: (1)
Posts: 444
Threads: 6
Joined: May 2018
Location: SW Ontario, CA
Find Reply
07-25-2019, 11:12 PM


Forum Jump:


Users browsing this thread: 2 Guest(s)