tov / libffi-rs Goto Github PK
View Code? Open in Web Editor NEWRust bindings for libffi
License: Apache License 2.0
Rust bindings for libffi
License: Apache License 2.0
Right now it’s repr(C)
, and I’m not sure whether that’s strictly correct.
Upstream issue: denoland/deno#15292.
Downstream issue: libffi/libffi#725.
It seems that libffi-rs doesn't provide a function pointer type, but after further investigation, it seems that this is because the C libffi does not support this, so I have opened an issue there too; feel free to subscribe to the downstream issue.
Nonetheless, in the meanwhile, it does seem that libffi-rs misuses *const c_void
as fn()
, which can still be fixed here.
See https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html and https://c-faq.com/ptrs/generic.html.
Rust claims that Rust's extern "ABI" fn(...) -> R
has the same size/alignment/etc. as C's void (*)()
, and that it may not necessarily map to C's void *
.
Furthermore, Rust's fn
documentation requests that code use fn
primitives for FFI.
As a result, some present usage here is unsound (on some platforms), such as https://docs.rs/libffi/latest/libffi/low/struct.CodePtr.html.
CI status appears to be random with qemu testing. Another very fundamental rust crate, libc
, has a workaround for a different problem they had with qemu-s390x. Is it a viable workaround for the qemu tests of this repo?
I get the following error when trying to build libffi:
Compiling libffi-sys v0.5.4
Compiling libffi v0.6.1
error[E0432]: unresolved import `raw::ffi_status`
--> /home/guillaume/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-0.6.1/src/low.rs:29:14
|
29 | use raw::ffi_status::*;
| ^^^^^^^^^^ Not a module `ffi_status`
error[E0599]: no associated item named `STRUCT` found for type `u32` in the current scope
--> /home/guillaume/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-0.6.1/src/low.rs:190:35
|
190 | pub const STRUCT: c_ushort = raw::ffi_type_enum::STRUCT as c_ushort;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: Could not compile `libffi`.
warning: build failed, waiting for other jobs to finish...
Any idea where this could come from?
I am on Linux Centos 7, with the latest stable rustc.
You get these errors:
...
Compiling bindgen v0.22.0
Compiling libffi-sys v0.4.7
Compiling libffi v0.4.0
error[E0432]: unresolved import raw::FFI_DEFAULT_ABI
--> /home/joris/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-0.4.0/src/low.rs:118:24
|
118 | pub use raw::{ffi_abi, FFI_DEFAULT_ABI, _ffi_type as ffi_type, ffi_status,
| ^^^^^^^^^^^^^^^ no FFI_DEFAULT_ABI
in raw
error[E0432]: unresolved import middle::FFI_DEFAULT_ABI
--> /home/joris/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-0.4.0/src/high/mod.rs:71:26
|
71 | pub use middle::{FfiAbi, FFI_DEFAULT_ABI};
| ^^^^^^^^^^^^^^^ no FFI_DEFAULT_ABI
in middle
error: aborting due to 2 previous errors
error: Could not compile libffi
.
You need to publish a version on crates.io with this commit included:
I have the same problem in apple M2:
error: failed to run custom build command for `libffi-sys v2.3.0`
Caused by:
process didn't exit successfully: `/home/ub/target/release/build/libffi-sys-bac7e949b60e9201/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-env-changed=CC_x86_64-pc-windows-gnu
CC_x86_64-pc-windows-gnu = None
cargo:rerun-if-env-changed=CC_x86_64_pc_windows_gnu
CC_x86_64_pc_windows_gnu = None
cargo:rerun-if-env-changed=TARGET_CC
TARGET_CC = Some("x86_64-w64-mingw32-gcc")
cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
CRATE_CC_NO_DEFAULTS = None
CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
cargo:rerun-if-env-changed=CFLAGS_x86_64-pc-windows-gnu
CFLAGS_x86_64-pc-windows-gnu = None
cargo:rerun-if-env-changed=CFLAGS_x86_64_pc_windows_gnu
CFLAGS_x86_64_pc_windows_gnu = None
cargo:rerun-if-env-changed=TARGET_CFLAGS
TARGET_CFLAGS = None
cargo:rerun-if-env-changed=CFLAGS
CFLAGS = None
checking build system type... aarch64-unknown-linux-gnu
checking host system type...
--- stderr
Invalid configuration `x86_64-pc-windows-gnu': Kernel `windows' not known to work with OS `gnu'.
configure: error: /bin/bash ./config.sub x86_64-pc-windows-gnu failed
thread 'main' panicked at /home/ub/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-2eab394af869c8a2/libffi-sys-2.3.0/build/common.rs:8:5:
Configuring libffi
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
in config.toml
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-ar"
and in env TARGET_CC=x86_64-w64-mingw32-gcc TARGET_AR=x86_64-w64-mingw32-ar
Hi!
I'm currently running a local fork of this project in order to do some FFI things in a no_std application (with alloc). Of course it'd be a lot nicer to simply rely on the upstream repo.
If you take a look at the comparison against my fork (where I put all changes behind a no_std
feature flag) you see its 90% just importing things from core
rather than std
. Would this be something feasible to get in libffi-rs
?
master...val3rius:libffi-rs:no_std
Thanks a bunch!
I'm trying to build an application that uses libffi-rs to use in a aws lambda function. I've spent quite some time on this the last two weeks and I just can't get it to work. Works fine on ubuntu and manjaro when I've tried on those.
The output I get is here
I've tried to distill this as much as I can and have made a repo a with a simple rust project and a Dockerfile, just run ./build.sh && ./run.sh
and it will build the image and then run cargo run within the container.
I you would find the time to take a look I would be very grateful.
Also thanks for your work on this lib
While transitioning from the low
api to the middle
api, I found that there is no new_variadic
function for Cif, which is a must for me. I can't create a pull request, so I'm pasting the function I created for myself here in hope that some variation of this function will be merged :)
/// Creates a new variadic [CIF](Cif) for the given argument and result
/// types.
///
/// Takes ownership of the argument and result [`Type`]s, because
/// the resulting [`Cif`] retains references to them. Defaults to
/// the platform’s default calling convention; this can be adjusted
/// using [`Cif::set_abi`].
pub fn new_variadic<I>(args: I, fixed_args: usize, result: Type) -> Self
where
I: IntoIterator<Item = Type>,
I::IntoIter: ExactSizeIterator<Item = Type>,
{
let args = args.into_iter();
let nargs = args.len();
let args = types::TypeArray::new(args);
let mut cif: low::ffi_cif = Default::default();
unsafe {
low::prep_cif_var(
&mut cif,
low::ffi_abi_FFI_DEFAULT_ABI,
fixed_args,
nargs,
result.as_raw_ptr(),
args.as_raw_ptr(),
)
}
.expect("low::prep_cif_var");
// Note that cif retains references to args and result,
// which is why we hold onto them here.
Cif { cif, args, result }
}
Currently we recognize only FFI_BAD_ABI
and FFI_BAD_TYPEDEF
, which we translate to Error::Typedef
and Error::Abi
. As of now, FFI_BAD_ARGTYPE
gets translated to Error::Abi
(which maybe isn’t strictly incorrect?). But it would be better to add a third enumerator, Error::Argtype
for representing FFI_BAD_ARGTYPE
. This isn’t difficult, but it will require a major version bump.
I started to get an error in my crate which uses libffi today.
Any ideas?
Compiling libffi v2.0.0
error[E0432]: unresolved import `crate::raw::ffi_type_longdouble`
--> /Users/../.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-2.0.0/src/low.rs:140:13
|
140 | pub use crate::raw::ffi_type_longdouble as longdouble;
| ^^^^^^^^^^^^-------------------^^^^^^^^^^^^^^
| | |
| | help: a similar name exists in the module: `FFI_TYPE_LONGDOUBLE`
| no `ffi_type_longdouble` in `raw`
For more information about this error, try `rustc --explain E0432`.
Hi everyone,
Currently, there is no support for mips and mips64 architecture. If I build libffi with the command -
cargo build --target mips64el-unknown-linux-gnuabi64
the compilation throws the following error -
error[E0425]: cannot find value `FFI_TRAMPOLINE_SIZE` in this scope
--> libffi-sys-rs/src/lib.rs:165:25
|
165 | pub tramp: [c_char; FFI_TRAMPOLINE_SIZE],
| ^^^^^^^^^^^^^^^^^^^ not found in this scope
|
note: these constants exist but are inaccessible
This seems to be sorted with the following changes in arch.rs
file as follows:
#[cfg(all(target_arch = "mips64", unix))]
pub use x86::x86_64::*;
#[cfg(all(target_arch = "mips", unix))]
pub use x86::x86::*;
Are these appropriate changes to make and apt for the problem mentioned?
FYI, I'm testing this from the RustPython project, whose jit
feature imports an outdated version of this library. RustPython/RustPython#3050 updates the libffi
crate to v2.0.0, which unfortunately still has this problem. A workaround is to specify the system
feature.
cargo build
Compiling libffi-sys v1.1.3
error: failed to run custom build command for `libffi-sys v1.1.3`
Caused by:
process didn't exit successfully: `~/Documents/GitHub/RustPython/target/release/build/libffi-sys-d3f96f963a2ec199/build-script-build` (exit status: 101)
--- stdout
glibtoolize: putting auxiliary files in '.'.
glibtoolize: copying file './ltmain.sh'
glibtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
glibtoolize: copying file 'm4/libtool.m4'
glibtoolize: copying file 'm4/ltoptions.m4'
glibtoolize: copying file 'm4/ltsugar.m4'
glibtoolize: copying file 'm4/ltversion.m4'
glibtoolize: copying file 'm4/lt~obsolete.m4'
checking build system type... arm-apple-darwin20.6.0
checking host system type... arm-apple-darwin20.6.0
checking target system type... arm-apple-darwin20.6.0
continue configure in default builddir "./aarch64-apple-darwin"
....exec /bin/sh ../configure "--srcdir=.." "--enable-builddir=aarch64-apple-darwin" "darwin20.6.0"
checking build system type... arm-apple-darwin20.6.0
checking host system type... arm-apple-darwin20.6.0
checking target system type... arm-apple-darwin20.6.0
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... ../install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether gcc accepts -g... yes
checking for gcc option to enable C11 features... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking for g++... g++
checking whether the compiler supports GNU C++... yes
checking whether g++ accepts -g... yes
checking for g++ option to enable C++11 features... none needed
checking dependency style of g++... gcc3
checking dependency style of gcc... gcc3
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
checking if the linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) is GNU ld... no
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 786432
checking how to convert arm-apple-darwin20.6.0 file names to arm-apple-darwin20.6.0 format... func_convert_file_noop
checking how to convert arm-apple-darwin20.6.0 file names to toolchain format... func_convert_file_noop
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... no
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for mt... no
checking if : is a manifest tool... no
checking for dsymutil... dsymutil
checking for nmedit... nmedit
checking for lipo... lipo
checking for otool... otool
checking for otool64... no
checking for -single_module linker flag... yes
checking for -exported_symbols_list linker flag... yes
checking for -force_load linker flag... yes
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... yes
checking for gcc option to produce PIC... -fno-common -DPIC
checking if gcc PIC flag -fno-common -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) supports shared libraries... yes
checking dynamic linker characteristics... darwin20.6.0 dyld
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking how to run the C++ preprocessor... g++ -E
checking for ld used by g++... /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
checking if the linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) is GNU ld... no
checking whether the g++ linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) supports shared libraries... yes
checking for g++ option to produce PIC... -fno-common -DPIC
checking if g++ PIC flag -fno-common -DPIC works... yes
checking if g++ static flag -static works... no
checking if g++ supports -c -o file.o... yes
checking if g++ supports -c -o file.o... (cached) yes
checking whether the g++ linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) supports shared libraries... yes
checking dynamic linker characteristics... darwin20.6.0 dyld
checking how to hardcode library paths into programs... immediate
checking size of size_t... 8
checking for C compiler vendor... clang
********************************************************
* WARNING: Don't know the best CFLAGS for this system *
* Use ./configure CFLAGS=... to specify your own flags *
* (otherwise, a default of CFLAGS=-O3 will be used) *
********************************************************
checking whether C compiler accepts -O3... yes
checking CFLAGS for maximum warnings... -Wall
checking whether to enable maintainer-specific portions of Makefiles... no
checking for sys/mman.h... yes
checking for mmap... yes
checking for mkostemp... yes
checking for sys/mman.h... (cached) yes
checking for mmap... (cached) yes
checking whether read-only mmap of a plain file works... yes
checking whether mmap from /dev/zero works... no
checking for MAP_ANON(YMOUS)... yes
checking whether mmap with MAP_ANON(YMOUS) works... yes
checking for egrep... (cached) /usr/bin/grep -E
checking for memcpy... yes
checking for size_t... yes
checking for working alloca.h... yes
checking for alloca... yes
checking size of double... 8
checking size of long double... 8
checking whether byte ordering is bigendian... no
checking assembler .cfi pseudo-op support... no
checking for _ prefix in compiled symbols... yes
checking whether .eh_frame section should be read-only... no
checking for __attribute__((visibility("hidden")))... yes
checking for ld used by gcc... (cached) /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
checking if the linker (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld) is GNU ld... (cached) no
configure: versioning on shared library symbols is no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating include/Makefile
config.status: creating include/ffi.h
config.status: creating Makefile
config.status: creating testsuite/Makefile
config.status: creating man/Makefile
config.status: creating doc/Makefile
config.status: creating libffi.pc
config.status: creating fficonfig.h
config.status: executing buildir commands
config.status: create top_srcdir/Makefile guessed from local Makefile
config.status: build in aarch64-apple-darwin (HOST=aarch64-apple-darwin)
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing include commands
config.status: executing src commands
MAKE aarch64-apple-darwin : 1 * install
Making install in include
make[3]: Nothing to be done for `install-exec-am'.
../../install-sh -c -d '~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/include'
/usr/bin/install -c -m 644 ffi.h ffitarget.h '~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/include'
Making install in testsuite
make[3]: Nothing to be done for `install-exec-am'.
make[3]: Nothing to be done for `install-data-am'.
Making install in man
make[3]: Nothing to be done for `install-exec-am'.
../../install-sh -c -d '~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/share/man/man3'
/usr/bin/install -c -m 644 ../../man/ffi.3 ../../man/ffi_call.3 ../../man/ffi_prep_cif.3 ../../man/ffi_prep_cif_var.3 '~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/share/man/man3'
depbase=`echo src/prep_cif.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF $depbase.Tpo -c -o src/prep_cif.lo ../src/prep_cif.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF src/.deps/prep_cif.Tpo -c ../src/prep_cif.c -fno-common -DPIC -o src/.libs/prep_cif.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/prep_cif.lo -MD -MP -MF src/.deps/prep_cif.Tpo -c ../src/prep_cif.c -fno-common -DPIC -o src/prep_cif.o >/dev/null 2>&1
depbase=`echo src/types.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/types.lo -MD -MP -MF $depbase.Tpo -c -o src/types.lo ../src/types.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/types.lo -MD -MP -MF src/.deps/types.Tpo -c ../src/types.c -fno-common -DPIC -o src/.libs/types.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/types.lo -MD -MP -MF src/.deps/types.Tpo -c ../src/types.c -fno-common -DPIC -o src/types.o >/dev/null 2>&1
depbase=`echo src/raw_api.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF $depbase.Tpo -c -o src/raw_api.lo ../src/raw_api.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF src/.deps/raw_api.Tpo -c ../src/raw_api.c -fno-common -DPIC -o src/.libs/raw_api.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/raw_api.lo -MD -MP -MF src/.deps/raw_api.Tpo -c ../src/raw_api.c -fno-common -DPIC -o src/raw_api.o >/dev/null 2>&1
depbase=`echo src/java_raw_api.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF $depbase.Tpo -c -o src/java_raw_api.lo ../src/java_raw_api.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF src/.deps/java_raw_api.Tpo -c ../src/java_raw_api.c -fno-common -DPIC -o src/.libs/java_raw_api.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/java_raw_api.lo -MD -MP -MF src/.deps/java_raw_api.Tpo -c ../src/java_raw_api.c -fno-common -DPIC -o src/java_raw_api.o >/dev/null 2>&1
depbase=`echo src/closures.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/closures.lo -MD -MP -MF $depbase.Tpo -c -o src/closures.lo ../src/closures.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/closures.lo -MD -MP -MF src/.deps/closures.Tpo -c ../src/closures.c -fno-common -DPIC -o src/.libs/closures.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/closures.lo -MD -MP -MF src/.deps/closures.Tpo -c ../src/closures.c -fno-common -DPIC -o src/closures.o >/dev/null 2>&1
depbase=`echo src/arm/ffi.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/arm/ffi.lo -MD -MP -MF $depbase.Tpo -c -o src/arm/ffi.lo ../src/arm/ffi.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/arm/ffi.lo -MD -MP -MF src/arm/.deps/ffi.Tpo -c ../src/arm/ffi.c -fno-common -DPIC -o src/arm/.libs/ffi.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -O3 -Wall -fexceptions -MT src/arm/ffi.lo -MD -MP -MF src/arm/.deps/ffi.Tpo -c ../src/arm/ffi.c -fno-common -DPIC -o src/arm/ffi.o >/dev/null 2>&1
depbase=`echo src/arm/sysv.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -MT src/arm/sysv.lo -MD -MP -MF $depbase.Tpo -c -o src/arm/sysv.lo ../src/arm/sysv.S &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -MT src/arm/sysv.lo -MD -MP -MF src/arm/.deps/sysv.Tpo -c ../src/arm/sysv.S -fno-common -DPIC -o src/arm/.libs/sysv.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -I. -I../include -Iinclude -I../src -MT src/arm/sysv.lo -MD -MP -MF src/arm/.deps/sysv.Tpo -c ../src/arm/sysv.S -fno-common -DPIC -o src/arm/sysv.o >/dev/null 2>&1
/bin/sh ./libtool --tag=CC --mode=link gcc -O3 -Wall -fexceptions -o libffi_convenience.la src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/arm/ffi.lo src/arm/sysv.lo
libtool: link: ar cru .libs/libffi_convenience.a 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/arm/.libs/ffi.o src/arm/.libs/sysv.o
libtool: link: ranlib .libs/libffi_convenience.a
libtool: link: ( cd ".libs" && rm -f "libffi_convenience.la" && ln -s "../libffi_convenience.la" "libffi_convenience.la" )
/bin/sh ./libtool --tag=CC --mode=link gcc -O3 -Wall -fexceptions -no-undefined -version-info `grep -v '^#' ../libtool-version` -o libffi.la -rpath ~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/lib src/prep_cif.lo src/types.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo src/arm/ffi.lo src/arm/sysv.lo
libtool: link: gcc -dynamiclib -o .libs/libffi.7.dylib 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/arm/.libs/ffi.o src/arm/.libs/sysv.o -O3 -install_name ~/Documents/GitHub/RustPython/target/release/build/libffi-sys-dc92f43a95626daf/out/libffi-root/lib/libffi.7.dylib -compatibility_version 9 -current_version 9.0 -Wl,-single_module
--- stderr
autoreconf: export WARNINGS=
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal -I m4
autoreconf: configure.ac: tracing
autoreconf: running: glibtoolize --copy
autoreconf: configure.ac: not using Intltool
autoreconf: configure.ac: not using Gtkdoc
autoreconf: running: aclocal -I m4
autoreconf: running: /opt/homebrew/Cellar/autoconf/2.71/bin/autoconf
configure.ac:8: warning: The macro `AC_CANONICAL_SYSTEM' is obsolete.
configure.ac:8: You should run autoupdate.
./lib/autoconf/general.m4:2081: AC_CANONICAL_SYSTEM is expanded from...
configure.ac:8: the top level
configure.ac:41: warning: The macro `AC_PROG_LIBTOOL' is obsolete.
configure.ac:41: You should run autoupdate.
m4/libtool.m4:99: AC_PROG_LIBTOOL is expanded from...
configure.ac:41: the top level
configure.ac:68: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:68: You should run autoupdate.
./lib/autoconf/general.m4:2847: AC_TRY_COMPILE is expanded from...
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/general.m4:2270: AC_CACHE_CHECK is expanded from...
acinclude.m4:3: AC_FUNC_MMAP_BLACKLIST is expanded from...
configure.ac:68: the top level
configure.ac:85: warning: The macro `AC_HEADER_STDC' is obsolete.
configure.ac:85: You should run autoupdate.
./lib/autoconf/headers.m4:704: AC_HEADER_STDC is expanded from...
configure.ac:85: the top level
configure.ac:112: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:112: You should run autoupdate.
./lib/autoconf/general.m4:2847: AC_TRY_COMPILE is expanded from...
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/general.m4:2270: AC_CACHE_CHECK is expanded from...
m4/asmcfi.m4:1: GCC_AS_CFI_PSEUDO_OP is expanded from...
configure.ac:112: the top level
configure.ac:116: warning: The macro `AC_TRY_LINK' is obsolete.
configure.ac:116: You should run autoupdate.
./lib/autoconf/general.m4:2920: AC_TRY_LINK is expanded from...
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/general.m4:2270: AC_CACHE_CHECK is expanded from...
configure.ac:116: the top level
configure.ac:132: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:132: You should run autoupdate.
./lib/autoconf/general.m4:2847: AC_TRY_COMPILE is expanded from...
lib/m4sugar/m4sh.m4:692: _AS_IF_ELSE is expanded from...
lib/m4sugar/m4sh.m4:699: AS_IF is expanded from...
./lib/autoconf/general.m4:2249: AC_CACHE_VAL is expanded from...
./lib/autoconf/general.m4:2270: AC_CACHE_CHECK is expanded from...
configure.ac:132: the top level
configure.ac:286: warning: The macro `AC_HELP_STRING' is obsolete.
configure.ac:286: You should run autoupdate.
./lib/autoconf/general.m4:204: AC_HELP_STRING is expanded from...
configure.ac:286: the top level
configure.ac:380: warning: The macro `AC_HELP_STRING' is obsolete.
configure.ac:380: You should run autoupdate.
./lib/autoconf/general.m4:204: AC_HELP_STRING is expanded from...
acinclude.m4:353: LIBFFI_ENABLE_SYMVERS is expanded from...
configure.ac:380: the top level
configure.ac:380: warning: The macro `AC_PROG_LD' is obsolete.
configure.ac:380: You should run autoupdate.
m4/libtool.m4:3325: AC_PROG_LD is expanded from...
acinclude.m4:251: LIBFFI_CHECK_LINKER_FEATURES is expanded from...
acinclude.m4:353: LIBFFI_ENABLE_SYMVERS is expanded from...
configure.ac:380: the top level
configure.ac:380: warning: The macro `AC_TRY_RUN' is obsolete.
configure.ac:380: You should run autoupdate.
./lib/autoconf/general.m4:2997: AC_TRY_RUN is expanded from...
acinclude.m4:251: LIBFFI_CHECK_LINKER_FEATURES is expanded from...
acinclude.m4:353: LIBFFI_ENABLE_SYMVERS is expanded from...
configure.ac:380: the top level
configure.ac:380: warning: The macro `AC_TRY_LINK' is obsolete.
configure.ac:380: You should run autoupdate.
./lib/autoconf/general.m4:2920: AC_TRY_LINK is expanded from...
acinclude.m4:353: LIBFFI_ENABLE_SYMVERS is expanded from...
configure.ac:380: the top level
autoreconf: running: /opt/homebrew/Cellar/autoconf/2.71/bin/autoheader
autoreconf: running: automake --add-missing --copy --no-force
configure.ac:31: installing './compile'
configure.ac:19: installing './install-sh'
configure.ac:19: installing './missing'
Makefile.am: installing './depcomp'
doc/Makefile.am:3: installing 'doc/mdate-sh'
doc/Makefile.am:3: installing 'doc/texinfo.tex'
autoreconf: Leaving directory '.'
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
../src/java_raw_api.c:328:46: warning: 'ffi_java_raw_size' is deprecated [-Wdeprecated-declarations]
ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
^
include/ffi.h:299:56: note: 'ffi_java_raw_size' has been explicitly marked deprecated here
size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
^
../src/java_raw_api.c:331:3: warning: 'ffi_java_ptrarray_to_raw' is deprecated [-Wdeprecated-declarations]
ffi_java_ptrarray_to_raw (cif, avalue, raw);
^
include/ffi.h:295:93: note: 'ffi_java_ptrarray_to_raw' has been explicitly marked deprecated here
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
^
2 warnings generated.
Undefined symbols for architecture arm64:
"_ffi_call", referenced from:
_ffi_raw_call in raw_api.o
_ffi_java_raw_call in java_raw_api.o
"_ffi_closure_trampoline_table_page", referenced from:
_ffi_closure_alloc in closures.o
"_ffi_prep_cif_machdep", referenced from:
_ffi_prep_cif_core in prep_cif.o
"_ffi_prep_cif_machdep_var", referenced from:
_ffi_prep_cif_core in prep_cif.o
"_ffi_prep_closure_loc", referenced from:
_ffi_prep_closure in prep_cif.o
_ffi_prep_raw_closure_loc in raw_api.o
_ffi_prep_raw_closure in raw_api.o
_ffi_prep_java_raw_closure_loc in java_raw_api.o
_ffi_prep_java_raw_closure in java_raw_api.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libffi.la] Error 1
make[1]: *** [install-recursive] Error 1
make: *** [install] Error 2
thread 'main' panicked at 'Building libffi', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-1.1.3/build/common.rs:8:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
The current version of libffi
is v3.4.2, while this crate vendors v3.3. v3.4.2 contains libffi/libffi#565, which adds some support for the M1 processor.
I have a system that includes msys2 and wsl. I was having trouble and still am having trouble in wsl linux. My focus was on a msvc build and I found a work around.
I was attempting to get this project to build.
svix/svix-webhooks#1128
fatal error C1083: Cannot open include file: 'fficonfig.h': No such file or **directory**
The windows build was erroring with a missing header file. The ubuntu build is failing without any real detail and I'm not sure how to debug or resolve that.
I was able to get the windows build working using the following before doing a cargo build:
set INCLUDE=%INCLUDE%;libffi\include;libffi-sys-2.3.0\libffi\src\x86\
I hope this helps someone else if they encounter the windows build issue. I'd really like to help resolve the issue without a work around. Please have a look at the associated ticket and let me know if there is anything I can test or help with further.
thanks.
The following code is safe but results in reading uninitialized data twice (which is undefined behavior):
use libffi::high::{Callback0, Cif0, Closure0, CType};
use libffi::low::ffi_cif;
extern "C" fn callback(_cif: &ffi_cif, result: &mut i32, _args: &(), _userdata: &()) {
println!("Reading uninitialized result: {}", *result);
}
fn main() {
println!("Hello, world!");
let c: Callback0<(), i32> = callback;
let closure = Closure0::from_parts(Cif0::new(i32::reify()), c, &());
println!("Result = {}", closure.code_ptr().call());
}
First, we read uninitialized data inside the callback, since there is no guarantee result
actually refers to a valid i32
. Second, we read uninitialized data inside main
, since the result of closure.code_ptr.call()
is uninitialized.
There are two issues. The first is that Callbackn
is defined to take result: &mut R
instead of result: &mut MaybeUninit<R>
or result: *mut R
. The second is that there is no static way of enforcing the requirement that callbacks actually write to result
.
Note that all issues raised here also apply to the Mut
and Once
versions, and to closures/callbacks of all arities (not just 0-ary). The same is true for the solutions.
All the types which implement CType
share a convenient property; they can be safely zero-initialized. Instead of using MaybeUninit::new_uninit()
to "initialize" the result and then passing a pointer to the callback, we could instead call MaybeUninit::zeroed().assume_init()
to initialize the result before invoking the callback. Since CType
is an unsafe trait and there is no documented way to safely implement it, this technically wouldn't be a breaking change. This would probably warrant updating the documentation for CType
, but I think it's fairly intuitive that all C types should be zero-initializable.
Costs: the runtime cost of zero-initialization.
Edit: it appears to be impossible to fix this in a non-breaking way from the Rust side, since we don't actually control how the code pointer is used except when we do dynamic calling. Unfortunately, any change would have to be breaking.
Change the definition of Callbackn
so that it takes result: &mut MaybeUninit<R>
. Mark from_parts
as unsafe.
Costs: breaks all code which relies on the definition of Callbackn
or from_parts
. Requires use of unsafe
to call from_parts
(but not to actually write the callbacks - the MaybeUninit
API has enough safe functions that this is unnecessary).
Compiling libffi-sys v1.1.0
Running `<MY_RUST_PROJECT_PATH>\target\release\build\libffi-sys-bcfb47f615dc8bff\build-script-build`
error: failed to run custom build command for `libffi-sys v1.1.0`
Caused by:
process didn't exit successfully: `<MY_RUST_PROJECT_PATH>\target\release\build\libffi-sys-bcfb47f615dc8bff\build-script-build` (exit code:101)
--- stderr
thread 'main' panicked at 'Copying libffi into the build directory: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }', <...>\rust-lang\.cargo\registry\src\github.com-1285ae84e5963aae\libffi-sys-1.1.0\build\common.rs:8:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
This looks similar to this issue:
tov/libffi-sys-rs#16
Shell command:
$> cargo +nightly-i686-pc-windows-gnu build --release --verbose --all --jobs 1 --target i686-pc-windows-gnu
My setup:
$> cargo -Vv
cargo 1.51.0 (43b129a20 2021-03-16)
release: 1.51.0
commit-hash: 43b129a20fbf1ede0df411396ccf0c024bf34134
commit-date: 2021-03-16
$> rustc -Vv
rustc 1.51.0 (2fd73fabe 2021-03-23)
binary: rustc
commit-hash: 2fd73fabe469357a12c2c974c140f67e7cdd76d0
commit-date: 2021-03-23
host: x86_64-pc-windows-gnu
release: 1.51.0
LLVM version: 11.0.1
GCC version:
gcc (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
i686-8.1.0-win32-dwarf-rt_v6-rev0
Once libffi-sys-rs 1.0.0 is released (tov/libffi-sys-rs#39), we can start working towards version 1.0.0 of the libffi crate. For this release it would be nice to also include ARMv7 support as added in #14, though that PR may need to be rebased after updating libffi-rs for libffi-sys-rs 1.0.0
master
to use this new versionThis can be seen in the tests from #23, but it's been around for a while (e.g. I saw it with other PRs/comits).
I don't know anything about PowerPC, nor do I have access to PowerPC hardware. The error provided is also completely useless. Either way, we should either find a way to fix these tests or somehow allow them to fail.
The code below triggers reading freed memory:
use libffi::middle::Type;
fn main() {
let inner_struct = Type::structure(vec!(Type::c_int()));
println!("Inner struct: {:?}", inner_struct);
let outer = Type::structure(vec!(inner_struct, Type::c_int()));
let mut offsets = Vec::new();
offsets.resize_with(2, Default::default);
unsafe {
libffi::raw::ffi_get_struct_offsets(
libffi::low::ffi_abi_FFI_DEFAULT_ABI,
outer.as_raw_ptr(),
offsets.as_mut_ptr())
};
println!("Offsets: {:?}", offsets);
}
The output is:
Offsets: [0, 94089412172272]
When running the program through valgrind --tool=memcheck
I get the output:
Inner struct: Type(0x4a6ab00)
==4739== Invalid read of size 8
==4739== at 0x118215: ffi_get_struct_offsets (in /home/jesho/tmp/fffi/target/debug/fffi)
==4739== by 0x110B6E: fffi::main (src/main.rs:16)
[...]
==4739== Address 0x4a6ab00 is 0 bytes inside a block of size 24 free'd
==4739== at 0x48399AB: free (vg_replace_malloc.c:538)
==4739== by 0x114371: libffi::middle::types::ffi_type_destroy (libffi-rs/libffi-rs/src/middle/types.rs:169)
==4739== by 0x114980: <libffi::middle::types::Type as core::ops::drop::Drop>::drop (libffi-rs/libffi-rs/src/middle/types.rs:175)
==4739== by 0x11465E: core::ptr::drop_in_place<libffi::middle::types::Type> (mod.rs:179)
==4739== by 0x113FAC: libffi::middle::types::ffi_type_array_create (libffi-rs/libffi-rs/src/middle/types.rs:106)
==4739== by 0x1113D1: libffi::middle::types::ffi_type_struct_create (types.rs:130)
==4739== by 0x111437: libffi::middle::types::Type::structure (types.rs:408)
==4739== by 0x110AF6: fffi::main (src/main.rs:10)
inner_struct is dropped in libffi::middle::types::ffi_type_array_create can be accessed through outer.
If I change the loop in ffi_type_array_create to:
for (i, element) in elements.enumerate() {
*new.add(i) = *element.0;
std::mem::forget(element); // Forget element
}
I get the correct output ("Offsets: [0, 4]"). Not sure if this introduces leaks, but Valgrind doesn't complain.
The soundness fixes of #27 are great, but now I don't see an obvious means of passing the FnPtrX
struct across a C API as an extern "C" fn
pointer directly as before. The func
member is private so what would the correct means of getting that pointer be?
These are the soundness issues I'm aware of in the high
interface:
Send
and Sync
)ClosureMutN
can be called by shared reference)There may be more that I'm not aware of, though the pattern seems to be that the high
interface erases too much information to be able to effectively lean on the compiler checking things for us.
I'd like to work on fixing these, though I'm having trouble forming a solid idea of how to fix the auto trait problem.
Attempting to build libffi-rs using clang-16 or later as the C compiler fails with:
../src/tramp.c:262:22: error: call to undeclared function 'open_temp_exec_file'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
tramp_globals.fd = open_temp_exec_file ();
^
1 error generated.
(This is the same problem pointed out here #69 (comment), pulled out into a new issue since it is really unrelated to that pull request.)
The C source code is in fact invalid, C99 and later do not support implicit function declarations. However, most compilers up to now have treated this as simply a warning (and you do indeed see that warning when building libffi-rs with older clang versions or GCC), but as of clang-16, this is now treated as hard error by default. (See https://reviews.llvm.org/D122983 for the upstream discussion.)
That invalid source code was introduced into the libffi sources here libffi/libffi@fc6b939, which made its way into the 3.4.4 release. The bug was subsequently fixed via libffi/libffi#760 and libffi/libffi#764, which landed upstream but is not yet part of any official release.
This is unfortunate as clang-16 starts to become more frequently used, as this will mean the current libffi-rs release will not build out of the box when that compiler is used as default. In particular, this showed up as failure preventing moving rust's miri tool to the latest libffi-rs release (see rust-lang/rust#109771), as some of the rust regression test builders already use clang-16.
I've been investigating options to fix this problem and make libffi-rs buildable again. These all boil down to one of two approaches: fix the actual problem in the C sources, or else downgrade the error back to a warning as it used to be:
-Wno-implicit-function-declaration
or -Wno-error=implicit-function-declaration
to the CFLAGS
when building the C portions of libffi, which could be done automatically e.g. by updating the libffi-sys-rs/build/not_msvc.rs
script. However, there might be some issue with compilers that do not recognize this flag (GCC and clang do, but I'm not sure if there are any other compilers that could possibly be used to build libffi-rs).My preference would be option 2, but the decision is of course up to you. I'd be happy to help implement any of those if needed.
Hi, thanks for this great crate.
I'm not sure how to store the intermediate types in a struct, could an example of this be added?
I'll give some context.
This works:
let user_f = |s: &str| {
println!("User got: {}", s);
};
let inner_f = |c_str| {
let c_str = unsafe { CStr::from_ptr(c_str) };
let str_slice = c_str.to_str().unwrap();
user_f(str_slice);
};
let libffi_f = Closure1::new(&inner_f);
let fun = libffi_f.code_ptr();
MyStruct::new_with_callbacks(fun).unwrap();
However, I would like this user API to only need to specify the first closure. So something like:
let user_f = |s: &str| {
println!("User got: {}", s);
};
MyStruct::new_with_callbacks(user_f).unwrap();
This means I have to do the other work further down in the call-chain, and store all the functions somewhere.
My assumptions:
user_f
is dropped, the inner_f
closure won't work since it uses that closureinner_f
is dropped, libffi_f
's reference is invalidlibffi_f
is dropped, any use of code_ptr()
is invalidPlease correct me if I am wrong on any of those.
So my attempt is to create something like:
struct MyStruct {
user_f: Box<dyn Fn(String)>,
inner_f: Box<dyn Fn(*const i8)>,
libffi_f: Closure1<*const i8, ()>,
}
But I am getting errors with needing named lifetime parameters on the pointers, and this struct references stuff in itself so I'm in a lot of trouble.
Could you help me out?
I will gladly contribute a PR with a test that shows the correct use if you teach me.
So others can benefit as well.
Because libffi is included as a git submodule, autotools are unnecessarily required to build. This is not the intended release strategy for autoconf - the configure script is meant to be generated as part of the release.
Would you accept a PR to include the libffi source code (not as a git submodule) plus the generated configure script to reduce the build dependencies?
The code_ptr
method on the ClosureN
structs in the high
interface is unsound, as fn(...) -> R
pointers are Copy
, so you can copy the returned function pointer out from behind the reference with the appropriate lifetime and "safely" call them after the backing closure has been dropped.
Could you release an new version that includes LoongArch support please?
Thanks
Just a quick note for ubuntu 14.04. I had to install texinfo to get cargo to compile libffi-sys. I didn't see that in the .travis.yaml so I was a little confused how you got it working.
I run into errors when trying to build/use the library in a nightly project inside an docker container (visual studio code dev container).
Cargo tells me the following when trying to build.
error: failed to run custom build command for `libffi-sys v2.1.0`
note: To improve backtraces for build dependencies, set the CARGO_PROFILE_DEV_BUILD_OVERRIDE_DEBUG=true environment variable to enable debug information generation.
Caused by:
process didn't exit successfully: `/workspaces/serverless/target/debug/build/libffi-sys-5ecfe1cce31411db/build-script-build` (exit status: 101)
--- stdout
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
continue configure in default builddir "./x86_64-unknown-linux-gnu"
....exec /bin/bash ../configure "--srcdir=.." "--enable-builddir=x86_64-unknown-linux-gnu" "linux
gnu"
--- stderr
../configure: line 2251: config.log: No such file or directory
../configure: line 2261: config.log: No such file or directory
cat: standard output: No such file or directory
thread 'main' panicked at 'Configuring libffi', /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/libffi-sys-2.1.0/build/common.rs:8:5
stack backtrace:
0: rust_begin_unwind
at /rustc/2036fdd24f77d607dcfaa24c48fbe85d3f785823/library/std/src/panicking.rs:577:5
1: core::panicking::panic_fmt
at /rustc/2036fdd24f77d607dcfaa24c48fbe85d3f785823/library/core/src/panicking.rs:67:14
2: core::panicking::panic_display
3: build_script_build::common::run_command
4: build_script_build::not_msvc::configure_libffi
5: build_script_build::not_msvc::build_and_link
6: build_script_build::main
7: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Versions:
rustc 1.70.0-nightly (2036fdd24 2023-03-27)
cargo 1.70.0-nightly (145219a9f 2023-03-27)
Environment:
Container Image: mcr.microsoft.com/devcontainers/rust:0-1-bullseye
(Guess it is debian because of the bullseye)
If any other information is needed, please tell me. It builds finde on my linux machine (arch) and on windows direct, only inside the container it does not build.
Ubuntu 17.10
$ rustc --version
rustc 1.25.0-nightly (f62f77403 2018-01-10)
--- stderr
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:31: installing './compile'
configure.ac:8: installing './config.guess'
configure.ac:8: installing './config.sub'
configure.ac:19: installing './install-sh'
configure.ac:19: installing './missing'
Makefile.am: installing './depcomp'
Makefile.am:56: installing './mdate-sh'
autoreconf: Leaving directory `.'
../src/closures.c: In function ‘dlmmap_locked’:
../src/closures.c:488:7: warning: ignoring return value of ‘ftruncate’, declared with attribute warn_unused_result [-Wunused-result]
ftruncate (execfd, offset);
^~~~~~~~~~~~~~~~~~~~~~~~~~
../src/closures.c:500:7: warning: ignoring return value of ‘ftruncate’, declared with attribute warn_unused_result [-Wunused-result]
ftruncate (execfd, offset);
^~~~~~~~~~~~~~~~~~~~~~~~~~
ar: `u' modifier ignored since `D' is the default (see `U')
ar: `u' modifier ignored since `D' is the default (see `U')
/home/ehiggs/src/home/ripawk/target/release/build/libffi-sys-075697e5eb3875eb/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:75:10: fatal error: 'stddef.h' file not found
/home/ehiggs/src/home/ripawk/target/release/build/libffi-sys-075697e5eb3875eb/out/libffi-root/lib/libffi-3.2.1/include/ffi.h:75:10: fatal error: 'stddef.h' file not found, err: true
thread 'main' panicked at '
**********
Bindgen generation failed. Please file a bug report.
**********
: ()', libcore/result.rs:916:5
If I make the following test file, I can build it using gcc ((Ubuntu 7.2.0-8ubuntu3) 7.2.0):
$ cat test.c
#include <stddef.h>
int main () {}
$ gcc test.c
$
I have libffi-dev
installed so it would be nice if pkg-config
and just used that version:
$ pkg-config --libs --cflags libffi
-lffi
A small issue with this crate is that it doesn't support any calling conventions other than the system's default ABI, even though libffi supports many different calling conventions. Unfortunately, I have a Windows API that uses the "stdcall"
calling convention. This is more-or-less OK because most of my users are on x86-64 where "stdcall" is equivalent to "C" on x86-64, but it is different on 32-bit x86.
Supporting 32-bit Windows isn't that important to me, so this isn't a big priority, but I'd like to at least register that it's a small issue.
Hi,
I've recently needed to use the libffi
crate to allow an interpreter to make native calls to external functions whose signatures are not known until runtime.
The examples in the repo demonstrate using statically-known signatures (and thus static arrays of arguments). The examples are of limited utility, because if you knew the signatures you wanted to call ahead of time, you'd just call an extern
-declared symbol directly without libffi. As far as I know, libffi is intended for scenarios where the type signatures are dynamic.
Once you start dealing with calls with dynamic types, it becomes unclear how to best safely use the crate. For example, my first attempt looked a bit like:
use libffi::middle::*;
use std::ffi::c_void;
// Pretend that this function is from an external dynamic C library.
fn f(a: u64, b: u64, c:u64) {
println!("a={}, b={}, c={}", a, b, c);
}
fn call_ext(addr: *mut c_void, num_args: usize) {
let mut args = Vec::new();
let mut builder = Builder::new();
for i in 0..num_args {
args.push(arg(&i)); // Bad!
builder = builder.arg(Type::u64());
}
builder = builder.res(Type::void());
let cif = builder.into_cif();
unsafe {cif.call::<()>(CodePtr(addr), &args)};
}
fn main() {
call_ext(&f as *const _ as *mut c_void, 3);
}
This program is UB because arg()
calls Arg::new()
, which looks like:
pub fn new<T>(r: &T) -> Self {
Arg(r as *const T as *mut c_void)
}
So it stashes a raw pointer to its argument, but in the case of my example above:
&i
on each iteration of the loop, so we'd unintentionally be doing the call with 3 identical arguments.i
dies once the loop finishes, so the Arg
stores a dangling pointer. Using the resulting pointers invokes UB.(Another gotcha here, is that we've inadvertently made a vector of usize
args, since we didn't add explicit type annotations. But that's another story)
My next attempt was to do something like:
use libffi::middle::*;
use std::ffi::c_void;
// Pretend that this function is from an external dynamic C library.
fn f(a: u64, b: u64, c:u64) {
println!("a={}, b={}, c={}", a, b, c);
}
fn call_ext(addr: *mut c_void, num_args: usize) {
let mut builder = Builder::new();
let mut args: Vec<u64> = Vec::new(); // <-----------------
for i in 0..num_args {
args.push(u64::try_from(i).unwrap());
builder = builder.arg(Type::u64());
}
let cif = builder.into_cif();
let ffi_args = args.iter().map(|a| arg(a)).collect::<Vec<Arg>>(); // <-----------------
unsafe {cif.call::<()>(CodePtr(addr), &ffi_args)};
}
fn main() {
call_ext(&f as *const _ as *mut c_void, 3);
println!("Hello, world!");
}
This solves the above problems by:
But I'm still not certain that this is correct. The example assumes that the backing storage of the vector holding the arguments is not moved: a guarantee I don't think we have(?).
My next attempt would be to take a slice from the argument vector. By taking a slice, Rust cannot move the vector's backing storage (if it wanted to, the program would (hopefully?) not compile). But having shown this to colleagues, they have concerns about pointer aliasing rules.
So my question is: what is the correct and safe way to use libffi::middle
to create dynamically-typed calls to external functions?
The only solution I can see is to manually manage an unmovable chunk of memory with malloc()
(or using a something like the alloc
crate). There has to be a better way.
(FWIW, all of the programs I've shown so far seg-fault, although when I used the approach from the latter example in my interpreter, it did work, but perhaps by chance).
(Side question: You can't use libffi::high
to do dynamic calls, can you? You'd need to ability to dynamically create a Rust type signature as far as i can see, and if you could do that, you wouldn't need libffi)
Thanks!
Hi, I'm not sure if this is an issue with libffi-rs/libffi-sys-rs or with docs.rs, but the current page for libffi-rs 0.7.0 on docs.rs says it failed to build. You can see the build output here, although the interesting bits in the output have \n
escaped, so I attempted to fix the output:
make[2]: Entering directory \'/home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/x86_64-unknown-linux-gnu\'
restore=: && backupdir=\".am$$\" && \\
am__cwd=`pwd` && CDPATH=\"${ZSH_VERSION+.}:\" && cd .. && \\
rm -rf $backupdir && mkdir $backupdir && \\
if (/bin/bash /home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/missing makeinfo --version) >/dev/null 2>&1; then \\
for f in ../doc/libffi.info ../doc/libffi.info-[0-9] ../doc/libffi.info-[0-9][0-9] ../doc/libffi.i[0-9] ../doc/libffi.i[0-9][0-9]; do \\
if test -f $f; then mv $f $backupdir; restore=mv; else :; fi; \\
done; \\
else :; fi && \\
cd \"$am__cwd\"; \\
if /bin/bash /home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/missing makeinfo -I doc -I ../doc \\
-o ../doc/libffi.info ../doc/libffi.texi; \\
then \\
rc=0; \\
CDPATH=\"${ZSH_VERSION+.}:\" && cd ..; \\
else \\
rc=$?; \\
CDPATH=\"${ZSH_VERSION+.}:\" && cd .. && \\
$restore $backupdir/* `echo \"./../doc/libffi.info\" | sed \'s|[^/]*$||\'`; \\
fi; \\
rm -rf $backupdir; exit $rc
Makefile:1419: recipe for target \'../doc/libffi.info\' failed
make[2]: Leaving directory \'/home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/x86_64-unknown-linux-gnu\'
Makefile:1604: recipe for target \'install-recursive\' failed
make[1]: Leaving directory \'/home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/x86_64-unknown-linux-gnu\'
Makefile:3153: recipe for target \'install\' failed
--- stderr
autoreconf: Entering directory `.\'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:31: installing \'./compile\'
configure.ac:8: installing \'./config.guess\'
configure.ac:8: installing \'./config.sub\'
configure.ac:19: installing \'./install-sh\'
configure.ac:19: installing \'./missing\'
Makefile.am: installing \'./depcomp\'
Makefile.am:56: installing \'./mdate-sh\'
autoreconf: Leaving directory `.\'
/home/cratesfyi/cratesfyi/debug/build/libffi-sys-7b10269bbdd70d1a/out/libffi-build/missing: line 81: makeinfo: command not found
WARNING: \'makeinfo\' is missing on your system.
You should only need it if you modified a \'.texi\' file, or
any other file indirectly affecting the aspect of the manual.
You might want to install the Texinfo package:
<http://www.gnu.org/software/texinfo/>
The spurious makeinfo call might also be the consequence of
using a buggy \'make\' (AIX, DU, IRIX), in which case you might
want to install GNU make:
<http://www.gnu.org/software/make/>
make[2]: *** [../doc/libffi.info] Error 127
make[1]: *** [install-recursive] Error 1
make: *** [install] Error 2
thread \'main\' panicked at \'Building libffi\', /home/cratesfyi/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-0.7.0/build.rs:41:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Unfortunately I don't have much experience with building C projects/libffi, or using make/texinfo, so I can't help figure out what's going on here. The docs for libffi-rs 0.6.4 appear to have compiled correctly, and the changelog entry for 0.7.0 doesn't mention any big API changes, so in the mean time people can just use the docs from 0.6.4.
Rust uses riscv64gc-unknown-linux-gnu
while ./configure
uses riscv64-unknown-linux-gnu
. One solution is the patch below. Is there a better way to handle this?
diff --git a/libffi-sys-rs/build/not_msvc.rs b/libffi-sys-rs/build/not_msvc.rs
index e41e076..634b710 100644
--- a/libffi-sys-rs/build/not_msvc.rs
+++ b/libffi-sys-rs/build/not_msvc.rs
@@ -53,7 +53,11 @@ pub fn configure_libffi(prefix: PathBuf, build_dir: &Path) {
let target = std::env::var("TARGET").unwrap();
if target != std::env::var("HOST").unwrap() {
- command.arg(format!("--host={}", target.to_string()));
+ if target == "riscv64gc-unknown-linux-gnu" {
+ command.arg("--host=riscv64-unknown-linux-gnu");
+ } else {
+ command.arg(format!("--host={}", target));
+ }
}
command.current_dir(&build_dir);
libffi::middle::Cif::new()
with one of the parameters containing a structure type argument.cif
into a struct that derives Clone
.cloned_struct.cif.as_raw_ptr()
observe the structure type argument's libffi::low::ffi_type
data.The cif
in the copied struct should contain expected size, alignment and elements for .
The cif
in the copy has zero's as its size and alignment.
The libffi implementation has a special historical quirk about promoting return types. This is documented here:
http://www.chiark.greenend.org.uk/doc/libffi-dev/html/The-Basics.html
In most situations, ‘libffi’ will handle promotion according to the ABI. However, for historical reasons, there is a special case with return values that must be handled by your code. In particular, for integral (not struct) types that are narrower than the system register size, the return value will be widened by ‘libffi’. ‘libffi’ provides a type, ffi_arg, that can be used as the return type. For example, if the CIF was defined with a return type of char, ‘libffi’ will try to store a full ffi_arg into the return value.
The current libffi-rs code base does not appear to accommodate that behavior at all anywhere. For example:
pub unsafe fn call<R>(cif: *mut ffi_cif, fun: CodePtr, args: *mut *mut c_void) -> R {
let mut result = mem::MaybeUninit::<R>::uninit();
raw::ffi_call(
cif,
Some(*fun.as_safe_fun()),
result.as_mut_ptr() as *mut c_void,
args,
);
result.assume_init()
}
When called with a small integer type for R
, like i8
or i16
, this will allocate only a small buffer as result
and pass its address to the C implementation - but that implementation will actually write a full ffi_arg
into it.
Now, on little-endian platforms, this mostly works transparently - but it is strictly speaking clobbering some memory on the Rust caller's stack. (Which probably has no practical effect due to stack slot alignment rules - but who knows what might happen if this is inlined into a more complicated caller in a LTO compilation ...)
However, on a big-endian platform, the return value will simply always be wrong. This is the problem I'm currently seeing as I'm working on enabling libffi-rs for the s390x architecture.
Note that in addition to ffi_call
, the same promotion rule also applies with closures - when a closure callback writes to its return value pointer, it is likewise expected to write a full ffi_arg
if the return type is a small integer.
I'd be happy to work on a fix, but it seems challenging to fix this across all the low/med/high layers without changing the external API, specifically for the closures. Any suggestions would be appreciated!
I'm trying to build libffi-sys
on OpenBSD current amd64, but get error:
$ RUST_BACKTRACE=full AUTOCONF_VERSION=2.69 AUTOMAKE_VERSION=1.16 cargo build
Compiling libffi-sys v1.1.2 (/home/bukhalo/tmp/libffi-rs/libffi-sys-rs)
error: failed to run custom build command for `libffi-sys v1.1.2 (/home/bukhalo/tmp/libffi-rs/libffi-sys-rs)`
Caused by:
process didn't exit successfully: `/home/bukhalo/tmp/libffi-rs/target/debug/build/libffi-sys-66b9400313667f38/build-script-build` (exit status: 101)
--- stdout
checking build system type... x86_64-unknown-openbsd7.0
checking host system type... x86_64-unknown-openbsd7.0
checking target system type... x86_64-unknown-openbsd7.0
continue configure in default builddir "./x86_64-unknown-openbsd"
....exec /bin/sh ../configure "--srcdir=.." "--enable-builddir=x86_64-unknown-openbsd" "openbsd7.0"
checking build system type... x86_64-unknown-openbsd7.0
checking host system type... x86_64-unknown-openbsd7.0
checking target system type... x86_64-unknown-openbsd7.0
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ../install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... gcc3
checking dependency style of gcc... gcc3
checking how to print strings... print -r
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 393216
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... no
checking how to convert x86_64-unknown-openbsd7.0 file names to x86_64-unknown-openbsd7.0 format... func_convert_file_noop
checking how to convert x86_64-unknown-openbsd7.0 file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$
checking for dlltool... no
checking how to associate runtime and link libraries... print -r --
checking for ar... ar
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for mt... mt
checking if mt is a manifest tool... no
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld) supports shared libraries... yes
checking whether -lc should be explicitly linked in... yes
checking dynamic linker characteristics... openbsd7.0 ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking how to run the C++ preprocessor... g++ -E
checking for ld used by g++... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking whether the g++ linker (/usr/bin/ld) supports shared libraries... yes
checking for g++ option to produce PIC... -fPIC -DPIC
checking if g++ PIC flag -fPIC -DPIC works... yes
checking if g++ static flag -static works... yes
checking if g++ supports -c -o file.o... yes
checking if g++ supports -c -o file.o... (cached) yes
checking whether the g++ linker (/usr/bin/ld) supports shared libraries... yes
checking dynamic linker characteristics... openbsd7.0 ld.so
checking how to hardcode library paths into programs... immediate
checking size of size_t... 8
checking for C compiler vendor... gnu
checking whether C compiler accepts -fstrict-aliasing... yes
checking whether C compiler accepts -ffast-math... yes
checking for gcc architecture flag...
checking for x86 cpuid 0 output... d:68747541:444d4163:69746e65
checking for x86 cpuid 1 output... 810f81:2040800:7ed8320b:178bfbff
checking whether C compiler accepts -march=amdfam10... yes
checking for gcc architecture flag... -march=amdfam10
checking whether C compiler accepts -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=amdfam10... yes
checking CFLAGS for maximum warnings... -Wall
checking whether to enable maintainer-specific portions of Makefiles... no
checking sys/mman.h usability... yes
checking sys/mman.h presence... yes
checking for sys/mman.h... yes
checking for mmap... yes
checking for mkostemp... yes
checking for sys/mman.h... (cached) yes
checking for mmap... (cached) yes
checking whether read-only mmap of a plain file works... yes
checking whether mmap from /dev/zero works... yes
checking for MAP_ANON(YMOUS)... yes
checking whether mmap with MAP_ANON(YMOUS) works... yes
checking for ANSI C header files... (cached) yes
checking for memcpy... yes
checking for size_t... yes
checking for working alloca.h... no
checking for alloca... yes
checking size of double... 8
checking size of long double... 16
checking whether byte ordering is bigendian... no
checking assembler .cfi pseudo-op support... yes
checking assembler supports pc related relocs... yes
checking for _ prefix in compiled symbols... no
checking toolchain supports unwind section type... yes
checking whether .eh_frame section should be read-only... yes
checking for __attribute__((visibility("hidden")))... yes
checking for ld used by gcc... (cached) /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... (cached) no
configure: versioning on shared library symbols is no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating include/Makefile
config.status: creating include/ffi.h
config.status: creating Makefile
config.status: creating testsuite/Makefile
config.status: creating man/Makefile
config.status: creating doc/Makefile
config.status: creating libffi.pc
config.status: creating fficonfig.h
config.status: executing buildir commands
config.status: create top_srcdir/Makefile guessed from local Makefile
config.status: build in x86_64-unknown-openbsd (HOST=x86_64-unknown-openbsd)
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing include commands
config.status: executing src commands
--- stderr
autoreconf-2.69: Entering directory `.'
autoreconf-2.69: configure.ac: not using Gettext
autoreconf-2.69: running: aclocal -I m4
autoreconf-2.69: configure.ac: tracing
autoreconf-2.69: running: libtoolize --copy
autoreconf-2.69: running: /usr/local/bin/autoconf-2.69
autoreconf-2.69: running: /usr/local/bin/autoheader-2.69
autoreconf-2.69: running: automake --add-missing --copy --no-force
autoreconf-2.69: Leaving directory `.'
thread 'main' panicked at 'Building libffi: Os { code: 2, kind: NotFound, message: "No such file or directory" }', libffi-sys-rs/build/common.rs:8:26
stack backtrace:
0: 0xe5d678546bd - <unknown>
1: 0xe5d6787d53c - <unknown>
2: 0xe5d67841ef3 - <unknown>
3: 0xe5d6784f23b - <unknown>
4: 0xe5d6784edc8 - <unknown>
5: 0xe5d6784f926 - <unknown>
6: 0xe5d67854bdc - <unknown>
7: 0xe5d67854820 - <unknown>
8: 0xe5d6784f3f6 - <unknown>
9: 0xe5d6787f550 - <unknown>
10: 0xe5d6787c176 - <unknown>
11: 0xe5d6783c305 - <unknown>
12: 0xe5d6783a1f5 - <unknown>
13: 0xe5d6783cf4f - <unknown>
14: 0xe5d67840a99 - <unknown>
15: 0xe5d6783e75e - <unknown>
16: 0xe5d67840b81 - <unknown>
17: 0xe5d67840534 - <unknown>
18: 0xe5d67866366 - <unknown>
19: 0xe5d67840512 - <unknown>
20: 0xe5d67840acb - <unknown>
21: 0xe5d67839198 - <unknown>
Unfortunately, I don't write in Rust, so I can't fix the error. Maybe someone can help me?
If there is a need, I can help with debugging on my computer
I'm trying to pass a rust closure to a C library as a callback using the high
interface and the code_ptr
function. The callback is passed a C struct as the only argument. I'm running into issues using the high
API as the rust type that bindgen
generates that maps to this argument doesn't implement the required CType
trait.
This struct is declared repr(C)
so I imagine this all should be possible, but I'm not sure if I'm missing something or if this is something that would have to be added to libffi-rs
. Maybe I'm misunderstanding things here and this just isn't possible.
I have tried digging into the libffi-rs
code to try to implement this trait but all the required functionality doesn't seem to be exported.
I'm trying to build deno in WSL which depends on this create. I'm running into the following error when configuring libffi:
Caused by:
process didn't exit successfully: `/home/marvinh/dev/deno/target/debug/build/libffi-sys-31e669a8307ea709/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-env-changed=CC_x86_64-unknown-linux-gnu
CC_x86_64-unknown-linux-gnu = None
cargo:rerun-if-env-changed=CC_x86_64_unknown_linux_gnu
CC_x86_64_unknown_linux_gnu = None
cargo:rerun-if-env-changed=HOST_CC
HOST_CC = None
cargo:rerun-if-env-changed=CC
CC = None
cargo:rerun-if-env-changed=CFLAGS_x86_64-unknown-linux-gnu
CFLAGS_x86_64-unknown-linux-gnu = None
cargo:rerun-if-env-changed=CFLAGS_x86_64_unknown_linux_gnu
CFLAGS_x86_64_unknown_linux_gnu = None
cargo:rerun-if-env-changed=HOST_CFLAGS
HOST_CFLAGS = None
cargo:rerun-if-env-changed=CFLAGS
CFLAGS = None
cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
CRATE_CC_NO_DEFAULTS = None
CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
continue configure in default builddir "./x86_64-unknown-linux-gnu"
....exec /bin/bash .././configure "--srcdir=.." "--enable-builddir=x86_64-unknown-linux-gnu" "linux
gnu"
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for gsed... sed
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... no
checking whether make supports nested variables... no
checking for gcc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether cc accepts -g... yes
checking for cc option to enable C11 features... none needed
checking whether cc understands -c and -o together... yes
checking whether make supports the include directive... no
checking dependency style of cc... none
checking for g++... no
checking for c++... c++
checking whether the compiler supports GNU C++... yes
checking whether c++ accepts -g... yes
checking for c++ option to enable C++11 features... none needed
checking dependency style of c++... none
checking dependency style of cc... none
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for fgrep... /usr/bin/grep -F
checking for ld used by cc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for file... file
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from cc object... ok
checking for sysroot... no
checking for a working dd... /usr/bin/dd
checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking for stdio.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for strings.h... yes
checking for sys/stat.h... yes
checking for sys/types.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if cc supports -fno-rtti -fno-exceptions... no
checking for cc option to produce PIC... -fPIC -DPIC
checking if cc PIC flag -fPIC -DPIC works... yes
checking if cc static flag -static works... yes
checking if cc supports -c -o file.o... yes
checking if cc supports -c -o file.o... (cached) yes
checking whether the cc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... no
checking whether to build static libraries... yes
checking how to run the C++ preprocessor... c++ -E
checking for ld used by c++... /usr/bin/ld -m elf_x86_64
checking if the linker (/usr/bin/ld -m elf_x86_64) is GNU ld... yes
checking whether the c++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking for c++ option to produce PIC... -fPIC -DPIC
checking if c++ PIC flag -fPIC -DPIC works... yes
checking if c++ static flag -static works... yes
checking if c++ supports -c -o file.o... yes
checking if c++ supports -c -o file.o... (cached) yes
checking whether the c++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... (cached) GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking for readelf... readelf
checking size of size_t... 8
checking for C compiler vendor... gnu
checking CFLAGS for most reasonable warnings... -Wall
checking whether to enable maintainer-specific portions of Makefiles... no
checking for sys/memfd.h... no
checking for memfd_create... yes
checking for sys/mman.h... yes
checking for mmap... yes
checking for mkostemp... yes
checking for mkstemp... yes
checking for sys/mman.h... (cached) yes
checking for mmap... (cached) yes
checking whether read-only mmap of a plain file works... yes
checking whether mmap from /dev/zero works... yes
checking for MAP_ANON(YMOUS)... yes
checking whether mmap with MAP_ANON(YMOUS) works... yes
checking for egrep... (cached) /usr/bin/grep -E
checking for memcpy... yes
checking for size_t... yes
checking for working alloca.h... yes
checking for alloca... yes
checking size of double... 8
checking size of long double... 16
checking whether byte ordering is bigendian... no
checking assembler .cfi pseudo-op support... yes
checking assembler supports pc related relocs... yes
checking whether compiler supports pointer authentication... no
checking for _ prefix in compiled symbols... no
checking toolchain supports unwind section type... yes
checking whether C compiler accepts -fno-lto... yes
checking whether .eh_frame section should be read-only... yes
checking for __attribute__((visibility("hidden")))... yes
configure: versioning on shared library symbols is no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating include/Makefile
config.status: creating include/ffi.h
config.status: creating Makefile
config.status: creating testsuite/Makefile
config.status: creating man/Makefile
config.status: creating doc/Makefile
config.status: creating libffi.pc
config.status: creating fficonfig.h
config.status: executing buildir commands
config.status: create top_srcdir/Makefile guessed from local Makefile
config.status: build in x86_64-unknown-linux-gnu (HOST=x86_64-unknown-linux-gnu)
config.status: executing depfiles commands
--- stderr
config.status: error: in `/home/marvinh/dev/deno/target/debug/build/libffi-sys-89a8cf0f07f9140e/out/libffi-build/x86_64-unknown-linux-gnu':
config.status: error: Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE="gmake" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).
See `config.log' for more details
thread 'main' panicked at 'Configuring libffi', /home/marvinh/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-2.3.0/build/common.rs:8:5
stack backtrace:
0: rust_begin_unwind
at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/std/src/panicking.rs:575:5
1: core::panicking::panic_fmt
at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/panicking.rs:64:14
2: core::panicking::panic_display
at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/panicking.rs:147:5
3: build_script_build::common::run_command
at ./build/common.rs:8:5
4: build_script_build::not_msvc::configure_libffi
at ./build/not_msvc.rs:123:5
5: build_script_build::not_msvc::build_and_link
at ./build/not_msvc.rs:26:5
6: build_script_build::main
at ./build/build.rs:16:9
7: core::ops::function::FnOnce::call_once
at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
I'm not entirely sure if this is the appropriate repo to report the error. Happy to transfer this issue to another one if this one isn't correct.
Hey,
I am recently trying to compile my rust binary that uses libffi-rs it is dependencies against the target x86_64-unknown-linux-musl because I want to deploy it on a minimal VM.
However I noticed that the compilation fails exactly at the libffi-rs part and returns and error
fatal error: linux/limits.h: No such file or directory
51 | #include <linux/limits.h>
I tried adjusting the compiler from within the build.rs as well as setting the CC env variable to musl-gcc but no luck there either.
I would appreciate any help or hints on how to make this work if possible please.
On M1 Mac, running rust with target x86_64-pc-windows-gnu
process didn't exit successfully: `target/release/build/libffi-sys-7f2a7ab9ea025606/build-script-build` (exit status: 101)
--- stdout
checking build system type... aarch64-apple-darwin21.6.0
checking host system type...
--- stderr
Invalid configuration `x86_64-pc-windows-gnu': Kernel `windows' not known to work with OS `gnu'.
configure: error: /bin/sh ./config.sub x86_64-pc-windows-gnu failed
thread 'main' panicked at 'Configuring libffi', /.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-2.0.1/build/common.rs:8:5
Backtrace
stack backtrace:
0: rust_begin_unwind
at /rustc/95a3a7277b44bbd2dd3485703d9a05f64652b60e/library/std/src/panicking.rs:575:5
1: core::panicking::panic_fmt
at /rustc/95a3a7277b44bbd2dd3485703d9a05f64652b60e/library/core/src/panicking.rs:65:14
2: core::panicking::panic_display
3: build_script_build::common::run_command
4: build_script_build::not_msvc::configure_libffi
5: build_script_build::not_msvc::build_and_link
6: build_script_build::main
7: core::ops::function::FnOnce::call_once
On this page, the link to C libffi documentation looks expired.
I encounter some strange behavior under Windows while using clang that is bundled with Visual studio; the solution to the original issue was reported here. With Visual Studio 2022, official LLVM 15.0.7 and rust 1.69, I've managed to compile a project using libffi-rs
and libffi-sys-rs
. After updating the rust toolchain to 1.70, I get the error:
libffi/src/x86/win64_intel.S(2): fatal error C1083: Cannot open include file: 'fficonfig.h': No such file or directory
After trying various LLVM combos (none of them worked), I reverted to LLVM 15.0.7 and Rust 1.69, but it still fails with the same message with missing fficonfig.h
.
Has anyone had this kind of issue under Windows?
error: failed to run custom build command for `libffi-sys v2.3.0`
Caused by:
process didn't exit successfully: `/mnt/c/Users/Bennet/Git/scryer-prolog-1/target/debug/build/libffi-sys-5ebf69dc60871829/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-env-changed=CC_x86_64-unknown-linux-gnu
CC_x86_64-unknown-linux-gnu = None
cargo:rerun-if-env-changed=CC_x86_64_unknown_linux_gnu
CC_x86_64_unknown_linux_gnu = None
cargo:rerun-if-env-changed=HOST_CC
HOST_CC = None
cargo:rerun-if-env-changed=CC
CC = None
cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
CRATE_CC_NO_DEFAULTS = None
CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
cargo:rerun-if-env-changed=CFLAGS_x86_64-unknown-linux-gnu
CFLAGS_x86_64-unknown-linux-gnu = None
cargo:rerun-if-env-changed=CFLAGS_x86_64_unknown_linux_gnu
CFLAGS_x86_64_unknown_linux_gnu = None
cargo:rerun-if-env-changed=HOST_CFLAGS
HOST_CFLAGS = None
cargo:rerun-if-env-changed=CFLAGS
CFLAGS = None
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
continue configure in default builddir "./x86_64-unknown-linux-gnu"
....exec /bin/bash .././configure "--srcdir=.." "--enable-builddir=x86_64-unknown-linux-gnu" "linux
gnu"
--- stderr
.././configure: line 2251: config.log: No such file or directory
.././configure: line 2261: config.log: No such file or directory
cat: standard output: No such file or directory
thread 'main' panicked at /home/bennet/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libffi-sys-2.3.0/build/common.rs:8:5:
Configuring libffi
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Appears to be the error from libffi/libffi#552 and is a similar but not identical error to #85
> lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy
Related to tov/libffi-sys-rs#8
Since you fixed the issue above, it would be great if you could bump this library, too.
Thank you! :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.