Merge "Backward compatibility for dlsym(RTLD_DEFAULT, ...)" into mnc-dev
This commit is contained in:
		
				
					committed by
					
						
						Android (Google) Code Review
					
				
			
			
				
	
			
			
			
					commit
					0c29aabad2
				
			@@ -22,6 +22,7 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <android/dlext.h>
 | 
					#include <android/dlext.h>
 | 
				
			||||||
 | 
					#include <android/api-level.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <bionic/pthread_internal.h>
 | 
					#include <bionic/pthread_internal.h>
 | 
				
			||||||
#include "private/bionic_tls.h"
 | 
					#include "private/bionic_tls.h"
 | 
				
			||||||
@@ -260,6 +261,7 @@ soinfo* get_libdl_info() {
 | 
				
			|||||||
    __libdl_info->strtab_size_ = sizeof(ANDROID_LIBDL_STRTAB);
 | 
					    __libdl_info->strtab_size_ = sizeof(ANDROID_LIBDL_STRTAB);
 | 
				
			||||||
    __libdl_info->local_group_root_ = __libdl_info;
 | 
					    __libdl_info->local_group_root_ = __libdl_info;
 | 
				
			||||||
    __libdl_info->soname_ = "libdl.so";
 | 
					    __libdl_info->soname_ = "libdl.so";
 | 
				
			||||||
 | 
					    __libdl_info->target_sdk_version_ = __ANDROID_API__;
 | 
				
			||||||
#if defined(__arm__)
 | 
					#if defined(__arm__)
 | 
				
			||||||
    strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
 | 
					    strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@
 | 
				
			|||||||
 * SUCH DAMAGE.
 | 
					 * SUCH DAMAGE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <android/api-level.h>
 | 
				
			||||||
#include <dlfcn.h>
 | 
					#include <dlfcn.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
@@ -1001,7 +1002,10 @@ const ElfW(Sym)* dlsym_linear_lookup(const char* name,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const ElfW(Sym)* s = nullptr;
 | 
					  const ElfW(Sym)* s = nullptr;
 | 
				
			||||||
  for (soinfo* si = start; si != nullptr; si = si->next) {
 | 
					  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;
 | 
					      continue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1230,8 +1234,7 @@ static int open_library(const char* name, off64_t* file_offset) {
 | 
				
			|||||||
static const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
 | 
					static const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
 | 
				
			||||||
#if !defined(__LP64__)
 | 
					#if !defined(__LP64__)
 | 
				
			||||||
  // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
 | 
					  // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
 | 
				
			||||||
  uint32_t target_sdk_version = get_application_target_sdk_version();
 | 
					  if (get_application_target_sdk_version() <= 22) {
 | 
				
			||||||
  if (target_sdk_version != 0 && target_sdk_version <= 22) {
 | 
					 | 
				
			||||||
    const char* bname = basename(dt_needed);
 | 
					    const char* bname = basename(dt_needed);
 | 
				
			||||||
    if (bname != dt_needed) {
 | 
					    if (bname != dt_needed) {
 | 
				
			||||||
      DL_WARN("'%s' library has invalid DT_NEEDED entry '%s'", sopath, dt_needed);
 | 
					      DL_WARN("'%s' library has invalid DT_NEEDED entry '%s'", sopath, dt_needed);
 | 
				
			||||||
@@ -2406,6 +2409,17 @@ soinfo* soinfo::get_local_group_root() const {
 | 
				
			|||||||
  return local_group_root_;
 | 
					  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
 | 
					/* Force any of the closed stdin, stdout and stderr to be associated with
 | 
				
			||||||
   /dev/null. */
 | 
					   /dev/null. */
 | 
				
			||||||
static int nullify_closed_stdio() {
 | 
					static int nullify_closed_stdio() {
 | 
				
			||||||
@@ -2877,13 +2891,13 @@ bool soinfo::prelink_image() {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Before M release linker was using basename in place of soname.
 | 
					  // 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.
 | 
					  // because they can't find dt_needed library by soname.
 | 
				
			||||||
  // This workaround should keep them working. (applies only
 | 
					  // This workaround should keep them working. (applies only
 | 
				
			||||||
  // for apps targeting sdk version <=22). Make an exception for main
 | 
					  // for apps targeting sdk version <=22). Make an exception for
 | 
				
			||||||
  // executable which does not need dt_soname.
 | 
					  // the main executable and linker; they do not need to have dt_soname
 | 
				
			||||||
  uint32_t target_sdk_version = get_application_target_sdk_version();
 | 
					  if (soname_ == nullptr && this != somain && (flags_ & FLAG_LINKER) == 0 &&
 | 
				
			||||||
  if (soname_ == nullptr && this != somain && target_sdk_version != 0 && target_sdk_version <= 22) {
 | 
					      get_application_target_sdk_version() <= 22) {
 | 
				
			||||||
    soname_ = basename(realpath_.c_str());
 | 
					    soname_ = basename(realpath_.c_str());
 | 
				
			||||||
    DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
 | 
					    DL_WARN("%s: is missing DT_SONAME will use basename as a replacement: \"%s\"",
 | 
				
			||||||
        get_realpath(), soname_);
 | 
					        get_realpath(), soname_);
 | 
				
			||||||
@@ -2899,6 +2913,10 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
 | 
				
			|||||||
    local_group_root_ = this;
 | 
					    local_group_root_ = this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
 | 
				
			||||||
 | 
					    target_sdk_version_ = get_application_target_sdk_version();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  VersionTracker version_tracker;
 | 
					  VersionTracker version_tracker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!version_tracker.init(this)) {
 | 
					  if (!version_tracker.init(this)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -334,6 +334,8 @@ struct soinfo {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;
 | 
					  bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t get_target_sdk_version() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
 | 
					  bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
 | 
				
			||||||
  ElfW(Sym)* elf_addr_lookup(const void* addr);
 | 
					  ElfW(Sym)* elf_addr_lookup(const void* addr);
 | 
				
			||||||
@@ -393,6 +395,8 @@ struct soinfo {
 | 
				
			|||||||
  ElfW(Addr) verneed_ptr_;
 | 
					  ElfW(Addr) verneed_ptr_;
 | 
				
			||||||
  size_t verneed_cnt_;
 | 
					  size_t verneed_cnt_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint32_t target_sdk_version_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  friend soinfo* get_libdl_info();
 | 
					  friend soinfo* get_libdl_info();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,9 +15,10 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "linker.h"
 | 
					#include "linker.h"
 | 
				
			||||||
 | 
					#include <android/api-level.h>
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static std::atomic<uint32_t> g_target_sdk_version;
 | 
					static std::atomic<uint32_t> g_target_sdk_version(__ANDROID_API__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void set_application_target_sdk_version(uint32_t target) {
 | 
					void set_application_target_sdk_version(uint32_t target) {
 | 
				
			||||||
  g_target_sdk_version = target;
 | 
					  g_target_sdk_version = target;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user