1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef __LINKER_SOINFO_H 30 #define __LINKER_SOINFO_H 31 32 #include <link.h> 33 34 #include <string> 35 36 #include "linker_namespaces.h" 37 38 #define FLAG_LINKED 0x00000001 39 #define FLAG_EXE 0x00000004 // The main executable 40 #define FLAG_LINKER 0x00000010 // The linker itself 41 #define FLAG_GNU_HASH 0x00000040 // uses gnu hash 42 #define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller 43 // and should not be unmapped 44 #define FLAG_NEW_SOINFO 0x40000000 // new soinfo format 45 46 #define SOINFO_VERSION 3 47 48 typedef void (*linker_dtor_function_t)(); 49 typedef void (*linker_ctor_function_t)(int, char**, char**); 50 51 class SymbolName { 52 public: 53 explicit SymbolName(const char* name) 54 : name_(name), has_elf_hash_(false), has_gnu_hash_(false), 55 elf_hash_(0), gnu_hash_(0) { } 56 57 const char* get_name() { 58 return name_; 59 } 60 61 uint32_t elf_hash(); 62 uint32_t gnu_hash(); 63 64 private: 65 const char* name_; 66 bool has_elf_hash_; 67 bool has_gnu_hash_; 68 uint32_t elf_hash_; 69 uint32_t gnu_hash_; 70 71 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName); 72 }; 73 74 struct version_info { 75 constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {} 76 77 uint32_t elf_hash; 78 const char* name; 79 const soinfo* target_si; 80 }; 81 82 // TODO(dimitry): remove reference from soinfo member functions to this class. 83 class VersionTracker; 84 85 #if defined(__work_around_b_24465209__) 86 #define SOINFO_NAME_LEN 128 87 #endif 88 89 struct soinfo { 90 #if defined(__work_around_b_24465209__) 91 private: 92 char old_name_[SOINFO_NAME_LEN]; 93 #endif 94 public: 95 const ElfW(Phdr)* phdr; 96 size_t phnum; 97 #if defined(__work_around_b_24465209__) 98 ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility. 99 #endif 100 ElfW(Addr) base; 101 size_t size; 102 103 #if defined(__work_around_b_24465209__) 104 uint32_t unused1; // DO NOT USE, maintained for compatibility. 105 #endif 106 107 ElfW(Dyn)* dynamic; 108 109 #if defined(__work_around_b_24465209__) 110 uint32_t unused2; // DO NOT USE, maintained for compatibility 111 uint32_t unused3; // DO NOT USE, maintained for compatibility 112 #endif 113 114 soinfo* next; 115 private: 116 uint32_t flags_; 117 118 const char* strtab_; 119 ElfW(Sym)* symtab_; 120 121 size_t nbucket_; 122 size_t nchain_; 123 uint32_t* bucket_; 124 uint32_t* chain_; 125 126 #if defined(__mips__) || !defined(__LP64__) 127 // This is only used by mips and mips64, but needs to be here for 128 // all 32-bit architectures to preserve binary compatibility. 129 ElfW(Addr)** plt_got_; 130 #endif 131 132 #if defined(USE_RELA) 133 ElfW(Rela)* plt_rela_; 134 size_t plt_rela_count_; 135 136 ElfW(Rela)* rela_; 137 size_t rela_count_; 138 #else 139 ElfW(Rel)* plt_rel_; 140 size_t plt_rel_count_; 141 142 ElfW(Rel)* rel_; 143 size_t rel_count_; 144 #endif 145 146 linker_ctor_function_t* preinit_array_; 147 size_t preinit_array_count_; 148 149 linker_ctor_function_t* init_array_; 150 size_t init_array_count_; 151 linker_dtor_function_t* fini_array_; 152 size_t fini_array_count_; 153 154 linker_ctor_function_t init_func_; 155 linker_dtor_function_t fini_func_; 156 157 #if defined(__arm__) 158 public: 159 // ARM EABI section used for stack unwinding. 160 uint32_t* ARM_exidx; 161 size_t ARM_exidx_count; 162 private: 163 #elif defined(__mips__) 164 uint32_t mips_symtabno_; 165 uint32_t mips_local_gotno_; 166 uint32_t mips_gotsym_; 167 bool mips_relocate_got(const VersionTracker& version_tracker, 168 const soinfo_list_t& global_group, 169 const soinfo_list_t& local_group); 170 #if !defined(__LP64__) 171 bool mips_check_and_adjust_fp_modes(); 172 #endif 173 #endif 174 size_t ref_count_; 175 public: 176 link_map link_map_head; 177 178 bool constructors_called; 179 180 // When you read a virtual address from the ELF file, add this 181 // value to get the corresponding address in the process' address space. 182 ElfW(Addr) load_bias; 183 184 #if !defined(__LP64__) 185 bool has_text_relocations; 186 #endif 187 bool has_DT_SYMBOLIC; 188 189 public: 190 soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat, 191 off64_t file_offset, int rtld_flags); 192 ~soinfo(); 193 194 void call_constructors(); 195 void call_destructors(); 196 void call_pre_init_constructors(); 197 bool prelink_image(); 198 bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group, 199 const android_dlextinfo* extinfo); 200 bool protect_relro(); 201 202 void add_child(soinfo* child); 203 void remove_all_links(); 204 205 ino_t get_st_ino() const; 206 dev_t get_st_dev() const; 207 off64_t get_file_offset() const; 208 209 uint32_t get_rtld_flags() const; 210 uint32_t get_dt_flags_1() const; 211 void set_dt_flags_1(uint32_t dt_flags_1); 212 213 soinfo_list_t& get_children(); 214 const soinfo_list_t& get_children() const; 215 216 soinfo_list_t& get_parents(); 217 218 bool find_symbol_by_name(SymbolName& symbol_name, 219 const version_info* vi, 220 const ElfW(Sym)** symbol) const; 221 222 ElfW(Sym)* find_symbol_by_address(const void* addr); 223 ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const; 224 225 const char* get_string(ElfW(Word) index) const; 226 bool can_unload() const; 227 bool is_gnu_hash() const; 228 229 bool inline has_min_version(uint32_t min_version __unused) const { 230 #if defined(__work_around_b_24465209__) 231 return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version; 232 #else 233 return true; 234 #endif 235 } 236 237 bool is_linked() const; 238 bool is_linker() const; 239 bool is_main_executable() const; 240 241 void set_linked(); 242 void set_linker_flag(); 243 void set_main_executable(); 244 void set_nodelete(); 245 246 void increment_ref_count(); 247 size_t decrement_ref_count(); 248 249 soinfo* get_local_group_root() const; 250 251 void set_soname(const char* soname); 252 const char* get_soname() const; 253 const char* get_realpath() const; 254 const ElfW(Versym)* get_versym(size_t n) const; 255 ElfW(Addr) get_verneed_ptr() const; 256 size_t get_verneed_cnt() const; 257 ElfW(Addr) get_verdef_ptr() const; 258 size_t get_verdef_cnt() const; 259 260 uint32_t get_target_sdk_version() const; 261 262 void set_dt_runpath(const char *); 263 const std::vector<std::string>& get_dt_runpath() const; 264 android_namespace_t* get_primary_namespace(); 265 void add_secondary_namespace(android_namespace_t* secondary_ns); 266 android_namespace_list_t& get_secondary_namespaces(); 267 268 void set_mapped_by_caller(bool reserved_map); 269 bool is_mapped_by_caller() const; 270 271 uintptr_t get_handle() const; 272 void generate_handle(); 273 void* to_handle(); 274 275 private: 276 bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 277 ElfW(Sym)* elf_addr_lookup(const void* addr); 278 bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 279 ElfW(Sym)* gnu_addr_lookup(const void* addr); 280 281 bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym, 282 const char* sym_name, const version_info** vi); 283 284 template<typename ElfRelIteratorT> 285 bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator, 286 const soinfo_list_t& global_group, const soinfo_list_t& local_group); 287 288 private: 289 // This part of the structure is only available 290 // when FLAG_NEW_SOINFO is set in this->flags. 291 uint32_t version_; 292 293 // version >= 0 294 dev_t st_dev_; 295 ino_t st_ino_; 296 297 // dependency graph 298 soinfo_list_t children_; 299 soinfo_list_t parents_; 300 301 // version >= 1 302 off64_t file_offset_; 303 uint32_t rtld_flags_; 304 uint32_t dt_flags_1_; 305 size_t strtab_size_; 306 307 // version >= 2 308 309 size_t gnu_nbucket_; 310 uint32_t* gnu_bucket_; 311 uint32_t* gnu_chain_; 312 uint32_t gnu_maskwords_; 313 uint32_t gnu_shift2_; 314 ElfW(Addr)* gnu_bloom_filter_; 315 316 soinfo* local_group_root_; 317 318 uint8_t* android_relocs_; 319 size_t android_relocs_size_; 320 321 const char* soname_; 322 std::string realpath_; 323 324 const ElfW(Versym)* versym_; 325 326 ElfW(Addr) verdef_ptr_; 327 size_t verdef_cnt_; 328 329 ElfW(Addr) verneed_ptr_; 330 size_t verneed_cnt_; 331 332 uint32_t target_sdk_version_; 333 334 // version >= 3 335 std::vector<std::string> dt_runpath_; 336 android_namespace_t* primary_namespace_; 337 android_namespace_list_t secondary_namespaces_; 338 uintptr_t handle_; 339 340 friend soinfo* get_libdl_info(const char* linker_path); 341 }; 342 343 // This function is used by dlvsym() to calculate hash of sym_ver 344 uint32_t calculate_elf_hash(const char* name); 345 346 const char* fix_dt_needed(const char* dt_needed, const char* sopath); 347 348 template<typename F> 349 void for_each_dt_needed(const soinfo* si, F action) { 350 for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) { 351 if (d->d_tag == DT_NEEDED) { 352 action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath())); 353 } 354 } 355 } 356 357 #endif /* __LINKER_SOINFO_H */ 358