diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2015-11-23 11:26:35 -0800 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2015-11-23 16:13:10 -0800 |
commit | 1ffec1cc4d0e283bb1ff6f49843769a3493b8d73 (patch) | |
tree | 083c8af007b9a2e2ed01fbde2eea50ded648e114 /linker/linker.cpp | |
parent | a7fc7f9909c221a0f64c5c5ecc5fadd5fba467c5 (diff) |
Introduce anonymous namespace
The anonymous namespace is introduced to
handle cases when linker can not find the
caller. This usually happens when caller
code was not loaded by dynamic linker;
for example mono-generated code.
Bug: http://b/25844435
Bug: http://b/22548808
Change-Id: I9e5b1d23c1c75bc78548d68e79216a6a943a33cf
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 1ecf65bb7..97802319a 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -111,6 +111,7 @@ struct android_namespace_t { }; android_namespace_t g_default_namespace; +android_namespace_t* g_anonymous_namespace = &g_default_namespace; static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf); @@ -2201,7 +2202,7 @@ soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo, return nullptr; } - android_namespace_t* ns = caller->get_namespace(); + android_namespace_t* ns = caller != nullptr ? caller->get_namespace() : g_anonymous_namespace; if (extinfo != nullptr) { if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) { @@ -2246,14 +2247,14 @@ void do_dlclose(soinfo* si) { soinfo_unload(si); } -bool init_public_namespace(const char* libs) { - CHECK(libs != nullptr); +bool init_namespaces(const char* public_ns_sonames, const char* anon_ns_library_path) { + CHECK(public_ns_sonames != nullptr); if (g_public_namespace_initialized) { - DL_ERR("Public namespace has already been initialized."); + DL_ERR("public namespace has already been initialized."); return false; } - std::vector<std::string> sonames = android::base::Split(libs, ":"); + std::vector<std::string> sonames = android::base::Split(public_ns_sonames, ":"); ProtectedDataGuard guard; @@ -2267,7 +2268,7 @@ bool init_public_namespace(const char* libs) { find_loaded_library_by_soname(&g_default_namespace, soname.c_str(), &candidate); if (candidate == nullptr) { - DL_ERR("Error initializing public namespace: \"%s\" was not found" + DL_ERR("error initializing public namespace: \"%s\" was not found" " in the default namespace", soname.c_str()); return false; } @@ -2276,8 +2277,18 @@ bool init_public_namespace(const char* libs) { g_public_namespace.push_back(candidate); } - failure_guard.disable(); g_public_namespace_initialized = true; + + // create anonymous namespace + android_namespace_t* anon_ns = + create_namespace("(anonymous)", nullptr, anon_ns_library_path, false); + + if (anon_ns == nullptr) { + g_public_namespace_initialized = false; + return false; + } + g_anonymous_namespace = anon_ns; + failure_guard.disable(); return true; } @@ -2286,7 +2297,7 @@ android_namespace_t* create_namespace(const char* name, const char* default_library_path, bool is_isolated) { if (!g_public_namespace_initialized) { - DL_ERR("Cannot create namespace: public namespace is not initialized."); + DL_ERR("cannot create namespace: public namespace is not initialized."); return nullptr; } |