Skip to content

Commit 80dfcb8

Browse files
committed
[GR-64610] Add multitarget support for libffi
PullRequest: graal/20776
2 parents b49fa84 + 3f5a4fe commit 80dfcb8

File tree

8 files changed

+627
-50
lines changed

8 files changed

+627
-50
lines changed

substratevm/src/com.oracle.svm.truffle.nfi/src/com/oracle/svm/truffle/nfi/libffi/LibFFIHeaderDirectives.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import java.io.File;
2828
import java.util.Collections;
2929
import java.util.List;
30+
import java.util.function.Function;
3031

32+
import com.oracle.svm.core.OS;
33+
import com.oracle.svm.core.SubstrateOptions;
34+
import com.oracle.svm.core.SubstrateUtil;
3135
import org.graalvm.nativeimage.ImageSingletons;
3236
import org.graalvm.nativeimage.c.CContext;
3337

@@ -46,10 +50,32 @@ public List<String> getHeaderFiles() {
4650
return Collections.singletonList("<svm_libffi.h>");
4751
}
4852

53+
private static String basePath() {
54+
/* Find location of library directory based on known header name */
55+
String libffiHeader = ProjectHeaderFile.resolve("com.oracle.svm.libffi", "include/svm_libffi.h");
56+
File libffiHeaderPath = new File(libffiHeader.substring(1));
57+
58+
return libffiHeaderPath.getParentFile().getParent();
59+
}
60+
61+
private static String multitargetSuffix() {
62+
String os = OS.getCurrent().asPackageName();
63+
String arch = SubstrateUtil.getArchitectureName();
64+
String libc = OS.LINUX.isCurrent() ? SubstrateOptions.UseLibC.getValue() : "default";
65+
66+
return os + "-" + arch + File.separator + libc;
67+
}
68+
4969
@Override
5070
public List<String> getOptions() {
51-
String libffiHeader = ProjectHeaderFile.resolve("com.oracle.svm.libffi", "include/svm_libffi.h");
52-
String libffiPath = new File(libffiHeader.substring(1)).getParent();
53-
return Collections.singletonList("-I" + libffiPath);
71+
/* Add base and target specific include directories */
72+
Function<String, String> bp = multitarget -> "-I" + basePath() + File.separator + multitarget + "include";
73+
return List.of(bp.apply(""), bp.apply(multitargetSuffix() + File.separator));
74+
}
75+
76+
@Override
77+
public List<String> getLibraryPaths() {
78+
/* Add multitarget style path */
79+
return List.of(basePath() + File.separator + multitargetSuffix());
5480
}
5581
}

truffle/mx.truffle/mx_truffle.py

Lines changed: 163 additions & 33 deletions
Large diffs are not rendered by default.

truffle/mx.truffle/suite.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,9 @@
999999

