1 /* 2 * Copyright (C) 2008 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_H_ 30 #define _LINKER_H_ 31 32 #include <elf.h> 33 #include <inttypes.h> 34 #include <link.h> 35 #include <unistd.h> 36 #include <android/dlext.h> 37 #include <sys/stat.h> 38 39 #include "private/libc_logging.h" 40 #include "linked_list.h" 41 42 #include <string> 43 #include <vector> 44 45 #define DL_ERR(fmt, x...) \ 46 do { \ 47 __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \ 48 /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \ 49 DEBUG("%s\n", linker_get_error_buffer()); \ 50 } while (false) 51 52 #define DL_WARN(fmt, x...) \ 53 do { \ 54 __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \ 55 __libc_format_fd(2, "WARNING: linker: "); \ 56 __libc_format_fd(2, fmt, ##x); \ 57 __libc_format_fd(2, "\n"); \ 58 } while (false) 59 60 #if defined(__LP64__) 61 #define ELFW(what) ELF64_ ## what 62 #else 63 #define ELFW(what) ELF32_ ## what 64 #endif 65 66 // mips64 interprets Elf64_Rel structures' r_info field differently. 67 // bionic (like other C libraries) has macros that assume regular ELF files, 68 // but the dynamic linker needs to be able to load mips64 ELF files. 69 #if defined(__mips__) && defined(__LP64__) 70 #undef ELF64_R_SYM 71 #undef ELF64_R_TYPE 72 #undef ELF64_R_INFO 73 #define ELF64_R_SYM(info) (((info) >> 0) & 0xffffffff) 74 #define ELF64_R_SSYM(info) (((info) >> 32) & 0xff) 75 #define ELF64_R_TYPE3(info) (((info) >> 40) & 0xff) 76 #define ELF64_R_TYPE2(info) (((info) >> 48) & 0xff) 77 #define ELF64_R_TYPE(info) (((info) >> 56) & 0xff) 78 #endif 79 80 // Returns the address of the page containing address 'x'. 81 #define PAGE_START(x) ((x) & PAGE_MASK) 82 83 // Returns the offset of address 'x' in its page. 84 #define PAGE_OFFSET(x) ((x) & ~PAGE_MASK) 85 86 // Returns the address of the next page after address 'x', unless 'x' is 87 // itself at the start of a page. 88 #define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1)) 89 90 #define FLAG_LINKED 0x00000001 91 #define FLAG_EXE 0x00000004 // The main executable 92 #define FLAG_LINKER 0x00000010 // The linker itself 93 #define FLAG_GNU_HASH 0x00000040 // uses gnu hash 94 #define FLAG_NEW_SOINFO 0x40000000 // new soinfo format 95 96 #define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE) 97 98 #define SOINFO_VERSION 2 99 100 #if defined(__work_around_b_19059885__) 101 #define SOINFO_NAME_LEN 128 102 #endif 103 104 typedef void (*linker_function_t)(); 105 106 // Android uses RELA for aarch64 and x86_64. mips64 still uses REL. 107 #if defined(__aarch64__) || defined(__x86_64__) 108 #define USE_RELA 1 109 #endif 110 111 struct soinfo; 112 113 class SoinfoListAllocator { 114 public: 115 static LinkedListEntry<soinfo>* alloc(); 116 static void free(LinkedListEntry<soinfo>* entry); 117 118 private: 119 // unconstructable 120 DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator); 121 }; 122 123 class SymbolName { 124 public: SymbolName(const char * name)125 explicit SymbolName(const char* name) 126 : name_(name), has_elf_hash_(false), has_gnu_hash_(false), 127 elf_hash_(0), gnu_hash_(0) { } 128 get_name()129 const char* get_name() { 130 return name_; 131 } 132 133 uint32_t elf_hash(); 134 uint32_t gnu_hash(); 135 136 private: 137 const char* name_; 138 bool has_elf_hash_; 139 bool has_gnu_hash_; 140 uint32_t elf_hash_; 141 uint32_t gnu_hash_; 142 143 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName); 144 }; 145 146 struct version_info { version_infoversion_info147 version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {} 148 149 uint32_t elf_hash; 150 const char* name; 151 const soinfo* target_si; 152 }; 153 154 // Class used construct version dependency graph. 155 class VersionTracker { 156 public: 157 VersionTracker() = default; 158 bool init(const soinfo* si_from); 159 160 const version_info* get_version_info(ElfW(Versym) source_symver) const; 161 private: 162 bool init_verneed(const soinfo* si_from); 163 bool init_verdef(const soinfo* si_from); 164 void add_version_info(size_t source_index, ElfW(Word) elf_hash, 165 const char* ver_name, const soinfo* target_si); 166 167 std::vector<version_info> version_infos; 168 169 DISALLOW_COPY_AND_ASSIGN(VersionTracker); 170 }; 171 172 struct soinfo { 173 public: 174 typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t; 175 #if defined(__work_around_b_19059885__) 176 private: 177 char old_name_[SOINFO_NAME_LEN]; 178 #endif 179 public: 180 const ElfW(Phdr)* phdr; 181 size_t phnum; 182 ElfW(Addr) entry; 183 ElfW(Addr) base; 184 size_t size; 185 186 #if defined(__work_around_b_19059885__) 187 uint32_t unused1; // DO NOT USE, maintained for compatibility. 188 #endif 189 190 ElfW(Dyn)* dynamic; 191 192 #if defined(__work_around_b_19059885__) 193 uint32_t unused2; // DO NOT USE, maintained for compatibility 194 uint32_t unused3; // DO NOT USE, maintained for compatibility 195 #endif 196 197 soinfo* next; 198 private: 199 uint32_t flags_; 200 201 const char* strtab_; 202 ElfW(Sym)* symtab_; 203 204 size_t nbucket_; 205 size_t nchain_; 206 uint32_t* bucket_; 207 uint32_t* chain_; 208 209 #if defined(__mips__) || !defined(__LP64__) 210 // This is only used by mips and mips64, but needs to be here for 211 // all 32-bit architectures to preserve binary compatibility. 212 ElfW(Addr)** plt_got_; 213 #endif 214 215 #if defined(USE_RELA) 216 ElfW(Rela)* plt_rela_; 217 size_t plt_rela_count_; 218 219 ElfW(Rela)* rela_; 220 size_t rela_count_; 221 #else 222 ElfW(Rel)* plt_rel_; 223 size_t plt_rel_count_; 224 225 ElfW(Rel)* rel_; 226 size_t rel_count_; 227 #endif 228 229 linker_function_t* preinit_array_; 230 size_t preinit_array_count_; 231 232 linker_function_t* init_array_; 233 size_t init_array_count_; 234 linker_function_t* fini_array_; 235 size_t fini_array_count_; 236 237 linker_function_t init_func_; 238 linker_function_t fini_func_; 239 240 #if defined(__arm__) 241 public: 242 // ARM EABI section used for stack unwinding. 243 uint32_t* ARM_exidx; 244 size_t ARM_exidx_count; 245 private: 246 #elif defined(__mips__) 247 uint32_t mips_symtabno_; 248 uint32_t mips_local_gotno_; 249 uint32_t mips_gotsym_; 250 bool mips_relocate_got(const VersionTracker& version_tracker, 251 const soinfo_list_t& global_group, 252 const soinfo_list_t& local_group); 253 254 #endif 255 size_t ref_count_; 256 public: 257 link_map link_map_head; 258 259 bool constructors_called; 260 261 // When you read a virtual address from the ELF file, add this 262 // value to get the corresponding address in the process' address space. 263 ElfW(Addr) load_bias; 264 265 #if !defined(__LP64__) 266 bool has_text_relocations; 267 #endif 268 bool has_DT_SYMBOLIC; 269 270 public: 271 soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags); 272 273 void call_constructors(); 274 void call_destructors(); 275 void call_pre_init_constructors(); 276 bool prelink_image(); 277 bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group, 278 const android_dlextinfo* extinfo); 279 280 void add_child(soinfo* child); 281 void remove_all_links(); 282 283 ino_t get_st_ino() const; 284 dev_t get_st_dev() const; 285 off64_t get_file_offset() const; 286 287 uint32_t get_rtld_flags() const; 288 uint32_t get_dt_flags_1() const; 289 void set_dt_flags_1(uint32_t dt_flags_1); 290 291 soinfo_list_t& get_children(); 292 const soinfo_list_t& get_children() const; 293 294 soinfo_list_t& get_parents(); 295 296 bool find_symbol_by_name(SymbolName& symbol_name, 297 const version_info* vi, 298 const ElfW(Sym)** symbol) const; 299 300 ElfW(Sym)* find_symbol_by_address(const void* addr); 301 ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const; 302 303 const char* get_string(ElfW(Word) index) const; 304 bool can_unload() const; 305 bool is_gnu_hash() const; 306 has_min_versionsoinfo307 bool inline has_min_version(uint32_t min_version __unused) const { 308 #if defined(__work_around_b_19059885__) 309 return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version; 310 #else 311 return true; 312 #endif 313 } 314 315 bool is_linked() const; 316 bool is_main_executable() const; 317 318 void set_linked(); 319 void set_linker_flag(); 320 void set_main_executable(); 321 322 void increment_ref_count(); 323 size_t decrement_ref_count(); 324 325 soinfo* get_local_group_root() const; 326 327 const char* get_soname() const; 328 const char* get_realpath() const; 329 const ElfW(Versym)* get_versym(size_t n) const; 330 ElfW(Addr) get_verneed_ptr() const; 331 size_t get_verneed_cnt() const; 332 ElfW(Addr) get_verdef_ptr() const; 333 size_t get_verdef_cnt() const; 334 335 bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const; 336 337 uint32_t get_target_sdk_version() const; 338 339 private: 340 bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 341 ElfW(Sym)* elf_addr_lookup(const void* addr); 342 bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 343 ElfW(Sym)* gnu_addr_lookup(const void* addr); 344 345 bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym, 346 const char* sym_name, const version_info** vi); 347 348 void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse); 349 void call_function(const char* function_name, linker_function_t function); 350 template<typename ElfRelIteratorT> 351 bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator, 352 const soinfo_list_t& global_group, const soinfo_list_t& local_group); 353 354 private: 355 // This part of the structure is only available 356 // when FLAG_NEW_SOINFO is set in this->flags. 357 uint32_t version_; 358 359 // version >= 0 360 dev_t st_dev_; 361 ino_t st_ino_; 362 363 // dependency graph 364 soinfo_list_t children_; 365 soinfo_list_t parents_; 366 367 // version >= 1 368 off64_t file_offset_; 369 uint32_t rtld_flags_; 370 uint32_t dt_flags_1_; 371 size_t strtab_size_; 372 373 // version >= 2 374 375 size_t gnu_nbucket_; 376 uint32_t* gnu_bucket_; 377 uint32_t* gnu_chain_; 378 uint32_t gnu_maskwords_; 379 uint32_t gnu_shift2_; 380 ElfW(Addr)* gnu_bloom_filter_; 381 382 soinfo* local_group_root_; 383 384 uint8_t* android_relocs_; 385 size_t android_relocs_size_; 386 387 const char* soname_; 388 std::string realpath_; 389 390 const ElfW(Versym)* versym_; 391 392 ElfW(Addr) verdef_ptr_; 393 size_t verdef_cnt_; 394 395 ElfW(Addr) verneed_ptr_; 396 size_t verneed_cnt_; 397 398 uint32_t target_sdk_version_; 399 400 friend soinfo* get_libdl_info(); 401 }; 402 403 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi, 404 soinfo** si_found_in, const soinfo::soinfo_list_t& global_group, 405 const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol); 406 407 enum RelocationKind { 408 kRelocAbsolute = 0, 409 kRelocRelative, 410 kRelocCopy, 411 kRelocSymbol, 412 kRelocMax 413 }; 414 415 void count_relocation(RelocationKind kind); 416 417 soinfo* get_libdl_info(); 418 419 void do_android_get_LD_LIBRARY_PATH(char*, size_t); 420 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path); 421 soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo); 422 void do_dlclose(soinfo* si); 423 424 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data); 425 426 const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle); 427 soinfo* find_containing_library(const void* addr); 428 429 const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name); 430 431 void debuggerd_init(); 432 extern "C" abort_msg_t* g_abort_message; 433 extern "C" void notify_gdb_of_libraries(); 434 435 char* linker_get_error_buffer(); 436 size_t linker_get_error_buffer_size(); 437 438 void set_application_target_sdk_version(uint32_t target); 439 uint32_t get_application_target_sdk_version(); 440 441 #endif 442