Remove dangling links in secondary namespaces
linker didn't remove link to the soinfo from shared
namespaces on soinfo_unload, because it didn't keep
record of all namespaces the library is added to.
This change adds test for this and also fixes the
problem by introducing list of secondary namespaces
to soinfo, which is used to remove soinfo in
soinfo::remove_all_links().
Bug: http://b/28115950
Change-Id: Ifbf6e54f92fa6e88f86b6a8dd6dc22d4553afd22
diff --git a/linker/linker.h b/linker/linker.h
index 81f93ac..4e2e0b9 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -114,6 +114,16 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
};
+class NamespaceListAllocator {
+ public:
+ static LinkedListEntry<android_namespace_t>* alloc();
+ static void free(LinkedListEntry<android_namespace_t>* entry);
+
+ private:
+ // unconstructable
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceListAllocator);
+};
+
class SymbolName {
public:
explicit SymbolName(const char* name)
@@ -166,6 +176,7 @@
struct soinfo {
public:
typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+ typedef LinkedList<android_namespace_t, NamespaceListAllocator> android_namespace_list_t;
#if defined(__work_around_b_24465209__)
private:
char old_name_[SOINFO_NAME_LEN];
@@ -342,7 +353,8 @@
void set_dt_runpath(const char *);
const std::vector<std::string>& get_dt_runpath() const;
- android_namespace_t* get_namespace();
+ android_namespace_t* get_primary_namespace();
+ void add_secondary_namespace(android_namespace_t* secondary_ns);
void set_mapped_by_caller(bool reserved_map);
bool is_mapped_by_caller() const;
@@ -414,7 +426,8 @@
// version >= 3
std::vector<std::string> dt_runpath_;
- android_namespace_t* namespace_;
+ android_namespace_t* primary_namespace_;
+ android_namespace_list_t secondary_namespaces_;
uintptr_t handle_;
friend soinfo* get_libdl_info();