From c6f31c0560027fae2d1d09bb87efbe32e4692a99 Mon Sep 17 00:00:00 2001 From: Sacha Coppey Date: Thu, 9 Oct 2025 12:09:05 +0200 Subject: [PATCH 1/2] Fix check for duplicate method descriptor --- .../com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java index 537d3d09d690..f68dac7f77b2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/SVMImageLayerWriter.java @@ -597,7 +597,7 @@ private void persistMethod(AnalysisMethod method, Supplier Date: Thu, 9 Oct 2025 12:09:13 +0200 Subject: [PATCH 2/2] Make native methods layer aware --- .../pointsto/AbstractAnalysisEngine.java | 32 +++++ .../com/oracle/graal/pointsto/BigBang.java | 5 + .../com/oracle/graal/pointsto/api/HostVM.java | 5 + .../DarwinPhysicalMemorySupportImpl.java | 2 +- .../svm/core/posix/headers/PosixLibC.java | 18 --- .../headers/darwin/DarwinDirectives.java | 36 ++++++ .../posix/headers/{ => darwin}/Sysctl.java | 6 +- .../oracle/svm/hosted/ImageClassLoader.java | 4 + .../svm/hosted/NativeImageGenerator.java | 1 + .../src/com/oracle/svm/hosted/SVMHost.java | 111 ++++++++++++++++-- .../oracle/svm/hosted/c/NativeLibraries.java | 28 +++++ .../HostedImageLayerBuildingSupport.java | 12 ++ .../src/JvmFuncs.c | 10 ++ 13 files changed, 241 insertions(+), 29 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/DarwinDirectives.java rename substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/{ => darwin}/Sysctl.java (87%) diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AbstractAnalysisEngine.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AbstractAnalysisEngine.java index a74490a6dc44..ab0d62d04e3e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AbstractAnalysisEngine.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AbstractAnalysisEngine.java @@ -27,8 +27,10 @@ import java.io.PrintWriter; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.function.Function; +import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.hosted.Feature; import com.oracle.graal.pointsto.ClassInclusionPolicy.SharedLayerImageInclusionPolicy; @@ -47,6 +49,8 @@ import com.oracle.graal.pointsto.util.Timer; import com.oracle.graal.pointsto.util.TimerCollection; import com.oracle.svm.common.meta.MultiMethod; +import com.oracle.svm.core.annotate.TargetClass; +import com.oracle.svm.util.OriginalClassProvider; import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; import jdk.graal.compiler.debug.DebugContext; @@ -411,6 +415,34 @@ public void tryRegisterFieldForBaseImage(AnalysisField field) { } } + @Override + public void tryRegisterNativeMethodsForBaseImage(ResolvedJavaType type) { + /* + * Some modules contain native methods that should not be included in the image because they + * are hosted only, or because they are currently unsupported. + */ + Set forbiddenModules = hostVM.getForbiddenModules(); + if (forbiddenModules.contains(OriginalClassProvider.getJavaClass(type).getModule())) { + return; + } + /* + * Some methods in target classes can be marked as native because the substitution only + * injects an annotation, or provides an alias, without changing the implementation. Those + * methods should not be included in the image. + */ + if (AnnotationAccess.isAnnotationPresent(type, TargetClass.class)) { + return; + } + ResolvedJavaMethod[] methods = tryApply(type, t -> t.getDeclaredMethods(false), NO_METHODS); + for (ResolvedJavaMethod method : methods) { + if (method.isNative()) { + if (getHostVM().isSupportedOriginalMethod(this, method)) { + classInclusionPolicy.includeMethod(method); + } + } + } + } + /** * Applies {@code function} to {@code type} and returns the result or, if * {@link NoClassDefFoundError} or {@link IncompatibleClassChangeError} thrown when applying the diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/BigBang.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/BigBang.java index 8c7fd5de64d3..5877df05f0f4 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/BigBang.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/BigBang.java @@ -159,4 +159,9 @@ default void tryRegisterMethodForBaseImage(AnalysisMethod method) { default void tryRegisterFieldForBaseImage(AnalysisField field) { } + + @SuppressWarnings("unused") + default void tryRegisterNativeMethodsForBaseImage(ResolvedJavaType analysisType) { + + } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java index e11184dbe405..c122adf8d0ff 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java @@ -32,6 +32,7 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.BiConsumer; import java.util.function.Predicate; @@ -456,6 +457,10 @@ public boolean preventConstantFolding(AnalysisField aField) { return false; } + public Set getForbiddenModules() { + return Set.of(); + } + /** * Helpers to determine what analysis actions should be taken for a given Multi-Method version. */ diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinPhysicalMemorySupportImpl.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinPhysicalMemorySupportImpl.java index 4ea4eb154cd5..548dbd5df4c4 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinPhysicalMemorySupportImpl.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinPhysicalMemorySupportImpl.java @@ -34,8 +34,8 @@ import com.oracle.svm.core.headers.LibC; import com.oracle.svm.core.heap.PhysicalMemory.PhysicalMemorySupport; import com.oracle.svm.core.log.Log; -import com.oracle.svm.core.posix.headers.Sysctl; import com.oracle.svm.core.posix.headers.darwin.DarwinSysctl; +import com.oracle.svm.core.posix.headers.darwin.Sysctl; import com.oracle.svm.core.traits.BuiltinTraits.NoLayeredCallbacks; import com.oracle.svm.core.traits.BuiltinTraits.RuntimeAccessOnly; import com.oracle.svm.core.traits.SingletonLayeredInstallationKind.Disallowed; diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/PosixLibC.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/PosixLibC.java index 36bfdcfeac15..2fb707628dfc 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/PosixLibC.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/PosixLibC.java @@ -77,27 +77,9 @@ public class PosixLibC { @CFunction(transition = CFunction.Transition.NO_TRANSITION) public static native int strcmp(PointerBase s1, PointerBase s2); - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native CCharPointer strcpy(CCharPointer dst, CCharPointer src); - - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native CCharPointer strncpy(CCharPointer dst, CCharPointer src, UnsignedWord len); - - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native UnsignedWord strlcpy(CCharPointer dst, CCharPointer src, UnsignedWord len); - @CFunction(transition = CFunction.Transition.NO_TRANSITION) public static native CCharPointer strdup(CCharPointer src); - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native CCharPointer strtok_r(CCharPointer str, CCharPointer delim, CCharPointerPointer saveptr); - - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native long strtol(CCharPointer nptr, CCharPointerPointer endptr, int base); - - @CFunction(transition = CFunction.Transition.NO_TRANSITION) - public static native CCharPointer strstr(CCharPointer str, CCharPointer substr); - @CFunction(transition = CFunction.Transition.NO_TRANSITION) public static native int isdigit(int c); diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/DarwinDirectives.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/DarwinDirectives.java new file mode 100644 index 000000000000..c4f3b4a04f95 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/DarwinDirectives.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.core.posix.headers.darwin; + +import org.graalvm.nativeimage.Platform; + +import com.oracle.svm.core.posix.headers.PosixDirectives; + +public class DarwinDirectives extends PosixDirectives { + @Override + public boolean isInConfiguration() { + return Platform.includedIn(Platform.DARWIN.class); + } +} diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/Sysctl.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/Sysctl.java similarity index 87% rename from substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/Sysctl.java rename to substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/Sysctl.java index 56366ec36e0d..1685096c90ac 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/Sysctl.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/darwin/Sysctl.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.core.posix.headers; +package com.oracle.svm.core.posix.headers.darwin; import org.graalvm.nativeimage.c.CContext; import org.graalvm.nativeimage.c.function.CFunction; @@ -35,9 +35,9 @@ /** * Definitions manually translated from the C header file sys/sysctl.h. */ -@CContext(PosixDirectives.class) +@CContext(DarwinDirectives.class) public class Sysctl { @CFunction - public static native int sysctl(CIntPointer name, long nlen, PointerBase oldval, WordPointer oldlenp, PointerBase newval, long newlen); + public static native int sysctl(CIntPointer name, int nlen, PointerBase oldval, WordPointer oldlenp, PointerBase newval, long newlen); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java index c790ab07772e..d0990bd1a2ee 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java @@ -463,4 +463,8 @@ public void initBuilderModules() { Module m1 = SVMHost.class.getModule(); builderModules = m0.equals(m1) ? Set.of(m0) : Set.of(m0, m1); } + + public EconomicSet> getApplicationClasses() { + return applicationClasses; + } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 70ad0262474c..84f1cb943fae 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -1109,6 +1109,7 @@ protected void setupNativeImage(OptionValues options, Map typeToHub = new ConcurrentHashMap<>(); @@ -225,6 +236,9 @@ public enum UsageKind { private final SymbolEncoder encoder = SymbolEncoder.singleton(); + private com.oracle.svm.hosted.c.NativeLibraries nativeLibraries; + private Collection allStaticLibNames; + private final int layerId; private final boolean buildingImageLayer = ImageLayerBuildingSupport.buildingImageLayer(); private final boolean buildingInitialLayer = ImageLayerBuildingSupport.buildingInitialLayer(); @@ -246,6 +260,12 @@ public enum UsageKind { private final boolean trackDynamicAccess; private DynamicAccessDetectionSupport dynamicAccessDetectionSupport = null; + /** + * Some modules contain native methods that should never be in the image, as they are either + * hosted only, or currently unsupported in layered images. + */ + private final Set forbiddenModules = new HashSet<>(); + @SuppressWarnings("this-escape") public SVMHost(OptionValues options, ImageClassLoader loader, ClassInitializationSupport classInitializationSupport, AnnotationSubstitutionProcessor annotationSubstitutions, MissingRegistrationSupport missingRegistrationSupport) { @@ -1082,12 +1102,7 @@ public boolean isSupportedAnalysisMethod(BigBang bb, AnalysisMethod method) { if (!platformSupported(method)) { return false; } - /* - * Methods annotated with @Fold should not be included in the base image as they are - * replaced by the invocation plugin with a constant. If reachable in an extension image, - * the plugin will replace it again. - */ - if (AnnotationAccess.isAnnotationPresent(method, Fold.class)) { + if (!isSupportedMethod(bb, method)) { return false; } return super.isSupportedAnalysisMethod(bb, method); @@ -1113,12 +1128,70 @@ public boolean isSupportedOriginalMethod(BigBang bb, ResolvedJavaMethod method) /* If the method is substituted we need to check the substitution layer for @Fold. */ ResolvedJavaMethod substitutionMethod = bb.getUniverse().getSubstitutions().lookup(method); - if (AnnotationAccess.isAnnotationPresent(substitutionMethod, Fold.class)) { + if (!isSupportedMethod(bb, method) || !isSupportedMethod(bb, substitutionMethod)) { return false; } return super.isSupportedOriginalMethod(bb, method); } + private boolean isSupportedMethod(BigBang bb, ResolvedJavaMethod method) { + /* + * Methods annotated with @Fold should not be included in the base image as they are + * replaced by the invocation plugin with a constant. If reachable in an extension image, + * the plugin will replace it again. + */ + if (AnnotationAccess.isAnnotationPresent(method, Fold.class)) { + return false; + } + + /* Deleted methods should not be included in the image. */ + if (AnnotationAccess.isAnnotationPresent(method, Delete.class)) { + return false; + } + + /* + * Methods whose graph cannot be created should not be in the image. Those methods are + * compiled in a different way and cannot be included in the same way as normal methods. + */ + if (AnnotationAccess.isAnnotationPresent(method, CConstant.class) || AnnotationAccess.isAnnotationPresent(method, Operation.class) || + AnnotationAccess.isAnnotationPresent(method, NodeIntrinsic.class) || AnnotationAccess.isAnnotationPresent(method, HotSpotOperation.class)) { + return false; + } + + /* Methods that are not provided in the current Libc should not be included. */ + if (OriginalMethodProvider.getJavaMethod(method) instanceof Method m && !HostedLibCBase.isMethodProvidedInCurrentLibc(m)) { + return false; + } + + /* Methods that are not in the native libraries configuration should not be included. */ + if (nativeLibraries == null) { + nativeLibraries = com.oracle.svm.hosted.c.NativeLibraries.singleton(); + allStaticLibNames = nativeLibraries.getAllStaticLibNames(); + } + if (!nativeLibraries.isMethodInConfiguration(method)) { + return false; + } + + /* + * Methods from a CLibrary that is not included in the static libraries of the image should + * not be included. + */ + CLibrary cLibrary = nativeLibraries.getCLibrary(method); + if (cLibrary != null && allStaticLibNames.stream().noneMatch(lib -> lib.toString().contains(cLibrary.value()))) { + return false; + } + + /* Methods with an invocation plugin should not be included. */ + InvocationPlugins invocationPlugins = getProviders(MultiMethod.ORIGINAL_METHOD).getGraphBuilderPlugins().getInvocationPlugins(); + if (invocationPlugins.lookupInvocation(method, bb.getOptions()) != null) { + return false; + } + + /* CEntryPoint methods should not be included according to their predicate. */ + CEntryPoint cEntryPoint = AnnotationAccess.getAnnotation(method, CEntryPoint.class); + return cEntryPoint == null || ReflectionUtil.newInstance(cEntryPoint.include()).getAsBoolean(); + } + /** * Check if an {@link AnalysisField} should be included in the image. For checking its * annotations we rely on the {@link AnnotationAccess} unwrapping mechanism to include any @@ -1474,4 +1547,28 @@ public SimulateClassInitializerSupport createSimulateClassInitializerSupport(Ana public ConstantExpressionRegistry getConstantExpressionRegistry() { return constantExpressionRegistry; } + + @Override + public Set getForbiddenModules() { + if (forbiddenModules.isEmpty()) { + forbiddenModules.add(JVMCI.class.getModule()); + Class llvm = ReflectionUtil.lookupClass(true, "com.oracle.svm.shadowed.org.bytedeco.llvm.global.LLVM"); + if (llvm != null) { + forbiddenModules.add(llvm.getModule()); + } + Class javacpp = ReflectionUtil.lookupClass(true, "com.oracle.svm.shadowed.org.bytedeco.javacpp.presets.javacpp"); + if (javacpp != null) { + forbiddenModules.add(javacpp.getModule()); + } + Class truffle = ReflectionUtil.lookupClass(true, "com.oracle.truffle.polyglot.JDKSupport"); + if (truffle != null) { + forbiddenModules.add(truffle.getModule()); + } + Class libGraal = ReflectionUtil.lookupClass(true, "com.oracle.truffle.runtime.hotspot.libgraal.LibGraal"); + if (libGraal != null) { + forbiddenModules.add(libGraal.getModule()); + } + } + return forbiddenModules; + } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/NativeLibraries.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/NativeLibraries.java index 0e16d162931c..8059b87250d2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/NativeLibraries.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/c/NativeLibraries.java @@ -48,6 +48,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.c.CContext; @@ -402,6 +403,10 @@ public void reportErrors() { } } + public boolean isMethodInConfiguration(ResolvedJavaMethod method) { + return makeContext(getDirectives(method)).isInConfiguration(); + } + public void loadJavaMethod(ResolvedJavaMethod method) { Class directives = getDirectives(method); NativeCodeContext context = makeContext(directives); @@ -493,6 +498,10 @@ private static Path getStaticLibraryPath(Map allStaticLibs, String s return allStaticLibs.get(Paths.get(getStaticLibraryName(staticLibraryName))); } + public Collection getAllStaticLibNames() { + return getAllStaticLibs().keySet(); + } + private Map getAllStaticLibs() { Map allStaticLibs = new LinkedHashMap<>(); String libSuffix = Platform.includedIn(InternalPlatform.WINDOWS_BASE.class) ? ".lib" : ".a"; @@ -575,6 +584,25 @@ private Class getDirectives(ResolvedJavaType type } } + public CLibrary getCLibrary(ResolvedJavaMethod method) { + CLibrary cLibrary = AnnotationAccess.getAnnotation(method, CLibrary.class); + if (cLibrary == null) { + return getCLibrary(method.getDeclaringClass()); + } + return cLibrary; + } + + public CLibrary getCLibrary(ResolvedJavaType type) { + CLibrary cLibrary = AnnotationAccess.getAnnotation(type, CLibrary.class); + if (cLibrary != null) { + return cLibrary; + } else if (type.getEnclosingType() != null) { + return getCLibrary(type.getEnclosingType()); + } else { + return null; + } + } + public void finish() { libraryPaths.addAll(SubstrateOptions.CLibraryPath.getValue().values().stream().map(Path::toString).toList()); for (NativeCodeContext context : compilationUnitToContext.values()) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedImageLayerBuildingSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedImageLayerBuildingSupport.java index a0dea8f283e0..9bc49096868e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedImageLayerBuildingSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/imagelayer/HostedImageLayerBuildingSupport.java @@ -423,4 +423,16 @@ public static void setupSharedLayerLibrary(NativeLibraries nativeLibs) { public static void registerBaseLayerTypes(BigBang bb, MetaAccessProvider originalMetaAccess, NativeImageClassLoaderSupport classLoaderSupport) { classLoaderSupport.getClassesToIncludeUnconditionally().forEach(clazz -> bb.tryRegisterTypeForBaseImage(originalMetaAccess.lookupJavaType(clazz))); } + + /** + * Native libraries can keep track of a state in C variables. Since native libraries are linked + * statically against each layer, the state is kept in a separate space for each layer. This + * means that if two methods access the same variable, but they are in a different layer, they + * will access to different instances. For this reason, all the native methods from a single + * native library need to be in the same layer. This method iterate through all native methods + * and try to include them in the current layer. + */ + public static void registerNativeMethodsForBaseImage(BigBang bb, MetaAccessProvider originalMetaAccess, ImageClassLoader loader) { + loader.getApplicationClasses().forEach(clazz -> bb.tryRegisterNativeMethodsForBaseImage(originalMetaAccess.lookupJavaType(clazz))); + } } diff --git a/substratevm/src/com.oracle.svm.native.jvm.posix/src/JvmFuncs.c b/substratevm/src/com.oracle.svm.native.jvm.posix/src/JvmFuncs.c index 89a975bbef73..bc84a9f0f5eb 100644 --- a/substratevm/src/com.oracle.svm.native.jvm.posix/src/JvmFuncs.c +++ b/substratevm/src/com.oracle.svm.native.jvm.posix/src/JvmFuncs.c @@ -364,6 +364,16 @@ JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs(JNIEnv *e return NULL; } +JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_receive0(JNIEnv *env) { + (*env)->FatalError(env, "Currently SCTP not supported for native-images"); + return NULL; +} + +JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0(JNIEnv *env) { + (*env)->FatalError(env, "Currently SCTP not supported for native-images"); + return NULL; +} + jboolean VerifyFixClassname(char *utf_name) { fprintf(stderr, "VerifyFixClassname(%s) called: Unimplemented\n", utf_name); abort();