From 460de9a33e8e8ed2bc5a55d0b536610f5c4b408b Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 10 Jun 2024 17:44:22 +0200 Subject: [PATCH 1/7] [android] Don't include `JNI_OnLoad` in `libSystem.Security.Cryptography.Native.Android.a` I'm working on a feature in .NET For Android which will allow us to link all the native bits into a single shared library at application build time. In order to make it possible, no archive (`.a`) may contain any `JNI_OnLoad` functions (called by `JavaVM` when initializing a Java extension DSO), because our runtime already contains one and there Can be Only One(tm). `libSystem.Security.Cryptography.Native.Android` is currently the only BCL support native library which contains `JNI_OnLoad` and thus it prevents us from linking it into our runtime. This PR changes things a bit my moving the initialization code to a separate function (`init_library_on_load`) which remains in the `.a` archive and can be called by `.NET For Android` runtime from its own `JNI_OnLoad` as well as by the `libSystem.Security.Cryptography.Native.Android.so` from its `JNI_OnLoad`, which this PR moves to a separate source file that is compiled only into the shared version of the crypto support library. --- .../CMakeLists.txt | 2 +- .../System.Security.Cryptography.Native.Android/pal_jni.c | 3 +-- .../System.Security.Cryptography.Native.Android/pal_jni.h | 1 + .../pal_jni_onload.c | 7 +++++++ 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/CMakeLists.txt b/src/native/libs/System.Security.Cryptography.Native.Android/CMakeLists.txt index a277d5df3e5bd..f87db8a8c75b6 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/CMakeLists.txt +++ b/src/native/libs/System.Security.Cryptography.Native.Android/CMakeLists.txt @@ -33,7 +33,7 @@ set(NATIVECRYPTO_SOURCES add_library(System.Security.Cryptography.Native.Android SHARED - ${NATIVECRYPTO_SOURCES} + ${NATIVECRYPTO_SOURCES} pal_jni_onload.c ${VERSION_FILE_PATH} ) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index 243dbd1d9466d..d2ad1ccd45cf0 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -689,8 +689,7 @@ int GetEnumAsInt(JNIEnv *env, jobject enumObj) return value; } -JNIEXPORT jint JNICALL -JNI_OnLoad(JavaVM *vm, void *reserved) +jint init_library_on_load (JavaVM *vm, void *reserved) { (void)reserved; LOG_INFO("JNI_OnLoad in pal_jni.c"); diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h index 79bc888224629..c109c0bd1a1b1 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h @@ -604,6 +604,7 @@ jmethodID GetOptionalMethod(JNIEnv *env, bool isStatic, jclass klass, const char jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; JNIEnv* GetJNIEnv(void); +jint init_library_on_load (JavaVM *vm, void *reserved); int GetEnumAsInt(JNIEnv *env, jobject enumObj) ARGS_NON_NULL_ALL; diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c new file mode 100644 index 0000000000000..b601470aa9339 --- /dev/null +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c @@ -0,0 +1,7 @@ +#include "pal_jni.h" + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved) +{ + return init_library_on_load (vm, reserved); +} From 17806dc70dce76b098bafcc48947712645001669 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 10 Jun 2024 21:32:51 +0200 Subject: [PATCH 2/7] Address feedback --- .../libs/System.Security.Cryptography.Native.Android/pal_jni.c | 2 +- .../libs/System.Security.Cryptography.Native.Android/pal_jni.h | 2 +- .../pal_jni_onload.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index d2ad1ccd45cf0..a506e8712a0a0 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -689,7 +689,7 @@ int GetEnumAsInt(JNIEnv *env, jobject enumObj) return value; } -jint init_library_on_load (JavaVM *vm, void *reserved) +jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved) { (void)reserved; LOG_INFO("JNI_OnLoad in pal_jni.c"); diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h index c109c0bd1a1b1..ce5ff95fa2fda 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h @@ -604,7 +604,7 @@ jmethodID GetOptionalMethod(JNIEnv *env, bool isStatic, jclass klass, const char jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; JNIEnv* GetJNIEnv(void); -jint init_library_on_load (JavaVM *vm, void *reserved); +jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved); int GetEnumAsInt(JNIEnv *env, jobject enumObj) ARGS_NON_NULL_ALL; diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c index b601470aa9339..353b9b27b4d76 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c @@ -3,5 +3,5 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - return init_library_on_load (vm, reserved); + return AndroidCryptoNative_InitLibraryOnLoad (vm, reserved); } From 915ebe7fb38964969482614daddc919725a1d37f Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 11 Jun 2024 10:23:06 +0000 Subject: [PATCH 3/7] Update src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Köplinger --- .../pal_jni_onload.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c index 353b9b27b4d76..e2ecc9f3b8aa5 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni_onload.c @@ -1,3 +1,6 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + #include "pal_jni.h" JNIEXPORT jint JNICALL From f21ae0bff57bdfc1e0f1d9e6db9244c15e7f36ca Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 11 Jun 2024 12:25:41 +0200 Subject: [PATCH 4/7] Add explanatory comment --- .../System.Security.Cryptography.Native.Android/pal_jni.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h index ce5ff95fa2fda..5f7d7c002c414 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h @@ -604,6 +604,10 @@ jmethodID GetOptionalMethod(JNIEnv *env, bool isStatic, jclass klass, const char jfieldID GetField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; jfieldID GetOptionalField(JNIEnv *env, bool isStatic, jclass klass, const char* name, const char* sig) ARGS_NON_NULL_ALL; JNIEnv* GetJNIEnv(void); + +// This is supposed to be called by embedders who link the **static** archive of this library. +// The function must be called from the embedder's `JNI_OnLoad` function prior to using any +// APIs in this library. jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved); int GetEnumAsInt(JNIEnv *env, jobject enumObj) ARGS_NON_NULL_ALL; From b850666e9b5ab594205afcb20eda9b9067b3da8b Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 11 Jun 2024 12:26:33 +0200 Subject: [PATCH 5/7] Log in debug severity, not info, logcat is expensive --- .../libs/System.Security.Cryptography.Native.Android/pal_jni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index a506e8712a0a0..49e82e1ccc525 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -692,7 +692,7 @@ int GetEnumAsInt(JNIEnv *env, jobject enumObj) jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved) { (void)reserved; - LOG_INFO("JNI_OnLoad in pal_jni.c"); + LOG_DEBUG("JNI_OnLoad in pal_jni.c"); gJvm = vm; JNIEnv* env = GetJNIEnv(); From 3de32bd81c6a8ebfa26bd4283ceff91f1be994ed Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 11 Jun 2024 12:27:44 +0200 Subject: [PATCH 6/7] Following Simon's suggestion, make the message more accurate --- .../libs/System.Security.Cryptography.Native.Android/pal_jni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index 49e82e1ccc525..34a881971c100 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -692,7 +692,7 @@ int GetEnumAsInt(JNIEnv *env, jobject enumObj) jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved) { (void)reserved; - LOG_DEBUG("JNI_OnLoad in pal_jni.c"); + LOG_DEBUG(__PRETTY_FUNCTION__); gJvm = vm; JNIEnv* env = GetJNIEnv(); From e212ed4f42d623b07a39c4f459b51da3d32a1960 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 11 Jun 2024 12:30:39 +0200 Subject: [PATCH 7/7] Prettier --- .../libs/System.Security.Cryptography.Native.Android/pal_jni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c index 34a881971c100..ee31a3ac58d64 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c @@ -692,7 +692,7 @@ int GetEnumAsInt(JNIEnv *env, jobject enumObj) jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved) { (void)reserved; - LOG_DEBUG(__PRETTY_FUNCTION__); + LOG_DEBUG("%s in %s", __PRETTY_FUNCTION__, __FILE__); gJvm = vm; JNIEnv* env = GetJNIEnv();