Skip to content
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

8265222: revisit foreign library loading #526

Closed
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -2426,7 +2426,7 @@ static NativeLibrary loadLibrary(Class<?> fromClass, String name) {
/*
* Invoked in the VM class linking code.
*/
private static long findNative(ClassLoader loader, String entryName) {
static long findNative(ClassLoader loader, String entryName) {
if (loader == null) {
return BootLoader.getNativeLibraries().find(entryName);
} else {
@@ -2344,6 +2344,11 @@ public Module addEnableNativeAccess(Module m) {
public boolean isEnableNativeAccess(Module m) {
return m.isEnableNativeAccess();
}

@Override
public long findNative(ClassLoader loader, String entry) {
return ClassLoader.findNative(loader, entry);
}
});
}
}
@@ -382,4 +382,6 @@ public interface JavaLangAccess {
Module addEnableNativeAccess(Module m);

boolean isEnableNativeAccess(Module m);

long findNative(ClassLoader loader, String entry);
}
@@ -384,20 +384,6 @@ boolean open() {
}
}

public static final NativeLibrary defaultLibrary = new NativeLibraryImpl(Object.class, "<default>", true, true) {

@Override
boolean open() {
throw new UnsupportedOperationException("Cannot load default library");
}

@Override
public long find(String name) {
return NativeLibraries.findEntryInProcess(name);
}

};

/*
* The run() method will be invoked when this class loader becomes
* phantom reachable to unload the native library.
@@ -478,5 +464,4 @@ private static Class<?> getFromClass() {
private static native void unload(String name, boolean isBuiltin, boolean isJNI, long handle);
private static native String findBuiltinLib(String name);
private static native long findEntry0(NativeLibraryImpl lib, String name);
private static native long findEntryInProcess(String name);
}
@@ -246,29 +246,6 @@ Java_jdk_internal_loader_NativeLibraries_findEntry0
return res;
}

/*
* Class: jdk_internal_loader_NativeLibraries
* Method: findEntryInProcess
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL
Java_jdk_internal_loader_NativeLibraries_findEntryInProcess
(JNIEnv *env, jclass cls, jstring name)
{
const char *cname;
jlong res;

if (!initIDs(env))
return jlong_zero;

cname = (*env)->GetStringUTFChars(env, name, 0);
if (cname == 0)
return jlong_zero;
res = ptr_to_jlong(findEntryInProcess(cname));
(*env)->ReleaseStringUTFChars(env, name, cname);
return res;
}

/*
* Class: jdk_internal_loader_NativeLibraries
* Method: findBuiltinLib
@@ -333,8 +333,6 @@ JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);

void* getProcessHandle();

void* findEntryInProcess(const char* name);

void buildJniFunctionName(const char *sym, const char *cname,
char *jniEntryName);

@@ -51,10 +51,6 @@ void* getProcessHandle() {
return procHandle;
}

void* findEntryInProcess(const char* name) {
return JVM_FindLibraryEntry(RTLD_DEFAULT, name);
}

void buildJniFunctionName(const char *sym, const char *cname,
char *jniEntryName) {
strcpy(jniEntryName, sym);
@@ -36,31 +36,6 @@ void* getProcessHandle() {
return (void*)GetModuleHandle(NULL);
}

/*
* Windows doesn't have an RTLD_DEFAULT equivalent, so in stead we have to
* iterate over all the modules loaded by the process to implement the
* default library behaviour.
*/
void* findEntryInProcess(const char* name) {
sundararajana marked this conversation as resolved.
Show resolved Hide resolved
HANDLE hProcess = GetCurrentProcess();

HMODULE hMods[1024];
DWORD cbNeeded; // array size in bytes

// first come, first served
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
for (size_t i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
HMODULE mod = hMods[i];
FARPROC proc = GetProcAddress(mod, name);
if(proc != NULL) {
return proc;
}
}
}

return NULL;
}

/*
* Windows symbols can be simple like JNI_OnLoad or __stdcall format
* like _JNI_OnLoad@8. We need to handle both.
@@ -25,6 +25,8 @@
*/
package jdk.incubator.foreign;

import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.foreign.NativeMemorySegmentImpl;
import jdk.internal.foreign.PlatformLayouts;
import jdk.internal.foreign.abi.SharedUtils;
@@ -36,6 +38,7 @@
import java.lang.invoke.MethodType;
import java.nio.charset.Charset;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;

import static jdk.internal.foreign.PlatformLayouts.*;
@@ -126,6 +129,20 @@ static CLinker getInstance() {
return SharedUtils.getSystemLinker();
}

@CallerSensitive
public static Optional<MemoryAddress> findNative(String name) {
sundararajana marked this conversation as resolved.
Show resolved Hide resolved
Reflection.ensureNativeAccess(Reflection.getCallerClass());
ClassLoader loader = Reflection.getCallerClass().getClassLoader();
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(new RuntimePermission("java.foreign.findNative"));
}
Objects.requireNonNull(name);
JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess();
MemoryAddress addr = MemoryAddress.ofLong(javaLangAccess.findNative(loader, name));
return addr == MemoryAddress.NULL? Optional.empty() : Optional.of(addr);
}

/**
* Obtains a foreign method handle, with the given type and featuring the given function descriptor,
* which can be used to call a target foreign function at the given address.

This file was deleted.