Pass the Java caller's location to OpenNativeLibrary.

Will be used to find the linker namespace to use.

Bug: 122874359
Test: m, gtest, run-test, CtsJdwpTests

Change-Id: Ibeebe20844e2bbdc306d65fb4f2ee3237343fa09
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 3c68389..ce987c1 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -659,7 +659,7 @@
 
   std::string reason;
   ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
-                  LoadNativeLibrary(env_, "", class_loader_, &reason))
+                  LoadNativeLibrary(env_, "", class_loader_, nullptr, &reason))
       << reason;
 
   jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 24);
@@ -675,7 +675,7 @@
 
   std::string reason;
   ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
-                  LoadNativeLibrary(env_, "", class_loader_, &reason))
+                  LoadNativeLibrary(env_, "", class_loader_, nullptr, &reason))
       << reason;
 
   jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 42);
diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc
index b2c4bb7..8297c54 100644
--- a/openjdkjvm/OpenjdkJvm.cc
+++ b/openjdkjvm/OpenjdkJvm.cc
@@ -318,7 +318,8 @@
 
 JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env,
                                  jstring javaFilename,
-                                 jobject javaLoader) {
+                                 jobject javaLoader,
+                                 jclass caller) {
   ScopedUtfChars filename(env, javaFilename);
   if (filename.c_str() == nullptr) {
     return nullptr;
@@ -330,6 +331,7 @@
     bool success = vm->LoadNativeLibrary(env,
                                          filename.c_str(),
                                          javaLoader,
+                                         caller,
                                          &error_msg);
     if (success) {
       return nullptr;
diff --git a/runtime/jni/java_vm_ext.cc b/runtime/jni/java_vm_ext.cc
index e7b244b..e54b807 100644
--- a/runtime/jni/java_vm_ext.cc
+++ b/runtime/jni/java_vm_ext.cc
@@ -857,6 +857,7 @@
 bool JavaVMExt::LoadNativeLibrary(JNIEnv* env,
                                   const std::string& path,
                                   jobject class_loader,
+                                  jclass caller_class,
                                   std::string* error_msg) {
   error_msg->clear();
 
@@ -872,6 +873,7 @@
     library = libraries_->Get(path);
   }
   void* class_loader_allocator = nullptr;
+  std::string caller_location;
   {
     ScopedObjectAccess soa(env);
     // As the incoming class loader is reachable/alive during the call of this function,
@@ -882,6 +884,13 @@
     if (class_linker->IsBootClassLoader(soa, loader.Ptr())) {
       loader = nullptr;
       class_loader = nullptr;
+      if (caller_class != nullptr) {
+        ObjPtr<mirror::Class> caller = soa.Decode<mirror::Class>(caller_class);
+        ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
+        if (dex_cache != nullptr) {
+          caller_location = dex_cache->GetLocation()->ToModifiedUtf8();
+        }
+      }
     }
 
     class_loader_allocator = class_linker->GetAllocatorForClassLoader(loader.Ptr());
@@ -964,13 +973,15 @@
   const char* path_str = path.empty() ? nullptr : path.c_str();
   bool needs_native_bridge = false;
   char* nativeloader_error_msg = nullptr;
-  void* handle = android::OpenNativeLibrary(env,
-                                            runtime_->GetTargetSdkVersion(),
-                                            path_str,
-                                            class_loader,
-                                            library_path.get(),
-                                            &needs_native_bridge,
-                                            &nativeloader_error_msg);
+  void* handle = android::OpenNativeLibrary(
+      env,
+      runtime_->GetTargetSdkVersion(),
+      path_str,
+      class_loader,
+      (caller_location.empty() ? nullptr : caller_location.c_str()),
+      library_path.get(),
+      &needs_native_bridge,
+      &nativeloader_error_msg);
   VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_NOW) returned " << handle << "]";
 
   if (handle == nullptr) {
diff --git a/runtime/jni/java_vm_ext.h b/runtime/jni/java_vm_ext.h
index 408d354..424dd7c 100644
--- a/runtime/jni/java_vm_ext.h
+++ b/runtime/jni/java_vm_ext.h
@@ -101,6 +101,7 @@
   bool LoadNativeLibrary(JNIEnv* env,
                          const std::string& path,
                          jobject class_loader,
+                         jclass caller_class,
                          std::string* error_msg);
 
   // Unload native libraries with cleared class loaders.
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index d79793b..d537de5 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1746,7 +1746,7 @@
   // libcore can't because it's the library that implements System.loadLibrary!
   {
     std::string error_msg;
-    if (!java_vm_->LoadNativeLibrary(env, "libjavacore.so", nullptr, &error_msg)) {
+    if (!java_vm_->LoadNativeLibrary(env, "libjavacore.so", nullptr, nullptr, &error_msg)) {
       LOG(FATAL) << "LoadNativeLibrary failed for \"libjavacore.so\": " << error_msg;
     }
   }
@@ -1755,7 +1755,7 @@
                                                 ? "libopenjdkd.so"
                                                 : "libopenjdk.so";
     std::string error_msg;
-    if (!java_vm_->LoadNativeLibrary(env, kOpenJdkLibrary, nullptr, &error_msg)) {
+    if (!java_vm_->LoadNativeLibrary(env, kOpenJdkLibrary, nullptr, nullptr, &error_msg)) {
       LOG(FATAL) << "LoadNativeLibrary failed for \"" << kOpenJdkLibrary << "\": " << error_msg;
     }
   }
diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc
index bd53958..cdfe727 100644
--- a/runtime/ti/agent.cc
+++ b/runtime/ti/agent.cc
@@ -123,6 +123,7 @@
                                                    Runtime::Current()->GetTargetSdkVersion(),
                                                    name_.c_str(),
                                                    class_loader,
+                                                   nullptr,
                                                    library_path.get(),
                                                    &needs_native_bridge,
                                                    &nativeloader_error_msg);
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index a19cc92..f61faa3 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -426,7 +426,7 @@
   // to make sure these JNI methods are available.
   java_lang_Runtime_nativeLoad =
       CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad",
-                  "(Ljava/lang/String;Ljava/lang/ClassLoader;)"
+                  "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Class;)"
                       "Ljava/lang/String;");
   java_lang_reflect_Proxy_init =
     CacheMethod(env, java_lang_reflect_Proxy, false, "<init>",