libffi / libffi

A portable foreign-function interface library.
http://sourceware.org/libffi
Other
3.23k stars 705 forks source link

3.0.13: avoiding undefined ffi_prep_raw_closure_loc #70

Open marksolaris opened 10 years ago

marksolaris commented 10 years ago

Compiling on Solaris 11 x86 64bit with Sun Studio 12.3 compiler

The combination of 64bit and -Di386 creates a situation where this issue occurs:

/bin/sh ./libtool --tag=CC   --mode=link cc -m64  -D__i386__  -no-undefined -version-info `grep -v '^#' ../libtool-version`  '-L/usr/local/lib' '-R/usr/local/lib'  -L/usr/local/lib -R/usr/local/lib -o libffi.la -rpath /libffi/lib src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo                           src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffi.lo src/x86/sysv.lo         -lpthread -lthread
libtool: link: cc -m64 -G -z defs -h libffi.so.6 -o .libs/libffi.so.6.0.1  src/.libs/prep_cif.o src/.libs/types.o src/.libs/raw_api.o src/.libs/java_raw_api.o src/.libs/closures.o src/x86/.libs/ffi64.o src/x86/.libs/unix64.o src/x86/.libs/ffi.o src/x86/.libs/sysv.o   -R/usr/local/lib -L/usr/local/lib -lpthread -lthread -lc  -m64  
Undefined                       first referenced
 symbol                             in file
ffi_prep_raw_closure_loc            src/.libs/raw_api.o
ld: fatal: symbol referencing errors. No output written to .libs/libffi.so.6.0.1

Removing -Di386 fixes this as then the "System specific configurations" redefines in src/x86/ffitarget.h don't mess with your compile.

Posted here for the record so it gets googled. Can be closed as "solved".

marksolaris commented 10 years ago

A #warning in src/x86/ffitarget.h that X86_64 is being undefined would be a useful thing as well.

atgreen commented 10 years ago

A #warning patch would be welcomed

marksolaris commented 10 years ago

Using setenv CFLAGS "-Di386" or setenv CFLAGS "-DX86_64" for 32bit or 64bit compiles respectively, on 3.0.13, avoids the issue.

These packages

libffi.3.0.13.SPARC.32bit.Solaris.10.pkg libffi.3.0.13.SPARC.32bit.Solaris.8.pkg libffi.3.0.13.SPARC.32bit.Solaris.9.pkg libffi.3.0.13.SPARC.64bit.Solaris.10.pkg libffi.3.0.13.SPARC.64bit.Solaris.11.pkg libffi.3.0.13.SPARC.64bit.Solaris.7.pkg libffi.3.0.13.SPARC.64bit.Solaris.8.pkg libffi.3.0.13.SPARC.64bit.Solaris.9.pkg libffi.3.0.13.i86pc.64bit.Solaris.11.pkg libffi.3.0.13.i86pc.Solaris.10.pkg libffi.3.0.13.i86pc.Solaris.11.pkg

are now at http://www.ibiblio.org/pub/packages/solaris/sparc/

atgreen commented 6 years ago

@marksolaris - could you please retest this from the github sources, and I don't have access to a Solaris box? Ideally you wouldn't have to set CFLAGS to make it compile.

Also, I don't think the patches referenced in this issue are actually for this issue.

marksolaris commented 6 years ago
# cc -V
cc: Studio 12.6 Sun C 5.15 SunOS_i386 2017/05/30
# uname -a
SunOS sol11i64 5.11 11.3 i86pc i386 i86pc
# isainfo -b
64

cd /var/tmp; rm -rf libffi-master
unzip libffi-master.2018_04_27.zip   
cd libffi-master
setenv CC "cc -m64"
setenv CXX "CC -m64"
setenv F77 "f77 -m64"
setenv CFLAGS "-I/usr/local/include"
setenv LDFLAGS "-L/usr/local/lib -R/usr/local/lib"
./autogen.sh
./configure --prefix=/libffi \
         --includedir=/libffi/include \
         --enable-portable-binary
