fix JNIEnv::FindClass calls from JNI_OnLoad for all supported class libraries

This also fixes the some Android build rot and updates the version of
OpenSSL used.
This commit is contained in:
Joel Dice 2014-07-01 10:18:45 -06:00
parent 735eaaba21
commit 5d3c612d0e
13 changed files with 157 additions and 75 deletions

View File

@ -388,7 +388,7 @@ the following, starting from the Avian directory:
git clone https://android.googlesource.com/platform/external/openssl \ git clone https://android.googlesource.com/platform/external/openssl \
external/openssl external/openssl
(cd external/openssl && \ (cd external/openssl && \
git checkout 7b972f1aa23172c4430ada7f3236fa1fd9b31756) git checkout 1417357d893849c4b6afdd98c32b6ca1b4b19a8b)
git clone https://android.googlesource.com/platform/external/zlib \ git clone https://android.googlesource.com/platform/external/zlib \
external/zlib external/zlib
@ -396,12 +396,11 @@ the following, starting from the Avian directory:
git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0) git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0)
git clone git://git.openssl.org/openssl.git openssl-upstream git clone git://git.openssl.org/openssl.git openssl-upstream
(cd openssl-upstream && \ (cd openssl-upstream && git checkout OpenSSL_1_0_1h)
git checkout OpenSSL_1_0_1e)
git clone https://github.com/dicej/android-libcore64 libcore git clone https://github.com/dicej/android-libcore64 libcore
curl -Of http://oss.readytalk.com/avian/expat-2.1.0.tar.gz curl -Of http://oss.readytalk.com/avian-web/expat-2.1.0.tar.gz
(cd external && tar xzf ../expat-2.1.0.tar.gz && mv expat-2.1.0 expat) (cd external && tar xzf ../expat-2.1.0.tar.gz && mv expat-2.1.0 expat)
(cd external/expat && CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure \ (cd external/expat && CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure \
@ -417,16 +416,8 @@ NB: use 'CC="gcc -fPIC" ./Configure darwin64-x86_64-cc' when building
for x86_64 OS X instead of 'CC="gcc -fPIC" ./config': for x86_64 OS X instead of 'CC="gcc -fPIC" ./config':
(cd openssl-upstream \ (cd openssl-upstream \
&& (for x in \ && (for x in ../external/openssl/patches/*.patch; \
progs \ do patch -p1 < $x; done) \
handshake_cutthrough \
jsse \
channelid \
eng_dyn_dirs \
fix_clang_build \
tls12_digests \
alpn; \
do patch -p1 < ../external/openssl/patches/$x.patch; done) \
&& CC="gcc -fPIC" ./config && make) && CC="gcc -fPIC" ./config && make)
cd ../avian cd ../avian

View File

@ -196,4 +196,7 @@ public abstract class ClassLoader {
return urls; return urls;
} }
static native Class getCaller();
static native void load(String name, Class caller, boolean mapName);
} }

View File

@ -29,7 +29,7 @@ public class Runtime {
public void load(String path) { public void load(String path) {
if (path != null) { if (path != null) {
load(path, false); ClassLoader.load(path, ClassLoader.getCaller(), false);
} else { } else {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -37,7 +37,7 @@ public class Runtime {
public void loadLibrary(String path) { public void loadLibrary(String path) {
if (path != null) { if (path != null) {
load(path, true); ClassLoader.load(path, ClassLoader.getCaller(), true);
} else { } else {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -120,8 +120,6 @@ public class Runtime {
private static native int waitFor(long pid, long tid); private static native int waitFor(long pid, long tid);
private static native void load(String name, boolean mapName);
private static native void kill(long pid); private static native void kill(long pid);
public native void gc(); public native void gc();

View File

@ -108,11 +108,11 @@ public abstract class System {
private static native String doMapLibraryName(String name); private static native String doMapLibraryName(String name);
public static void load(String path) { public static void load(String path) {
Runtime.getRuntime().load(path); ClassLoader.load(path, ClassLoader.getCaller(), false);
} }
public static void loadLibrary(String name) { public static void loadLibrary(String name) {
Runtime.getRuntime().loadLibrary(name); ClassLoader.load(name, ClassLoader.getCaller(), true);
} }
public static void gc() { public static void gc() {

View File

@ -260,6 +260,9 @@ ifneq ($(android),)
platform-lflags := -lgdi32 -lshlwapi -lwsock32 platform-lflags := -lgdi32 -lshlwapi -lwsock32
else else
android-cflags += -fPIC -DHAVE_SYS_UIO_H android-cflags += -fPIC -DHAVE_SYS_UIO_H
blacklist = $(luni-native)/java_math_NativeBN.cpp
luni-cpps := $(filter-out $(blacklist),$(luni-cpps))
icu-libs := $(android)/external/icu4c/lib/libicui18n.a \ icu-libs := $(android)/external/icu4c/lib/libicui18n.a \
$(android)/external/icu4c/lib/libicuuc.a \ $(android)/external/icu4c/lib/libicuuc.a \
$(android)/external/icu4c/lib/libicudata.a $(android)/external/icu4c/lib/libicudata.a

View File

@ -1423,11 +1423,11 @@ class Thread {
class LibraryLoadStack: public AutoResource { class LibraryLoadStack: public AutoResource {
public: public:
LibraryLoadStack(Thread* t, object class_): LibraryLoadStack(Thread* t, object classLoader)
AutoResource(t), : AutoResource(t),
next(t->libraryLoadStack), next(t->libraryLoadStack),
class_(class_), classLoader(classLoader),
protector(t, &(this->class_)) protector(t, &(this->classLoader))
{ {
t->libraryLoadStack = this; t->libraryLoadStack = this;
} }
@ -1441,7 +1441,7 @@ class Thread {
} }
LibraryLoadStack* next; LibraryLoadStack* next;
object class_; object classLoader;
SingleProtector protector; SingleProtector protector;
}; };
@ -1610,6 +1610,8 @@ class Classpath {
canTailCall(Thread* t, object caller, object calleeClassName, canTailCall(Thread* t, object caller, object calleeClassName,
object calleeMethodName, object calleeMethodSpec) = 0; object calleeMethodName, object calleeMethodSpec) = 0;
virtual object libraryClassLoader(Thread* t, object caller) = 0;
virtual void virtual void
shutDown(Thread* t) = 0; shutDown(Thread* t) = 0;

View File

@ -55,6 +55,8 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
{ {
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[1]);
Thread::LibraryLoadStack stack(t, reinterpret_cast<object>(arguments[2]));
unsigned length = stringLength(t, name); unsigned length = stringLength(t, name);
THREAD_RUNTIME_ARRAY(t, char, n, length + 1); THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n)); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
@ -568,6 +570,17 @@ class MyClasspath : public Classpath {
return true; return true;
} }
virtual object libraryClassLoader(Thread* t, object caller)
{
return strcmp(
"java/lang/Runtime",
reinterpret_cast<char*>(
&byteArrayBody(t, className(t, methodClass(t, caller)), 0)))
== 0
? t->libraryLoadStack->classLoader
: classLoader(t, methodClass(t, caller));
}
virtual void virtual void
shutDown(Thread*) shutDown(Thread*)
{ {
@ -988,6 +1001,12 @@ register_org_apache_harmony_dalvik_NativeTestTarget(_JNIEnv*)
return 0; return 0;
} }
int register_java_math_NativeBN(_JNIEnv*)
{
// ignore
return 0;
}
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_String_compareTo Avian_java_lang_String_compareTo
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)

View File

@ -179,10 +179,37 @@ class MyClasspath : public Classpath {
return fieldAtOffset<int32_t>(b, fieldOffset(t, field)); return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
} }
virtual bool virtual bool canTailCall(Thread* t,
canTailCall(Thread*, object, object, object, object) object,
object calleeClassName,
object calleeMethodName,
object)
{ {
return true; // we can't tail call System.load[Library] or
// Runtime.load[Library] due to their use of
// ClassLoader.getCaller, which gets confused if we elide stack
// frames.
return (
(strcmp("loadLibrary",
reinterpret_cast<char*>(&byteArrayBody(t, calleeMethodName, 0)))
and strcmp("load",
reinterpret_cast<char*>(
&byteArrayBody(t, calleeMethodName, 0))))
or (strcmp(
"java/lang/System",
reinterpret_cast<char*>(&byteArrayBody(t, calleeClassName, 0)))
and strcmp("java/lang/Runtime",
reinterpret_cast<char*>(
&byteArrayBody(t, calleeClassName, 0)))));
}
virtual object libraryClassLoader(Thread* t, object caller)
{
return (methodClass(t, caller) == type(t, Machine::ClassLoaderType)
and t->libraryLoadStack)
? t->libraryLoadStack->classLoader
: classLoader(t, methodClass(t, caller));
} }
virtual void virtual void
@ -550,12 +577,23 @@ Avian_java_lang_System_identityHashCode
} }
} }
extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_ClassLoader_getCaller(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<int64_t>(
getJClass(t, methodClass(t, getCaller(t, 2))));
}
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Runtime_load Avian_java_lang_ClassLoader_load(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object name = reinterpret_cast<object>(arguments[0]); object name = reinterpret_cast<object>(arguments[0]);
bool mapName = arguments[1];
Thread::LibraryLoadStack stack(
t,
classLoader(t, jclassVmClass(t, reinterpret_cast<object>(arguments[1]))));
bool mapName = arguments[2];
unsigned length = stringLength(t, name); unsigned length = stringLength(t, name);
THREAD_RUNTIME_ARRAY(t, char, n, length + 1); THREAD_RUNTIME_ARRAY(t, char, n, length + 1);

View File

@ -844,6 +844,32 @@ class MyClasspath : public Classpath {
(&byteArrayBody(t, calleeClassName, 0)))); (&byteArrayBody(t, calleeClassName, 0))));
} }
virtual object libraryClassLoader(Thread* t, object caller)
{
#ifdef AVIAN_OPENJDK_SRC
return (methodClass(t, caller) == type(t, Machine::ClassLoaderType)
and t->libraryLoadStack)
? t->libraryLoadStack->classLoader
#else
return strcmp(
"java/lang/ClassLoader$NativeLibrary",
reinterpret_cast<char*>(
&byteArrayBody(t, className(t, methodClass(t, caller)), 0)))
== 0
? classLoader(
t,
jclassVmClass(t,
t->m->processor->invoke(
t,
resolveMethod(t,
methodClass(t, caller),
"getFromClass",
"()Ljava/lang/Class;"),
0)))
#endif
: classLoader(t, methodClass(t, caller));
}
virtual void virtual void
shutDown(Thread* t) shutDown(Thread* t)
{ {
@ -1845,8 +1871,9 @@ management_JNI_OnLoad(JavaVM*, void*);
void JNICALL void JNICALL
loadLibrary(Thread* t, object, uintptr_t* arguments) loadLibrary(Thread* t, object, uintptr_t* arguments)
{ {
Thread::LibraryLoadStack stack Thread::LibraryLoadStack stack(
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))); t,
classLoader(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))));
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[1]);
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1); THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);

View File

@ -10,12 +10,6 @@
#ifdef __x86_64__ #ifdef __x86_64__
#define THREAD_CONTINUATION 2256
#define THREAD_EXCEPTION 80
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2264
#define THREAD_EXCEPTION_OFFSET 2272
#define THREAD_EXCEPTION_HANDLER 2280
#define CONTINUATION_NEXT 8 #define CONTINUATION_NEXT 8
#define CONTINUATION_ADDRESS 32 #define CONTINUATION_ADDRESS 32
#define CONTINUATION_RETURN_ADDRESS_OFFSET 40 #define CONTINUATION_RETURN_ADDRESS_OFFSET 40
@ -24,7 +18,7 @@
#define CONTINUATION_BODY 64 #define CONTINUATION_BODY 64
// call the next continuation, if any // call the next continuation, if any
movq THREAD_CONTINUATION(%rbx),%rcx movq TARGET_THREAD_CONTINUATION(%rbx),%rcx
cmpq $0,%rcx cmpq $0,%rcx
je LOCAL(vmInvoke_exit) je LOCAL(vmInvoke_exit)
@ -69,34 +63,28 @@ LOCAL(vmInvoke_continuationTest):
// consume the continuation // consume the continuation
movq CONTINUATION_NEXT(%rcx),%rdi movq CONTINUATION_NEXT(%rcx),%rdi
movq %rdi,THREAD_CONTINUATION(%rbx) movq %rdi,TARGET_THREAD_CONTINUATION(%rbx)
// call the continuation unless we're handling an exception // call the continuation unless we're handling an exception
movq THREAD_EXCEPTION(%rbx),%rsi movq TARGET_THREAD_EXCEPTION(%rbx),%rsi
cmpq $0,%rsi cmpq $0,%rsi
jne LOCAL(vmInvoke_handleException) jne LOCAL(vmInvoke_handleException)
jmp *CONTINUATION_ADDRESS(%rcx) jmp *CONTINUATION_ADDRESS(%rcx)
LOCAL(vmInvoke_handleException): LOCAL(vmInvoke_handleException):
// we're handling an exception - call the exception handler instead // we're handling an exception - call the exception handler instead
movq $0,THREAD_EXCEPTION(%rbx) movq $0,TARGET_THREAD_EXCEPTION(%rbx)
movq THREAD_EXCEPTION_STACK_ADJUSTMENT(%rbx),%rdi movq TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%rbx),%rdi
subq %rdi,%rsp subq %rdi,%rsp
movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi movq TARGET_THREAD_EXCEPTIONOFFSET(%rbx),%rdi
movq %rsi,(%rsp,%rdi,1) movq %rsi,(%rsp,%rdi,1)
jmp *THREAD_EXCEPTION_HANDLER(%rbx) jmp *TARGET_THREAD_EXCEPTIONHANDLER(%rbx)
LOCAL(vmInvoke_exit): LOCAL(vmInvoke_exit):
#elif defined __i386__ #elif defined __i386__
#define THREAD_CONTINUATION 2164
#define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2168
#define THREAD_EXCEPTION_OFFSET 2172
#define THREAD_EXCEPTION_HANDLER 2176
#define CONTINUATION_NEXT 4 #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16 #define CONTINUATION_ADDRESS 16
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20 #define CONTINUATION_RETURN_ADDRESS_OFFSET 20
@ -111,7 +99,7 @@ LOCAL(vmInvoke_exit):
#endif #endif
// call the next continuation, if any // call the next continuation, if any
movl THREAD_CONTINUATION(%ebx),%ecx movl TARGET_THREAD_CONTINUATION(%ebx),%ecx
cmpl $0,%ecx cmpl $0,%ecx
je LOCAL(vmInvoke_exit) je LOCAL(vmInvoke_exit)
@ -169,10 +157,10 @@ LOCAL(vmInvoke_offset):
// consume the continuation // consume the continuation
movl CONTINUATION_NEXT(%ecx),%edi movl CONTINUATION_NEXT(%ecx),%edi
movl %edi,THREAD_CONTINUATION(%ebx) movl %edi,TARGET_THREAD_CONTINUATION(%ebx)
// call the continuation unless we're handling an exception // call the continuation unless we're handling an exception
movl THREAD_EXCEPTION(%ebx),%esi movl TARGET_THREAD_EXCEPTION(%ebx),%esi
cmpl $0,%esi cmpl $0,%esi
jne LOCAL(vmInvoke_handleException) jne LOCAL(vmInvoke_handleException)
@ -180,13 +168,13 @@ LOCAL(vmInvoke_offset):
LOCAL(vmInvoke_handleException): LOCAL(vmInvoke_handleException):
// we're handling an exception - call the exception handler instead // we're handling an exception - call the exception handler instead
movl $0,THREAD_EXCEPTION(%ebx) movl $0,TARGET_THREAD_EXCEPTION(%ebx)
movl THREAD_EXCEPTION_STACK_ADJUSTMENT(%ebx),%edi movl TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%ebx),%edi
subl %edi,%esp subl %edi,%esp
movl THREAD_EXCEPTION_OFFSET(%ebx),%edi movl TARGET_THREAD_EXCEPTIONOFFSET(%ebx),%edi
movl %esi,(%esp,%edi,1) movl %esi,(%esp,%edi,1)
jmp *THREAD_EXCEPTION_HANDLER(%ebx) jmp *TARGET_THREAD_EXCEPTIONHANDLER(%ebx)
LOCAL(vmInvoke_exit): LOCAL(vmInvoke_exit):

View File

@ -349,20 +349,11 @@ findClass(Thread* t, uintptr_t* arguments)
object caller = getCaller(t, 0); object caller = getCaller(t, 0);
object loader; object c
if (caller) { = resolveClass(t,
if (methodClass(t, caller) == type(t, Machine::ClassLoaderType) caller ? t->m->classpath->libraryClassLoader(t, caller)
and t->libraryLoadStack) : root(t, Machine::AppLoader),
{ n);
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()) { if (t->m->classpath->mayInitClasses()) {
PROTECT(t, c); PROTECT(t, c);

View File

@ -3,6 +3,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
public class JNI { public class JNI {
private static boolean onLoadCalled;
static { static {
System.loadLibrary("test"); System.loadLibrary("test");
} }
@ -64,6 +66,8 @@ public class JNI {
public static final int field950 = 950; public static final int field950 = 950;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
expect(onLoadCalled);
expect(addDoubles expect(addDoubles
(1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d, (1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d,
12.0d, 13.0d, 14.0d, 15.0d, 16.0d, 17.0d, 18.0d, 19.0d, 20.0d) 12.0d, 13.0d, 14.0d, 15.0d, 16.0d, 17.0d, 18.0d, 19.0d, 20.0d)

View File

@ -1,6 +1,24 @@
#include <jni.h> #include <jni.h>
#include "jni-util.h" #include "jni-util.h"
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
JNIEnv* e;
if (vm->GetEnv(reinterpret_cast<void**>(&e), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
jclass c = e->FindClass("JNI");
if (c == 0) {
return -1;
}
e->SetStaticBooleanField(
c, e->GetStaticFieldID(c, "onLoadCalled", "Z"), true);
return JNI_VERSION_1_6;
}
extern "C" JNIEXPORT jdouble JNICALL extern "C" JNIEXPORT jdouble JNICALL
Java_JNI_addDoubles Java_JNI_addDoubles
(JNIEnv*, jclass, (JNIEnv*, jclass,