summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6bec348)
raw | patch | inline | side by side (parent: 6bec348)
author | Dmitriy Ivanov <dimitry@google.com> | |
Wed, 3 Dec 2014 01:08:42 +0000 (17:08 -0800) | ||
committer | Dmitriy Ivanov <dimitry@google.com> | |
Wed, 3 Dec 2014 01:28:34 +0000 (17:28 -0800) |
1. Take into consideration that the local_group_root_
is not set for all of not linked libraries.
2. We need to check visited list earlier to avoid double
soinfo_free.
Change-Id: Iabc0a06a97c63f7e6bd4641731f50bb1466fed4f
is not set for all of not linked libraries.
2. We need to check visited list earlier to avoid double
soinfo_free.
Change-Id: Iabc0a06a97c63f7e6bd4641731f50bb1466fed4f
linker/linker.cpp | patch | blob | history |
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b2e746444d0452324d5e4897bb9c0984353e56c5..34099316fe163eda504e9cd52cb7581012bcdb6c 100644 (file)
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
if (trav == nullptr) {
// si was not in solist
- DL_ERR("name \"%s\" is not in solist!", si->name);
+ DL_ERR("name \"%s\"@%p is not in solist!", si->name, si);
return;
}
soinfo* si = nullptr;
while ((si = depth_first_list.pop_front()) != nullptr) {
+ if (local_unload_list.contains(si)) {
+ continue;
+ }
+
local_unload_list.push_back(si);
+
if (si->has_min_version(0)) {
soinfo* child = nullptr;
while ((child = si->get_children().pop_front()) != nullptr) {
- TRACE("%s needs to unload %s", si->name, child->name);
+ TRACE("%s@%p needs to unload %s@%p", si->name, si, child->name, child);
if (local_unload_list.contains(child)) {
continue;
- } else if (child->get_local_group_root() != root) {
+ } else if (child->is_linked() && child->get_local_group_root() != root) {
external_unload_list.push_back(child);
} else {
depth_first_list.push_front(child);
}
}
} else {
+#ifdef __LP64__
+ __libc_fatal("soinfo for \"%s\"@%p has no version", si->name, si);
+#else
+ PRINT("warning: soinfo for \"%s\"@%p has no version", si->name, si);
for_each_dt_needed(si, [&] (const char* library_name) {
TRACE("deprecated (old format of soinfo): %s needs to unload %s", si->name, library_name);
soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
} else if (local_unload_list.contains(needed)) {
// already visited
return;
- } else if (needed->get_local_group_root() != root) {
+ } else if (needed->is_linked() && needed->get_local_group_root() != root) {
// external group
external_unload_list.push_back(needed);
} else {
depth_first_list.push_front(needed);
}
});
+#endif
}
}