mirror of
https://github.com/corda/corda.git
synced 2025-01-01 02:36:44 +00:00
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:
parent
735eaaba21
commit
5d3c612d0e
19
README.md
19
README.md
@ -388,7 +388,7 @@ the following, starting from the Avian directory:
|
||||
git clone https://android.googlesource.com/platform/external/openssl \
|
||||
external/openssl
|
||||
(cd external/openssl && \
|
||||
git checkout 7b972f1aa23172c4430ada7f3236fa1fd9b31756)
|
||||
git checkout 1417357d893849c4b6afdd98c32b6ca1b4b19a8b)
|
||||
|
||||
git clone https://android.googlesource.com/platform/external/zlib \
|
||||
external/zlib
|
||||
@ -396,12 +396,11 @@ the following, starting from the Avian directory:
|
||||
git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0)
|
||||
|
||||
git clone git://git.openssl.org/openssl.git openssl-upstream
|
||||
(cd openssl-upstream && \
|
||||
git checkout OpenSSL_1_0_1e)
|
||||
(cd openssl-upstream && git checkout OpenSSL_1_0_1h)
|
||||
|
||||
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/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':
|
||||
|
||||
(cd openssl-upstream \
|
||||
&& (for x in \
|
||||
progs \
|
||||
handshake_cutthrough \
|
||||
jsse \
|
||||
channelid \
|
||||
eng_dyn_dirs \
|
||||
fix_clang_build \
|
||||
tls12_digests \
|
||||
alpn; \
|
||||
do patch -p1 < ../external/openssl/patches/$x.patch; done) \
|
||||
&& (for x in ../external/openssl/patches/*.patch; \
|
||||
do patch -p1 < $x; done) \
|
||||
&& CC="gcc -fPIC" ./config && make)
|
||||
|
||||
cd ../avian
|
||||
|
@ -195,5 +195,8 @@ public abstract class ClassLoader {
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
static native Class getCaller();
|
||||
|
||||
static native void load(String name, Class caller, boolean mapName);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class Runtime {
|
||||
|
||||
public void load(String path) {
|
||||
if (path != null) {
|
||||
load(path, false);
|
||||
ClassLoader.load(path, ClassLoader.getCaller(), false);
|
||||
} else {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@ -37,7 +37,7 @@ public class Runtime {
|
||||
|
||||
public void loadLibrary(String path) {
|
||||
if (path != null) {
|
||||
load(path, true);
|
||||
ClassLoader.load(path, ClassLoader.getCaller(), true);
|
||||
} else {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@ -120,8 +120,6 @@ public class Runtime {
|
||||
|
||||
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);
|
||||
|
||||
public native void gc();
|
||||
|
@ -108,11 +108,11 @@ public abstract class System {
|
||||
private static native String doMapLibraryName(String name);
|
||||
|
||||
public static void load(String path) {
|
||||
Runtime.getRuntime().load(path);
|
||||
ClassLoader.load(path, ClassLoader.getCaller(), false);
|
||||
}
|
||||
|
||||
public static void loadLibrary(String name) {
|
||||
Runtime.getRuntime().loadLibrary(name);
|
||||
ClassLoader.load(name, ClassLoader.getCaller(), true);
|
||||
}
|
||||
|
||||
public static void gc() {
|
||||
|
3
makefile
3
makefile
@ -260,6 +260,9 @@ ifneq ($(android),)
|
||||
platform-lflags := -lgdi32 -lshlwapi -lwsock32
|
||||
else
|
||||
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 \
|
||||
$(android)/external/icu4c/lib/libicuuc.a \
|
||||
$(android)/external/icu4c/lib/libicudata.a
|
||||
|
@ -1423,11 +1423,11 @@ class Thread {
|
||||
|
||||
class LibraryLoadStack: public AutoResource {
|
||||
public:
|
||||
LibraryLoadStack(Thread* t, object class_):
|
||||
AutoResource(t),
|
||||
next(t->libraryLoadStack),
|
||||
class_(class_),
|
||||
protector(t, &(this->class_))
|
||||
LibraryLoadStack(Thread* t, object classLoader)
|
||||
: AutoResource(t),
|
||||
next(t->libraryLoadStack),
|
||||
classLoader(classLoader),
|
||||
protector(t, &(this->classLoader))
|
||||
{
|
||||
t->libraryLoadStack = this;
|
||||
}
|
||||
@ -1441,7 +1441,7 @@ class Thread {
|
||||
}
|
||||
|
||||
LibraryLoadStack* next;
|
||||
object class_;
|
||||
object classLoader;
|
||||
SingleProtector protector;
|
||||
};
|
||||
|
||||
@ -1610,6 +1610,8 @@ class Classpath {
|
||||
canTailCall(Thread* t, object caller, object calleeClassName,
|
||||
object calleeMethodName, object calleeMethodSpec) = 0;
|
||||
|
||||
virtual object libraryClassLoader(Thread* t, object caller) = 0;
|
||||
|
||||
virtual void
|
||||
shutDown(Thread* t) = 0;
|
||||
|
||||
|
@ -55,6 +55,8 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object name = reinterpret_cast<object>(arguments[1]);
|
||||
|
||||
Thread::LibraryLoadStack stack(t, reinterpret_cast<object>(arguments[2]));
|
||||
|
||||
unsigned length = stringLength(t, name);
|
||||
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
|
||||
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||
@ -568,6 +570,17 @@ class MyClasspath : public Classpath {
|
||||
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
|
||||
shutDown(Thread*)
|
||||
{
|
||||
@ -988,6 +1001,12 @@ register_org_apache_harmony_dalvik_NativeTestTarget(_JNIEnv*)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int register_java_math_NativeBN(_JNIEnv*)
|
||||
{
|
||||
// ignore
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||
Avian_java_lang_String_compareTo
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
|
@ -179,10 +179,37 @@ class MyClasspath : public Classpath {
|
||||
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
|
||||
}
|
||||
|
||||
virtual bool
|
||||
canTailCall(Thread*, object, object, object, object)
|
||||
virtual bool canTailCall(Thread* t,
|
||||
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
|
||||
@ -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
|
||||
Avian_java_lang_Runtime_load
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
Avian_java_lang_ClassLoader_load(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
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);
|
||||
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
|
||||
|
@ -844,6 +844,32 @@ class MyClasspath : public Classpath {
|
||||
(&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
|
||||
shutDown(Thread* t)
|
||||
{
|
||||
@ -1845,8 +1871,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])));
|
||||
Thread::LibraryLoadStack stack(
|
||||
t,
|
||||
classLoader(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);
|
||||
|
@ -10,12 +10,6 @@
|
||||
|
||||
#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_ADDRESS 32
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 40
|
||||
@ -24,7 +18,7 @@
|
||||
#define CONTINUATION_BODY 64
|
||||
|
||||
// call the next continuation, if any
|
||||
movq THREAD_CONTINUATION(%rbx),%rcx
|
||||
movq TARGET_THREAD_CONTINUATION(%rbx),%rcx
|
||||
cmpq $0,%rcx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
@ -69,34 +63,28 @@ LOCAL(vmInvoke_continuationTest):
|
||||
|
||||
// consume the continuation
|
||||
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
|
||||
movq THREAD_EXCEPTION(%rbx),%rsi
|
||||
movq TARGET_THREAD_EXCEPTION(%rbx),%rsi
|
||||
cmpq $0,%rsi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
jmp *CONTINUATION_ADDRESS(%rcx)
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movq $0,THREAD_EXCEPTION(%rbx)
|
||||
movq THREAD_EXCEPTION_STACK_ADJUSTMENT(%rbx),%rdi
|
||||
movq $0,TARGET_THREAD_EXCEPTION(%rbx)
|
||||
movq TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%rbx),%rdi
|
||||
subq %rdi,%rsp
|
||||
movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi
|
||||
movq TARGET_THREAD_EXCEPTIONOFFSET(%rbx),%rdi
|
||||
movq %rsi,(%rsp,%rdi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%rbx)
|
||||
jmp *TARGET_THREAD_EXCEPTIONHANDLER(%rbx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
|
||||
#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_ADDRESS 16
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20
|
||||
@ -111,7 +99,7 @@ LOCAL(vmInvoke_exit):
|
||||
#endif
|
||||
|
||||
// call the next continuation, if any
|
||||
movl THREAD_CONTINUATION(%ebx),%ecx
|
||||
movl TARGET_THREAD_CONTINUATION(%ebx),%ecx
|
||||
cmpl $0,%ecx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
@ -169,10 +157,10 @@ LOCAL(vmInvoke_offset):
|
||||
|
||||
// consume the continuation
|
||||
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
|
||||
movl THREAD_EXCEPTION(%ebx),%esi
|
||||
movl TARGET_THREAD_EXCEPTION(%ebx),%esi
|
||||
cmpl $0,%esi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
|
||||
@ -180,13 +168,13 @@ LOCAL(vmInvoke_offset):
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movl $0,THREAD_EXCEPTION(%ebx)
|
||||
movl THREAD_EXCEPTION_STACK_ADJUSTMENT(%ebx),%edi
|
||||
movl $0,TARGET_THREAD_EXCEPTION(%ebx)
|
||||
movl TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%ebx),%edi
|
||||
subl %edi,%esp
|
||||
movl THREAD_EXCEPTION_OFFSET(%ebx),%edi
|
||||
movl TARGET_THREAD_EXCEPTIONOFFSET(%ebx),%edi
|
||||
movl %esi,(%esp,%edi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%ebx)
|
||||
jmp *TARGET_THREAD_EXCEPTIONHANDLER(%ebx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
|
||||
|
@ -349,20 +349,11 @@ findClass(Thread* t, uintptr_t* arguments)
|
||||
|
||||
object caller = getCaller(t, 0);
|
||||
|
||||
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);
|
||||
object c
|
||||
= resolveClass(t,
|
||||
caller ? t->m->classpath->libraryClassLoader(t, caller)
|
||||
: root(t, Machine::AppLoader),
|
||||
n);
|
||||
|
||||
if (t->m->classpath->mayInitClasses()) {
|
||||
PROTECT(t, c);
|
||||
|
@ -3,6 +3,8 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class JNI {
|
||||
private static boolean onLoadCalled;
|
||||
|
||||
static {
|
||||
System.loadLibrary("test");
|
||||
}
|
||||
@ -64,6 +66,8 @@ public class JNI {
|
||||
public static final int field950 = 950;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
expect(onLoadCalled);
|
||||
|
||||
expect(addDoubles
|
||||
(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)
|
||||
|
18
test/jni.cpp
18
test/jni.cpp
@ -1,6 +1,24 @@
|
||||
#include <jni.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
|
||||
Java_JNI_addDoubles
|
||||
(JNIEnv*, jclass,
|
||||
|
Loading…
Reference in New Issue
Block a user