am 69c5d108: Revert "Add RTLD_NODELETE flag support"
* commit '69c5d108a5cb44167a04d42ffdad6a39648ed235': Revert "Add RTLD_NODELETE flag support"
This commit is contained in:
commit
e1d9881a8d
@ -64,7 +64,6 @@ enum {
|
|||||||
RTLD_GLOBAL = 2,
|
RTLD_GLOBAL = 2,
|
||||||
#endif
|
#endif
|
||||||
RTLD_NOLOAD = 4,
|
RTLD_NOLOAD = 4,
|
||||||
RTLD_NODELETE = 0x01000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined (__LP64__)
|
#if defined (__LP64__)
|
||||||
|
@ -987,11 +987,6 @@ static soinfo* find_library(const char* name, int rtld_flags, const android_dlex
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void soinfo_unload(soinfo* si) {
|
static void soinfo_unload(soinfo* si) {
|
||||||
if (!si->can_unload()) {
|
|
||||||
TRACE("not unloading '%s' - the binary is flagged with NODELETE", si->name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (si->ref_count == 1) {
|
if (si->ref_count == 1) {
|
||||||
TRACE("unloading '%s'", si->name);
|
TRACE("unloading '%s'", si->name);
|
||||||
si->CallDestructors();
|
si->CallDestructors();
|
||||||
@ -1050,7 +1045,7 @@ void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo) {
|
soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo) {
|
||||||
if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
|
if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NOLOAD)) != 0) {
|
||||||
DL_ERR("invalid flags to dlopen: %x", flags);
|
DL_ERR("invalid flags to dlopen: %x", flags);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1813,9 +1808,6 @@ const char* soinfo::get_string(ElfW(Word) index) const {
|
|||||||
return strtab + index;
|
return strtab + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool soinfo::can_unload() const {
|
|
||||||
return (rtld_flags & (RTLD_NODELETE | RTLD_GLOBAL)) == 0;
|
|
||||||
}
|
|
||||||
/* 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() {
|
||||||
@ -2119,13 +2111,9 @@ bool soinfo::PrelinkImage() {
|
|||||||
if ((d->d_un.d_val & DF_1_GLOBAL) != 0) {
|
if ((d->d_un.d_val & DF_1_GLOBAL) != 0) {
|
||||||
rtld_flags |= RTLD_GLOBAL;
|
rtld_flags |= RTLD_GLOBAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((d->d_un.d_val & DF_1_NODELETE) != 0) {
|
|
||||||
rtld_flags |= RTLD_NODELETE;
|
|
||||||
}
|
|
||||||
// TODO: Implement other flags
|
// TODO: Implement other flags
|
||||||
|
|
||||||
if ((d->d_un.d_val & ~(DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE)) != 0) {
|
if ((d->d_un.d_val & ~(DF_1_NOW | DF_1_GLOBAL)) != 0) {
|
||||||
DL_WARN("Unsupported flags DT_FLAGS_1=%p", reinterpret_cast<void*>(d->d_un.d_val));
|
DL_WARN("Unsupported flags DT_FLAGS_1=%p", reinterpret_cast<void*>(d->d_un.d_val));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -134,7 +134,7 @@ struct soinfo {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
soinfo* next;
|
soinfo* next;
|
||||||
uint32_t flags;
|
unsigned flags;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* strtab;
|
const char* strtab;
|
||||||
@ -143,8 +143,8 @@ struct soinfo {
|
|||||||
|
|
||||||
size_t nbucket;
|
size_t nbucket;
|
||||||
size_t nchain;
|
size_t nchain;
|
||||||
uint32_t* bucket;
|
unsigned* bucket;
|
||||||
uint32_t* chain;
|
unsigned* chain;
|
||||||
|
|
||||||
#if defined(__mips__) || !defined(__LP64__)
|
#if defined(__mips__) || !defined(__LP64__)
|
||||||
// This is only used by mips and mips64, but needs to be here for
|
// This is only used by mips and mips64, but needs to be here for
|
||||||
@ -179,12 +179,12 @@ struct soinfo {
|
|||||||
|
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
// ARM EABI section used for stack unwinding.
|
// ARM EABI section used for stack unwinding.
|
||||||
uint32_t* ARM_exidx;
|
unsigned* ARM_exidx;
|
||||||
size_t ARM_exidx_count;
|
size_t ARM_exidx_count;
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
uint32_t mips_symtabno;
|
unsigned mips_symtabno;
|
||||||
uint32_t mips_local_gotno;
|
unsigned mips_local_gotno;
|
||||||
uint32_t mips_gotsym;
|
unsigned mips_gotsym;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t ref_count;
|
size_t ref_count;
|
||||||
@ -224,12 +224,10 @@ struct soinfo {
|
|||||||
ElfW(Addr) resolve_symbol_address(ElfW(Sym)* s);
|
ElfW(Addr) resolve_symbol_address(ElfW(Sym)* s);
|
||||||
|
|
||||||
const char* get_string(ElfW(Word) index) const;
|
const char* get_string(ElfW(Word) index) const;
|
||||||
bool can_unload() const;
|
|
||||||
|
|
||||||
bool inline has_min_version(uint32_t min_version) const {
|
bool inline has_min_version(uint32_t min_version) const {
|
||||||
return (flags & FLAG_NEW_SOINFO) != 0 && version >= min_version;
|
return (flags & FLAG_NEW_SOINFO) != 0 && version >= min_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
|
void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
|
||||||
void CallFunction(const char* function_name, linker_function_t function);
|
void CallFunction(const char* function_name, linker_function_t function);
|
||||||
@ -260,7 +258,7 @@ struct soinfo {
|
|||||||
friend soinfo* get_libdl_info();
|
friend soinfo* get_libdl_info();
|
||||||
};
|
};
|
||||||
|
|
||||||
soinfo* get_libdl_info();
|
extern soinfo* get_libdl_info();
|
||||||
|
|
||||||
void do_android_get_LD_LIBRARY_PATH(char*, size_t);
|
void do_android_get_LD_LIBRARY_PATH(char*, size_t);
|
||||||
void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
|
void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
|
||||||
|
@ -232,15 +232,10 @@ TEST(dlfcn, dlopen_check_rtld_global) {
|
|||||||
ASSERT_TRUE(sym == nullptr);
|
ASSERT_TRUE(sym == nullptr);
|
||||||
|
|
||||||
void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_GLOBAL);
|
void* handle = dlopen("libtest_simple.so", RTLD_NOW | RTLD_GLOBAL);
|
||||||
ASSERT_TRUE(handle != nullptr) << dlerror();
|
|
||||||
sym = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
sym = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
||||||
ASSERT_TRUE(sym != nullptr) << dlerror();
|
ASSERT_TRUE(sym != nullptr) << dlerror();
|
||||||
ASSERT_TRUE(reinterpret_cast<bool (*)(void)>(sym)());
|
ASSERT_TRUE(reinterpret_cast<bool (*)(void)>(sym)());
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
|
|
||||||
// RTLD_GLOBAL implies RTLD_NODELETE, let's check that
|
|
||||||
void* sym_after_dlclose = dlsym(RTLD_DEFAULT, "dlopen_testlib_simple_func");
|
|
||||||
ASSERT_EQ(sym, sym_after_dlclose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// libtest_with_dependency_loop.so -> libtest_with_dependency_loop_a.so ->
|
// libtest_with_dependency_loop.so -> libtest_with_dependency_loop_a.so ->
|
||||||
@ -268,81 +263,6 @@ TEST(dlfcn, dlopen_check_loop) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(dlfcn, dlopen_nodelete) {
|
|
||||||
static bool is_unloaded = false;
|
|
||||||
|
|
||||||
void* handle = dlopen("libtest_nodelete_1.so", RTLD_NOW | RTLD_NODELETE);
|
|
||||||
ASSERT_TRUE(handle != nullptr) << dlerror();
|
|
||||||
void (*set_unload_flag_ptr)(bool*);
|
|
||||||
set_unload_flag_ptr = reinterpret_cast<void (*)(bool*)>(dlsym(handle, "dlopen_nodelete_1_set_unload_flag_ptr"));
|
|
||||||
ASSERT_TRUE(set_unload_flag_ptr != nullptr) << dlerror();
|
|
||||||
set_unload_flag_ptr(&is_unloaded);
|
|
||||||
|
|
||||||
uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_nodelete_1_taxicab_number"));
|
|
||||||
ASSERT_TRUE(taxicab_number != nullptr) << dlerror();
|
|
||||||
ASSERT_EQ(1729U, *taxicab_number);
|
|
||||||
*taxicab_number = 2;
|
|
||||||
|
|
||||||
dlclose(handle);
|
|
||||||
ASSERT_TRUE(!is_unloaded);
|
|
||||||
|
|
||||||
uint32_t* taxicab_number_after_dlclose = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_nodelete_1_taxicab_number"));
|
|
||||||
ASSERT_EQ(taxicab_number_after_dlclose, taxicab_number);
|
|
||||||
ASSERT_EQ(2U, *taxicab_number_after_dlclose);
|
|
||||||
|
|
||||||
|
|
||||||
handle = dlopen("libtest_nodelete_1.so", RTLD_NOW);
|
|
||||||
uint32_t* taxicab_number2 = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_nodelete_1_taxicab_number"));
|
|
||||||
ASSERT_EQ(taxicab_number2, taxicab_number);
|
|
||||||
|
|
||||||
ASSERT_EQ(2U, *taxicab_number2);
|
|
||||||
|
|
||||||
dlclose(handle);
|
|
||||||
ASSERT_TRUE(!is_unloaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dlfcn, dlopen_nodelete_on_second_dlopen) {
|
|
||||||
static bool is_unloaded = false;
|
|
||||||
|
|
||||||
void* handle = dlopen("libtest_nodelete_2.so", RTLD_NOW);
|
|
||||||
ASSERT_TRUE(handle != nullptr) << dlerror();
|
|
||||||
void (*set_unload_flag_ptr)(bool*);
|
|
||||||
set_unload_flag_ptr = reinterpret_cast<void (*)(bool*)>(dlsym(handle, "dlopen_nodelete_2_set_unload_flag_ptr"));
|
|
||||||
ASSERT_TRUE(set_unload_flag_ptr != nullptr) << dlerror();
|
|
||||||
set_unload_flag_ptr(&is_unloaded);
|
|
||||||
|
|
||||||
uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_nodelete_2_taxicab_number"));
|
|
||||||
ASSERT_TRUE(taxicab_number != nullptr) << dlerror();
|
|
||||||
|
|
||||||
ASSERT_EQ(1729U, *taxicab_number);
|
|
||||||
*taxicab_number = 2;
|
|
||||||
|
|
||||||
// This RTLD_NODELETE should be ignored
|
|
||||||
void* handle1 = dlopen("libtest_nodelete_2.so", RTLD_NOW | RTLD_NODELETE);
|
|
||||||
ASSERT_TRUE(handle1 != nullptr) << dlerror();
|
|
||||||
ASSERT_EQ(handle, handle1);
|
|
||||||
|
|
||||||
dlclose(handle1);
|
|
||||||
dlclose(handle);
|
|
||||||
|
|
||||||
ASSERT_TRUE(is_unloaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(dlfcn, dlopen_nodelete_dt_flags_1) {
|
|
||||||
static bool is_unloaded = false;
|
|
||||||
|
|
||||||
void* handle = dlopen("libtest_nodelete_dt_flags_1.so", RTLD_NOW);
|
|
||||||
ASSERT_TRUE(handle != nullptr) << dlerror();
|
|
||||||
void (*set_unload_flag_ptr)(bool*);
|
|
||||||
set_unload_flag_ptr = reinterpret_cast<void (*)(bool*)>(dlsym(handle, "dlopen_nodelete_dt_flags_1_set_unload_flag_ptr"));
|
|
||||||
ASSERT_TRUE(set_unload_flag_ptr != nullptr) << dlerror();
|
|
||||||
set_unload_flag_ptr(&is_unloaded);
|
|
||||||
|
|
||||||
dlclose(handle);
|
|
||||||
ASSERT_TRUE(!is_unloaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(dlfcn, dlopen_failure) {
|
TEST(dlfcn, dlopen_failure) {
|
||||||
void* self = dlopen("/does/not/exist", RTLD_NOW);
|
void* self = dlopen("/does/not/exist", RTLD_NOW);
|
||||||
ASSERT_TRUE(self == NULL);
|
ASSERT_TRUE(self == NULL);
|
||||||
|
@ -120,35 +120,6 @@ libtest_simple_src_files := \
|
|||||||
module := libtest_simple
|
module := libtest_simple
|
||||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
include $(LOCAL_PATH)/Android.build.testlib.mk
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Library used by dlfcn nodelete tests
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
libtest_nodelete_1_src_files := \
|
|
||||||
dlopen_nodelete_1.cpp
|
|
||||||
|
|
||||||
module := libtest_nodelete_1
|
|
||||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Library used by dlfcn nodelete tests
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
libtest_nodelete_2_src_files := \
|
|
||||||
dlopen_nodelete_2.cpp
|
|
||||||
|
|
||||||
module := libtest_nodelete_2
|
|
||||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Library used by dlfcn nodelete tests
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
libtest_nodelete_dt_flags_1_src_files := \
|
|
||||||
dlopen_nodelete_dt_flags_1.cpp
|
|
||||||
|
|
||||||
libtest_nodelete_dt_flags_1_ldflags := -Wl,-z,nodelete
|
|
||||||
|
|
||||||
module := libtest_nodelete_dt_flags_1
|
|
||||||
include $(LOCAL_PATH)/Android.build.testlib.mk
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Libraries used by dlfcn tests to verify correct load order:
|
# Libraries used by dlfcn tests to verify correct load order:
|
||||||
# libtest_check_order_2_right.so
|
# libtest_check_order_2_right.so
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
uint32_t dlopen_nodelete_1_taxicab_number = 1729;
|
|
||||||
static bool* unload_flag_ptr = nullptr;
|
|
||||||
|
|
||||||
extern "C" void dlopen_nodelete_1_set_unload_flag_ptr(bool* ptr) {
|
|
||||||
unload_flag_ptr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((destructor)) unload_guard() {
|
|
||||||
if (unload_flag_ptr != nullptr) {
|
|
||||||
*unload_flag_ptr = true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
uint32_t dlopen_nodelete_2_taxicab_number = 1729;
|
|
||||||
static bool* unload_flag_ptr = nullptr;
|
|
||||||
|
|
||||||
extern "C" void dlopen_nodelete_2_set_unload_flag_ptr(bool* ptr) {
|
|
||||||
unload_flag_ptr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((destructor)) unload_guard() {
|
|
||||||
if (unload_flag_ptr != nullptr) {
|
|
||||||
*unload_flag_ptr = true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static bool* unload_flag_ptr = nullptr;
|
|
||||||
|
|
||||||
extern "C" void dlopen_nodelete_dt_flags_1_set_unload_flag_ptr(bool* ptr) {
|
|
||||||
unload_flag_ptr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((destructor)) unload_guard() {
|
|
||||||
if (unload_flag_ptr != nullptr) {
|
|
||||||
*unload_flag_ptr = true;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user