10001000
"libffi" : {
10011001
"class" : "LibffiBuilderProject",
1002+
"multitarget": {
1003+
"libc": ["glibc", "musl", "default"],
1004+
},
10021005
"dependencies" : [
10031006
"LIBFFI_SOURCES",
10041007
],
@@ -1008,8 +1011,10 @@
10081011
"com.oracle.truffle.nfi.native" : {
10091012
"subDir" : "src",
10101013
"native" : "shared_lib",
1011-
"toolchain" : "sdk:LLVM_NINJA_TOOLCHAIN",
10121014
"deliverable" : "trufflenfi",
1015+
"multitarget": {
1016+
"libc": ["glibc", "musl", "default"],
1017+
},
10131018
"use_jdk_headers" : True,
10141019
"buildDependencies" : [
10151020
"libffi",
@@ -1034,12 +1039,6 @@
10341039
"ldlibs" : ["-ldl"],
10351040
},
10361041
},
1037-
"linux-musl" : {
1038-
"<others>" : {
1039-
"cflags" : ["-g", "-O3", "-Wall", "-Werror", "-fvisibility=hidden"],
1040-
"ldlibs" : ["-ldl"],
1041-
},
1042-
},
10431042
"<others>" : {
10441043
"<others>" : {
10451044
"cflags" : ["-g", "-O3", "-Wall", "-Werror", "-fvisibility=hidden"],
@@ -1920,7 +1919,7 @@
19201919
"darwin-aarch64",
19211920
],
19221921
"layout" : {
1923-
"bin/" : "dependency:com.oracle.truffle.nfi.native",
1922+
"bin/" : "dependency:com.oracle.truffle.nfi.native/*",
19241923
"include/" : "dependency:com.oracle.truffle.nfi.native/include/*.h",
19251924
},
19261925
"include_dirs" : ["include"],
@@ -1944,8 +1943,18 @@
19441943
"windows-amd64",
19451944
"windows-aarch64",
19461945
],
1947-
"layout" : {
1948-
"META-INF/resources/nfi-native/libnfi/<os>/<arch>/bin/" : "dependency:com.oracle.truffle.nfi.native",
1946+
"os": {
1947+
"linux": {
1948+
"layout": {
1949+
# only glibc.
1950+
"META-INF/resources/nfi-native/libnfi/<os>/<arch>/bin/" : "dependency:com.oracle.truffle.nfi.native/linux-*/glibc/*"
1951+
},
1952+
},
1953+
"<others>": {
1954+
"layout": {
1955+
"META-INF/resources/nfi-native/libnfi/<os>/<arch>/bin/" : "dependency:com.oracle.truffle.nfi.native/*/*/*",
1956+
},
1957+
},
19491958
},
19501959
"description" : "Contains the native library needed by the libffi NFI backend.",
19511960
"maven": False,
@@ -2291,8 +2300,18 @@
22912300
"native" : True,
22922301
"platformDependent" : True,
22932302
"description" : "Truffle NFI support distribution for the GraalVM",
2294-
"layout" : {
2295-
"./" : ["dependency:com.oracle.truffle.nfi.native"],
2303+
"os": {
2304+
"linux": {
2305+
"layout": {
2306+
# only glibc.
2307+
"./" : "dependency:com.oracle.truffle.nfi.native/linux-*/glibc/*"
2308+
},
2309+
},
2310+
"<others>": {
2311+
"layout": {
2312+
"./" : "dependency:com.oracle.truffle.nfi.native/*/*/*",
2313+
},
2314+
},
22962315
},
22972316
"maven" : False,
22982317
"graalCompilerSourceEdition": "ignore",

truffle/src/com.oracle.truffle.nfi.native/src/internal.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,28 @@
4141
#ifndef __TRUFFLE_INTERNAL_H
4242
#define __TRUFFLE_INTERNAL_H
4343

44-
#if defined(__linux__) && defined(_GNU_SOURCE)
44+
#if defined(__linux__)
45+
46+
#if !defined(_GNU_SOURCE)
47+
#error "expected to be set via CLFAGS. required for detection below"
48+
#endif
49+
50+
/* musl does not set __USE_GNU in features.h
51+
* source: https://stackoverflow.com/a/70211227
52+
*/
53+
#include <features.h>
54+
55+
#ifdef __USE_GNU
56+
/* glibc */
4557
#define ENABLE_ISOLATED_NAMESPACE
4658
#define ISOLATED_NAMESPACE 0x10000
4759
#include <dlfcn.h>
48-
#endif
60+
61+
#else // !__USE_GNU
62+
/* musl. dlmopen not available */
63+
#endif // !__USE_GNU
64+
65+
#endif // __linux__
4966

5067
#include "native.h"
5168
#include "trufflenfi.h"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
From 7c9a81783f63d37fb68131d6e0621e9476e7b11c Mon Sep 17 00:00:00 2001
2+
From: =?UTF-8?q?Aleksandar=20Pejovi=C4=87?= <[email protected]>
3+
Date: Tue, 15 Jan 2019 00:40:01 +0100
4+
Subject: [PATCH] Add mx bootstrap Makefile
5+
6+
---
7+
Makefile | 14 ++++++++++++++
8+
1 file changed, 14 insertions(+)
9+
create mode 100644 Makefile
10+
11+
diff --git a/Makefile b/Makefile
12+
new file mode 100644
13+
index 0000000..da887c1
14+
--- /dev/null
15+
+++ b/Makefile
16+
@@ -0,0 +1,14 @@
17+
+# This Makefile is used by mx to bootstrap libffi build.
18+
+
19+
+# `make MX_VERBOSE=y` will report all lines executed. The actual value doesn't
20+
+# matter as long as it's not empty.
21+
+QUIETLY$(MX_VERBOSE) = @
22+
+
23+
+.PHONY: default
24+
+
25+
+default:
26+
+ $(QUIETLY) echo CONFIGURE libffi
27+
+ $(QUIETLY) mkdir ../$(OUTPUT)
28+
+ $(QUIETLY) cd ../$(OUTPUT) && ../$(SOURCES)/configure $(CONFIGURE_ARGS) > ../libffi.configure.log
29+
+ $(QUIETLY) echo MAKE libffi
30+
+ $(QUIETLY) $(MAKE) -C ../$(OUTPUT) > ../libffi.build.log
31+
--
32+
2.38.4
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
From 3aa0ebdd2ee6b5634443d7464f1e37be5c20786e Mon Sep 17 00:00:00 2001
2+
From: Gilles Duboscq <[email protected]>
3+
Date: Wed, 23 Apr 2025 18:42:40 +0200
4+
Subject: [PATCH 1/3] If other methods fail, attempt to use mprotect in
5+
ffi_tramp_init_os
6+
7+
---
8+
src/tramp.c | 39 ++++++++++++++++++++++++++++-----------
9+
1 file changed, 28 insertions(+), 11 deletions(-)
10+
11+
diff --git a/src/tramp.c b/src/tramp.c
12+
index 8ec0848..7edaebc 100644
13+
--- a/src/tramp.c
14+
+++ b/src/tramp.c
15+
@@ -289,7 +289,10 @@ ffi_tramp_init_os (void)
16+
{
17+
if (ffi_tramp_get_libffi ())
18+
return 1;
19+
- return ffi_tramp_get_temp_file ();
20+
+ if (ffi_tramp_get_temp_file ())
21+
+ return 1;
22+
+ // try to allocate with the mprotect fall-back
23+
+ return tramp_table_alloc ();
24+
}
25+
26+
#endif /* defined (__linux__) || defined (__CYGWIN__) */
27+
@@ -347,18 +350,32 @@ tramp_table_map (struct tramp_table *table)
28+
if (addr == MAP_FAILED)
29+
return 0;
30+
31+
- /*
32+
- * Replace the top half of the anonymous mapping with the code table mapping.
33+
- */
34+
- table->code_table = mmap (addr, tramp_globals.map_size, PROT_READ | PROT_EXEC,
35+
- MAP_PRIVATE | MAP_FIXED, tramp_globals.fd, tramp_globals.offset);
36+
- if (table->code_table == MAP_FAILED)
37+
+ if (tramp_globals.fd != -1)
38+
{
39+
- (void) munmap (addr, tramp_globals.map_size * 2);
40+
- return 0;
41+
+ /*
42+
+ * Replace the top half of the anonymous mapping with the code table mapping.
43+
+ */
44+
+ table->code_table = mmap(addr, tramp_globals.map_size, PROT_READ | PROT_EXEC,
45+
+ MAP_PRIVATE | MAP_FIXED, tramp_globals.fd, tramp_globals.offset);
46+
+ if (table->code_table != MAP_FAILED) {
47+
+ table->parm_table = table->code_table + tramp_globals.map_size;
48+
+ return 1;
49+
+ }
50+
}
51+
- table->parm_table = table->code_table + tramp_globals.map_size;
52+
- return 1;
53+
+
54+
+ /*
55+
+ * Try to copy the trampolines and mprotect
56+
+ */
57+
+ memcpy(addr, tramp_globals.text, tramp_globals.map_size);
58+
+ if (mprotect(addr, tramp_globals.map_size, PROT_READ | PROT_EXEC) == 0)
59+
+ {
60+
+ table->code_table = addr;
61+
+ table->parm_table = table->code_table + tramp_globals.map_size;
62+
+ return 1;
63+
+ }
64+
+
65+
+ (void) munmap (addr, tramp_globals.map_size * 2);
66+
+ return 0;
67+
}
68+
69+
static void
70+
--
71+
2.43.0
72+

0 commit comments

Comments
 (0)