OSDN Git Service

Improve library lookup logic
authorDmitriy Ivanov <dimitry@google.com>
Tue, 16 Jun 2015 22:38:21 +0000 (15:38 -0700)
committerDmitriy Ivanov <dimitry@google.com>
Wed, 17 Jun 2015 17:18:28 +0000 (10:18 -0700)
Linker tries to open a library even if it can
be found by soname. This only happens if the
library was previously opened under different
target sdk version.

Bug: http://b/21876587
Bug: http://b/21153477
Bug: http://b/21171302
Bug: https://code.google.com/p/android/issues/detail?id=160921
Change-Id: I769a04b6b1368a107d43f399297be14050338bbc
(cherry picked from commit ea4ef52fa46602a5853df0e5b1ddd71b194d54ce)

linker/linker.cpp
linker/linker_sdk_versions.cpp

index 8480ab7..ee4f2d4 100644 (file)
@@ -1393,7 +1393,19 @@ static soinfo *find_loaded_library_by_soname(const char* name) {
     return nullptr;
   }
 
+  uint32_t target_sdk_version = get_application_target_sdk_version();
+
   for (soinfo* si = solist; si != nullptr; si = si->next) {
+    // If the library was opened under different target sdk version
+    // skip this step and try to reopen it. The exceptions are
+    // "libdl.so" and global group. There is no point in skipping
+    // them because relocation process is going to use them
+    // in any case.
+    if (si != solist && (si->get_dt_flags_1() & DF_1_GLOBAL) == 0 &&
+        si->is_linked() && si->get_target_sdk_version() != target_sdk_version) {
+      continue;
+    }
+
     const char* soname = si->get_soname();
     if (soname != nullptr && (strcmp(name, soname) == 0)) {
       return si;
index e9ad3dc..9aebb06 100644 (file)
 static std::atomic<uint32_t> g_target_sdk_version(__ANDROID_API__);
 
 void set_application_target_sdk_version(uint32_t target) {
+  // translate current sdk_version to platform sdk_version
+  if (target == 0) {
+    target = __ANDROID_API__;
+  }
   g_target_sdk_version = target;
 }