mirror of
https://github.com/corda/corda.git
synced 2025-06-03 08:00:57 +00:00
rework loadLibrary interception to handle builtins properly
This commit is contained in:
parent
bc2b4802ec
commit
d381ece44b
@ -174,7 +174,7 @@ class MyClasspath : public Classpath {
|
|||||||
|
|
||||||
MyClasspath(System* s, Allocator* allocator, const char* javaHome,
|
MyClasspath(System* s, Allocator* allocator, const char* javaHome,
|
||||||
const char* embedPrefix):
|
const char* embedPrefix):
|
||||||
allocator(allocator)
|
allocator(allocator), ranNetOnLoad(0)
|
||||||
{
|
{
|
||||||
class StringBuilder {
|
class StringBuilder {
|
||||||
public:
|
public:
|
||||||
@ -239,30 +239,6 @@ class MyClasspath : public Classpath {
|
|||||||
#endif
|
#endif
|
||||||
sb.append('\0');
|
sb.append('\0');
|
||||||
|
|
||||||
this->zipLibrary = sb.pointer;
|
|
||||||
sb.append(this->libraryPath);
|
|
||||||
sb.append("/");
|
|
||||||
sb.append(SO_PREFIX);
|
|
||||||
sb.append("zip");
|
|
||||||
sb.append(SO_SUFFIX);
|
|
||||||
sb.append('\0');
|
|
||||||
|
|
||||||
this->netLibrary = sb.pointer;
|
|
||||||
sb.append(this->libraryPath);
|
|
||||||
sb.append("/");
|
|
||||||
sb.append(SO_PREFIX);
|
|
||||||
sb.append("net");
|
|
||||||
sb.append(SO_SUFFIX);
|
|
||||||
sb.append('\0');
|
|
||||||
|
|
||||||
this->nioLibrary = sb.pointer;
|
|
||||||
sb.append(this->libraryPath);
|
|
||||||
sb.append("/");
|
|
||||||
sb.append(SO_PREFIX);
|
|
||||||
sb.append("nio");
|
|
||||||
sb.append(SO_SUFFIX);
|
|
||||||
sb.append('\0');
|
|
||||||
|
|
||||||
this->tzMappings = sb.pointer;
|
this->tzMappings = sb.pointer;
|
||||||
sb.append(javaHome);
|
sb.append(javaHome);
|
||||||
sb.append("/lib/tzmappings");
|
sb.append("/lib/tzmappings");
|
||||||
@ -445,9 +421,6 @@ class MyClasspath : public Classpath {
|
|||||||
const char* javaHome;
|
const char* javaHome;
|
||||||
const char* classpath;
|
const char* classpath;
|
||||||
const char* libraryPath;
|
const char* libraryPath;
|
||||||
const char* zipLibrary;
|
|
||||||
const char* netLibrary;
|
|
||||||
const char* nioLibrary;
|
|
||||||
const char* tzMappings;
|
const char* tzMappings;
|
||||||
const char* embedPrefix;
|
const char* embedPrefix;
|
||||||
unsigned tzMappingsLength;
|
unsigned tzMappingsLength;
|
||||||
@ -455,6 +428,7 @@ class MyClasspath : public Classpath {
|
|||||||
unsigned filePathField;
|
unsigned filePathField;
|
||||||
unsigned fileDescriptorFdField;
|
unsigned fileDescriptorFdField;
|
||||||
unsigned fileInputStreamFdField;
|
unsigned fileInputStreamFdField;
|
||||||
|
bool ranNetOnLoad;
|
||||||
char buffer[BufferSize];
|
char buffer[BufferSize];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -595,44 +569,37 @@ getFileAttributes
|
|||||||
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
||||||
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
||||||
|
|
||||||
if (pathEqual(cp->zipLibrary, RUNTIME_ARRAY_BODY(p))
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
|
||||||
or pathEqual(cp->netLibrary, RUNTIME_ARRAY_BODY(p))
|
if (ef.jar) {
|
||||||
or pathEqual(cp->nioLibrary, RUNTIME_ARRAY_BODY(p)))
|
if (ef.jarLength == 0) {
|
||||||
{
|
return Exists | Directory;
|
||||||
return Exists | Regular;
|
}
|
||||||
} else {
|
|
||||||
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
||||||
if (ef.jar) {
|
if (finder) {
|
||||||
if (ef.jarLength == 0) {
|
if (ef.pathLength == 0) {
|
||||||
return Exists | Directory;
|
return Exists | Directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
unsigned length;
|
||||||
if (finder) {
|
System::FileType type = finder->stat(ef.path, &length, true);
|
||||||
if (ef.pathLength == 0) {
|
switch (type) {
|
||||||
return Exists | Directory;
|
case System::TypeUnknown: return Exists;
|
||||||
}
|
case System::TypeDoesNotExist: return 0;
|
||||||
|
case System::TypeFile: return Exists | Regular;
|
||||||
unsigned length;
|
case System::TypeDirectory: return Exists | Directory;
|
||||||
System::FileType type = finder->stat(ef.path, &length, true);
|
default: abort(t);
|
||||||
switch (type) {
|
|
||||||
case System::TypeUnknown: return Exists;
|
|
||||||
case System::TypeDoesNotExist: return 0;
|
|
||||||
case System::TypeFile: return Exists | Regular;
|
|
||||||
case System::TypeDirectory: return Exists | Directory;
|
|
||||||
default: abort(t);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object r = t->m->processor->invoke
|
return 0;
|
||||||
(t, nativeInterceptOriginal
|
|
||||||
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
|
||||||
reinterpret_cast<object>(arguments[0]), file);
|
|
||||||
|
|
||||||
return (r ? intValue(t, r) : 0);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
object r = t->m->processor->invoke
|
||||||
|
(t, nativeInterceptOriginal
|
||||||
|
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
||||||
|
reinterpret_cast<object>(arguments[0]), file);
|
||||||
|
|
||||||
|
return (r ? intValue(t, r) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,44 +619,37 @@ checkFileAccess
|
|||||||
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
||||||
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
||||||
|
|
||||||
if (pathEqual(cp->zipLibrary, RUNTIME_ARRAY_BODY(p))
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
|
||||||
or pathEqual(cp->netLibrary, RUNTIME_ARRAY_BODY(p))
|
if (ef.jar) {
|
||||||
or pathEqual(cp->nioLibrary, RUNTIME_ARRAY_BODY(p)))
|
if (ef.jarLength == 0) {
|
||||||
{
|
return mask == Read;
|
||||||
return mask == Read;
|
}
|
||||||
} else {
|
|
||||||
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), stringLength(t, path));
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
||||||
if (ef.jar) {
|
if (finder) {
|
||||||
if (ef.jarLength == 0) {
|
if (ef.pathLength == 0) {
|
||||||
return mask == Read;
|
return mask == Read;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
unsigned length;
|
||||||
if (finder) {
|
System::FileType type = finder->stat(ef.path, &length, true);
|
||||||
if (ef.pathLength == 0) {
|
switch (type) {
|
||||||
return mask == Read;
|
case System::TypeDoesNotExist: return false;
|
||||||
}
|
case System::TypeUnknown:
|
||||||
|
case System::TypeFile:
|
||||||
unsigned length;
|
case System::TypeDirectory: return mask == Read;
|
||||||
System::FileType type = finder->stat(ef.path, &length, true);
|
default: abort(t);
|
||||||
switch (type) {
|
|
||||||
case System::TypeDoesNotExist: return false;
|
|
||||||
case System::TypeUnknown:
|
|
||||||
case System::TypeFile:
|
|
||||||
case System::TypeDirectory: return mask == Read;
|
|
||||||
default: abort(t);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object r = t->m->processor->invoke
|
return 0;
|
||||||
(t, nativeInterceptOriginal
|
|
||||||
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
|
||||||
reinterpret_cast<object>(arguments[0]), file, mask);
|
|
||||||
|
|
||||||
return (r ? booleanValue(t, r) : false);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
object r = t->m->processor->invoke
|
||||||
|
(t, nativeInterceptOriginal
|
||||||
|
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
|
||||||
|
reinterpret_cast<object>(arguments[0]), file, mask);
|
||||||
|
|
||||||
|
return (r ? booleanValue(t, r) : false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1048,6 +1008,50 @@ getBootstrapResources(Thread* t, object, uintptr_t* arguments)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
net_JNI_OnLoad(JavaVM*, void*);
|
||||||
|
|
||||||
|
void JNICALL
|
||||||
|
loadLibrary(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object name = reinterpret_cast<object>(arguments[1]);
|
||||||
|
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
|
||||||
|
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||||
|
|
||||||
|
bool absolute = arguments[2];
|
||||||
|
|
||||||
|
#ifdef AVIAN_OPENJDK_SRC
|
||||||
|
if (not absolute) {
|
||||||
|
if (strcmp(n, "net") == 0) {
|
||||||
|
bool ran;
|
||||||
|
|
||||||
|
{ ACQUIRE(t, t->m->classLock);
|
||||||
|
|
||||||
|
local::MyClasspath* c = static_cast<local::MyClasspath*>
|
||||||
|
(t->m->classpath);
|
||||||
|
|
||||||
|
ran = c->ranNetOnLoad;
|
||||||
|
c->ranNetOnLoad = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not ran) {
|
||||||
|
net_JNI_OnLoad(t->m, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (strcmp(n, "zip") == 0
|
||||||
|
or strcmp(n, "nio") == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // AVIAN_OPENJDK_SRC
|
||||||
|
|
||||||
|
loadLibrary
|
||||||
|
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
||||||
|
RUNTIME_ARRAY_BODY(n), not absolute, false);
|
||||||
|
}
|
||||||
|
|
||||||
// only safe to call during bootstrap when there's only one thread
|
// only safe to call during bootstrap when there's only one thread
|
||||||
// running:
|
// running:
|
||||||
void
|
void
|
||||||
@ -1160,6 +1164,10 @@ interceptFileOperations(Thread* t)
|
|||||||
voidPointer(getFileLength));
|
voidPointer(getFileLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intercept(t, type(t, Machine::ClassLoaderType), "loadLibrary",
|
||||||
|
"(Ljava/lang/Class;Ljava/lang/String;Z)V",
|
||||||
|
voidPointer(loadLibrary));
|
||||||
|
|
||||||
intercept(t, type(t, Machine::ClassLoaderType), "getBootstrapResource",
|
intercept(t, type(t, Machine::ClassLoaderType), "getBootstrapResource",
|
||||||
"(Ljava/lang/String;)Ljava/net/URL;",
|
"(Ljava/lang/String;)Ljava/net/URL;",
|
||||||
voidPointer(getBootstrapResource));
|
voidPointer(getBootstrapResource));
|
||||||
@ -2060,9 +2068,6 @@ EXPORT(JVM_ActiveProcessorCount)()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
net_JNI_OnLoad(JavaVM*, void*);
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void* JNICALL
|
extern "C" JNIEXPORT void* JNICALL
|
||||||
EXPORT(JVM_LoadLibrary)(const char* path)
|
EXPORT(JVM_LoadLibrary)(const char* path)
|
||||||
{
|
{
|
||||||
@ -2071,26 +2076,6 @@ EXPORT(JVM_LoadLibrary)(const char* path)
|
|||||||
RUNTIME_ARRAY(char, p, strlen(path) + 1);
|
RUNTIME_ARRAY(char, p, strlen(path) + 1);
|
||||||
replace('\\', '/', RUNTIME_ARRAY_BODY(p), path);
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p), path);
|
||||||
|
|
||||||
#ifdef AVIAN_OPENJDK_SRC
|
|
||||||
if (local::pathEqual
|
|
||||||
(static_cast<local::MyClasspath*>(t->m->classpath)->zipLibrary,
|
|
||||||
RUNTIME_ARRAY_BODY(p))
|
|
||||||
or local::pathEqual
|
|
||||||
(static_cast<local::MyClasspath*>(t->m->classpath)->nioLibrary,
|
|
||||||
RUNTIME_ARRAY_BODY(p)))
|
|
||||||
{
|
|
||||||
return t->m->libraries;
|
|
||||||
} else if (local::pathEqual
|
|
||||||
(static_cast<local::MyClasspath*>(t->m->classpath)->netLibrary,
|
|
||||||
RUNTIME_ARRAY_BODY(p)))
|
|
||||||
{
|
|
||||||
net_JNI_OnLoad(t->m, 0);
|
|
||||||
return t->m->libraries;
|
|
||||||
}
|
|
||||||
#endif // AVIAN_OPENJDK_SRC
|
|
||||||
|
|
||||||
ENTER(t, Thread::ActiveState);
|
|
||||||
|
|
||||||
return loadLibrary
|
return loadLibrary
|
||||||
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
||||||
RUNTIME_ARRAY_BODY(p), false, false);
|
RUNTIME_ARRAY_BODY(p), false, false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user