gmake

Solaris CC 12.6 has a problem with the X86-64 definition naming. The '-' sign in the definition breaks it.

libtool: compile:  cc -m64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DX86_64 -DX86-64 -I/usr/local/include -c ../src/closures.c -o src/closures.o >/dev/null 2>&1
source='../src/x86/ffi64.c' object='src/x86/ffi64.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ../depcomp \
/bin/sh ./libtool  --tag=CC   --mode=compile cc -m64 -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -DX86_64 -DX86-64 -I/usr/local/include -c -o src/x86/ffi64.lo ../src/x86/ffi64.c
libtool: compile:  cc -m64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -DX86_64 -DX86-64 -I/usr/local/include -c ../src/x86/ffi64.c  -KPIC -DPIC -o src/x86/.libs/ffi64.o
"command line:", warning: -D option argument not followed by "="
"../src/x86/ffi64.c", line 681: void function cannot return value
"../src/x86/ffi64.c", line 869: warning: assignment type mismatch:
        pointer to void "=" pointer to function(void) returning void

Not defining it still fails at that location

source='../src/x86/ffi64.c' object='src/x86/ffi64.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ../depcomp \
/bin/sh ./libtool  --tag=CC   --mode=compile cc -m64 -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -I/usr/local/include -c -o src/x86/ffi64.lo ../src/x86/ffi64.c
libtool: compile:  cc -m64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I/usr/local/include -c ../src/x86/ffi64.c  -KPIC -DPIC -o src/x86/.libs/ffi64.o
"../src/x86/ffi64.c", line 681: void function cannot return value
"../src/x86/ffi64.c", line 869: warning: assignment type mismatch:
        pointer to void "=" pointer to function(void) returning void
cc: acomp failed for ../src/x86/ffi64.c
Makefile:1207: recipe for target 'src/x86/ffi64.lo' failed
marksolaris commented 6 years ago
include/ffi.h:
typedef struct {
  void      *tramp;
  ffi_cif   *cif;
  void     (*fun)(ffi_cif*,void*,void**,void*);
} ffi_go_closure;

src/x86/ffi64.c:
extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;

  closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS
            ? ffi_go_closure_unix64_sse
            : ffi_go_closure_unix64);

The struct should be defining tramp as

void (*tramp)(void);
marksolaris commented 6 years ago

That worked, and then:

source='../src/x86/ffi64.c' object='src/x86/ffi64.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ../depcomp \
/bin/sh ./libtool  --tag=CC   --mode=compile cc -m64 -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src   -I/usr/local/include -c -o src/x86/ffi64.lo ../src/x86/ffi64.c
libtool: compile:  cc -m64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I/usr/local/include -c ../src/x86/ffi64.c  -KPIC -DPIC -o src/x86/.libs/ffi64.o
"../src/x86/ffi64.c", line 681: void function cannot return value
cc: acomp failed for ../src/x86/ffi64.c
Makefile:1207: recipe for target 'src/x86/ffi64.lo' failed
gmake[3]: *** [src/x86/ffi64.lo] Error 1

This return() is the problem:

x86/ffi64.c:
#ifndef __ILP32__
  if (cif->abi == FFI_EFI64)
    return ffi_call_efi64(cif, fn, rvalue, avalue);
#endif

Changed to:

#ifndef __ILP32__
  if (cif->abi == FFI_EFI64) {
    ffi_call_efi64(cif, fn, rvalue, avalue);
    return;
  }
#endif

Then there's the next roadblock:

