Merge "Add ANDROID_DLEXT_FORCE_LOAD flag"
This commit is contained in:
		@@ -59,16 +59,28 @@ enum {
 | 
				
			|||||||
  /* If opening a library using library_fd read it starting at library_fd_offset.
 | 
					  /* If opening a library using library_fd read it starting at library_fd_offset.
 | 
				
			||||||
   * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
 | 
					   * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET    = 0x20,
 | 
					  ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET    = 0x20,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* When set, do not check if the library has already been loaded by file stat(2)s.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * This flag allows forced loading of the library in the case when for some
 | 
				
			||||||
 | 
					   * reason multiple ELF files share the same filename (because the already-loaded
 | 
				
			||||||
 | 
					   * library has been removed and overwritten, for example).
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * Note that if the library has the same dt_soname as an old one and some other
 | 
				
			||||||
 | 
					   * library has the soname in DT_NEEDED list, the first one will be used to resolve any
 | 
				
			||||||
 | 
					   * dependencies.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  ANDROID_DLEXT_FORCE_LOAD = 0x40,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Mask of valid bits */
 | 
					  /* Mask of valid bits */
 | 
				
			||||||
  ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |
 | 
					  ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |
 | 
				
			||||||
                                        ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
 | 
					                                        ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
 | 
				
			||||||
                                        ANDROID_DLEXT_WRITE_RELRO |
 | 
					                                        ANDROID_DLEXT_WRITE_RELRO |
 | 
				
			||||||
                                        ANDROID_DLEXT_USE_RELRO |
 | 
					                                        ANDROID_DLEXT_USE_RELRO |
 | 
				
			||||||
                                        ANDROID_DLEXT_USE_LIBRARY_FD |
 | 
					                                        ANDROID_DLEXT_USE_LIBRARY_FD |
 | 
				
			||||||
                                        ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET,
 | 
					                                        ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
 | 
				
			||||||
 | 
					                                        ANDROID_DLEXT_FORCE_LOAD,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1044,7 +1044,8 @@ static soinfo* load_library(LoadTaskList& load_tasks,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Check for symlink and other situations where
 | 
					  // Check for symlink and other situations where
 | 
				
			||||||
  // file can have different names.
 | 
					  // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
 | 
				
			||||||
 | 
					  if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
 | 
				
			||||||
    for (soinfo* si = solist; si != nullptr; si = si->next) {
 | 
					    for (soinfo* si = solist; si != nullptr; si = si->next) {
 | 
				
			||||||
      if (si->get_st_dev() != 0 &&
 | 
					      if (si->get_st_dev() != 0 &&
 | 
				
			||||||
          si->get_st_ino() != 0 &&
 | 
					          si->get_st_ino() != 0 &&
 | 
				
			||||||
@@ -1056,6 +1057,7 @@ static soinfo* load_library(LoadTaskList& load_tasks,
 | 
				
			|||||||
        return si;
 | 
					        return si;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((rtld_flags & RTLD_NOLOAD) != 0) {
 | 
					  if ((rtld_flags & RTLD_NOLOAD) != 0) {
 | 
				
			||||||
    DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
 | 
					    DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -173,6 +173,40 @@ TEST_F(DlExtTest, ExtInfoUseOffsetWihtoutFd) {
 | 
				
			|||||||
  ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror());
 | 
					  ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(dlext, android_dlopen_ext_force_load_smoke) {
 | 
				
			||||||
 | 
					  // 1. Open actual file
 | 
				
			||||||
 | 
					  void* handle = dlopen("libdlext_test.so", RTLD_NOW);
 | 
				
			||||||
 | 
					  ASSERT_DL_NOTNULL(handle);
 | 
				
			||||||
 | 
					  // 2. Open link with force_load flag set
 | 
				
			||||||
 | 
					  android_dlextinfo extinfo;
 | 
				
			||||||
 | 
					  extinfo.flags = ANDROID_DLEXT_FORCE_LOAD;
 | 
				
			||||||
 | 
					  void* handle2 = android_dlopen_ext("libdlext_test_v2.so", RTLD_NOW, &extinfo);
 | 
				
			||||||
 | 
					  ASSERT_DL_NOTNULL(handle2);
 | 
				
			||||||
 | 
					  ASSERT_TRUE(handle != handle2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dlclose(handle2);
 | 
				
			||||||
 | 
					  dlclose(handle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(dlext, android_dlopen_ext_force_load_soname_exception) {
 | 
				
			||||||
 | 
					  // Check if soname lookup still returns already loaded library
 | 
				
			||||||
 | 
					  // when ANDROID_DLEXT_FORCE_LOAD flag is specified.
 | 
				
			||||||
 | 
					  void* handle = dlopen("libdlext_test_v2.so", RTLD_NOW);
 | 
				
			||||||
 | 
					  ASSERT_DL_NOTNULL(handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  android_dlextinfo extinfo;
 | 
				
			||||||
 | 
					  extinfo.flags = ANDROID_DLEXT_FORCE_LOAD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Note that 'libdlext_test.so' is dt_soname for libdlext_test_v2.so
 | 
				
			||||||
 | 
					  void* handle2 = android_dlopen_ext("libdlext_test.so", RTLD_NOW, &extinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ASSERT_DL_NOTNULL(handle2);
 | 
				
			||||||
 | 
					  ASSERT_TRUE(handle == handle2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dlclose(handle2);
 | 
				
			||||||
 | 
					  dlclose(handle);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST(dlfcn, dlopen_from_zip_absolute_path) {
 | 
					TEST(dlfcn, dlopen_from_zip_absolute_path) {
 | 
				
			||||||
  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH;
 | 
					  const std::string lib_path = std::string(getenv("ANDROID_DATA")) + LIBZIPPATH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user