diff options
author | Dmitriy Ivanov <dimitry@google.com> | 2014-11-29 13:57:41 -0800 |
---|---|---|
committer | Dmitriy Ivanov <dimitry@google.com> | 2014-12-02 10:54:26 -0800 |
commit | ab972b9adf8789a9e1b03129cd7f0c22e6bba117 (patch) | |
tree | 33b816d65afbcd622e38730b7516ba59ddb48fac /linker/linker.h | |
parent | f64c43ba6c9244c50e904961dc432f04b1dfcfd9 (diff) | |
download | bionic-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.h | 28 |
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(); }; |