source='../src/x86/unix64.S' object='src/x86/unix64.lo' libtool=yes \
DEPDIR=.deps depmode=none /bin/sh ../depcomp \
/bin/sh ./libtool    --mode=compile cc -m64 -DHAVE_CONFIG_H -I. -I..  -I. -I../include -Iinclude -I../src  -I. -I../include -Iinclude -I../src -I/usr/local/include -c -o src/x86/unix64.lo ../src/x86/unix64.S
libtool: compile:  cc -m64 -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -I/usr/local/include -c ../src/x86/unix64.S  -KPIC -DPIC -o src/x86/.libs/unix64.o
Assembler: 
        "../src/x86/unix64.S", line 60 : Illegal mnemonic
        Near line: ".L ##   UW0:"
        "../src/x86/unix64.S", line 60 : Syntax error
        Near line: ".L ##   UW0:"
        "../src/x86/unix64.S", line 76 : Illegal mnemonic
        Near line: ".L ##   UW1:"
        "../src/x86/unix64.S", line 76 : Syntax error
        Near line: ".L ##   UW1:"
        "../src/x86/unix64.S", line 94 : Illegal mnemonic
        Near line: ".L ##   ret_from_load_sse:"
        "../src/x86/unix64.S", line 94 : Syntax error
marksolaris commented 6 years ago

Looks like unix.S has radically changed:

libffi-3.0.13/src/x86/unix.S:

        .align  2
        .globl  ffi_call_unix64
        .type   ffi_call_unix64,@function

ffi_call_unix64:
.LUW0:
        movq    (%rsp), %r10            /* Load return address.  */
        leaq    (%rdi, %rsi), %rax      /* Find local stack base.  */
        movq    %rdx, (%rax)            /* Save flags.  */
        movq    %rcx, 8(%rax)           /* Save raddr.  */
        movq    %rbp, 16(%rax)          /* Save old frame pointer.  */
        movq    %r10, 24(%rax)          /* Relocate return address.  */
        movq    %rax, %rbp              /* Finalize local stack frame.  */
.LUW1:
        movq    %rdi, %r10              /* Save a copy of the register area. */
        movq    %r8, %r11               /* Save a copy of the target fn.  */
        movl    %r9d, %eax              /* Set number of SSE registers.  */

v's libffi-master/src/x86/unix64.S:


    .balign 8
    .globl  C(ffi_call_unix64)
    FFI_HIDDEN(C(ffi_call_unix64))

C(ffi_call_unix64):
L(UW0):
    movq    (%rsp), %r10        /* Load return address.  */
    leaq    (%rdi, %rsi), %rax  /* Find local stack base.  */
    movq    %rdx, (%rax)        /* Save flags.  */
    movq    %rcx, 8(%rax)       /* Save raddr.  */
    movq    %rbp, 16(%rax)      /* Save old frame pointer.  */
    movq    %r10, 24(%rax)      /* Relocate return address.  */
    movq    %rax, %rbp      /* Finalize local stack frame.  */

    /* New stack frame based off rbp.  This is a itty bit of unwind
       trickery in that the CFA *has* changed.  There is no easy way
       to describe it correctly on entry to the function.  Fortunately,
       it doesn't matter too much since at all points we can correctly
       unwind back to ffi_call.  Note that the location to which we
       moved the return address is (the new) CFA-8, so from the
       perspective of the unwind info, it hasn't moved.  */
L(UW1):
    /* cfi_def_cfa(%rbp, 32) */
    /* cfi_rel_offset(%rbp, 16) */

    movq    %rdi, %r10      /* Save a copy of the register area. */
    movq    %r8, %r11       /* Save a copy of the target fn.  */
    movl    %r9d, %eax      /* Set number of SSE registers.  */
tromey commented 6 years ago

"../src/x86/ffi64.c", line 681: void function cannot return value

There's a similar case in ffi_call_go where, it seems to me, the return is missing.

tromey commented 6 years ago

Solaris CC 12.6 has a problem with the X86-64 definition naming. The '-' sign in the definition breaks it.

That's invalid - do you know what generates it?

marksolaris commented 6 years ago

That's invalid - do you know what generates it?

That would have been me taking the README too seriously. An ID:01(T) error I believe. I was hunting for -D combinations to get it to compile like it used to.

./README.md:| X86-64 | Solaris | Oracle Solaris Studio C |