summaryrefslogtreecommitdiffstats
path: root/linker/linker.h
diff options
context:
space:
mode:
authorDmitriy Ivanov <dimitry@google.com>2014-11-29 13:57:41 -0800
committerDmitriy Ivanov <dimitry@google.com>2014-12-02 10:54:26 -0800
commitab972b9adf8789a9e1b03129cd7f0c22e6bba117 (patch)
tree33b816d65afbcd622e38730b7516ba59ddb48fac /linker/linker.h
parentf64c43ba6c9244c50e904961dc432f04b1dfcfd9 (diff)
downloadbionic-ab972b9adf8789a9e1b03129cd7f0c22e6bba117.zip
bionic-ab972b9adf8789a9e1b03129cd7f0c22e6bba117.tar.gz
bionic-ab972b9adf8789a9e1b03129cd7f0c22e6bba117.tar.bz2
Count references for groups instead of instances
Count references on the group level to avoid partially unloading function that might be referenced by other libraries in the local_group Bonus: with this change we can correctly unload recursively linked libraries. is_recursive check is removed. Also dynamic executables (not .so) with 0 DT_NEEDED libraries are now correctly linked. Change-Id: Idfa83baef402840599b93a875f2881d9f020dbcd
Diffstat (limited to 'linker/linker.h')
-rw-r--r--linker/linker.h28
1 files changed, 20 insertions, 8 deletions
diff --git a/linker/linker.h b/linker/linker.h
index d28f70e..f7aa11c 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -161,9 +161,9 @@ struct soinfo {
#endif
soinfo* next;
- uint32_t flags;
-
private:
+ uint32_t flags_;
+
const char* strtab_;
ElfW(Sym)* symtab_;
@@ -203,22 +203,21 @@ struct soinfo {
linker_function_t init_func_;
linker_function_t fini_func_;
- public:
#if defined(__arm__)
+ public:
// ARM EABI section used for stack unwinding.
uint32_t* ARM_exidx;
size_t ARM_exidx_count;
-#elif defined(__mips__)
private:
+#elif defined(__mips__)
uint32_t mips_symtabno_;
uint32_t mips_local_gotno_;
uint32_t mips_gotsym_;
bool mips_relocate_got(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
#endif
-
+ size_t ref_count_;
public:
- size_t ref_count;
link_map link_map_head;
bool constructors_called;
@@ -264,9 +263,21 @@ struct soinfo {
bool is_gnu_hash() 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;
}
+ bool is_linked() const;
+ bool is_main_executable() const;
+
+ void set_linked();
+ void set_linker_flag();
+ void set_main_executable();
+
+ void increment_ref_count();
+ size_t decrement_ref_count();
+
+ soinfo* get_local_group_root() const;
+
private:
ElfW(Sym)* elf_lookup(SymbolName& symbol_name);
ElfW(Sym)* elf_addr_lookup(const void* addr);
@@ -303,9 +314,10 @@ struct soinfo {
// version >= 2
uint32_t gnu_maskwords_;
uint32_t gnu_shift2_;
-
ElfW(Addr)* gnu_bloom_filter_;
+ soinfo* local_group_root_;
+
friend soinfo* get_libdl_info();
};