7 Commits
Author SHA1 Message Date
Sergei Trofimovich 01a75ed76e powerpc: fix build failure on power7 and older (#532)
Build failure looks as:
```
libtool: compile:  powerpc-unknown-linux-gnu-gcc \
    -O2 -mcpu=powerpc -mtune=powerpc -pipe ... -c src/powerpc/ffi.c ...
In file included from src/powerpc/ffi.c:33:
src/powerpc/ffi_powerpc.h:65:9: error: '__int128' is not supported on this target
   65 | typedef __int128 float128;
      |         ^~~~~~~~
```

The fix avoids using __int128 in favour of aligned char[16].

Closes: https://github.com/libffi/libffi/issues/531
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2019-11-28 07:42:41 -05:00
Sergei Trofimovich fadf1eb530 hppa: avoid TEXTREL in .eh_frame section (#447)
Before the change hand-crafted .eh_frame section contained
ABS relocation and caused TEXTREL tag to be emitted:

```
$ ./configure --host=hppa2.0-unknown-linux-gnu LDFLAGS=-Wl,-z,text
$ make
...
/usr/libexec/gcc/hppa2.0-unknown-linux-gnu/ld:
    read-only segment has dynamic relocations.
```

Link failure is caused by absolute address of FDEs
encoded into .eh_frame entries.

Fixed TEXTREL by using pcrel (instead of ABS) encoding
for absolute addresses (__PIC__ code) by adding augmentation
information ("zR" CIE type).

All tests still pass on hppa2.0. The specific tests that still pass
and exercise this code path:
    testsuite/libffi.call/unwindtest.cc
    testsuite/libffi.call/unwindtest_ffi_call.cc

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2019-04-27 15:53:28 -04:00
Sergei Trofimovich b58caef7fd ia64: fix small struct return
This change fixes libffi.call/struct10.c failure on ia64:
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O0 execution test

.Lst_small_struct handles returns for structs less than 32 bytes
(following ia64 return value ABI [1]). Subroutine does roughly the
following:

```
    mov [sp+0]  = r8
    mov [sp+8]  = r9
    mov [sp+16] = r10
    mov [sp+24] = r11
    memcpy(destination, source=sp, 12);
```

The problem: ia64 ABI guarantees that top 16 bytes of stack are
scratch space for callee function. Thus it can clobber it. [1]
says (7.1 Procedure Frames):
"""
* Scratch area. This 16-byte region is provided as scratch storage
  for procedures that are called by the current procedure. Leaf
  procedures do not need to allocate this region. A procedure may
  use the 16 bytes at the top of its own frame as scratch memory,
  but the contents of this area are not preserved by a procedure call.
"""

In our case 16 top bytes are clobbered by a PLT resolver when memcpy()
is called for the first time. As a result memcpy implementation reads
already clobbered data frop top of stack.

The fix is simple: allocate 16 bytes of scrats space prior to memcpy()
call.

[1]: https://www.intel.com/content/dam/www/public/us/en/documents/guides/itanium-software-runtime-architecture-guide.pdf

Bug: https://bugs.gentoo.org/634190
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2018-02-17 19:01:29 +00:00
Sergei Trofimovich 45da2fcbcd new test: return small struct
The bug originally was discovered in https://bugs.gentoo.org/634190
where complicated callback was returning invalid data on ia64.

This change adds minimal reproducer that fails only on ia64 as:

FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O0 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O2 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O3 execution test
FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -Os execution test

Test passes on amd64. The fix is in the following commit.

Bug: https://bugs.gentoo.org/634190
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2018-02-17 18:53:02 +00:00
Sergei Trofimovich 11de69ddb7 ia64: fix variadic function closures with FP arguments
libffi test framework already flagged failures as:

```
    FAIL: libffi.call/cls_double_va.c -W -Wall -Wno-psabi -O0 output pattern test, is 7.0
    res: 4
    0.0
    res: 4
    ? should match 7.0
    ?es: 4
    ?.0
    res: 4
```

Failure happens here at

```c
    // testsuite/libffi.call/cls_double_va.c
    ...
    char*  format    = "%.1f\n";
    double doubleArg = 7;
    ...
    CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL,
                               code) == FFI_OK);
    res = ((int(*)(char*, ...))(code))(format, doubleArg);
```

libffi expects 'doubleArg' to be located in 'f9' (second FP argument) but
gcc placed it to 'r33' (second GR).

ia64 software [1] manual described argument passing ABI in
"8.5.2 Register Parameters" as:

"""
    If an actual parameter is known to correspond to a floating-point
    formal parameter, the following rules apply:
    a) The actual parameter is passed in the next available floating-point
       parameter register, if one is available. Floating-point parameter
       registers are allocated as needed from the range f8-f15, starting
       with f8.
    b) If all available floating-point parameter registers have been used,
       the actual parameter is passed in the appropriate general register(s).
       (This case can occur only as a result of homogeneous floating-point
       aggregates, described below.)

    If a floating-point actual parameter is known to correspond to
    a variable-argument specification in  the formal parameter list,
    the following rule applies:
    c) The actual parameter is passed in the appropriate general
       register(s).

    If the compiler cannot determine, at the point of call,
    whether the corresponding formal parameter is a varargs parameter,
    it must generate code that satisfies both of the above conditions.
    (The compiler’s determination may be based on prototype declarations,
    language standard assumptions,  analysis, or other user options or
    information.)
"""

We have [c] case here and gcc uses only GR for parameter passing.

The change binds known variadic arguments ro GRs instead of FPs as those
are always expected to be initialized for all variadic call types.

This fixes all 10 failures on ia64-unknown-linux-gnu:

```
                 === libffi Summary ===
    -# of expected passes            1945
    -# of unexpected failures        10
    +
    +# of expected passes            1955
```

[1]: https://www.intel.com/content/dam/www/public/us/en/documents/guides/itanium-software-runtime-architecture-guide.pdf

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2018-02-11 12:17:32 +00:00
Sergei Trofimovich cd5e9f8b87 Makefile.am: add 'src/s390/internal.h' to source tarball
commit 2f530de168
("s390: Reorganize assembly") introduced new header
(similar to other arches) but did not add it to source
tarball.

As a result build from 'make dist' tarballs failed as:

```
../src/s390/ffi.c:34:10: fatal error: internal.h: No such file or directory
 #include "internal.h"
          ^~~~~~~~~~~~
```

To fix it the change adds file to 'Makefile.am'.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2017-11-05 13:56:42 +00:00
Sergei Trofimovich ed7488c003 src/ia64/unix.S: unbreak small struct handling
commit 6e8a446083
added FFI_TYPE_COMPLEX value type (comes after FFI_TYPE_POINTER)

ia64 ffi_closure_unix reiles on the ordering of
FFI_ enums as ia64 has ia64-specific FFI types:
small struct and FPU extesions.

As a result all tests handling small structs broke.

The change fixes dispatch table by adding (no-op)
FFI_TYPE_COMPLEX entry
This has positive effect of unbreaking most tests
on ia64:

                 === libffi Summary ===

-# of expected passes            1595
-# of unexpected failures        295
+# of expected passes            1930
+# of unexpected failures        10
 # of unsupported tests          30

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2017-10-17 13:00:51 +01:00