fix case of JNIEnv::FindClass called from JNI_OnLoad

If an JNI_OnLoad implementation calls FindClass when using the OpenJDK
class library, the calling method on the Java stack will be
ClassLoader.loadLibrary.  However, we must use the class loader of the
class attempting to load the library in this case, not the system
classloader.

Therefore, we now maintain a stack such that the latest class to load
a library in the current thread is at the top, and we use that class
whenever FindClass is called by ClassLoader.loadLibrary (via
JNI_OnLoad).

Note that this patch does not attempt to address the same problem for
the Avian or Android class libraries, but the same strategy should
work for them as well.
This commit is contained in:
Joel Dice 2014-06-23 17:17:13 -06:00
parent 9d4f9901bc
commit 4dc76a50a2
6 changed files with 81 additions and 42 deletions

View File

@ -1421,6 +1421,30 @@ class Thread {
SingleProtector protector;
};
class LibraryLoadStack: public AutoResource {
public:
LibraryLoadStack(Thread* t, object class_):
AutoResource(t),
next(t->libraryLoadStack),
class_(class_),
protector(t, &(this->class_))
{
t->libraryLoadStack = this;
}
~LibraryLoadStack() {
t->libraryLoadStack = next;
}
virtual void release() {
this->LibraryLoadStack::~LibraryLoadStack();
}
LibraryLoadStack* next;
object class_;
SingleProtector protector;
};
class Checkpoint {
public:
Checkpoint(Thread* t):
@ -1516,6 +1540,7 @@ class Thread {
unsigned heapOffset;
Protector* protector;
ClassInitStack* classInitStack;
LibraryLoadStack* libraryLoadStack;
Resource* resource;
Checkpoint* checkpoint;
Runnable runnable;

View File

@ -16,42 +16,42 @@
# if (TARGET_BYTES_PER_WORD == 8)
#define TARGET_THREAD_EXCEPTION 80
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2256
#define TARGET_THREAD_EXCEPTIONOFFSET 2264
#define TARGET_THREAD_EXCEPTIONHANDLER 2272
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2264
#define TARGET_THREAD_EXCEPTIONOFFSET 2272
#define TARGET_THREAD_EXCEPTIONHANDLER 2280
#define TARGET_THREAD_IP 2216
#define TARGET_THREAD_STACK 2224
#define TARGET_THREAD_NEWSTACK 2232
#define TARGET_THREAD_SCRATCH 2240
#define TARGET_THREAD_CONTINUATION 2248
#define TARGET_THREAD_TAILADDRESS 2280
#define TARGET_THREAD_VIRTUALCALLTARGET 2288
#define TARGET_THREAD_VIRTUALCALLINDEX 2296
#define TARGET_THREAD_HEAPIMAGE 2304
#define TARGET_THREAD_CODEIMAGE 2312
#define TARGET_THREAD_THUNKTABLE 2320
#define TARGET_THREAD_STACKLIMIT 2368
#define TARGET_THREAD_IP 2224
#define TARGET_THREAD_STACK 2232
#define TARGET_THREAD_NEWSTACK 2240
#define TARGET_THREAD_SCRATCH 2248
#define TARGET_THREAD_CONTINUATION 2256
#define TARGET_THREAD_TAILADDRESS 2288
#define TARGET_THREAD_VIRTUALCALLTARGET 2296
#define TARGET_THREAD_VIRTUALCALLINDEX 2304
#define TARGET_THREAD_HEAPIMAGE 2312
#define TARGET_THREAD_CODEIMAGE 2320
#define TARGET_THREAD_THUNKTABLE 2328
#define TARGET_THREAD_STACKLIMIT 2376
# elif (TARGET_BYTES_PER_WORD == 4)
#define TARGET_THREAD_EXCEPTION 44
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2164
#define TARGET_THREAD_EXCEPTIONOFFSET 2168
#define TARGET_THREAD_EXCEPTIONHANDLER 2172
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2168
#define TARGET_THREAD_EXCEPTIONOFFSET 2172
#define TARGET_THREAD_EXCEPTIONHANDLER 2176
#define TARGET_THREAD_IP 2144
#define TARGET_THREAD_STACK 2148
#define TARGET_THREAD_NEWSTACK 2152
#define TARGET_THREAD_SCRATCH 2156
#define TARGET_THREAD_CONTINUATION 2160
#define TARGET_THREAD_TAILADDRESS 2176
#define TARGET_THREAD_VIRTUALCALLTARGET 2180
#define TARGET_THREAD_VIRTUALCALLINDEX 2184
#define TARGET_THREAD_HEAPIMAGE 2188
#define TARGET_THREAD_CODEIMAGE 2192
#define TARGET_THREAD_THUNKTABLE 2196
#define TARGET_THREAD_STACKLIMIT 2220
#define TARGET_THREAD_IP 2148
#define TARGET_THREAD_STACK 2152
#define TARGET_THREAD_NEWSTACK 2156
#define TARGET_THREAD_SCRATCH 2160
#define TARGET_THREAD_CONTINUATION 2164
#define TARGET_THREAD_TAILADDRESS 2180
#define TARGET_THREAD_VIRTUALCALLTARGET 2184
#define TARGET_THREAD_VIRTUALCALLINDEX 2188
#define TARGET_THREAD_HEAPIMAGE 2192
#define TARGET_THREAD_CODEIMAGE 2196
#define TARGET_THREAD_THUNKTABLE 2200
#define TARGET_THREAD_STACKLIMIT 2224
# else
# error

View File

@ -1845,6 +1845,9 @@ management_JNI_OnLoad(JavaVM*, void*);
void JNICALL
loadLibrary(Thread* t, object, uintptr_t* arguments)
{
Thread::LibraryLoadStack stack
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
object name = reinterpret_cast<object>(arguments[1]);
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));

View File

@ -10,11 +10,11 @@
#ifdef __x86_64__
#define THREAD_CONTINUATION 2248
#define THREAD_CONTINUATION 2256
#define THREAD_EXCEPTION 80
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2256
#define THREAD_EXCEPTION_OFFSET 2264
#define THREAD_EXCEPTION_HANDLER 2272
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2264
#define THREAD_EXCEPTION_OFFSET 2272
#define THREAD_EXCEPTION_HANDLER 2280
#define CONTINUATION_NEXT 8
#define CONTINUATION_ADDRESS 32
@ -91,11 +91,11 @@ LOCAL(vmInvoke_exit):
#elif defined __i386__
#define THREAD_CONTINUATION 2160
#define THREAD_CONTINUATION 2164
#define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2164
#define THREAD_EXCEPTION_OFFSET 2168
#define THREAD_EXCEPTION_HANDLER 2172
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2168
#define THREAD_EXCEPTION_OFFSET 2172
#define THREAD_EXCEPTION_HANDLER 2176
#define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16

View File

@ -349,10 +349,20 @@ findClass(Thread* t, uintptr_t* arguments)
object caller = getCaller(t, 0);
object c = resolveClass(t,
caller ? classLoader(t, methodClass(t, caller))
: root(t, Machine::AppLoader),
n);
object loader;
if (caller) {
if (methodClass(t, caller) == type(t, Machine::ClassLoaderType)
and t->libraryLoadStack)
{
loader = classLoader(t, t->libraryLoadStack->class_);
} else {
loader = classLoader(t, methodClass(t, caller));
}
} else {
loader = root(t, Machine::AppLoader);
}
object c = resolveClass(t, loader, n);
if (t->m->classpath->mayInitClasses()) {
PROTECT(t, c);

View File

@ -3337,6 +3337,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
heapOffset(0),
protector(0),
classInitStack(0),
libraryLoadStack(0),
runnable(this),
defaultHeap(static_cast<uintptr_t*>
(m->heap->allocate(ThreadHeapSizeInBytes))),