#include <stdlib.h>
#include <string.h>
#include <android/dlext.h>
+#include <android/api-level.h>
#include <bionic/pthread_internal.h>
#include "private/bionic_tls.h"
__libdl_info->strtab_size_ = sizeof(ANDROID_LIBDL_STRTAB);
__libdl_info->local_group_root_ = __libdl_info;
__libdl_info->soname_ = "libdl.so";
+ __libdl_info->target_sdk_version_ = __ANDROID_API__;
#if defined(__arm__)
strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
#endif
* SUCH DAMAGE.
*/
+#include <android/api-level.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
const ElfW(Sym)* s = nullptr;
for (soinfo* si = start; si != nullptr; si = si->next) {
- if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0) {
+ // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
+ // if the library is opened by application with target api level <= 22
+ // See http://b/21565766
+ if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0 && si->get_target_sdk_version() > 22) {
continue;
}
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) {
+ if (get_application_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 local_group_root_;
}
+// This function returns api-level at the time of
+// dlopen/load. Note that libraries opened by system
+// will always have 'current' api level.
+uint32_t soinfo::get_target_sdk_version() const {
+ if (!has_min_version(2)) {
+ return __ANDROID_API__;
+ }
+
+ return local_group_root_->target_sdk_version_;
+}
+
/* Force any of the closed stdin, stdout and stderr to be associated with
/dev/null. */
static int nullify_closed_stdio() {
}
// Before M release linker was using basename in place of soname.
- // In the case when dt_soname is absent some apps stop working:
+ // In the case when dt_soname is absent some apps stop working
// because they can't find dt_needed library by soname.
// This workaround should keep them working. (applies only
- // for apps targeting sdk version <=22). Make an exception for main
- // executable which does not need dt_soname.
- uint32_t target_sdk_version = get_application_target_sdk_version();
- if (soname_ == nullptr && this != somain && target_sdk_version != 0 && target_sdk_version <= 22) {
+ // for apps targeting sdk version <=22). Make an exception for
+ // the main executable and linker; they do not need to have dt_soname
+ if (soname_ == nullptr && this != somain && (flags_ & FLAG_LINKER) == 0 &&
+ get_application_target_sdk_version() <= 22) {
soname_ = basename(realpath_.c_str());
DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
get_realpath(), soname_);
local_group_root_ = this;
}
+ if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
+ target_sdk_version_ = get_application_target_sdk_version();
+ }
+
VersionTracker version_tracker;
if (!version_tracker.init(this)) {