diff options
author | 2021-10-11 19:09:00 -0700 | |
---|---|---|
committer | 2021-10-26 17:36:32 +0000 | |
commit | 9c924e89e5f52da9faadd1e4e60c73eaed6bc9d1 (patch) | |
tree | 8ffdc7f0c144cb392b50144a9ae9cb4ac4d3cca7 /runtime/class_linker.cc | |
parent | d690f8ae8f8e2675bc52089a83ac18c749f8e6d2 (diff) |
Add support to place shared libraries after the dex path
This allows for a shared library to overriden by content in the dex path
Bug: 179429740
Test: m test-art-host-gtest-art_runtime_tests32
Change-Id: I5f69c7bf32b7bd389eff8bdbb21616ba89ed9e87
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 0d50dd3bd5..4875298e68 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2612,6 +2612,16 @@ bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable& /*out*/ ObjPtr<mirror::Class>* result) { ArtField* field = jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); + return FindClassInSharedLibrariesHelper(soa, self, descriptor, hash, class_loader, field, result); +} + +bool ClassLinker::FindClassInSharedLibrariesHelper(ScopedObjectAccessAlreadyRunnable& soa, + Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader, + ArtField* field, + /*out*/ ObjPtr<mirror::Class>* result) { ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader.Get()); if (raw_shared_libraries == nullptr) { return true; @@ -2631,6 +2641,17 @@ bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable& return true; } +bool ClassLinker::FindClassInSharedLibrariesAfter(ScopedObjectAccessAlreadyRunnable& soa, + Thread* self, + const char* descriptor, + size_t hash, + Handle<mirror::ClassLoader> class_loader, + /*out*/ ObjPtr<mirror::Class>* result) { + ArtField* field = jni::DecodeArtField( + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter); + return FindClassInSharedLibrariesHelper(soa, self, descriptor, hash, class_loader, field, result); +} + bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa, Thread* self, const char* descriptor, @@ -2665,6 +2686,10 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader, result), *result, self); + RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION( + FindClassInSharedLibrariesAfter(soa, self, descriptor, hash, class_loader, result), + *result, + self); // We did not find a class, but the class loader chain was recognized, so we // return true. return true; @@ -2686,6 +2711,10 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader, result), *result, self); + RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION( + FindClassInSharedLibrariesAfter(soa, self, descriptor, hash, class_loader, result), + *result, + self); // Create a handle as RegisterDexFile may allocate dex caches (and cause thread suspension). StackHandleScope<1> hs(self); @@ -9839,7 +9868,8 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( const std::vector<const DexFile*>& dex_files, Handle<mirror::Class> loader_class, Handle<mirror::ClassLoader> parent_loader, - Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries) { + Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries, + Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_after) { StackHandleScope<5> hs(self); @@ -9959,6 +9989,12 @@ ObjPtr<mirror::ClassLoader> ClassLinker::CreateWellKnownClassLoader( DCHECK(shared_libraries_field != nullptr); shared_libraries_field->SetObject<false>(h_class_loader.Get(), shared_libraries.Get()); + ArtField* shared_libraries_after_field = + jni::DecodeArtField( + WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter); + DCHECK(shared_libraries_after_field != nullptr); + shared_libraries_after_field->SetObject<false>(h_class_loader.Get(), + shared_libraries_after.Get()); return h_class_loader.Get(); } @@ -9966,7 +10002,8 @@ jobject ClassLinker::CreateWellKnownClassLoader(Thread* self, const std::vector<const DexFile*>& dex_files, jclass loader_class, jobject parent_loader, - jobject shared_libraries) { + jobject shared_libraries, + jobject shared_libraries_after) { CHECK(self->GetJniEnv()->IsSameObject(loader_class, WellKnownClasses::dalvik_system_PathClassLoader) || self->GetJniEnv()->IsSameObject(loader_class, @@ -9979,7 +10016,7 @@ jobject ClassLinker::CreateWellKnownClassLoader(Thread* self, ScopedObjectAccessUnchecked soa(self); // For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex. - StackHandleScope<4> hs(self); + StackHandleScope<5> hs(self); Handle<mirror::Class> h_loader_class = hs.NewHandle<mirror::Class>(soa.Decode<mirror::Class>(loader_class)); @@ -9987,13 +10024,16 @@ jobject ClassLinker::CreateWellKnownClassLoader(Thread* self, hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(parent_loader)); Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries)); + Handle<mirror::ObjectArray<mirror::ClassLoader>> h_shared_libraries_after = + hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::ClassLoader>>(shared_libraries_after)); ObjPtr<mirror::ClassLoader> loader = CreateWellKnownClassLoader( self, dex_files, h_loader_class, h_parent, - h_shared_libraries); + h_shared_libraries, + h_shared_libraries_after); // Make it a global ref and return. ScopedLocalRef<jobject> local_ref( |