diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2015-05-27 18:29:41 -0700 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2015-05-28 15:25:55 -0700 |
commit | 4a7c3af054fdb525c8e458434f57f20696f43e31 (patch) | |
tree | 50b18bbc6677318071ef2627a4e9b7fd9809d137 /linker | |
parent | d8ead18145cba98fdc7256f9a0e69b8c1c90cd1c (diff) | |
download | bionic-4a7c3af054fdb525c8e458434f57f20696f43e31.zip bionic-4a7c3af054fdb525c8e458434f57f20696f43e31.tar.gz bionic-4a7c3af054fdb525c8e458434f57f20696f43e31.tar.bz2 |
Work around incorrect dt_needed entries
This applies for apps targeting sdk<=22 and
only for lp32 platforms.
Bug: http://b/21364029
Change-Id: I903e81c9ccda2a8beaba1d132d68c77d30a4cdb2
(cherry picked from commit d974e8804689058714dc4fe9adcb57ee9a6996a8)
Diffstat (limited to 'linker')
-rw-r--r-- | linker/dlfcn.cpp | 2 | ||||
-rw-r--r-- | linker/linker.cpp | 18 |
2 files changed, 19 insertions, 1 deletions
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp index 8fafded..8705d9a 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -158,6 +158,8 @@ int dlclose(void* handle) { } void android_set_application_target_sdk_version(uint32_t target) { + // lock to avoid modification in the middle of dlopen. + ScopedPthreadMutexLocker locker(&g_dl_mutex); set_application_target_sdk_version(target); } diff --git a/linker/linker.cpp b/linker/linker.cpp index f3ca761..e8bebff 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1215,11 +1215,27 @@ static int open_library(const char* name, off64_t* file_offset) { return fd; } +static const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) { +#if !defined(__LP64__) + // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029 + uint32_t target_sdk_version = get_application_target_sdk_version(); + if (target_sdk_version != 0 && target_sdk_version <= 22) { + const char* bname = basename(dt_needed); + if (bname != dt_needed) { + DL_WARN("'%s' library has invalid DT_NEEDED entry '%s'", sopath, dt_needed); + } + + return bname; + } +#endif + return dt_needed; +} + template<typename F> static void for_each_dt_needed(const soinfo* si, F action) { for (ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) { if (d->d_tag == DT_NEEDED) { - action(si->get_string(d->d_un.d_val)); + action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath())); } } } |