Skip to content

[GR-54648] Require that built-in libraries must have a JNI_OnLoad_libname function. #9279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,14 @@ public class JNILibraryInitializer implements NativeLibrarySupport.LibraryInitia

private final EconomicMap<String, CGlobalData<PointerBase>> onLoadCGlobalDataMap = ImageHeapMap.create(Equivalence.IDENTITY);

public static String getOnLoadName(String libName, boolean isBuiltIn) {
private static String getOnLoadName(String libName, boolean isBuiltIn) {
String name = "JNI_OnLoad";
if (isBuiltIn) {
return name + "_" + libName;
}
return name;
}

private static void callOnLoadFunction(String libName, PointerBase onLoadFunction) {
if (onLoadFunction.isNonNull()) {
JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction;
int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer());
checkSupportedJNIVersion(libName, expected);
}
}

private static void checkSupportedJNIVersion(String libName, int expected) {
if (!JNIVersion.isSupported(expected)) {
String message = "Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName;
throw new UnsatisfiedLinkError(message);
}
}

public boolean fillCGlobalDataMap(Collection<String> staticLibNames) {
List<String> libsWithOnLoad = Arrays.asList("net", "java", "nio", "zip", "sunec", "jaas", "sctp", "extnet",
"j2gss", "j2pkcs11", "j2pcsc", "prefs", "verify", "awt", "awt_xawt", "awt_headless", "lcms",
Expand Down Expand Up @@ -118,17 +103,23 @@ public void initialize(PlatformNativeLibrarySupport.NativeLibrary lib) {
if (lib.isBuiltin()) {
onLoadFunction = getOnLoadSymbolAddress(libName);
if (onLoadFunction.isNull()) {
/*
* If pointer for static library not found, try to initialize library as shared
*/
String symbolName = getOnLoadName(libName, true);
onLoadFunction = lib.findSymbol(symbolName);
if (onLoadFunction.isNull()) {
throw new UnsatisfiedLinkError("Missing mandatory function for statically linked JNI library: " + symbolName);
}
}
} else {
String symbolName = getOnLoadName(libName, false);
onLoadFunction = lib.findSymbol(symbolName);
}
callOnLoadFunction(libName, onLoadFunction);
if (onLoadFunction.isNonNull()) {
JNIOnLoadFunctionPointer onLoad = (JNIOnLoadFunctionPointer) onLoadFunction;
int expected = onLoad.invoke(JNIFunctionTables.singleton().getGlobalJavaVM(), WordFactory.nullPointer());
if (!JNIVersion.isSupported(expected, lib.isBuiltin())) {
throw new UnsatisfiedLinkError("Unsupported JNI version 0x" + Integer.toHexString(expected) + ", required by " + libName);
}
}
}

private PointerBase getOnLoadSymbolAddress(String libName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static int JNI_CreateJavaVM(@SuppressWarnings("unused") JNIJavaVMPointer vmBuf,
@Uninterruptible(reason = "No Java context")
static int JNI_GetDefaultJavaVMInitArgs(JNIJavaVMInitArgs vmArgs) {
int version = vmArgs.getVersion();
if (JNIVersion.isSupported(vmArgs.getVersion()) && version != JNIVersion.JNI_VERSION_1_1()) {
if (JNIVersion.isSupported(vmArgs.getVersion(), false) && version != JNIVersion.JNI_VERSION_1_1()) {
return JNIErrors.JNI_OK();
}
if (version == JNIVersion.JNI_VERSION_1_1()) {
Expand Down Expand Up @@ -320,7 +320,7 @@ static int enter(JNIJavaVM vm, WordPointer env, int version) {
if (vm.isNull() || env.isNull()) {
return JNIErrors.JNI_ERR();
}
if (!JNIVersion.isSupported(version)) {
if (!JNIVersion.isSupported(version, false)) {
env.write(WordFactory.nullPointer());
return JNIErrors.JNI_EVERSION();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@
@CContext(JNIHeaderDirectives.class)
public final class JNIVersion {
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public static boolean isSupported(int version) {
return (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) ||
version == JNI_VERSION_21() ||
version == JNI_VERSION_20() ||
version == JNI_VERSION_19() ||
version == JNI_VERSION_10() ||
version == JNI_VERSION_9() ||
version == JNI_VERSION_1_8() ||
version == JNI_VERSION_1_6() ||
version == JNI_VERSION_1_4() ||
version == JNI_VERSION_1_2() ||
version == JNI_VERSION_1_1();
public static boolean isSupported(int version, boolean builtInLibrary) {
if (JavaVersionUtil.JAVA_SPEC >= 22 && version == JNIVersionJDKLatest.JNI_VERSION_LATEST()) {
return true;
}
if (version == JNI_VERSION_21() || version == JNI_VERSION_20() || version == JNI_VERSION_19() || version == JNI_VERSION_10() || version == JNI_VERSION_9() || version == JNI_VERSION_1_8()) {
return true;
}
if (builtInLibrary) {
// Specification requires 1.8 or later for built-in (statically linked) libraries.
return false;
}
return version == JNI_VERSION_1_6() || version == JNI_VERSION_1_4() || version == JNI_VERSION_1_2() || version == JNI_VERSION_1_1();
}

// Checkstyle: stop
Expand Down