Home | History | Annotate | Download | only in linker
      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 #include <android/api-level.h>
     30 #include <errno.h>
     31 #include <fcntl.h>
     32 #include <inttypes.h>
     33 #include <pthread.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <sys/mman.h>
     38 #include <sys/param.h>
     39 #include <sys/vfs.h>
     40 #include <unistd.h>
     41 
     42 #include <new>
     43 #include <string>
     44 #include <unordered_map>
     45 #include <vector>
     46 
     47 #include <android-base/properties.h>
     48 #include <android-base/scopeguard.h>
     49 
     50 #include <async_safe/log.h>
     51 
     52 // Private C library headers.
     53 
     54 #include "linker.h"
     55 #include "linker_block_allocator.h"
     56 #include "linker_cfi.h"
     57 #include "linker_config.h"
     58 #include "linker_gdb_support.h"
     59 #include "linker_globals.h"
     60 #include "linker_debug.h"
     61 #include "linker_dlwarning.h"
     62 #include "linker_main.h"
     63 #include "linker_namespaces.h"
     64 #include "linker_sleb128.h"
     65 #include "linker_phdr.h"
     66 #include "linker_relocs.h"
     67 #include "linker_reloc_iterators.h"
     68 #include "linker_utils.h"
     69 
     70 #include "android-base/macros.h"
     71 #include "android-base/strings.h"
     72 #include "android-base/stringprintf.h"
     73 #include "ziparchive/zip_archive.h"
     74 
     75 // Override macros to use C++ style casts.
     76 #undef ELF_ST_TYPE
     77 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
     78 
     79 static std::unordered_map<void*, size_t> g_dso_handle_counters;
     80 
     81 static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
     82 static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
     83 
     84 static LinkerTypeAllocator<soinfo> g_soinfo_allocator;
     85 static LinkerTypeAllocator<LinkedListEntry<soinfo>> g_soinfo_links_allocator;
     86 
     87 static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
     88 static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
     89 
     90 static const char* const kLdConfigArchFilePath = "/system/etc/ld.config." ABI_STRING ".txt";
     91 
     92 static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
     93 static const char* const kLdConfigVndkLiteFilePath = "/system/etc/ld.config.vndk_lite.txt";
     94 
     95 #if defined(__LP64__)
     96 static const char* const kSystemLibDir     = "/system/lib64";
     97 static const char* const kOdmLibDir        = "/odm/lib64";
     98 static const char* const kVendorLibDir     = "/vendor/lib64";
     99 static const char* const kAsanSystemLibDir = "/data/asan/system/lib64";
    100 static const char* const kAsanOdmLibDir    = "/data/asan/odm/lib64";
    101 static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib64";
    102 #else
    103 static const char* const kSystemLibDir     = "/system/lib";
    104 static const char* const kOdmLibDir        = "/odm/lib";
    105 static const char* const kVendorLibDir     = "/vendor/lib";
    106 static const char* const kAsanSystemLibDir = "/data/asan/system/lib";
    107 static const char* const kAsanOdmLibDir    = "/data/asan/odm/lib";
    108 static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib";
    109 #endif
    110 
    111 static const char* const kAsanLibDirPrefix = "/data/asan";
    112 
    113 static const char* const kDefaultLdPaths[] = {
    114   kSystemLibDir,
    115   kOdmLibDir,
    116   kVendorLibDir,
    117   nullptr
    118 };
    119 
    120 static const char* const kAsanDefaultLdPaths[] = {
    121   kAsanSystemLibDir,
    122   kSystemLibDir,
    123   kAsanOdmLibDir,
    124   kOdmLibDir,
    125   kAsanVendorLibDir,
    126   kVendorLibDir,
    127   nullptr
    128 };
    129 
    130 // Is ASAN enabled?
    131 static bool g_is_asan = false;
    132 
    133 static CFIShadowWriter g_cfi_shadow;
    134 
    135 CFIShadowWriter* get_cfi_shadow() {
    136   return &g_cfi_shadow;
    137 }
    138 
    139 static bool is_system_library(const std::string& realpath) {
    140   for (const auto& dir : g_default_namespace.get_default_library_paths()) {
    141     if (file_is_in_dir(realpath, dir)) {
    142       return true;
    143     }
    144   }
    145   return false;
    146 }
    147 
    148 // Checks if the file exists and not a directory.
    149 static bool file_exists(const char* path) {
    150   struct stat s;
    151 
    152   if (stat(path, &s) != 0) {
    153     return false;
    154   }
    155 
    156   return S_ISREG(s.st_mode);
    157 }
    158 
    159 static std::string resolve_soname(const std::string& name) {
    160   // We assume that soname equals to basename here
    161 
    162   // TODO(dimitry): consider having honest absolute-path -> soname resolution
    163   // note that since we might end up refusing to load this library because
    164   // it is not in shared libs list we need to get the soname without actually loading
    165   // the library.
    166   //
    167   // On the other hand there are several places where we already assume that
    168   // soname == basename in particular for any not-loaded library mentioned
    169   // in DT_NEEDED list.
    170   return basename(name.c_str());
    171 }
    172 
    173 static bool maybe_accessible_via_namespace_links(android_namespace_t* ns, const char* name) {
    174   std::string soname = resolve_soname(name);
    175   for (auto& ns_link : ns->linked_namespaces()) {
    176     if (ns_link.is_accessible(soname.c_str())) {
    177       return true;
    178     }
    179   }
    180 
    181   return false;
    182 }
    183 
    184 // TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
    185 // gradually remove libraries from this list until it is gone.
    186 static bool is_greylisted(android_namespace_t* ns, const char* name, const soinfo* needed_by) {
    187   static const char* const kLibraryGreyList[] = {
    188     "libandroid_runtime.so",
    189     "libbinder.so",
    190     "libcrypto.so",
    191     "libcutils.so",
    192     "libexpat.so",
    193     "libgui.so",
    194     "libmedia.so",
    195     "libnativehelper.so",
    196     "libskia.so",
    197     "libssl.so",
    198     "libstagefright.so",
    199     "libsqlite.so",
    200     "libui.so",
    201     "libutils.so",
    202     "libvorbisidec.so",
    203     nullptr
    204   };
    205 
    206   // If you're targeting N, you don't get the greylist.
    207   if (g_greylist_disabled || get_application_target_sdk_version() >= __ANDROID_API_N__) {
    208     return false;
    209   }
    210 
    211   // if the library needed by a system library - implicitly assume it
    212   // is greylisted unless it is in the list of shared libraries for one or
    213   // more linked namespaces
    214   if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
    215     return !maybe_accessible_via_namespace_links(ns, name);
    216   }
    217 
    218   // if this is an absolute path - make sure it points to /system/lib(64)
    219   if (name[0] == '/' && dirname(name) == kSystemLibDir) {
    220     // and reduce the path to basename
    221     name = basename(name);
    222   }
    223 
    224   for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
    225     if (strcmp(name, kLibraryGreyList[i]) == 0) {
    226       return true;
    227     }
    228   }
    229 
    230   return false;
    231 }
    232 // END OF WORKAROUND
    233 
    234 static std::vector<std::string> g_ld_preload_names;
    235 
    236 static bool g_anonymous_namespace_initialized;
    237 
    238 #if STATS
    239 struct linker_stats_t {
    240   int count[kRelocMax];
    241 };
    242 
    243 static linker_stats_t linker_stats;
    244 
    245 void count_relocation(RelocationKind kind) {
    246   ++linker_stats.count[kind];
    247 }
    248 #else
    249 void count_relocation(RelocationKind) {
    250 }
    251 #endif
    252 
    253 #if COUNT_PAGES
    254 uint32_t bitmask[4096];
    255 #endif
    256 
    257 static void notify_gdb_of_load(soinfo* info) {
    258   if (info->is_linker() || info->is_main_executable()) {
    259     // gdb already knows about the linker and the main executable.
    260     return;
    261   }
    262 
    263   link_map* map = &(info->link_map_head);
    264 
    265   map->l_addr = info->load_bias;
    266   // link_map l_name field is not const.
    267   map->l_name = const_cast<char*>(info->get_realpath());
    268   map->l_ld = info->dynamic;
    269 
    270   CHECK(map->l_name != nullptr);
    271   CHECK(map->l_name[0] != '\0');
    272 
    273   notify_gdb_of_load(map);
    274 }
    275 
    276 static void notify_gdb_of_unload(soinfo* info) {
    277   notify_gdb_of_unload(&(info->link_map_head));
    278 }
    279 
    280 LinkedListEntry<soinfo>* SoinfoListAllocator::alloc() {
    281   return g_soinfo_links_allocator.alloc();
    282 }
    283 
    284 void SoinfoListAllocator::free(LinkedListEntry<soinfo>* entry) {
    285   g_soinfo_links_allocator.free(entry);
    286 }
    287 
    288 LinkedListEntry<android_namespace_t>* NamespaceListAllocator::alloc() {
    289   return g_namespace_list_allocator.alloc();
    290 }
    291 
    292 void NamespaceListAllocator::free(LinkedListEntry<android_namespace_t>* entry) {
    293   g_namespace_list_allocator.free(entry);
    294 }
    295 
    296 soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
    297                      struct stat* file_stat, off64_t file_offset,
    298                      uint32_t rtld_flags) {
    299   if (strlen(name) >= PATH_MAX) {
    300     async_safe_fatal("library name \"%s\" too long", name);
    301   }
    302 
    303   TRACE("name %s: allocating soinfo for ns=%p", name, ns);
    304 
    305   soinfo* si = new (g_soinfo_allocator.alloc()) soinfo(ns, name, file_stat,
    306                                                        file_offset, rtld_flags);
    307 
    308   solist_add_soinfo(si);
    309 
    310   si->generate_handle();
    311   ns->add_soinfo(si);
    312 
    313   TRACE("name %s: allocated soinfo @ %p", name, si);
    314   return si;
    315 }
    316 
    317 static void soinfo_free(soinfo* si) {
    318   if (si == nullptr) {
    319     return;
    320   }
    321 
    322   if (si->base != 0 && si->size != 0) {
    323     if (!si->is_mapped_by_caller()) {
    324       munmap(reinterpret_cast<void*>(si->base), si->size);
    325     } else {
    326       // remap the region as PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE
    327       mmap(reinterpret_cast<void*>(si->base), si->size, PROT_NONE,
    328            MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
    329     }
    330   }
    331 
    332   TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
    333 
    334   if (!solist_remove_soinfo(si)) {
    335     async_safe_fatal("soinfo=%p is not in soinfo_list (double unload?)", si);
    336   }
    337 
    338   // clear links to/from si
    339   si->remove_all_links();
    340 
    341   si->~soinfo();
    342   g_soinfo_allocator.free(si);
    343 }
    344 
    345 static void parse_path(const char* path, const char* delimiters,
    346                        std::vector<std::string>* resolved_paths) {
    347   std::vector<std::string> paths;
    348   split_path(path, delimiters, &paths);
    349   resolve_paths(paths, resolved_paths);
    350 }
    351 
    352 static void parse_LD_LIBRARY_PATH(const char* path) {
    353   std::vector<std::string> ld_libary_paths;
    354   parse_path(path, ":", &ld_libary_paths);
    355   g_default_namespace.set_ld_library_paths(std::move(ld_libary_paths));
    356 }
    357 
    358 static bool realpath_fd(int fd, std::string* realpath) {
    359   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
    360   async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
    361   if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
    362     PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
    363     return false;
    364   }
    365 
    366   *realpath = &buf[0];
    367   return true;
    368 }
    369 
    370 #if defined(__arm__)
    371 
    372 // For a given PC, find the .so that it belongs to.
    373 // Returns the base address of the .ARM.exidx section
    374 // for that .so, and the number of 8-byte entries
    375 // in that section (via *pcount).
    376 //
    377 // Intended to be called by libc's __gnu_Unwind_Find_exidx().
    378 _Unwind_Ptr do_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
    379   for (soinfo* si = solist_get_head(); si != 0; si = si->next) {
    380     if ((pc >= si->base) && (pc < (si->base + si->size))) {
    381         *pcount = si->ARM_exidx_count;
    382         return reinterpret_cast<_Unwind_Ptr>(si->ARM_exidx);
    383     }
    384   }
    385   *pcount = 0;
    386   return 0;
    387 }
    388 
    389 #endif
    390 
    391 // Here, we only have to provide a callback to iterate across all the
    392 // loaded libraries. gcc_eh does the rest.
    393 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
    394   int rv = 0;
    395   for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
    396     dl_phdr_info dl_info;
    397     dl_info.dlpi_addr = si->link_map_head.l_addr;
    398     dl_info.dlpi_name = si->link_map_head.l_name;
    399     dl_info.dlpi_phdr = si->phdr;
    400     dl_info.dlpi_phnum = si->phnum;
    401     rv = cb(&dl_info, sizeof(dl_phdr_info), data);
    402     if (rv != 0) {
    403       break;
    404     }
    405   }
    406   return rv;
    407 }
    408 
    409 
    410 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
    411                       soinfo** si_found_in, const soinfo_list_t& global_group,
    412                       const soinfo_list_t& local_group, const ElfW(Sym)** symbol) {
    413   SymbolName symbol_name(name);
    414   const ElfW(Sym)* s = nullptr;
    415 
    416   /* "This element's presence in a shared object library alters the dynamic linker's
    417    * symbol resolution algorithm for references within the library. Instead of starting
    418    * a symbol search with the executable file, the dynamic linker starts from the shared
    419    * object itself. If the shared object fails to supply the referenced symbol, the
    420    * dynamic linker then searches the executable file and other shared objects as usual."
    421    *
    422    * http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html
    423    *
    424    * Note that this is unlikely since static linker avoids generating
    425    * relocations for -Bsymbolic linked dynamic executables.
    426    */
    427   if (si_from->has_DT_SYMBOLIC) {
    428     DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
    429     if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
    430       return false;
    431     }
    432 
    433     if (s != nullptr) {
    434       *si_found_in = si_from;
    435     }
    436   }
    437 
    438   // 1. Look for it in global_group
    439   if (s == nullptr) {
    440     bool error = false;
    441     global_group.visit([&](soinfo* global_si) {
    442       DEBUG("%s: looking up %s in %s (from global group)",
    443           si_from->get_realpath(), name, global_si->get_realpath());
    444       if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
    445         error = true;
    446         return false;
    447       }
    448 
    449       if (s != nullptr) {
    450         *si_found_in = global_si;
    451         return false;
    452       }
    453 
    454       return true;
    455     });
    456 
    457     if (error) {
    458       return false;
    459     }
    460   }
    461 
    462   // 2. Look for it in the local group
    463   if (s == nullptr) {
    464     bool error = false;
    465     local_group.visit([&](soinfo* local_si) {
    466       if (local_si == si_from && si_from->has_DT_SYMBOLIC) {
    467         // we already did this - skip
    468         return true;
    469       }
    470 
    471       DEBUG("%s: looking up %s in %s (from local group)",
    472           si_from->get_realpath(), name, local_si->get_realpath());
    473       if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
    474         error = true;
    475         return false;
    476       }
    477 
    478       if (s != nullptr) {
    479         *si_found_in = local_si;
    480         return false;
    481       }
    482 
    483       return true;
    484     });
    485 
    486     if (error) {
    487       return false;
    488     }
    489   }
    490 
    491   if (s != nullptr) {
    492     TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
    493                "found in %s, base = %p, load bias = %p",
    494                si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
    495                (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
    496                reinterpret_cast<void*>((*si_found_in)->load_bias));
    497   }
    498 
    499   *symbol = s;
    500   return true;
    501 }
    502 
    503 ProtectedDataGuard::ProtectedDataGuard() {
    504   if (ref_count_++ == 0) {
    505     protect_data(PROT_READ | PROT_WRITE);
    506   }
    507 
    508   if (ref_count_ == 0) { // overflow
    509     async_safe_fatal("Too many nested calls to dlopen()");
    510   }
    511 }
    512 
    513 ProtectedDataGuard::~ProtectedDataGuard() {
    514   if (--ref_count_ == 0) {
    515     protect_data(PROT_READ);
    516   }
    517 }
    518 
    519 void ProtectedDataGuard::protect_data(int protection) {
    520   g_soinfo_allocator.protect_all(protection);
    521   g_soinfo_links_allocator.protect_all(protection);
    522   g_namespace_allocator.protect_all(protection);
    523   g_namespace_list_allocator.protect_all(protection);
    524 }
    525 
    526 size_t ProtectedDataGuard::ref_count_ = 0;
    527 
    528 // Each size has it's own allocator.
    529 template<size_t size>
    530 class SizeBasedAllocator {
    531  public:
    532   static void* alloc() {
    533     return allocator_.alloc();
    534   }
    535 
    536   static void free(void* ptr) {
    537     allocator_.free(ptr);
    538   }
    539 
    540  private:
    541   static LinkerBlockAllocator allocator_;
    542 };
    543 
    544 template<size_t size>
    545 LinkerBlockAllocator SizeBasedAllocator<size>::allocator_(size);
    546 
    547 template<typename T>
    548 class TypeBasedAllocator {
    549  public:
    550   static T* alloc() {
    551     return reinterpret_cast<T*>(SizeBasedAllocator<sizeof(T)>::alloc());
    552   }
    553 
    554   static void free(T* ptr) {
    555     SizeBasedAllocator<sizeof(T)>::free(ptr);
    556   }
    557 };
    558 
    559 class LoadTask {
    560  public:
    561   struct deleter_t {
    562     void operator()(LoadTask* t) {
    563       t->~LoadTask();
    564       TypeBasedAllocator<LoadTask>::free(t);
    565     }
    566   };
    567 
    568   static deleter_t deleter;
    569 
    570   static LoadTask* create(const char* name,
    571                           soinfo* needed_by,
    572                           android_namespace_t* start_from,
    573                           std::unordered_map<const soinfo*, ElfReader>* readers_map) {
    574     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
    575     return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
    576   }
    577 
    578   const char* get_name() const {
    579     return name_;
    580   }
    581 
    582   soinfo* get_needed_by() const {
    583     return needed_by_;
    584   }
    585 
    586   soinfo* get_soinfo() const {
    587     return si_;
    588   }
    589 
    590   void set_soinfo(soinfo* si) {
    591     si_ = si;
    592   }
    593 
    594   off64_t get_file_offset() const {
    595     return file_offset_;
    596   }
    597 
    598   void set_file_offset(off64_t offset) {
    599     file_offset_ = offset;
    600   }
    601 
    602   int get_fd() const {
    603     return fd_;
    604   }
    605 
    606   void set_fd(int fd, bool assume_ownership) {
    607     fd_ = fd;
    608     close_fd_ = assume_ownership;
    609   }
    610 
    611   const android_dlextinfo* get_extinfo() const {
    612     return extinfo_;
    613   }
    614 
    615   void set_extinfo(const android_dlextinfo* extinfo) {
    616     extinfo_ = extinfo;
    617   }
    618 
    619   bool is_dt_needed() const {
    620     return is_dt_needed_;
    621   }
    622 
    623   void set_dt_needed(bool is_dt_needed) {
    624     is_dt_needed_ = is_dt_needed;
    625   }
    626 
    627   // returns the namespace from where we need to start loading this.
    628   const android_namespace_t* get_start_from() const {
    629     return start_from_;
    630   }
    631 
    632   const ElfReader& get_elf_reader() const {
    633     CHECK(si_ != nullptr);
    634     return (*elf_readers_map_)[si_];
    635   }
    636 
    637   ElfReader& get_elf_reader() {
    638     CHECK(si_ != nullptr);
    639     return (*elf_readers_map_)[si_];
    640   }
    641 
    642   std::unordered_map<const soinfo*, ElfReader>* get_readers_map() {
    643     return elf_readers_map_;
    644   }
    645 
    646   bool read(const char* realpath, off64_t file_size) {
    647     ElfReader& elf_reader = get_elf_reader();
    648     return elf_reader.Read(realpath, fd_, file_offset_, file_size);
    649   }
    650 
    651   bool load() {
    652     ElfReader& elf_reader = get_elf_reader();
    653     if (!elf_reader.Load(extinfo_)) {
    654       return false;
    655     }
    656 
    657     si_->base = elf_reader.load_start();
    658     si_->size = elf_reader.load_size();
    659     si_->set_mapped_by_caller(elf_reader.is_mapped_by_caller());
    660     si_->load_bias = elf_reader.load_bias();
    661     si_->phnum = elf_reader.phdr_count();
    662     si_->phdr = elf_reader.loaded_phdr();
    663 
    664     return true;
    665   }
    666 
    667  private:
    668   LoadTask(const char* name,
    669            soinfo* needed_by,
    670            android_namespace_t* start_from,
    671            std::unordered_map<const soinfo*, ElfReader>* readers_map)
    672     : name_(name), needed_by_(needed_by), si_(nullptr),
    673       fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
    674       is_dt_needed_(false), start_from_(start_from) {}
    675 
    676   ~LoadTask() {
    677     if (fd_ != -1 && close_fd_) {
    678       close(fd_);
    679     }
    680   }
    681 
    682   const char* name_;
    683   soinfo* needed_by_;
    684   soinfo* si_;
    685   const android_dlextinfo* extinfo_;
    686   int fd_;
    687   bool close_fd_;
    688   off64_t file_offset_;
    689   std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
    690   // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
    691   bool is_dt_needed_;
    692   // END OF WORKAROUND
    693   const android_namespace_t* const start_from_;
    694 
    695   DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
    696 };
    697 
    698 LoadTask::deleter_t LoadTask::deleter;
    699 
    700 template <typename T>
    701 using linked_list_t = LinkedList<T, TypeBasedAllocator<LinkedListEntry<T>>>;
    702 
    703 typedef linked_list_t<soinfo> SoinfoLinkedList;
    704 typedef linked_list_t<const char> StringLinkedList;
    705 typedef std::vector<LoadTask*> LoadTaskList;
    706 
    707 enum walk_action_result_t : uint32_t {
    708   kWalkStop = 0,
    709   kWalkContinue = 1,
    710   kWalkSkip = 2
    711 };
    712 
    713 // This function walks down the tree of soinfo dependencies
    714 // in breadth-first order and
    715 //   * calls action(soinfo* si) for each node, and
    716 //   * terminates walk if action returns kWalkStop
    717 //   * skips children of the node if action
    718 //     return kWalkSkip
    719 //
    720 // walk_dependencies_tree returns false if walk was terminated
    721 // by the action and true otherwise.
    722 template<typename F>
    723 static bool walk_dependencies_tree(soinfo* root_soinfo, F action) {
    724   SoinfoLinkedList visit_list;
    725   SoinfoLinkedList visited;
    726 
    727   visit_list.push_back(root_soinfo);
    728 
    729   soinfo* si;
    730   while ((si = visit_list.pop_front()) != nullptr) {
    731     if (visited.contains(si)) {
    732       continue;
    733     }
    734 
    735     walk_action_result_t result = action(si);
    736 
    737     if (result == kWalkStop) {
    738       return false;
    739     }
    740 
    741     visited.push_back(si);
    742 
    743     if (result != kWalkSkip) {
    744       si->get_children().for_each([&](soinfo* child) {
    745         visit_list.push_back(child);
    746       });
    747     }
    748   }
    749 
    750   return true;
    751 }
    752 
    753 
    754 static const ElfW(Sym)* dlsym_handle_lookup(android_namespace_t* ns,
    755                                             soinfo* root,
    756                                             soinfo* skip_until,
    757                                             soinfo** found,
    758                                             SymbolName& symbol_name,
    759                                             const version_info* vi) {
    760   const ElfW(Sym)* result = nullptr;
    761   bool skip_lookup = skip_until != nullptr;
    762 
    763   walk_dependencies_tree(root, [&](soinfo* current_soinfo) {
    764     if (skip_lookup) {
    765       skip_lookup = current_soinfo != skip_until;
    766       return kWalkContinue;
    767     }
    768 
    769     if (!ns->is_accessible(current_soinfo)) {
    770       return kWalkSkip;
    771     }
    772 
    773     if (!current_soinfo->find_symbol_by_name(symbol_name, vi, &result)) {
    774       result = nullptr;
    775       return kWalkStop;
    776     }
    777 
    778     if (result != nullptr) {
    779       *found = current_soinfo;
    780       return kWalkStop;
    781     }
    782 
    783     return kWalkContinue;
    784   });
    785 
    786   return result;
    787 }
    788 
    789 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
    790                                             const char* name,
    791                                             const version_info* vi,
    792                                             soinfo** found,
    793                                             soinfo* caller,
    794                                             void* handle);
    795 
    796 // This is used by dlsym(3).  It performs symbol lookup only within the
    797 // specified soinfo object and its dependencies in breadth first order.
    798 static const ElfW(Sym)* dlsym_handle_lookup(soinfo* si,
    799                                             soinfo** found,
    800                                             const char* name,
    801                                             const version_info* vi) {
    802   // According to man dlopen(3) and posix docs in the case when si is handle
    803   // of the main executable we need to search not only in the executable and its
    804   // dependencies but also in all libraries loaded with RTLD_GLOBAL.
    805   //
    806   // Since RTLD_GLOBAL is always set for the main executable and all dt_needed shared
    807   // libraries and they are loaded in breath-first (correct) order we can just execute
    808   // dlsym(RTLD_DEFAULT, ...); instead of doing two stage lookup.
    809   if (si == solist_get_somain()) {
    810     return dlsym_linear_lookup(&g_default_namespace, name, vi, found, nullptr, RTLD_DEFAULT);
    811   }
    812 
    813   SymbolName symbol_name(name);
    814   // note that the namespace is not the namespace associated with caller_addr
    815   // we use ns associated with root si intentionally here. Using caller_ns
    816   // causes problems when user uses dlopen_ext to open a library in the separate
    817   // namespace and then calls dlsym() on the handle.
    818   return dlsym_handle_lookup(si->get_primary_namespace(), si, nullptr, found, symbol_name, vi);
    819 }
    820 
    821 /* This is used by dlsym(3) to performs a global symbol lookup. If the
    822    start value is null (for RTLD_DEFAULT), the search starts at the
    823    beginning of the global solist. Otherwise the search starts at the
    824    specified soinfo (for RTLD_NEXT).
    825  */
    826 static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
    827                                             const char* name,
    828                                             const version_info* vi,
    829                                             soinfo** found,
    830                                             soinfo* caller,
    831                                             void* handle) {
    832   SymbolName symbol_name(name);
    833 
    834   auto& soinfo_list = ns->soinfo_list();
    835   auto start = soinfo_list.begin();
    836 
    837   if (handle == RTLD_NEXT) {
    838     if (caller == nullptr) {
    839       return nullptr;
    840     } else {
    841       auto it = soinfo_list.find(caller);
    842       CHECK (it != soinfo_list.end());
    843       start = ++it;
    844     }
    845   }
    846 
    847   const ElfW(Sym)* s = nullptr;
    848   for (auto it = start, end = soinfo_list.end(); it != end; ++it) {
    849     soinfo* si = *it;
    850     // Do not skip RTLD_LOCAL libraries in dlsym(RTLD_DEFAULT, ...)
    851     // if the library is opened by application with target api level < M.
    852     // See http://b/21565766
    853     if ((si->get_rtld_flags() & RTLD_GLOBAL) == 0 &&
    854         si->get_target_sdk_version() >= __ANDROID_API_M__) {
    855       continue;
    856     }
    857 
    858     if (!si->find_symbol_by_name(symbol_name, vi, &s)) {
    859       return nullptr;
    860     }
    861 
    862     if (s != nullptr) {
    863       *found = si;
    864       break;
    865     }
    866   }
    867 
    868   // If not found - use dlsym_handle_lookup for caller's local_group
    869   if (s == nullptr && caller != nullptr) {
    870     soinfo* local_group_root = caller->get_local_group_root();
    871 
    872     return dlsym_handle_lookup(local_group_root->get_primary_namespace(),
    873                                local_group_root,
    874                                (handle == RTLD_NEXT) ? caller : nullptr,
    875                                found,
    876                                symbol_name,
    877                                vi);
    878   }
    879 
    880   if (s != nullptr) {
    881     TRACE_TYPE(LOOKUP, "%s s->st_value = %p, found->base = %p",
    882                name, reinterpret_cast<void*>(s->st_value), reinterpret_cast<void*>((*found)->base));
    883   }
    884 
    885   return s;
    886 }
    887 
    888 soinfo* find_containing_library(const void* p) {
    889   ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
    890   for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
    891     if (address >= si->base && address - si->base < si->size) {
    892       return si;
    893     }
    894   }
    895   return nullptr;
    896 }
    897 
    898 class ZipArchiveCache {
    899  public:
    900   ZipArchiveCache() {}
    901   ~ZipArchiveCache();
    902 
    903   bool get_or_open(const char* zip_path, ZipArchiveHandle* handle);
    904  private:
    905   DISALLOW_COPY_AND_ASSIGN(ZipArchiveCache);
    906 
    907   std::unordered_map<std::string, ZipArchiveHandle> cache_;
    908 };
    909 
    910 bool ZipArchiveCache::get_or_open(const char* zip_path, ZipArchiveHandle* handle) {
    911   std::string key(zip_path);
    912 
    913   auto it = cache_.find(key);
    914   if (it != cache_.end()) {
    915     *handle = it->second;
    916     return true;
    917   }
    918 
    919   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
    920   if (fd == -1) {
    921     return false;
    922   }
    923 
    924   if (OpenArchiveFd(fd, "", handle) != 0) {
    925     // invalid zip-file (?)
    926     CloseArchive(handle);
    927     close(fd);
    928     return false;
    929   }
    930 
    931   cache_[key] = *handle;
    932   return true;
    933 }
    934 
    935 ZipArchiveCache::~ZipArchiveCache() {
    936   for (const auto& it : cache_) {
    937     CloseArchive(it.second);
    938   }
    939 }
    940 
    941 static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache,
    942                                    const char* const input_path,
    943                                    off64_t* file_offset, std::string* realpath) {
    944   std::string normalized_path;
    945   if (!normalize_path(input_path, &normalized_path)) {
    946     return -1;
    947   }
    948 
    949   const char* const path = normalized_path.c_str();
    950   TRACE("Trying zip file open from path \"%s\" -> normalized \"%s\"", input_path, path);
    951 
    952   // Treat an '!/' separator inside a path as the separator between the name
    953   // of the zip file on disk and the subdirectory to search within it.
    954   // For example, if path is "foo.zip!/bar/bas/x.so", then we search for
    955   // "bar/bas/x.so" within "foo.zip".
    956   const char* const separator = strstr(path, kZipFileSeparator);
    957   if (separator == nullptr) {
    958     return -1;
    959   }
    960 
    961   char buf[512];
    962   if (strlcpy(buf, path, sizeof(buf)) >= sizeof(buf)) {
    963     PRINT("Warning: ignoring very long library path: %s", path);
    964     return -1;
    965   }
    966 
    967   buf[separator - path] = '\0';
    968 
    969   const char* zip_path = buf;
    970   const char* file_path = &buf[separator - path + 2];
    971   int fd = TEMP_FAILURE_RETRY(open(zip_path, O_RDONLY | O_CLOEXEC));
    972   if (fd == -1) {
    973     return -1;
    974   }
    975 
    976   ZipArchiveHandle handle;
    977   if (!zip_archive_cache->get_or_open(zip_path, &handle)) {
    978     // invalid zip-file (?)
    979     close(fd);
    980     return -1;
    981   }
    982 
    983   ZipEntry entry;
    984 
    985   if (FindEntry(handle, ZipString(file_path), &entry) != 0) {
    986     // Entry was not found.
    987     close(fd);
    988     return -1;
    989   }
    990 
    991   // Check if it is properly stored
    992   if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
    993     close(fd);
    994     return -1;
    995   }
    996 
    997   *file_offset = entry.offset;
    998 
    999   if (realpath_fd(fd, realpath)) {
   1000     *realpath += separator;
   1001   } else {
   1002     PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
   1003           normalized_path.c_str());
   1004     *realpath = normalized_path;
   1005   }
   1006 
   1007   return fd;
   1008 }
   1009 
   1010 static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) {
   1011   int n = async_safe_format_buffer(buf, buf_size, "%s/%s", path, name);
   1012   if (n < 0 || n >= static_cast<int>(buf_size)) {
   1013     PRINT("Warning: ignoring very long library path: %s/%s", path, name);
   1014     return false;
   1015   }
   1016 
   1017   return true;
   1018 }
   1019 
   1020 static int open_library_on_paths(ZipArchiveCache* zip_archive_cache,
   1021                                  const char* name, off64_t* file_offset,
   1022                                  const std::vector<std::string>& paths,
   1023                                  std::string* realpath) {
   1024   for (const auto& path : paths) {
   1025     char buf[512];
   1026     if (!format_path(buf, sizeof(buf), path.c_str(), name)) {
   1027       continue;
   1028     }
   1029 
   1030     int fd = -1;
   1031     if (strstr(buf, kZipFileSeparator) != nullptr) {
   1032       fd = open_library_in_zipfile(zip_archive_cache, buf, file_offset, realpath);
   1033     }
   1034 
   1035     if (fd == -1) {
   1036       fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
   1037       if (fd != -1) {
   1038         *file_offset = 0;
   1039         if (!realpath_fd(fd, realpath)) {
   1040           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", buf);
   1041           *realpath = buf;
   1042         }
   1043       }
   1044     }
   1045 
   1046     if (fd != -1) {
   1047       return fd;
   1048     }
   1049   }
   1050 
   1051   return -1;
   1052 }
   1053 
   1054 static int open_library(android_namespace_t* ns,
   1055                         ZipArchiveCache* zip_archive_cache,
   1056                         const char* name, soinfo *needed_by,
   1057                         off64_t* file_offset, std::string* realpath) {
   1058   TRACE("[ opening %s at namespace %s]", name, ns->get_name());
   1059 
   1060   // If the name contains a slash, we should attempt to open it directly and not search the paths.
   1061   if (strchr(name, '/') != nullptr) {
   1062     int fd = -1;
   1063 
   1064     if (strstr(name, kZipFileSeparator) != nullptr) {
   1065       fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
   1066     }
   1067 
   1068     if (fd == -1) {
   1069       fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
   1070       if (fd != -1) {
   1071         *file_offset = 0;
   1072         if (!realpath_fd(fd, realpath)) {
   1073           PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", name);
   1074           *realpath = name;
   1075         }
   1076       }
   1077     }
   1078 
   1079     return fd;
   1080   }
   1081 
   1082   // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
   1083   int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
   1084   if (fd == -1 && needed_by != nullptr) {
   1085     fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
   1086     // Check if the library is accessible
   1087     if (fd != -1 && !ns->is_accessible(*realpath)) {
   1088       fd = -1;
   1089     }
   1090   }
   1091 
   1092   if (fd == -1) {
   1093     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
   1094   }
   1095 
   1096   // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
   1097   if (fd == -1 && ns->is_greylist_enabled() && is_greylisted(ns, name, needed_by)) {
   1098     // try searching for it on default_namespace default_library_path
   1099     fd = open_library_on_paths(zip_archive_cache, name, file_offset,
   1100                                g_default_namespace.get_default_library_paths(), realpath);
   1101   }
   1102   // END OF WORKAROUND
   1103 
   1104   return fd;
   1105 }
   1106 
   1107 const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
   1108 #if !defined(__LP64__)
   1109   // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
   1110   int app_target_api_level = get_application_target_sdk_version();
   1111   if (app_target_api_level < __ANDROID_API_M__) {
   1112     const char* bname = basename(dt_needed);
   1113     if (bname != dt_needed) {
   1114       DL_WARN_documented_change(__ANDROID_API_M__,
   1115                                 "invalid-dt_needed-entries-enforced-for-api-level-23",
   1116                                 "library \"%s\" has invalid DT_NEEDED entry \"%s\"",
   1117                                 sopath, dt_needed, app_target_api_level);
   1118       add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
   1119     }
   1120 
   1121     return bname;
   1122   }
   1123 #endif
   1124   return dt_needed;
   1125 }
   1126 
   1127 template<typename F>
   1128 static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
   1129   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
   1130     if (d->d_tag == DT_NEEDED) {
   1131       action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
   1132     }
   1133   }
   1134 }
   1135 
   1136 static bool find_loaded_library_by_inode(android_namespace_t* ns,
   1137                                          const struct stat& file_stat,
   1138                                          off64_t file_offset,
   1139                                          bool search_linked_namespaces,
   1140                                          soinfo** candidate) {
   1141 
   1142   auto predicate = [&](soinfo* si) {
   1143     return si->get_st_dev() != 0 &&
   1144            si->get_st_ino() != 0 &&
   1145            si->get_st_dev() == file_stat.st_dev &&
   1146            si->get_st_ino() == file_stat.st_ino &&
   1147            si->get_file_offset() == file_offset;
   1148   };
   1149 
   1150   *candidate = ns->soinfo_list().find_if(predicate);
   1151 
   1152   if (*candidate == nullptr && search_linked_namespaces) {
   1153     for (auto& link : ns->linked_namespaces()) {
   1154       android_namespace_t* linked_ns = link.linked_namespace();
   1155       soinfo* si = linked_ns->soinfo_list().find_if(predicate);
   1156 
   1157       if (si != nullptr && link.is_accessible(si->get_soname())) {
   1158         *candidate = si;
   1159         return true;
   1160       }
   1161     }
   1162   }
   1163 
   1164   return *candidate != nullptr;
   1165 }
   1166 
   1167 static bool find_loaded_library_by_realpath(android_namespace_t* ns, const char* realpath,
   1168                                             bool search_linked_namespaces, soinfo** candidate) {
   1169   auto predicate = [&](soinfo* si) { return strcmp(realpath, si->get_realpath()) == 0; };
   1170 
   1171   *candidate = ns->soinfo_list().find_if(predicate);
   1172 
   1173   if (*candidate == nullptr && search_linked_namespaces) {
   1174     for (auto& link : ns->linked_namespaces()) {
   1175       android_namespace_t* linked_ns = link.linked_namespace();
   1176       soinfo* si = linked_ns->soinfo_list().find_if(predicate);
   1177 
   1178       if (si != nullptr && link.is_accessible(si->get_soname())) {
   1179         *candidate = si;
   1180         return true;
   1181       }
   1182     }
   1183   }
   1184 
   1185   return *candidate != nullptr;
   1186 }
   1187 
   1188 static bool load_library(android_namespace_t* ns,
   1189                          LoadTask* task,
   1190                          LoadTaskList* load_tasks,
   1191                          int rtld_flags,
   1192                          const std::string& realpath,
   1193                          bool search_linked_namespaces) {
   1194   off64_t file_offset = task->get_file_offset();
   1195   const char* name = task->get_name();
   1196   const android_dlextinfo* extinfo = task->get_extinfo();
   1197 
   1198   if ((file_offset % PAGE_SIZE) != 0) {
   1199     DL_ERR("file offset for the library \"%s\" is not page-aligned: %" PRId64, name, file_offset);
   1200     return false;
   1201   }
   1202   if (file_offset < 0) {
   1203     DL_ERR("file offset for the library \"%s\" is negative: %" PRId64, name, file_offset);
   1204     return false;
   1205   }
   1206 
   1207   struct stat file_stat;
   1208   if (TEMP_FAILURE_RETRY(fstat(task->get_fd(), &file_stat)) != 0) {
   1209     DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
   1210     return false;
   1211   }
   1212   if (file_offset >= file_stat.st_size) {
   1213     DL_ERR("file offset for the library \"%s\" >= file size: %" PRId64 " >= %" PRId64,
   1214         name, file_offset, file_stat.st_size);
   1215     return false;
   1216   }
   1217 
   1218   // Check for symlink and other situations where
   1219   // file can have different names, unless ANDROID_DLEXT_FORCE_LOAD is set
   1220   if (extinfo == nullptr || (extinfo->flags & ANDROID_DLEXT_FORCE_LOAD) == 0) {
   1221     soinfo* si = nullptr;
   1222     if (find_loaded_library_by_inode(ns, file_stat, file_offset, search_linked_namespaces, &si)) {
   1223       TRACE("library \"%s\" is already loaded under different name/path \"%s\" - "
   1224             "will return existing soinfo", name, si->get_realpath());
   1225       task->set_soinfo(si);
   1226       return true;
   1227     }
   1228   }
   1229 
   1230   if ((rtld_flags & RTLD_NOLOAD) != 0) {
   1231     DL_ERR("library \"%s\" wasn't loaded and RTLD_NOLOAD prevented it", name);
   1232     return false;
   1233   }
   1234 
   1235   struct statfs fs_stat;
   1236   if (TEMP_FAILURE_RETRY(fstatfs(task->get_fd(), &fs_stat)) != 0) {
   1237     DL_ERR("unable to fstatfs file for the library \"%s\": %s", name, strerror(errno));
   1238     return false;
   1239   }
   1240 
   1241   // do not check accessibility using realpath if fd is located on tmpfs
   1242   // this enables use of memfd_create() for apps
   1243   if ((fs_stat.f_type != TMPFS_MAGIC) && (!ns->is_accessible(realpath))) {
   1244     // TODO(dimitry): workaround for http://b/26394120 - the grey-list
   1245 
   1246     // TODO(dimitry) before O release: add a namespace attribute to have this enabled
   1247     // only for classloader-namespaces
   1248     const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
   1249     if (is_greylisted(ns, name, needed_by)) {
   1250       // print warning only if needed by non-system library
   1251       if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
   1252         const soinfo* needed_or_dlopened_by = task->get_needed_by();
   1253         const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
   1254                                                       needed_or_dlopened_by->get_realpath();
   1255         DL_WARN_documented_change(__ANDROID_API_N__,
   1256                                   "private-api-enforced-for-api-level-24",
   1257                                   "library \"%s\" (\"%s\") needed or dlopened by \"%s\" "
   1258                                   "is not accessible by namespace \"%s\"",
   1259                                   name, realpath.c_str(), sopath, ns->get_name());
   1260         add_dlwarning(sopath, "unauthorized access to",  name);
   1261       }
   1262     } else {
   1263       // do not load libraries if they are not accessible for the specified namespace.
   1264       const char* needed_or_dlopened_by = task->get_needed_by() == nullptr ?
   1265                                           "(unknown)" :
   1266                                           task->get_needed_by()->get_realpath();
   1267 
   1268       DL_ERR("library \"%s\" needed or dlopened by \"%s\" is not accessible for the namespace \"%s\"",
   1269              name, needed_or_dlopened_by, ns->get_name());
   1270 
   1271       // do not print this if a library is in the list of shared libraries for linked namespaces
   1272       if (!maybe_accessible_via_namespace_links(ns, name)) {
   1273         PRINT("library \"%s\" (\"%s\") needed or dlopened by \"%s\" is not accessible for the"
   1274               " namespace: [name=\"%s\", ld_library_paths=\"%s\", default_library_paths=\"%s\","
   1275               " permitted_paths=\"%s\"]",
   1276               name, realpath.c_str(),
   1277               needed_or_dlopened_by,
   1278               ns->get_name(),
   1279               android::base::Join(ns->get_ld_library_paths(), ':').c_str(),
   1280               android::base::Join(ns->get_default_library_paths(), ':').c_str(),
   1281               android::base::Join(ns->get_permitted_paths(), ':').c_str());
   1282       }
   1283       return false;
   1284     }
   1285   }
   1286 
   1287   soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
   1288   if (si == nullptr) {
   1289     return false;
   1290   }
   1291 
   1292   task->set_soinfo(si);
   1293 
   1294   // Read the ELF header and some of the segments.
   1295   if (!task->read(realpath.c_str(), file_stat.st_size)) {
   1296     soinfo_free(si);
   1297     task->set_soinfo(nullptr);
   1298     return false;
   1299   }
   1300 
   1301   // find and set DT_RUNPATH and dt_soname
   1302   // Note that these field values are temporary and are
   1303   // going to be overwritten on soinfo::prelink_image
   1304   // with values from PT_LOAD segments.
   1305   const ElfReader& elf_reader = task->get_elf_reader();
   1306   for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
   1307     if (d->d_tag == DT_RUNPATH) {
   1308       si->set_dt_runpath(elf_reader.get_string(d->d_un.d_val));
   1309     }
   1310     if (d->d_tag == DT_SONAME) {
   1311       si->set_soname(elf_reader.get_string(d->d_un.d_val));
   1312     }
   1313   }
   1314 
   1315   for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
   1316     load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
   1317   });
   1318 
   1319   return true;
   1320 }
   1321 
   1322 static bool load_library(android_namespace_t* ns,
   1323                          LoadTask* task,
   1324                          ZipArchiveCache* zip_archive_cache,
   1325                          LoadTaskList* load_tasks,
   1326                          int rtld_flags,
   1327                          bool search_linked_namespaces) {
   1328   const char* name = task->get_name();
   1329   soinfo* needed_by = task->get_needed_by();
   1330   const android_dlextinfo* extinfo = task->get_extinfo();
   1331 
   1332   off64_t file_offset;
   1333   std::string realpath;
   1334   if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
   1335     file_offset = 0;
   1336     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
   1337       file_offset = extinfo->library_fd_offset;
   1338     }
   1339 
   1340     if (!realpath_fd(extinfo->library_fd, &realpath)) {
   1341       PRINT("warning: unable to get realpath for the library \"%s\" by extinfo->library_fd. "
   1342             "Will use given name.", name);
   1343       realpath = name;
   1344     }
   1345 
   1346     task->set_fd(extinfo->library_fd, false);
   1347     task->set_file_offset(file_offset);
   1348     return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
   1349   }
   1350 
   1351   // Open the file.
   1352   int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
   1353   if (fd == -1) {
   1354     DL_ERR("library \"%s\" not found", name);
   1355     return false;
   1356   }
   1357 
   1358   task->set_fd(fd, true);
   1359   task->set_file_offset(file_offset);
   1360 
   1361   return load_library(ns, task, load_tasks, rtld_flags, realpath, search_linked_namespaces);
   1362 }
   1363 
   1364 static bool find_loaded_library_by_soname(android_namespace_t* ns,
   1365                                           const char* name,
   1366                                           soinfo** candidate) {
   1367   return !ns->soinfo_list().visit([&](soinfo* si) {
   1368     const char* soname = si->get_soname();
   1369     if (soname != nullptr && (strcmp(name, soname) == 0)) {
   1370       *candidate = si;
   1371       return false;
   1372     }
   1373 
   1374     return true;
   1375   });
   1376 }
   1377 
   1378 // Returns true if library was found and false otherwise
   1379 static bool find_loaded_library_by_soname(android_namespace_t* ns,
   1380                                          const char* name,
   1381                                          bool search_linked_namespaces,
   1382                                          soinfo** candidate) {
   1383   *candidate = nullptr;
   1384 
   1385   // Ignore filename with path.
   1386   if (strchr(name, '/') != nullptr) {
   1387     return false;
   1388   }
   1389 
   1390   bool found = find_loaded_library_by_soname(ns, name, candidate);
   1391 
   1392   if (!found && search_linked_namespaces) {
   1393     // if a library was not found - look into linked namespaces
   1394     for (auto& link : ns->linked_namespaces()) {
   1395       if (!link.is_accessible(name)) {
   1396         continue;
   1397       }
   1398 
   1399       android_namespace_t* linked_ns = link.linked_namespace();
   1400 
   1401       if (find_loaded_library_by_soname(linked_ns, name, candidate)) {
   1402         return true;
   1403       }
   1404     }
   1405   }
   1406 
   1407   return found;
   1408 }
   1409 
   1410 static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
   1411                                              LoadTask* task) {
   1412   android_namespace_t* ns = namespace_link.linked_namespace();
   1413 
   1414   soinfo* candidate;
   1415   bool loaded = false;
   1416 
   1417   std::string soname;
   1418   if (find_loaded_library_by_soname(ns, task->get_name(), false, &candidate)) {
   1419     loaded = true;
   1420     soname = candidate->get_soname();
   1421   } else {
   1422     soname = resolve_soname(task->get_name());
   1423   }
   1424 
   1425   if (!namespace_link.is_accessible(soname.c_str())) {
   1426     // the library is not accessible via namespace_link
   1427     return false;
   1428   }
   1429 
   1430   // if library is already loaded - return it
   1431   if (loaded) {
   1432     task->set_soinfo(candidate);
   1433     return true;
   1434   }
   1435 
   1436   // returning true with empty soinfo means that the library is okay to be
   1437   // loaded in the namespace but has not yet been loaded there before.
   1438   task->set_soinfo(nullptr);
   1439   return true;
   1440 }
   1441 
   1442 static bool find_library_internal(android_namespace_t* ns,
   1443                                   LoadTask* task,
   1444                                   ZipArchiveCache* zip_archive_cache,
   1445                                   LoadTaskList* load_tasks,
   1446                                   int rtld_flags,
   1447                                   bool search_linked_namespaces) {
   1448   soinfo* candidate;
   1449 
   1450   if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) {
   1451     task->set_soinfo(candidate);
   1452     return true;
   1453   }
   1454 
   1455   // Library might still be loaded, the accurate detection
   1456   // of this fact is done by load_library.
   1457   TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",
   1458       task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
   1459 
   1460   if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) {
   1461     return true;
   1462   }
   1463 
   1464   if (search_linked_namespaces) {
   1465     // if a library was not found - look into linked namespaces
   1466     // preserve current dlerror in the case it fails.
   1467     DlErrorRestorer dlerror_restorer;
   1468     for (auto& linked_namespace : ns->linked_namespaces()) {
   1469       if (find_library_in_linked_namespace(linked_namespace,
   1470                                            task)) {
   1471         if (task->get_soinfo() == nullptr) {
   1472           // try to load the library - once namespace boundary is crossed
   1473           // we need to load a library within separate load_group
   1474           // to avoid using symbols from foreign namespace while.
   1475           //
   1476           // However, actual linking is deferred until when the global group
   1477           // is fully identified and is applied to all namespaces.
   1478           // Otherwise, the libs in the linked namespace won't get symbols from
   1479           // the global group.
   1480           if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
   1481             return true;
   1482           }
   1483         } else {
   1484           // lib is already loaded
   1485           return true;
   1486         }
   1487       }
   1488     }
   1489   }
   1490 
   1491   return false;
   1492 }
   1493 
   1494 static void soinfo_unload(soinfo* si);
   1495 
   1496 static void shuffle(std::vector<LoadTask*>* v) {
   1497   for (size_t i = 0, size = v->size(); i < size; ++i) {
   1498     size_t n = size - i;
   1499     size_t r = arc4random_uniform(n);
   1500     std::swap((*v)[n-1], (*v)[r]);
   1501   }
   1502 }
   1503 
   1504 // add_as_children - add first-level loaded libraries (i.e. library_names[], but
   1505 // not their transitive dependencies) as children of the start_with library.
   1506 // This is false when find_libraries is called for dlopen(), when newly loaded
   1507 // libraries must form a disjoint tree.
   1508 bool find_libraries(android_namespace_t* ns,
   1509                     soinfo* start_with,
   1510                     const char* const library_names[],
   1511                     size_t library_names_count,
   1512                     soinfo* soinfos[],
   1513                     std::vector<soinfo*>* ld_preloads,
   1514                     size_t ld_preloads_count,
   1515                     int rtld_flags,
   1516                     const android_dlextinfo* extinfo,
   1517                     bool add_as_children,
   1518                     bool search_linked_namespaces,
   1519                     std::vector<android_namespace_t*>* namespaces) {
   1520   // Step 0: prepare.
   1521   std::unordered_map<const soinfo*, ElfReader> readers_map;
   1522   LoadTaskList load_tasks;
   1523 
   1524   for (size_t i = 0; i < library_names_count; ++i) {
   1525     const char* name = library_names[i];
   1526     load_tasks.push_back(LoadTask::create(name, start_with, ns, &readers_map));
   1527   }
   1528 
   1529   // If soinfos array is null allocate one on stack.
   1530   // The array is needed in case of failure; for example
   1531   // when library_names[] = {libone.so, libtwo.so} and libone.so
   1532   // is loaded correctly but libtwo.so failed for some reason.
   1533   // In this case libone.so should be unloaded on return.
   1534   // See also implementation of failure_guard below.
   1535 
   1536   if (soinfos == nullptr) {
   1537     size_t soinfos_size = sizeof(soinfo*)*library_names_count;
   1538     soinfos = reinterpret_cast<soinfo**>(alloca(soinfos_size));
   1539     memset(soinfos, 0, soinfos_size);
   1540   }
   1541 
   1542   // list of libraries to link - see step 2.
   1543   size_t soinfos_count = 0;
   1544 
   1545   auto scope_guard = android::base::make_scope_guard([&]() {
   1546     for (LoadTask* t : load_tasks) {
   1547       LoadTask::deleter(t);
   1548     }
   1549   });
   1550 
   1551   ZipArchiveCache zip_archive_cache;
   1552 
   1553   // Step 1: expand the list of load_tasks to include
   1554   // all DT_NEEDED libraries (do not load them just yet)
   1555   for (size_t i = 0; i<load_tasks.size(); ++i) {
   1556     LoadTask* task = load_tasks[i];
   1557     soinfo* needed_by = task->get_needed_by();
   1558 
   1559     bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
   1560     task->set_extinfo(is_dt_needed ? nullptr : extinfo);
   1561     task->set_dt_needed(is_dt_needed);
   1562 
   1563     // Note: start from the namespace that is stored in the LoadTask. This namespace
   1564     // is different from the current namespace when the LoadTask is for a transitive
   1565     // dependency and the lib that created the LoadTask is not found in the
   1566     // current namespace but in one of the linked namespace.
   1567     if (!find_library_internal(const_cast<android_namespace_t*>(task->get_start_from()),
   1568                                task,
   1569                                &zip_archive_cache,
   1570                                &load_tasks,
   1571                                rtld_flags,
   1572                                search_linked_namespaces || is_dt_needed)) {
   1573       return false;
   1574     }
   1575 
   1576     soinfo* si = task->get_soinfo();
   1577 
   1578     if (is_dt_needed) {
   1579       needed_by->add_child(si);
   1580     }
   1581 
   1582     // When ld_preloads is not null, the first
   1583     // ld_preloads_count libs are in fact ld_preloads.
   1584     if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) {
   1585       ld_preloads->push_back(si);
   1586     }
   1587 
   1588     if (soinfos_count < library_names_count) {
   1589       soinfos[soinfos_count++] = si;
   1590     }
   1591   }
   1592 
   1593   // Step 2: Load libraries in random order (see b/24047022)
   1594   LoadTaskList load_list;
   1595   for (auto&& task : load_tasks) {
   1596     soinfo* si = task->get_soinfo();
   1597     auto pred = [&](const LoadTask* t) {
   1598       return t->get_soinfo() == si;
   1599     };
   1600 
   1601     if (!si->is_linked() &&
   1602         std::find_if(load_list.begin(), load_list.end(), pred) == load_list.end() ) {
   1603       load_list.push_back(task);
   1604     }
   1605   }
   1606   shuffle(&load_list);
   1607 
   1608   for (auto&& task : load_list) {
   1609     if (!task->load()) {
   1610       return false;
   1611     }
   1612   }
   1613 
   1614   // Step 3: pre-link all DT_NEEDED libraries in breadth first order.
   1615   for (auto&& task : load_tasks) {
   1616     soinfo* si = task->get_soinfo();
   1617     if (!si->is_linked() && !si->prelink_image()) {
   1618       return false;
   1619     }
   1620   }
   1621 
   1622   // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
   1623   // determined at step 3.
   1624 
   1625   // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they
   1626   // must be added to the global group
   1627   if (ld_preloads != nullptr) {
   1628     for (auto&& si : *ld_preloads) {
   1629       si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
   1630     }
   1631   }
   1632 
   1633   // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this
   1634   // run. These will be the new member of the global group
   1635   soinfo_list_t new_global_group_members;
   1636   for (auto&& task : load_tasks) {
   1637     soinfo* si = task->get_soinfo();
   1638     if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
   1639       new_global_group_members.push_back(si);
   1640     }
   1641   }
   1642 
   1643   // Step 4-3: Add the new global group members to all the linked namespaces
   1644   if (namespaces != nullptr) {
   1645     for (auto linked_ns : *namespaces) {
   1646       for (auto si : new_global_group_members) {
   1647         if (si->get_primary_namespace() != linked_ns) {
   1648           linked_ns->add_soinfo(si);
   1649           si->add_secondary_namespace(linked_ns);
   1650         }
   1651       }
   1652     }
   1653   }
   1654 
   1655   // Step 5: Collect roots of local_groups.
   1656   // Whenever needed_by->si link crosses a namespace boundary it forms its own local_group.
   1657   // Here we collect new roots to link them separately later on. Note that we need to avoid
   1658   // collecting duplicates. Also the order is important. They need to be linked in the same
   1659   // BFS order we link individual libraries.
   1660   std::vector<soinfo*> local_group_roots;
   1661   if (start_with != nullptr && add_as_children) {
   1662     local_group_roots.push_back(start_with);
   1663   } else {
   1664     CHECK(soinfos_count == 1);
   1665     local_group_roots.push_back(soinfos[0]);
   1666   }
   1667 
   1668   for (auto&& task : load_tasks) {
   1669     soinfo* si = task->get_soinfo();
   1670     soinfo* needed_by = task->get_needed_by();
   1671     bool is_dt_needed = needed_by != nullptr && (needed_by != start_with || add_as_children);
   1672     android_namespace_t* needed_by_ns =
   1673         is_dt_needed ? needed_by->get_primary_namespace() : ns;
   1674 
   1675     if (!si->is_linked() && si->get_primary_namespace() != needed_by_ns) {
   1676       auto it = std::find(local_group_roots.begin(), local_group_roots.end(), si);
   1677       LD_LOG(kLogDlopen,
   1678              "Crossing namespace boundary (si=%s@%p, si_ns=%s@%p, needed_by=%s@%p, ns=%s@%p, needed_by_ns=%s@%p) adding to local_group_roots: %s",
   1679              si->get_realpath(),
   1680              si,
   1681              si->get_primary_namespace()->get_name(),
   1682              si->get_primary_namespace(),
   1683              needed_by == nullptr ? "(nullptr)" : needed_by->get_realpath(),
   1684              needed_by,
   1685              ns->get_name(),
   1686              ns,
   1687              needed_by_ns->get_name(),
   1688              needed_by_ns,
   1689              it == local_group_roots.end() ? "yes" : "no");
   1690 
   1691       if (it == local_group_roots.end()) {
   1692         local_group_roots.push_back(si);
   1693       }
   1694     }
   1695   }
   1696 
   1697   // Step 6: Link all local groups
   1698   for (auto root : local_group_roots) {
   1699     soinfo_list_t local_group;
   1700     android_namespace_t* local_group_ns = root->get_primary_namespace();
   1701 
   1702     walk_dependencies_tree(root,
   1703       [&] (soinfo* si) {
   1704         if (local_group_ns->is_accessible(si)) {
   1705           local_group.push_back(si);
   1706           return kWalkContinue;
   1707         } else {
   1708           return kWalkSkip;
   1709         }
   1710       });
   1711 
   1712     soinfo_list_t global_group = local_group_ns->get_global_group();
   1713     bool linked = local_group.visit([&](soinfo* si) {
   1714       // Even though local group may contain accessible soinfos from other namesapces
   1715       // we should avoid linking them (because if they are not linked -> they
   1716       // are in the local_group_roots and will be linked later).
   1717       if (!si->is_linked() && si->get_primary_namespace() == local_group_ns) {
   1718         if (!si->link_image(global_group, local_group, extinfo) ||
   1719             !get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
   1720           return false;
   1721         }
   1722       }
   1723 
   1724       return true;
   1725     });
   1726 
   1727     if (!linked) {
   1728       return false;
   1729     }
   1730   }
   1731 
   1732   // Step 7: Mark all load_tasks as linked and increment refcounts
   1733   // for references between load_groups (at this point it does not matter if
   1734   // referenced load_groups were loaded by previous dlopen or as part of this
   1735   // one on step 6)
   1736   if (start_with != nullptr && add_as_children) {
   1737     start_with->set_linked();
   1738   }
   1739 
   1740   for (auto&& task : load_tasks) {
   1741     soinfo* si = task->get_soinfo();
   1742     si->set_linked();
   1743   }
   1744 
   1745   for (auto&& task : load_tasks) {
   1746     soinfo* si = task->get_soinfo();
   1747     soinfo* needed_by = task->get_needed_by();
   1748     if (needed_by != nullptr &&
   1749         needed_by != start_with &&
   1750         needed_by->get_local_group_root() != si->get_local_group_root()) {
   1751       si->increment_ref_count();
   1752     }
   1753   }
   1754 
   1755 
   1756   return true;
   1757 }
   1758 
   1759 static soinfo* find_library(android_namespace_t* ns,
   1760                             const char* name, int rtld_flags,
   1761                             const android_dlextinfo* extinfo,
   1762                             soinfo* needed_by) {
   1763   soinfo* si = nullptr;
   1764 
   1765   if (name == nullptr) {
   1766     si = solist_get_somain();
   1767   } else if (!find_libraries(ns,
   1768                              needed_by,
   1769                              &name,
   1770                              1,
   1771                              &si,
   1772                              nullptr,
   1773                              0,
   1774                              rtld_flags,
   1775                              extinfo,
   1776                              false /* add_as_children */,
   1777                              true /* search_linked_namespaces */)) {
   1778     if (si != nullptr) {
   1779       soinfo_unload(si);
   1780     }
   1781     return nullptr;
   1782   }
   1783 
   1784   si->increment_ref_count();
   1785 
   1786   return si;
   1787 }
   1788 
   1789 static void soinfo_unload_impl(soinfo* root) {
   1790   ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
   1791   bool is_linked = root->is_linked();
   1792 
   1793   if (!root->can_unload()) {
   1794     LD_LOG(kLogDlopen,
   1795            "... dlclose(root=\"%s\"@%p) ... not unloading - the load group is flagged with NODELETE",
   1796            root->get_realpath(),
   1797            root);
   1798     return;
   1799   }
   1800 
   1801 
   1802   soinfo_list_t unload_list;
   1803   unload_list.push_back(root);
   1804 
   1805   soinfo_list_t local_unload_list;
   1806   soinfo_list_t external_unload_list;
   1807   soinfo* si = nullptr;
   1808 
   1809   while ((si = unload_list.pop_front()) != nullptr) {
   1810     if (local_unload_list.contains(si)) {
   1811       continue;
   1812     }
   1813 
   1814     local_unload_list.push_back(si);
   1815 
   1816     if (si->has_min_version(0)) {
   1817       soinfo* child = nullptr;
   1818       while ((child = si->get_children().pop_front()) != nullptr) {
   1819         TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
   1820             child->get_realpath(), child);
   1821 
   1822         child->get_parents().remove(si);
   1823 
   1824         if (local_unload_list.contains(child)) {
   1825           continue;
   1826         } else if (child->is_linked() && child->get_local_group_root() != root) {
   1827           external_unload_list.push_back(child);
   1828         } else if (child->get_parents().empty()) {
   1829           unload_list.push_back(child);
   1830         }
   1831       }
   1832     } else {
   1833 #if !defined(__work_around_b_24465209__)
   1834       async_safe_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
   1835 #else
   1836       PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
   1837       for_each_dt_needed(si, [&] (const char* library_name) {
   1838         TRACE("deprecated (old format of soinfo): %s needs to unload %s",
   1839             si->get_realpath(), library_name);
   1840 
   1841         soinfo* needed = find_library(si->get_primary_namespace(),
   1842                                       library_name, RTLD_NOLOAD, nullptr, nullptr);
   1843 
   1844         if (needed != nullptr) {
   1845           // Not found: for example if symlink was deleted between dlopen and dlclose
   1846           // Since we cannot really handle errors at this point - print and continue.
   1847           PRINT("warning: couldn't find %s needed by %s on unload.",
   1848               library_name, si->get_realpath());
   1849           return;
   1850         } else if (local_unload_list.contains(needed)) {
   1851           // already visited
   1852           return;
   1853         } else if (needed->is_linked() && needed->get_local_group_root() != root) {
   1854           // external group
   1855           external_unload_list.push_back(needed);
   1856         } else {
   1857           // local group
   1858           unload_list.push_front(needed);
   1859         }
   1860       });
   1861 #endif
   1862     }
   1863   }
   1864 
   1865   local_unload_list.for_each([](soinfo* si) {
   1866     LD_LOG(kLogDlopen,
   1867            "... dlclose: calling destructors for \"%s\"@%p ... ",
   1868            si->get_realpath(),
   1869            si);
   1870     si->call_destructors();
   1871     LD_LOG(kLogDlopen,
   1872            "... dlclose: calling destructors for \"%s\"@%p ... done",
   1873            si->get_realpath(),
   1874            si);
   1875   });
   1876 
   1877   while ((si = local_unload_list.pop_front()) != nullptr) {
   1878     LD_LOG(kLogDlopen,
   1879            "... dlclose: unloading \"%s\"@%p ...",
   1880            si->get_realpath(),
   1881            si);
   1882     notify_gdb_of_unload(si);
   1883     get_cfi_shadow()->BeforeUnload(si);
   1884     soinfo_free(si);
   1885   }
   1886 
   1887   if (is_linked) {
   1888     while ((si = external_unload_list.pop_front()) != nullptr) {
   1889       LD_LOG(kLogDlopen,
   1890              "... dlclose: unloading external reference \"%s\"@%p ...",
   1891              si->get_realpath(),
   1892              si);
   1893       soinfo_unload(si);
   1894     }
   1895   } else {
   1896       LD_LOG(kLogDlopen,
   1897              "... dlclose: unload_si was not linked - not unloading external references ...");
   1898   }
   1899 }
   1900 
   1901 static void soinfo_unload(soinfo* unload_si) {
   1902   // Note that the library can be loaded but not linked;
   1903   // in which case there is no root but we still need
   1904   // to walk the tree and unload soinfos involved.
   1905   //
   1906   // This happens on unsuccessful dlopen, when one of
   1907   // the DT_NEEDED libraries could not be linked/found.
   1908   bool is_linked = unload_si->is_linked();
   1909   soinfo* root = is_linked ? unload_si->get_local_group_root() : unload_si;
   1910 
   1911   LD_LOG(kLogDlopen,
   1912          "... dlclose(realpath=\"%s\"@%p) ... load group root is \"%s\"@%p",
   1913          unload_si->get_realpath(),
   1914          unload_si,
   1915          root->get_realpath(),
   1916          root);
   1917 
   1918 
   1919   size_t ref_count = is_linked ? root->decrement_ref_count() : 0;
   1920   if (ref_count > 0) {
   1921     LD_LOG(kLogDlopen,
   1922            "... dlclose(root=\"%s\"@%p) ... not unloading - decrementing ref_count to %zd",
   1923            root->get_realpath(),
   1924            root,
   1925            ref_count);
   1926     return;
   1927   }
   1928 
   1929   soinfo_unload_impl(root);
   1930 }
   1931 
   1932 void increment_dso_handle_reference_counter(void* dso_handle) {
   1933   if (dso_handle == nullptr) {
   1934     return;
   1935   }
   1936 
   1937   auto it = g_dso_handle_counters.find(dso_handle);
   1938   if (it != g_dso_handle_counters.end()) {
   1939     CHECK(++it->second != 0);
   1940   } else {
   1941     soinfo* si = find_containing_library(dso_handle);
   1942     if (si != nullptr) {
   1943       ProtectedDataGuard guard;
   1944       si->set_tls_nodelete();
   1945     } else {
   1946       async_safe_fatal(
   1947           "increment_dso_handle_reference_counter: Couldn't find soinfo by dso_handle=%p",
   1948           dso_handle);
   1949     }
   1950     g_dso_handle_counters[dso_handle] = 1U;
   1951   }
   1952 }
   1953 
   1954 void decrement_dso_handle_reference_counter(void* dso_handle) {
   1955   if (dso_handle == nullptr) {
   1956     return;
   1957   }
   1958 
   1959   auto it = g_dso_handle_counters.find(dso_handle);
   1960   CHECK(it != g_dso_handle_counters.end());
   1961   CHECK(it->second != 0);
   1962 
   1963   if (--it->second == 0) {
   1964     soinfo* si = find_containing_library(dso_handle);
   1965     if (si != nullptr) {
   1966       ProtectedDataGuard guard;
   1967       si->unset_tls_nodelete();
   1968       if (si->get_ref_count() == 0) {
   1969         // Perform deferred unload - note that soinfo_unload_impl does not decrement ref_count
   1970         soinfo_unload_impl(si);
   1971       }
   1972     } else {
   1973       async_safe_fatal(
   1974           "decrement_dso_handle_reference_counter: Couldn't find soinfo by dso_handle=%p",
   1975           dso_handle);
   1976     }
   1977     g_dso_handle_counters.erase(it);
   1978   }
   1979 }
   1980 
   1981 static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
   1982   if (sym_ver == nullptr) {
   1983     return sym_name;
   1984   }
   1985 
   1986   return std::string(sym_name) + ", version " + sym_ver;
   1987 }
   1988 
   1989 static android_namespace_t* get_caller_namespace(soinfo* caller) {
   1990   return caller != nullptr ? caller->get_primary_namespace() : g_anonymous_namespace;
   1991 }
   1992 
   1993 void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
   1994   // Use basic string manipulation calls to avoid snprintf.
   1995   // snprintf indirectly calls pthread_getspecific to get the size of a buffer.
   1996   // When debug malloc is enabled, this call returns 0. This in turn causes
   1997   // snprintf to do nothing, which causes libraries to fail to load.
   1998   // See b/17302493 for further details.
   1999   // Once the above bug is fixed, this code can be modified to use
   2000   // snprintf again.
   2001   const auto& default_ld_paths = g_default_namespace.get_default_library_paths();
   2002 
   2003   size_t required_size = 0;
   2004   for (const auto& path : default_ld_paths) {
   2005     required_size += path.size() + 1;
   2006   }
   2007 
   2008   if (buffer_size < required_size) {
   2009     async_safe_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
   2010                      "buffer len %zu, required len %zu", buffer_size, required_size);
   2011   }
   2012 
   2013   char* end = buffer;
   2014   for (size_t i = 0; i < default_ld_paths.size(); ++i) {
   2015     if (i > 0) *end++ = ':';
   2016     end = stpcpy(end, default_ld_paths[i].c_str());
   2017   }
   2018 }
   2019 
   2020 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
   2021   parse_LD_LIBRARY_PATH(ld_library_path);
   2022 }
   2023 
   2024 static std::string android_dlextinfo_to_string(const android_dlextinfo* info) {
   2025   if (info == nullptr) {
   2026     return "(null)";
   2027   }
   2028 
   2029   return android::base::StringPrintf("[flags=0x%" PRIx64 ","
   2030                                      " reserved_addr=%p,"
   2031                                      " reserved_size=0x%zx,"
   2032                                      " relro_fd=%d,"
   2033                                      " library_fd=%d,"
   2034                                      " library_fd_offset=0x%" PRIx64 ","
   2035                                      " library_namespace=%s@%p]",
   2036                                      info->flags,
   2037                                      info->reserved_addr,
   2038                                      info->reserved_size,
   2039                                      info->relro_fd,
   2040                                      info->library_fd,
   2041                                      info->library_fd_offset,
   2042                                      (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
   2043                                         (info->library_namespace != nullptr ?
   2044                                           info->library_namespace->get_name() : "(null)") : "(n/a)",
   2045                                      (info->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0 ?
   2046                                         info->library_namespace : nullptr);
   2047 }
   2048 
   2049 void* do_dlopen(const char* name, int flags,
   2050                 const android_dlextinfo* extinfo,
   2051                 const void* caller_addr) {
   2052   std::string trace_prefix = std::string("dlopen: ") + (name == nullptr ? "(nullptr)" : name);
   2053   ScopedTrace trace(trace_prefix.c_str());
   2054   ScopedTrace loading_trace((trace_prefix + " - loading and linking").c_str());
   2055   soinfo* const caller = find_containing_library(caller_addr);
   2056   android_namespace_t* ns = get_caller_namespace(caller);
   2057 
   2058   LD_LOG(kLogDlopen,
   2059          "dlopen(name=\"%s\", flags=0x%x, extinfo=%s, caller=\"%s\", caller_ns=%s@%p) ...",
   2060          name,
   2061          flags,
   2062          android_dlextinfo_to_string(extinfo).c_str(),
   2063          caller == nullptr ? "(null)" : caller->get_realpath(),
   2064          ns == nullptr ? "(null)" : ns->get_name(),
   2065          ns);
   2066 
   2067   auto failure_guard = android::base::make_scope_guard(
   2068       [&]() { LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer()); });
   2069 
   2070   if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
   2071     DL_ERR("invalid flags to dlopen: %x", flags);
   2072     return nullptr;
   2073   }
   2074 
   2075   if (extinfo != nullptr) {
   2076     if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {
   2077       DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);
   2078       return nullptr;
   2079     }
   2080 
   2081     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&
   2082         (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
   2083       DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "
   2084           "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);
   2085       return nullptr;
   2086     }
   2087 
   2088     if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&
   2089         (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {
   2090       DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "
   2091              "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");
   2092       return nullptr;
   2093     }
   2094 
   2095     if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {
   2096       if (extinfo->library_namespace == nullptr) {
   2097         DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");
   2098         return nullptr;
   2099       }
   2100       ns = extinfo->library_namespace;
   2101     }
   2102   }
   2103 
   2104   std::string asan_name_holder;
   2105 
   2106   const char* translated_name = name;
   2107   if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
   2108     char original_path[PATH_MAX];
   2109     if (realpath(name, original_path) != nullptr) {
   2110       asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
   2111       if (file_exists(asan_name_holder.c_str())) {
   2112         soinfo* si = nullptr;
   2113         if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
   2114           PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
   2115                 asan_name_holder.c_str());
   2116         } else {
   2117           PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
   2118           translated_name = asan_name_holder.c_str();
   2119         }
   2120       }
   2121     }
   2122   }
   2123 
   2124   ProtectedDataGuard guard;
   2125   soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
   2126   loading_trace.End();
   2127 
   2128   if (si != nullptr) {
   2129     void* handle = si->to_handle();
   2130     LD_LOG(kLogDlopen,
   2131            "... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p",
   2132            si->get_realpath(), si->get_soname(), handle);
   2133     si->call_constructors();
   2134     failure_guard.Disable();
   2135     LD_LOG(kLogDlopen,
   2136            "... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p",
   2137            si->get_realpath(), si->get_soname(), handle);
   2138     return handle;
   2139   }
   2140 
   2141   return nullptr;
   2142 }
   2143 
   2144 int do_dladdr(const void* addr, Dl_info* info) {
   2145   // Determine if this address can be found in any library currently mapped.
   2146   soinfo* si = find_containing_library(addr);
   2147   if (si == nullptr) {
   2148     return 0;
   2149   }
   2150 
   2151   memset(info, 0, sizeof(Dl_info));
   2152 
   2153   info->dli_fname = si->get_realpath();
   2154   // Address at which the shared object is loaded.
   2155   info->dli_fbase = reinterpret_cast<void*>(si->base);
   2156 
   2157   // Determine if any symbol in the library contains the specified address.
   2158   ElfW(Sym)* sym = si->find_symbol_by_address(addr);
   2159   if (sym != nullptr) {
   2160     info->dli_sname = si->get_string(sym->st_name);
   2161     info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
   2162   }
   2163 
   2164   return 1;
   2165 }
   2166 
   2167 static soinfo* soinfo_from_handle(void* handle) {
   2168   if ((reinterpret_cast<uintptr_t>(handle) & 1) != 0) {
   2169     auto it = g_soinfo_handles_map.find(reinterpret_cast<uintptr_t>(handle));
   2170     if (it == g_soinfo_handles_map.end()) {
   2171       return nullptr;
   2172     } else {
   2173       return it->second;
   2174     }
   2175   }
   2176 
   2177   return static_cast<soinfo*>(handle);
   2178 }
   2179 
   2180 bool do_dlsym(void* handle,
   2181               const char* sym_name,
   2182               const char* sym_ver,
   2183               const void* caller_addr,
   2184               void** symbol) {
   2185   ScopedTrace trace("dlsym");
   2186 #if !defined(__LP64__)
   2187   if (handle == nullptr) {
   2188     DL_ERR("dlsym failed: library handle is null");
   2189     return false;
   2190   }
   2191 #endif
   2192 
   2193   soinfo* found = nullptr;
   2194   const ElfW(Sym)* sym = nullptr;
   2195   soinfo* caller = find_containing_library(caller_addr);
   2196   android_namespace_t* ns = get_caller_namespace(caller);
   2197   soinfo* si = nullptr;
   2198   if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
   2199     si = soinfo_from_handle(handle);
   2200   }
   2201 
   2202   LD_LOG(kLogDlsym,
   2203          "dlsym(handle=%p(\"%s\"), sym_name=\"%s\", sym_ver=\"%s\", caller=\"%s\", caller_ns=%s@%p) ...",
   2204          handle,
   2205          si != nullptr ? si->get_realpath() : "n/a",
   2206          sym_name,
   2207          sym_ver,
   2208          caller == nullptr ? "(null)" : caller->get_realpath(),
   2209          ns == nullptr ? "(null)" : ns->get_name(),
   2210          ns);
   2211 
   2212   auto failure_guard = android::base::make_scope_guard(
   2213       [&]() { LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer()); });
   2214 
   2215   if (sym_name == nullptr) {
   2216     DL_ERR("dlsym failed: symbol name is null");
   2217     return false;
   2218   }
   2219 
   2220   version_info vi_instance;
   2221   version_info* vi = nullptr;
   2222 
   2223   if (sym_ver != nullptr) {
   2224     vi_instance.name = sym_ver;
   2225     vi_instance.elf_hash = calculate_elf_hash(sym_ver);
   2226     vi = &vi_instance;
   2227   }
   2228 
   2229   if (handle == RTLD_DEFAULT || handle == RTLD_NEXT) {
   2230     sym = dlsym_linear_lookup(ns, sym_name, vi, &found, caller, handle);
   2231   } else {
   2232     if (si == nullptr) {
   2233       DL_ERR("dlsym failed: invalid handle: %p", handle);
   2234       return false;
   2235     }
   2236     sym = dlsym_handle_lookup(si, &found, sym_name, vi);
   2237   }
   2238 
   2239   if (sym != nullptr) {
   2240     uint32_t bind = ELF_ST_BIND(sym->st_info);
   2241 
   2242     if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
   2243       *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
   2244       failure_guard.Disable();
   2245       LD_LOG(kLogDlsym,
   2246              "... dlsym successful: sym_name=\"%s\", sym_ver=\"%s\", found in=\"%s\", address=%p",
   2247              sym_name, sym_ver, found->get_soname(), *symbol);
   2248       return true;
   2249     }
   2250 
   2251     DL_ERR("symbol \"%s\" found but not global", symbol_display_name(sym_name, sym_ver).c_str());
   2252     return false;
   2253   }
   2254 
   2255   DL_ERR("undefined symbol: %s", symbol_display_name(sym_name, sym_ver).c_str());
   2256   return false;
   2257 }
   2258 
   2259 int do_dlclose(void* handle) {
   2260   ScopedTrace trace("dlclose");
   2261   ProtectedDataGuard guard;
   2262   soinfo* si = soinfo_from_handle(handle);
   2263   if (si == nullptr) {
   2264     DL_ERR("invalid handle: %p", handle);
   2265     return -1;
   2266   }
   2267 
   2268   LD_LOG(kLogDlopen,
   2269          "dlclose(handle=%p, realpath=\"%s\"@%p) ...",
   2270          handle,
   2271          si->get_realpath(),
   2272          si);
   2273   soinfo_unload(si);
   2274   LD_LOG(kLogDlopen,
   2275          "dlclose(handle=%p) ... done",
   2276          handle);
   2277   return 0;
   2278 }
   2279 
   2280 bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) {
   2281   if (g_anonymous_namespace_initialized) {
   2282     DL_ERR("anonymous namespace has already been initialized.");
   2283     return false;
   2284   }
   2285 
   2286   ProtectedDataGuard guard;
   2287 
   2288   // create anonymous namespace
   2289   // When the caller is nullptr - create_namespace will take global group
   2290   // from the anonymous namespace, which is fine because anonymous namespace
   2291   // is still pointing to the default one.
   2292   android_namespace_t* anon_ns =
   2293       create_namespace(nullptr,
   2294                        "(anonymous)",
   2295                        nullptr,
   2296                        library_search_path,
   2297                        ANDROID_NAMESPACE_TYPE_ISOLATED,
   2298                        nullptr,
   2299                        &g_default_namespace);
   2300 
   2301   if (anon_ns == nullptr) {
   2302     return false;
   2303   }
   2304 
   2305   if (!link_namespaces(anon_ns, &g_default_namespace, shared_lib_sonames)) {
   2306     return false;
   2307   }
   2308 
   2309   g_anonymous_namespace = anon_ns;
   2310   g_anonymous_namespace_initialized = true;
   2311 
   2312   return true;
   2313 }
   2314 
   2315 static void add_soinfos_to_namespace(const soinfo_list_t& soinfos, android_namespace_t* ns) {
   2316   ns->add_soinfos(soinfos);
   2317   for (auto si : soinfos) {
   2318     si->add_secondary_namespace(ns);
   2319   }
   2320 }
   2321 
   2322 android_namespace_t* create_namespace(const void* caller_addr,
   2323                                       const char* name,
   2324                                       const char* ld_library_path,
   2325                                       const char* default_library_path,
   2326                                       uint64_t type,
   2327                                       const char* permitted_when_isolated_path,
   2328                                       android_namespace_t* parent_namespace) {
   2329   if (parent_namespace == nullptr) {
   2330     // if parent_namespace is nullptr -> set it to the caller namespace
   2331     soinfo* caller_soinfo = find_containing_library(caller_addr);
   2332 
   2333     parent_namespace = caller_soinfo != nullptr ?
   2334                        caller_soinfo->get_primary_namespace() :
   2335                        g_anonymous_namespace;
   2336   }
   2337 
   2338   ProtectedDataGuard guard;
   2339   std::vector<std::string> ld_library_paths;
   2340   std::vector<std::string> default_library_paths;
   2341   std::vector<std::string> permitted_paths;
   2342 
   2343   parse_path(ld_library_path, ":", &ld_library_paths);
   2344   parse_path(default_library_path, ":", &default_library_paths);
   2345   parse_path(permitted_when_isolated_path, ":", &permitted_paths);
   2346 
   2347   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
   2348   ns->set_name(name);
   2349   ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
   2350   ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
   2351 
   2352   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
   2353     // append parent namespace paths.
   2354     std::copy(parent_namespace->get_ld_library_paths().begin(),
   2355               parent_namespace->get_ld_library_paths().end(),
   2356               back_inserter(ld_library_paths));
   2357 
   2358     std::copy(parent_namespace->get_default_library_paths().begin(),
   2359               parent_namespace->get_default_library_paths().end(),
   2360               back_inserter(default_library_paths));
   2361 
   2362     std::copy(parent_namespace->get_permitted_paths().begin(),
   2363               parent_namespace->get_permitted_paths().end(),
   2364               back_inserter(permitted_paths));
   2365 
   2366     // If shared - clone the parent namespace
   2367     add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
   2368     // and copy parent namespace links
   2369     for (auto& link : parent_namespace->linked_namespaces()) {
   2370       ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames(),
   2371                                link.allow_all_shared_libs());
   2372     }
   2373   } else {
   2374     // If not shared - copy only the shared group
   2375     add_soinfos_to_namespace(parent_namespace->get_shared_group(), ns);
   2376   }
   2377 
   2378   ns->set_ld_library_paths(std::move(ld_library_paths));
   2379   ns->set_default_library_paths(std::move(default_library_paths));
   2380   ns->set_permitted_paths(std::move(permitted_paths));
   2381 
   2382   return ns;
   2383 }
   2384 
   2385 bool link_namespaces(android_namespace_t* namespace_from,
   2386                      android_namespace_t* namespace_to,
   2387                      const char* shared_lib_sonames) {
   2388   if (namespace_to == nullptr) {
   2389     namespace_to = &g_default_namespace;
   2390   }
   2391 
   2392   if (namespace_from == nullptr) {
   2393     DL_ERR("error linking namespaces: namespace_from is null.");
   2394     return false;
   2395   }
   2396 
   2397   if (shared_lib_sonames == nullptr || shared_lib_sonames[0] == '\0') {
   2398     DL_ERR("error linking namespaces \"%s\"->\"%s\": the list of shared libraries is empty.",
   2399            namespace_from->get_name(), namespace_to->get_name());
   2400     return false;
   2401   }
   2402 
   2403   auto sonames = android::base::Split(shared_lib_sonames, ":");
   2404   std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
   2405 
   2406   ProtectedDataGuard guard;
   2407   namespace_from->add_linked_namespace(namespace_to, sonames_set, false);
   2408 
   2409   return true;
   2410 }
   2411 
   2412 bool link_namespaces_all_libs(android_namespace_t* namespace_from,
   2413                               android_namespace_t* namespace_to) {
   2414   if (namespace_from == nullptr) {
   2415     DL_ERR("error linking namespaces: namespace_from is null.");
   2416     return false;
   2417   }
   2418 
   2419   if (namespace_to == nullptr) {
   2420     DL_ERR("error linking namespaces: namespace_to is null.");
   2421     return false;
   2422   }
   2423 
   2424   ProtectedDataGuard guard;
   2425   namespace_from->add_linked_namespace(namespace_to, std::unordered_set<std::string>(), true);
   2426 
   2427   return true;
   2428 }
   2429 
   2430 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
   2431   typedef ElfW(Addr) (*ifunc_resolver_t)(void);
   2432   ifunc_resolver_t ifunc_resolver = reinterpret_cast<ifunc_resolver_t>(resolver_addr);
   2433   ElfW(Addr) ifunc_addr = ifunc_resolver();
   2434   TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
   2435       ifunc_resolver, reinterpret_cast<void*>(ifunc_addr));
   2436 
   2437   return ifunc_addr;
   2438 }
   2439 
   2440 const version_info* VersionTracker::get_version_info(ElfW(Versym) source_symver) const {
   2441   if (source_symver < 2 ||
   2442       source_symver >= version_infos.size() ||
   2443       version_infos[source_symver].name == nullptr) {
   2444     return nullptr;
   2445   }
   2446 
   2447   return &version_infos[source_symver];
   2448 }
   2449 
   2450 void VersionTracker::add_version_info(size_t source_index,
   2451                                       ElfW(Word) elf_hash,
   2452                                       const char* ver_name,
   2453                                       const soinfo* target_si) {
   2454   if (source_index >= version_infos.size()) {
   2455     version_infos.resize(source_index+1);
   2456   }
   2457 
   2458   version_infos[source_index].elf_hash = elf_hash;
   2459   version_infos[source_index].name = ver_name;
   2460   version_infos[source_index].target_si = target_si;
   2461 }
   2462 
   2463 bool VersionTracker::init_verneed(const soinfo* si_from) {
   2464   uintptr_t verneed_ptr = si_from->get_verneed_ptr();
   2465 
   2466   if (verneed_ptr == 0) {
   2467     return true;
   2468   }
   2469 
   2470   size_t verneed_cnt = si_from->get_verneed_cnt();
   2471 
   2472   for (size_t i = 0, offset = 0; i<verneed_cnt; ++i) {
   2473     const ElfW(Verneed)* verneed = reinterpret_cast<ElfW(Verneed)*>(verneed_ptr + offset);
   2474     size_t vernaux_offset = offset + verneed->vn_aux;
   2475     offset += verneed->vn_next;
   2476 
   2477     if (verneed->vn_version != 1) {
   2478       DL_ERR("unsupported verneed[%zd] vn_version: %d (expected 1)", i, verneed->vn_version);
   2479       return false;
   2480     }
   2481 
   2482     const char* target_soname = si_from->get_string(verneed->vn_file);
   2483     // find it in dependencies
   2484     soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
   2485       return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
   2486     });
   2487 
   2488     if (target_si == nullptr) {
   2489       DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
   2490           target_soname, i, si_from->get_realpath());
   2491       return false;
   2492     }
   2493 
   2494     for (size_t j = 0; j<verneed->vn_cnt; ++j) {
   2495       const ElfW(Vernaux)* vernaux = reinterpret_cast<ElfW(Vernaux)*>(verneed_ptr + vernaux_offset);
   2496       vernaux_offset += vernaux->vna_next;
   2497 
   2498       const ElfW(Word) elf_hash = vernaux->vna_hash;
   2499       const char* ver_name = si_from->get_string(vernaux->vna_name);
   2500       ElfW(Half) source_index = vernaux->vna_other;
   2501 
   2502       add_version_info(source_index, elf_hash, ver_name, target_si);
   2503     }
   2504   }
   2505 
   2506   return true;
   2507 }
   2508 
   2509 template <typename F>
   2510 static bool for_each_verdef(const soinfo* si, F functor) {
   2511   if (!si->has_min_version(2)) {
   2512     return true;
   2513   }
   2514 
   2515   uintptr_t verdef_ptr = si->get_verdef_ptr();
   2516   if (verdef_ptr == 0) {
   2517     return true;
   2518   }
   2519 
   2520   size_t offset = 0;
   2521 
   2522   size_t verdef_cnt = si->get_verdef_cnt();
   2523   for (size_t i = 0; i<verdef_cnt; ++i) {
   2524     const ElfW(Verdef)* verdef = reinterpret_cast<ElfW(Verdef)*>(verdef_ptr + offset);
   2525     size_t verdaux_offset = offset + verdef->vd_aux;
   2526     offset += verdef->vd_next;
   2527 
   2528     if (verdef->vd_version != 1) {
   2529       DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
   2530           i, verdef->vd_version, si->get_realpath());
   2531       return false;
   2532     }
   2533 
   2534     if ((verdef->vd_flags & VER_FLG_BASE) != 0) {
   2535       // "this is the version of the file itself.  It must not be used for
   2536       //  matching a symbol. It can be used to match references."
   2537       //
   2538       // http://www.akkadia.org/drepper/symbol-versioning
   2539       continue;
   2540     }
   2541 
   2542     if (verdef->vd_cnt == 0) {
   2543       DL_ERR("invalid verdef[%zd] vd_cnt == 0 (version without a name)", i);
   2544       return false;
   2545     }
   2546 
   2547     const ElfW(Verdaux)* verdaux = reinterpret_cast<ElfW(Verdaux)*>(verdef_ptr + verdaux_offset);
   2548 
   2549     if (functor(i, verdef, verdaux) == true) {
   2550       break;
   2551     }
   2552   }
   2553 
   2554   return true;
   2555 }
   2556 
   2557 bool find_verdef_version_index(const soinfo* si, const version_info* vi, ElfW(Versym)* versym) {
   2558   if (vi == nullptr) {
   2559     *versym = kVersymNotNeeded;
   2560     return true;
   2561   }
   2562 
   2563   *versym = kVersymGlobal;
   2564 
   2565   return for_each_verdef(si,
   2566     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
   2567       if (verdef->vd_hash == vi->elf_hash &&
   2568           strcmp(vi->name, si->get_string(verdaux->vda_name)) == 0) {
   2569         *versym = verdef->vd_ndx;
   2570         return true;
   2571       }
   2572 
   2573       return false;
   2574     }
   2575   );
   2576 }
   2577 
   2578 bool VersionTracker::init_verdef(const soinfo* si_from) {
   2579   return for_each_verdef(si_from,
   2580     [&](size_t, const ElfW(Verdef)* verdef, const ElfW(Verdaux)* verdaux) {
   2581       add_version_info(verdef->vd_ndx, verdef->vd_hash,
   2582           si_from->get_string(verdaux->vda_name), si_from);
   2583       return false;
   2584     }
   2585   );
   2586 }
   2587 
   2588 bool VersionTracker::init(const soinfo* si_from) {
   2589   if (!si_from->has_min_version(2)) {
   2590     return true;
   2591   }
   2592 
   2593   return init_verneed(si_from) && init_verdef(si_from);
   2594 }
   2595 
   2596 // TODO (dimitry): Methods below need to be moved out of soinfo
   2597 // and in more isolated file in order minimize dependencies on
   2598 // unnecessary object in the linker binary. Consider making them
   2599 // independent from soinfo (?).
   2600 bool soinfo::lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
   2601                                  const char* sym_name, const version_info** vi) {
   2602   const ElfW(Versym)* sym_ver_ptr = get_versym(sym);
   2603   ElfW(Versym) sym_ver = sym_ver_ptr == nullptr ? 0 : *sym_ver_ptr;
   2604 
   2605   if (sym_ver != VER_NDX_LOCAL && sym_ver != VER_NDX_GLOBAL) {
   2606     *vi = version_tracker.get_version_info(sym_ver);
   2607 
   2608     if (*vi == nullptr) {
   2609       DL_ERR("cannot find verneed/verdef for version index=%d "
   2610           "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
   2611       return false;
   2612     }
   2613   } else {
   2614     // there is no version info
   2615     *vi = nullptr;
   2616   }
   2617 
   2618   return true;
   2619 }
   2620 
   2621 void soinfo::apply_relr_reloc(ElfW(Addr) offset) {
   2622   ElfW(Addr) address = offset + load_bias;
   2623   *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
   2624 }
   2625 
   2626 // Process relocations in SHT_RELR section (experimental).
   2627 // Details of the encoding are described in this post:
   2628 //   https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
   2629 bool soinfo::relocate_relr() {
   2630   ElfW(Relr)* begin = relr_;
   2631   ElfW(Relr)* end = relr_ + relr_count_;
   2632   constexpr size_t wordsize = sizeof(ElfW(Addr));
   2633 
   2634   ElfW(Addr) base = 0;
   2635   for (ElfW(Relr)* current = begin; current < end; ++current) {
   2636     ElfW(Relr) entry = *current;
   2637     ElfW(Addr) offset;
   2638 
   2639     if ((entry&1) == 0) {
   2640       // Even entry: encodes the offset for next relocation.
   2641       offset = static_cast<ElfW(Addr)>(entry);
   2642       apply_relr_reloc(offset);
   2643       // Set base offset for subsequent bitmap entries.
   2644       base = offset + wordsize;
   2645       continue;
   2646     }
   2647 
   2648     // Odd entry: encodes bitmap for relocations starting at base.
   2649     offset = base;
   2650     while (entry != 0) {
   2651       entry >>= 1;
   2652       if ((entry&1) != 0) {
   2653         apply_relr_reloc(offset);
   2654       }
   2655       offset += wordsize;
   2656     }
   2657 
   2658     // Advance base offset by 63 words for 64-bit platforms,
   2659     // or 31 words for 32-bit platforms.
   2660     base += (8*wordsize - 1) * wordsize;
   2661   }
   2662   return true;
   2663 }
   2664 
   2665 #if !defined(__mips__)
   2666 #if defined(USE_RELA)
   2667 static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
   2668   return rela->r_addend;
   2669 }
   2670 #else
   2671 static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
   2672   if (ELFW(R_TYPE)(rel->r_info) == R_GENERIC_RELATIVE ||
   2673       ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE) {
   2674     return *reinterpret_cast<ElfW(Addr)*>(reloc_addr);
   2675   }
   2676   return 0;
   2677 }
   2678 #endif
   2679 
   2680 template<typename ElfRelIteratorT>
   2681 bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
   2682                       const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
   2683   for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
   2684     const auto rel = rel_iterator.next();
   2685     if (rel == nullptr) {
   2686       return false;
   2687     }
   2688 
   2689     ElfW(Word) type = ELFW(R_TYPE)(rel->r_info);
   2690     ElfW(Word) sym = ELFW(R_SYM)(rel->r_info);
   2691 
   2692     ElfW(Addr) reloc = static_cast<ElfW(Addr)>(rel->r_offset + load_bias);
   2693     ElfW(Addr) sym_addr = 0;
   2694     const char* sym_name = nullptr;
   2695     ElfW(Addr) addend = get_addend(rel, reloc);
   2696 
   2697     DEBUG("Processing \"%s\" relocation at index %zd", get_realpath(), idx);
   2698     if (type == R_GENERIC_NONE) {
   2699       continue;
   2700     }
   2701 
   2702     const ElfW(Sym)* s = nullptr;
   2703     soinfo* lsi = nullptr;
   2704 
   2705     if (sym != 0) {
   2706       sym_name = get_string(symtab_[sym].st_name);
   2707       const version_info* vi = nullptr;
   2708 
   2709       if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
   2710         return false;
   2711       }
   2712 
   2713       if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
   2714         return false;
   2715       }
   2716 
   2717       if (s == nullptr) {
   2718         // We only allow an undefined symbol if this is a weak reference...
   2719         s = &symtab_[sym];
   2720         if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
   2721           DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
   2722           return false;
   2723         }
   2724 
   2725         /* IHI0044C AAELF 4.5.1.1:
   2726 
   2727            Libraries are not searched to resolve weak references.
   2728            It is not an error for a weak reference to remain unsatisfied.
   2729 
   2730            During linking, the value of an undefined weak reference is:
   2731            - Zero if the relocation type is absolute
   2732            - The address of the place if the relocation is pc-relative
   2733            - The address of nominal base address if the relocation
   2734              type is base-relative.
   2735          */
   2736 
   2737         switch (type) {
   2738           case R_GENERIC_JUMP_SLOT:
   2739           case R_GENERIC_GLOB_DAT:
   2740           case R_GENERIC_RELATIVE:
   2741           case R_GENERIC_IRELATIVE:
   2742 #if defined(__aarch64__)
   2743           case R_AARCH64_ABS64:
   2744           case R_AARCH64_ABS32:
   2745           case R_AARCH64_ABS16:
   2746 #elif defined(__x86_64__)
   2747           case R_X86_64_32:
   2748           case R_X86_64_64:
   2749 #elif defined(__arm__)
   2750           case R_ARM_ABS32:
   2751 #elif defined(__i386__)
   2752           case R_386_32:
   2753 #endif
   2754             /*
   2755              * The sym_addr was initialized to be zero above, or the relocation
   2756              * code below does not care about value of sym_addr.
   2757              * No need to do anything.
   2758              */
   2759             break;
   2760 #if defined(__x86_64__)
   2761           case R_X86_64_PC32:
   2762             sym_addr = reloc;
   2763             break;
   2764 #elif defined(__i386__)
   2765           case R_386_PC32:
   2766             sym_addr = reloc;
   2767             break;
   2768 #endif
   2769           default:
   2770             DL_ERR("unknown weak reloc type %d @ %p (%zu)", type, rel, idx);
   2771             return false;
   2772         }
   2773       } else { // We got a definition.
   2774 #if !defined(__LP64__)
   2775         // When relocating dso with text_relocation .text segment is
   2776         // not executable. We need to restore elf flags before resolving
   2777         // STT_GNU_IFUNC symbol.
   2778         bool protect_segments = has_text_relocations &&
   2779                                 lsi == this &&
   2780                                 ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC;
   2781         if (protect_segments) {
   2782           if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
   2783             DL_ERR("can't protect segments for \"%s\": %s",
   2784                    get_realpath(), strerror(errno));
   2785             return false;
   2786           }
   2787         }
   2788 #endif
   2789         if (ELF_ST_TYPE(s->st_info) == STT_TLS) {
   2790           DL_ERR("unsupported ELF TLS symbol \"%s\" referenced by \"%s\"",
   2791                  sym_name, get_realpath());
   2792           return false;
   2793         }
   2794         sym_addr = lsi->resolve_symbol_address(s);
   2795 #if !defined(__LP64__)
   2796         if (protect_segments) {
   2797           if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
   2798             DL_ERR("can't unprotect loadable segments for \"%s\": %s",
   2799                    get_realpath(), strerror(errno));
   2800             return false;
   2801           }
   2802         }
   2803 #endif
   2804       }
   2805       count_relocation(kRelocSymbol);
   2806     }
   2807 
   2808     switch (type) {
   2809       case R_GENERIC_JUMP_SLOT:
   2810         count_relocation(kRelocAbsolute);
   2811         MARK(rel->r_offset);
   2812         TRACE_TYPE(RELO, "RELO JMP_SLOT %16p <- %16p %s\n",
   2813                    reinterpret_cast<void*>(reloc),
   2814                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
   2815 
   2816         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
   2817         break;
   2818       case R_GENERIC_GLOB_DAT:
   2819         count_relocation(kRelocAbsolute);
   2820         MARK(rel->r_offset);
   2821         TRACE_TYPE(RELO, "RELO GLOB_DAT %16p <- %16p %s\n",
   2822                    reinterpret_cast<void*>(reloc),
   2823                    reinterpret_cast<void*>(sym_addr + addend), sym_name);
   2824         *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
   2825         break;
   2826       case R_GENERIC_RELATIVE:
   2827         count_relocation(kRelocRelative);
   2828         MARK(rel->r_offset);
   2829         TRACE_TYPE(RELO, "RELO RELATIVE %16p <- %16p\n",
   2830                    reinterpret_cast<void*>(reloc),
   2831                    reinterpret_cast<void*>(load_bias + addend));
   2832         *reinterpret_cast<ElfW(Addr)*>(reloc) = (load_bias + addend);
   2833         break;
   2834       case R_GENERIC_IRELATIVE:
   2835         count_relocation(kRelocRelative);
   2836         MARK(rel->r_offset);
   2837         TRACE_TYPE(RELO, "RELO IRELATIVE %16p <- %16p\n",
   2838                     reinterpret_cast<void*>(reloc),
   2839                     reinterpret_cast<void*>(load_bias + addend));
   2840         {
   2841 #if !defined(__LP64__)
   2842           // When relocating dso with text_relocation .text segment is
   2843           // not executable. We need to restore elf flags for this
   2844           // particular call.
   2845           if (has_text_relocations) {
   2846             if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
   2847               DL_ERR("can't protect segments for \"%s\": %s",
   2848                      get_realpath(), strerror(errno));
   2849               return false;
   2850             }
   2851           }
   2852 #endif
   2853           ElfW(Addr) ifunc_addr = call_ifunc_resolver(load_bias + addend);
   2854 #if !defined(__LP64__)
   2855           // Unprotect it afterwards...
   2856           if (has_text_relocations) {
   2857             if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
   2858               DL_ERR("can't unprotect loadable segments for \"%s\": %s",
   2859                      get_realpath(), strerror(errno));
   2860               return false;
   2861             }
   2862           }
   2863 #endif
   2864           *reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
   2865         }
   2866         break;
   2867 
   2868 #if defined(__aarch64__)
   2869       case R_AARCH64_ABS64:
   2870         count_relocation(kRelocAbsolute);
   2871         MARK(rel->r_offset);
   2872         TRACE_TYPE(RELO, "RELO ABS64 %16llx <- %16llx %s\n",
   2873                    reloc, sym_addr + addend, sym_name);
   2874         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
   2875         break;
   2876       case R_AARCH64_ABS32:
   2877         count_relocation(kRelocAbsolute);
   2878         MARK(rel->r_offset);
   2879         TRACE_TYPE(RELO, "RELO ABS32 %16llx <- %16llx %s\n",
   2880                    reloc, sym_addr + addend, sym_name);
   2881         {
   2882           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
   2883           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
   2884           if ((min_value <= (sym_addr + addend)) &&
   2885               ((sym_addr + addend) <= max_value)) {
   2886             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend;
   2887           } else {
   2888             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
   2889                    sym_addr + addend, min_value, max_value);
   2890             return false;
   2891           }
   2892         }
   2893         break;
   2894       case R_AARCH64_ABS16:
   2895         count_relocation(kRelocAbsolute);
   2896         MARK(rel->r_offset);
   2897         TRACE_TYPE(RELO, "RELO ABS16 %16llx <- %16llx %s\n",
   2898                    reloc, sym_addr + addend, sym_name);
   2899         {
   2900           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
   2901           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
   2902           if ((min_value <= (sym_addr + addend)) &&
   2903               ((sym_addr + addend) <= max_value)) {
   2904             *reinterpret_cast<ElfW(Addr)*>(reloc) = (sym_addr + addend);
   2905           } else {
   2906             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
   2907                    sym_addr + addend, min_value, max_value);
   2908             return false;
   2909           }
   2910         }
   2911         break;
   2912       case R_AARCH64_PREL64:
   2913         count_relocation(kRelocRelative);
   2914         MARK(rel->r_offset);
   2915         TRACE_TYPE(RELO, "RELO REL64 %16llx <- %16llx - %16llx %s\n",
   2916                    reloc, sym_addr + addend, rel->r_offset, sym_name);
   2917         *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
   2918         break;
   2919       case R_AARCH64_PREL32:
   2920         count_relocation(kRelocRelative);
   2921         MARK(rel->r_offset);
   2922         TRACE_TYPE(RELO, "RELO REL32 %16llx <- %16llx - %16llx %s\n",
   2923                    reloc, sym_addr + addend, rel->r_offset, sym_name);
   2924         {
   2925           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT32_MIN);
   2926           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT32_MAX);
   2927           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
   2928               ((sym_addr + addend - rel->r_offset) <= max_value)) {
   2929             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
   2930           } else {
   2931             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
   2932                    sym_addr + addend - rel->r_offset, min_value, max_value);
   2933             return false;
   2934           }
   2935         }
   2936         break;
   2937       case R_AARCH64_PREL16:
   2938         count_relocation(kRelocRelative);
   2939         MARK(rel->r_offset);
   2940         TRACE_TYPE(RELO, "RELO REL16 %16llx <- %16llx - %16llx %s\n",
   2941                    reloc, sym_addr + addend, rel->r_offset, sym_name);
   2942         {
   2943           const ElfW(Addr) min_value = static_cast<ElfW(Addr)>(INT16_MIN);
   2944           const ElfW(Addr) max_value = static_cast<ElfW(Addr)>(UINT16_MAX);
   2945           if ((min_value <= (sym_addr + addend - rel->r_offset)) &&
   2946               ((sym_addr + addend - rel->r_offset) <= max_value)) {
   2947             *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend - rel->r_offset;
   2948           } else {
   2949             DL_ERR("0x%016llx out of range 0x%016llx to 0x%016llx",
   2950                    sym_addr + addend - rel->r_offset, min_value, max_value);
   2951             return false;
   2952           }
   2953         }
   2954         break;
   2955 
   2956       case R_AARCH64_COPY:
   2957         /*
   2958          * ET_EXEC is not supported so this should not happen.
   2959          *
   2960          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
   2961          *
   2962          * Section 4.6.11 "Dynamic relocations"
   2963          * R_AARCH64_COPY may only appear in executable objects where e_type is
   2964          * set to ET_EXEC.
   2965          */
   2966         DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
   2967         return false;
   2968       case R_AARCH64_TLS_TPREL64:
   2969         TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
   2970                    reloc, (sym_addr + addend), rel->r_offset);
   2971         break;
   2972       case R_AARCH64_TLS_DTPREL32:
   2973         TRACE_TYPE(RELO, "RELO TLS_DTPREL32 *** %16llx <- %16llx - %16llx\n",
   2974                    reloc, (sym_addr + addend), rel->r_offset);
   2975         break;
   2976 #elif defined(__x86_64__)
   2977       case R_X86_64_32:
   2978         count_relocation(kRelocRelative);
   2979         MARK(rel->r_offset);
   2980         TRACE_TYPE(RELO, "RELO R_X86_64_32 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
   2981                    static_cast<size_t>(sym_addr), sym_name);
   2982         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend;
   2983         break;
   2984       case R_X86_64_64:
   2985         count_relocation(kRelocRelative);
   2986         MARK(rel->r_offset);
   2987         TRACE_TYPE(RELO, "RELO R_X86_64_64 %08zx <- +%08zx %s", static_cast<size_t>(reloc),
   2988                    static_cast<size_t>(sym_addr), sym_name);
   2989         *reinterpret_cast<Elf64_Addr*>(reloc) = sym_addr + addend;
   2990         break;
   2991       case R_X86_64_PC32:
   2992         count_relocation(kRelocRelative);
   2993         MARK(rel->r_offset);
   2994         TRACE_TYPE(RELO, "RELO R_X86_64_PC32 %08zx <- +%08zx (%08zx - %08zx) %s",
   2995                    static_cast<size_t>(reloc), static_cast<size_t>(sym_addr - reloc),
   2996                    static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
   2997         *reinterpret_cast<Elf32_Addr*>(reloc) = sym_addr + addend - reloc;
   2998         break;
   2999 #elif defined(__arm__)
   3000       case R_ARM_ABS32:
   3001         count_relocation(kRelocAbsolute);
   3002         MARK(rel->r_offset);
   3003         TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name);
   3004         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
   3005         break;
   3006       case R_ARM_REL32:
   3007         count_relocation(kRelocRelative);
   3008         MARK(rel->r_offset);
   3009         TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s",
   3010                    reloc, sym_addr, rel->r_offset, sym_name);
   3011         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr - rel->r_offset;
   3012         break;
   3013       case R_ARM_COPY:
   3014         /*
   3015          * ET_EXEC is not supported so this should not happen.
   3016          *
   3017          * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
   3018          *
   3019          * Section 4.6.1.10 "Dynamic relocations"
   3020          * R_ARM_COPY may only appear in executable objects where e_type is
   3021          * set to ET_EXEC.
   3022          */
   3023         DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
   3024         return false;
   3025 #elif defined(__i386__)
   3026       case R_386_32:
   3027         count_relocation(kRelocRelative);
   3028         MARK(rel->r_offset);
   3029         TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
   3030         *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
   3031         break;
   3032       case R_386_PC32:
   3033         count_relocation(kRelocRelative);
   3034         MARK(rel->r_offset);
   3035         TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
   3036                    reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
   3037         *reinterpret_cast<ElfW(Addr)*>(reloc) += (sym_addr - reloc);
   3038         break;
   3039 #endif
   3040       default:
   3041         DL_ERR("unknown reloc type %d @ %p (%zu)", type, rel, idx);
   3042         return false;
   3043     }
   3044   }
   3045   return true;
   3046 }
   3047 #endif  // !defined(__mips__)
   3048 
   3049 // An empty list of soinfos
   3050 static soinfo_list_t g_empty_list;
   3051 
   3052 bool soinfo::prelink_image() {
   3053   /* Extract dynamic section */
   3054   ElfW(Word) dynamic_flags = 0;
   3055   phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
   3056 
   3057   /* We can't log anything until the linker is relocated */
   3058   bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
   3059   if (!relocating_linker) {
   3060     INFO("[ Linking \"%s\" ]", get_realpath());
   3061     DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
   3062   }
   3063 
   3064   if (dynamic == nullptr) {
   3065     if (!relocating_linker) {
   3066       DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
   3067     }
   3068     return false;
   3069   } else {
   3070     if (!relocating_linker) {
   3071       DEBUG("dynamic = %p", dynamic);
   3072     }
   3073   }
   3074 
   3075 #if defined(__arm__)
   3076   (void) phdr_table_get_arm_exidx(phdr, phnum, load_bias,
   3077                                   &ARM_exidx, &ARM_exidx_count);
   3078 #endif
   3079 
   3080   // Extract useful information from dynamic section.
   3081   // Note that: "Except for the DT_NULL element at the end of the array,
   3082   // and the relative order of DT_NEEDED elements, entries may appear in any order."
   3083   //
   3084   // source: http://www.sco.com/developers/gabi/1998-04-29/ch5.dynamic.html
   3085   uint32_t needed_count = 0;
   3086   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
   3087     DEBUG("d = %p, d[0](tag) = %p d[1](val) = %p",
   3088           d, reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
   3089     switch (d->d_tag) {
   3090       case DT_SONAME:
   3091         // this is parsed after we have strtab initialized (see below).
   3092         break;
   3093 
   3094       case DT_HASH:
   3095         nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
   3096         nchain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
   3097         bucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8);
   3098         chain_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr + 8 + nbucket_ * 4);
   3099         break;
   3100 
   3101       case DT_GNU_HASH:
   3102         gnu_nbucket_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[0];
   3103         // skip symndx
   3104         gnu_maskwords_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[2];
   3105         gnu_shift2_ = reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[3];
   3106 
   3107         gnu_bloom_filter_ = reinterpret_cast<ElfW(Addr)*>(load_bias + d->d_un.d_ptr + 16);
   3108         gnu_bucket_ = reinterpret_cast<uint32_t*>(gnu_bloom_filter_ + gnu_maskwords_);
   3109         // amend chain for symndx = header[1]
   3110         gnu_chain_ = gnu_bucket_ + gnu_nbucket_ -
   3111             reinterpret_cast<uint32_t*>(load_bias + d->d_un.d_ptr)[1];
   3112 
   3113         if (!powerof2(gnu_maskwords_)) {
   3114           DL_ERR("invalid maskwords for gnu_hash = 0x%x, in \"%s\" expecting power to two",
   3115               gnu_maskwords_, get_realpath());
   3116           return false;
   3117         }
   3118         --gnu_maskwords_;
   3119 
   3120         flags_ |= FLAG_GNU_HASH;
   3121         break;
   3122 
   3123       case DT_STRTAB:
   3124         strtab_ = reinterpret_cast<const char*>(load_bias + d->d_un.d_ptr);
   3125         break;
   3126 
   3127       case DT_STRSZ:
   3128         strtab_size_ = d->d_un.d_val;
   3129         break;
   3130 
   3131       case DT_SYMTAB:
   3132         symtab_ = reinterpret_cast<ElfW(Sym)*>(load_bias + d->d_un.d_ptr);
   3133         break;
   3134 
   3135       case DT_SYMENT:
   3136         if (d->d_un.d_val != sizeof(ElfW(Sym))) {
   3137           DL_ERR("invalid DT_SYMENT: %zd in \"%s\"",
   3138               static_cast<size_t>(d->d_un.d_val), get_realpath());
   3139           return false;
   3140         }
   3141         break;
   3142 
   3143       case DT_PLTREL:
   3144 #if defined(USE_RELA)
   3145         if (d->d_un.d_val != DT_RELA) {
   3146           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_RELA", get_realpath());
   3147           return false;
   3148         }
   3149 #else
   3150         if (d->d_un.d_val != DT_REL) {
   3151           DL_ERR("unsupported DT_PLTREL in \"%s\"; expected DT_REL", get_realpath());
   3152           return false;
   3153         }
   3154 #endif
   3155         break;
   3156 
   3157       case DT_JMPREL:
   3158 #if defined(USE_RELA)
   3159         plt_rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
   3160 #else
   3161         plt_rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
   3162 #endif
   3163         break;
   3164 
   3165       case DT_PLTRELSZ:
   3166 #if defined(USE_RELA)
   3167         plt_rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
   3168 #else
   3169         plt_rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
   3170 #endif
   3171         break;
   3172 
   3173       case DT_PLTGOT:
   3174 #if defined(__mips__)
   3175         // Used by mips and mips64.
   3176         plt_got_ = reinterpret_cast<ElfW(Addr)**>(load_bias + d->d_un.d_ptr);
   3177 #endif
   3178         // Ignore for other platforms... (because RTLD_LAZY is not supported)
   3179         break;
   3180 
   3181       case DT_DEBUG:
   3182         // Set the DT_DEBUG entry to the address of _r_debug for GDB
   3183         // if the dynamic table is writable
   3184 // FIXME: not working currently for N64
   3185 // The flags for the LOAD and DYNAMIC program headers do not agree.
   3186 // The LOAD section containing the dynamic table has been mapped as
   3187 // read-only, but the DYNAMIC header claims it is writable.
   3188 #if !(defined(__mips__) && defined(__LP64__))
   3189         if ((dynamic_flags & PF_W) != 0) {
   3190           d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
   3191         }
   3192 #endif
   3193         break;
   3194 #if defined(USE_RELA)
   3195       case DT_RELA:
   3196         rela_ = reinterpret_cast<ElfW(Rela)*>(load_bias + d->d_un.d_ptr);
   3197         break;
   3198 
   3199       case DT_RELASZ:
   3200         rela_count_ = d->d_un.d_val / sizeof(ElfW(Rela));
   3201         break;
   3202 
   3203       case DT_ANDROID_RELA:
   3204         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
   3205         break;
   3206 
   3207       case DT_ANDROID_RELASZ:
   3208         android_relocs_size_ = d->d_un.d_val;
   3209         break;
   3210 
   3211       case DT_ANDROID_REL:
   3212         DL_ERR("unsupported DT_ANDROID_REL in \"%s\"", get_realpath());
   3213         return false;
   3214 
   3215       case DT_ANDROID_RELSZ:
   3216         DL_ERR("unsupported DT_ANDROID_RELSZ in \"%s\"", get_realpath());
   3217         return false;
   3218 
   3219       case DT_RELAENT:
   3220         if (d->d_un.d_val != sizeof(ElfW(Rela))) {
   3221           DL_ERR("invalid DT_RELAENT: %zd", static_cast<size_t>(d->d_un.d_val));
   3222           return false;
   3223         }
   3224         break;
   3225 
   3226       // Ignored (see DT_RELCOUNT comments for details).
   3227       case DT_RELACOUNT:
   3228         break;
   3229 
   3230       case DT_REL:
   3231         DL_ERR("unsupported DT_REL in \"%s\"", get_realpath());
   3232         return false;
   3233 
   3234       case DT_RELSZ:
   3235         DL_ERR("unsupported DT_RELSZ in \"%s\"", get_realpath());
   3236         return false;
   3237 
   3238 #else
   3239       case DT_REL:
   3240         rel_ = reinterpret_cast<ElfW(Rel)*>(load_bias + d->d_un.d_ptr);
   3241         break;
   3242 
   3243       case DT_RELSZ:
   3244         rel_count_ = d->d_un.d_val / sizeof(ElfW(Rel));
   3245         break;
   3246 
   3247       case DT_RELENT:
   3248         if (d->d_un.d_val != sizeof(ElfW(Rel))) {
   3249           DL_ERR("invalid DT_RELENT: %zd", static_cast<size_t>(d->d_un.d_val));
   3250           return false;
   3251         }
   3252         break;
   3253 
   3254       case DT_ANDROID_REL:
   3255         android_relocs_ = reinterpret_cast<uint8_t*>(load_bias + d->d_un.d_ptr);
   3256         break;
   3257 
   3258       case DT_ANDROID_RELSZ:
   3259         android_relocs_size_ = d->d_un.d_val;
   3260         break;
   3261 
   3262       case DT_ANDROID_RELA:
   3263         DL_ERR("unsupported DT_ANDROID_RELA in \"%s\"", get_realpath());
   3264         return false;
   3265 
   3266       case DT_ANDROID_RELASZ:
   3267         DL_ERR("unsupported DT_ANDROID_RELASZ in \"%s\"", get_realpath());
   3268         return false;
   3269 
   3270       // "Indicates that all RELATIVE relocations have been concatenated together,
   3271       // and specifies the RELATIVE relocation count."
   3272       //
   3273       // TODO: Spec also mentions that this can be used to optimize relocation process;
   3274       // Not currently used by bionic linker - ignored.
   3275       case DT_RELCOUNT:
   3276         break;
   3277 
   3278       case DT_RELA:
   3279         DL_ERR("unsupported DT_RELA in \"%s\"", get_realpath());
   3280         return false;
   3281 
   3282       case DT_RELASZ:
   3283         DL_ERR("unsupported DT_RELASZ in \"%s\"", get_realpath());
   3284         return false;
   3285 
   3286 #endif
   3287       case DT_RELR:
   3288         relr_ = reinterpret_cast<ElfW(Relr)*>(load_bias + d->d_un.d_ptr);
   3289         break;
   3290 
   3291       case DT_RELRSZ:
   3292         relr_count_ = d->d_un.d_val / sizeof(ElfW(Relr));
   3293         break;
   3294 
   3295       case DT_RELRENT:
   3296         if (d->d_un.d_val != sizeof(ElfW(Relr))) {
   3297           DL_ERR("invalid DT_RELRENT: %zd", static_cast<size_t>(d->d_un.d_val));
   3298           return false;
   3299         }
   3300         break;
   3301 
   3302       // Ignored (see DT_RELCOUNT comments for details).
   3303       case DT_RELRCOUNT:
   3304         break;
   3305 
   3306       case DT_INIT:
   3307         init_func_ = reinterpret_cast<linker_ctor_function_t>(load_bias + d->d_un.d_ptr);
   3308         DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
   3309         break;
   3310 
   3311       case DT_FINI:
   3312         fini_func_ = reinterpret_cast<linker_dtor_function_t>(load_bias + d->d_un.d_ptr);
   3313         DEBUG("%s destructors (DT_FINI) found at %p", get_realpath(), fini_func_);
   3314         break;
   3315 
   3316       case DT_INIT_ARRAY:
   3317         init_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
   3318         DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", get_realpath(), init_array_);
   3319         break;
   3320 
   3321       case DT_INIT_ARRAYSZ:
   3322         init_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
   3323         break;
   3324 
   3325       case DT_FINI_ARRAY:
   3326         fini_array_ = reinterpret_cast<linker_dtor_function_t*>(load_bias + d->d_un.d_ptr);
   3327         DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", get_realpath(), fini_array_);
   3328         break;
   3329 
   3330       case DT_FINI_ARRAYSZ:
   3331         fini_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
   3332         break;
   3333 
   3334       case DT_PREINIT_ARRAY:
   3335         preinit_array_ = reinterpret_cast<linker_ctor_function_t*>(load_bias + d->d_un.d_ptr);
   3336         DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", get_realpath(), preinit_array_);
   3337         break;
   3338 
   3339       case DT_PREINIT_ARRAYSZ:
   3340         preinit_array_count_ = static_cast<uint32_t>(d->d_un.d_val) / sizeof(ElfW(Addr));
   3341         break;
   3342 
   3343       case DT_TEXTREL:
   3344 #if defined(__LP64__)
   3345         DL_ERR("\"%s\" has text relocations", get_realpath());
   3346         return false;
   3347 #else
   3348         has_text_relocations = true;
   3349         break;
   3350 #endif
   3351 
   3352       case DT_SYMBOLIC:
   3353         has_DT_SYMBOLIC = true;
   3354         break;
   3355 
   3356       case DT_NEEDED:
   3357         ++needed_count;
   3358         break;
   3359 
   3360       case DT_FLAGS:
   3361         if (d->d_un.d_val & DF_TEXTREL) {
   3362 #if defined(__LP64__)
   3363           DL_ERR("\"%s\" has text relocations", get_realpath());
   3364           return false;
   3365 #else
   3366           has_text_relocations = true;
   3367 #endif
   3368         }
   3369         if (d->d_un.d_val & DF_SYMBOLIC) {
   3370           has_DT_SYMBOLIC = true;
   3371         }
   3372         break;
   3373 
   3374       case DT_FLAGS_1:
   3375         set_dt_flags_1(d->d_un.d_val);
   3376 
   3377         if ((d->d_un.d_val & ~SUPPORTED_DT_FLAGS_1) != 0) {
   3378           DL_WARN("Warning: \"%s\" has unsupported flags DT_FLAGS_1=%p "
   3379                   "(ignoring unsupported flags)",
   3380                   get_realpath(), reinterpret_cast<void*>(d->d_un.d_val));
   3381         }
   3382         break;
   3383 #if defined(__mips__)
   3384       case DT_MIPS_RLD_MAP:
   3385         // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
   3386         {
   3387           r_debug** dp = reinterpret_cast<r_debug**>(load_bias + d->d_un.d_ptr);
   3388           *dp = &_r_debug;
   3389         }
   3390         break;
   3391       case DT_MIPS_RLD_MAP_REL:
   3392         // Set the DT_MIPS_RLD_MAP_REL entry to the address of _r_debug for GDB.
   3393         {
   3394           r_debug** dp = reinterpret_cast<r_debug**>(
   3395               reinterpret_cast<ElfW(Addr)>(d) + d->d_un.d_val);
   3396           *dp = &_r_debug;
   3397         }
   3398         break;
   3399 
   3400       case DT_MIPS_RLD_VERSION:
   3401       case DT_MIPS_FLAGS:
   3402       case DT_MIPS_BASE_ADDRESS:
   3403       case DT_MIPS_UNREFEXTNO:
   3404         break;
   3405 
   3406       case DT_MIPS_SYMTABNO:
   3407         mips_symtabno_ = d->d_un.d_val;
   3408         break;
   3409 
   3410       case DT_MIPS_LOCAL_GOTNO:
   3411         mips_local_gotno_ = d->d_un.d_val;
   3412         break;
   3413 
   3414       case DT_MIPS_GOTSYM:
   3415         mips_gotsym_ = d->d_un.d_val;
   3416         break;
   3417 #endif
   3418       // Ignored: "Its use has been superseded by the DF_BIND_NOW flag"
   3419       case DT_BIND_NOW:
   3420         break;
   3421 
   3422       case DT_VERSYM:
   3423         versym_ = reinterpret_cast<ElfW(Versym)*>(load_bias + d->d_un.d_ptr);
   3424         break;
   3425 
   3426       case DT_VERDEF:
   3427         verdef_ptr_ = load_bias + d->d_un.d_ptr;
   3428         break;
   3429       case DT_VERDEFNUM:
   3430         verdef_cnt_ = d->d_un.d_val;
   3431         break;
   3432 
   3433       case DT_VERNEED:
   3434         verneed_ptr_ = load_bias + d->d_un.d_ptr;
   3435         break;
   3436 
   3437       case DT_VERNEEDNUM:
   3438         verneed_cnt_ = d->d_un.d_val;
   3439         break;
   3440 
   3441       case DT_RUNPATH:
   3442         // this is parsed after we have strtab initialized (see below).
   3443         break;
   3444 
   3445       default:
   3446         if (!relocating_linker) {
   3447           if (d->d_tag == DT_TLSDESC_GOT || d->d_tag == DT_TLSDESC_PLT) {
   3448             DL_ERR("unsupported ELF TLS DT entry in \"%s\"", get_realpath());
   3449             return false;
   3450           }
   3451 
   3452           const char* tag_name;
   3453           if (d->d_tag == DT_RPATH) {
   3454             tag_name = "DT_RPATH";
   3455           } else if (d->d_tag == DT_ENCODING) {
   3456             tag_name = "DT_ENCODING";
   3457           } else if (d->d_tag >= DT_LOOS && d->d_tag <= DT_HIOS) {
   3458             tag_name = "unknown OS-specific";
   3459           } else if (d->d_tag >= DT_LOPROC && d->d_tag <= DT_HIPROC) {
   3460             tag_name = "unknown processor-specific";
   3461           } else {
   3462             tag_name = "unknown";
   3463           }
   3464           DL_WARN("Warning: \"%s\" unused DT entry: %s (type %p arg %p) (ignoring)",
   3465                   get_realpath(),
   3466                   tag_name,
   3467                   reinterpret_cast<void*>(d->d_tag),
   3468                   reinterpret_cast<void*>(d->d_un.d_val));
   3469         }
   3470         break;
   3471     }
   3472   }
   3473 
   3474 #if defined(__mips__) && !defined(__LP64__)
   3475   if (!mips_check_and_adjust_fp_modes()) {
   3476     return false;
   3477   }
   3478 #endif
   3479 
   3480   DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
   3481         reinterpret_cast<void*>(base), strtab_, symtab_);
   3482 
   3483   // Sanity checks.
   3484   if (relocating_linker && needed_count != 0) {
   3485     DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
   3486     return false;
   3487   }
   3488   if (nbucket_ == 0 && gnu_nbucket_ == 0) {
   3489     DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
   3490         "(new hash type from the future?)", get_realpath());
   3491     return false;
   3492   }
   3493   if (strtab_ == 0) {
   3494     DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
   3495     return false;
   3496   }
   3497   if (symtab_ == 0) {
   3498     DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
   3499     return false;
   3500   }
   3501 
   3502   // second pass - parse entries relying on strtab
   3503   for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
   3504     switch (d->d_tag) {
   3505       case DT_SONAME:
   3506         set_soname(get_string(d->d_un.d_val));
   3507         break;
   3508       case DT_RUNPATH:
   3509         set_dt_runpath(get_string(d->d_un.d_val));
   3510         break;
   3511     }
   3512   }
   3513 
   3514   // Before M release linker was using basename in place of soname.
   3515   // In the case when dt_soname is absent some apps stop working
   3516   // because they can't find dt_needed library by soname.
   3517   // This workaround should keep them working. (Applies only
   3518   // for apps targeting sdk version < M.) Make an exception for
   3519   // the main executable and linker; they do not need to have dt_soname.
   3520   // TODO: >= O the linker doesn't need this workaround.
   3521   if (soname_ == nullptr &&
   3522       this != solist_get_somain() &&
   3523       (flags_ & FLAG_LINKER) == 0 &&
   3524       get_application_target_sdk_version() < __ANDROID_API_M__) {
   3525     soname_ = basename(realpath_.c_str());
   3526     DL_WARN_documented_change(__ANDROID_API_M__,
   3527                               "missing-soname-enforced-for-api-level-23",
   3528                               "\"%s\" has no DT_SONAME (will use %s instead)",
   3529                               get_realpath(), soname_);
   3530 
   3531     // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
   3532   }
   3533   return true;
   3534 }
   3535 
   3536 bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
   3537                         const android_dlextinfo* extinfo) {
   3538   if (is_image_linked()) {
   3539     // already linked.
   3540     return true;
   3541   }
   3542 
   3543   local_group_root_ = local_group.front();
   3544   if (local_group_root_ == nullptr) {
   3545     local_group_root_ = this;
   3546   }
   3547 
   3548   if ((flags_ & FLAG_LINKER) == 0 && local_group_root_ == this) {
   3549     target_sdk_version_ = get_application_target_sdk_version();
   3550   }
   3551 
   3552   VersionTracker version_tracker;
   3553 
   3554   if (!version_tracker.init(this)) {
   3555     return false;
   3556   }
   3557 
   3558 #if !defined(__LP64__)
   3559   if (has_text_relocations) {
   3560     // Fail if app is targeting M or above.
   3561     int app_target_api_level = get_application_target_sdk_version();
   3562     if (app_target_api_level >= __ANDROID_API_M__) {
   3563       DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/"
   3564                      "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-"
   3565                      "Enforced-for-API-level-23)", get_realpath());
   3566       return false;
   3567     }
   3568     // Make segments writable to allow text relocations to work properly. We will later call
   3569     // phdr_table_protect_segments() after all of them are applied.
   3570     DL_WARN_documented_change(__ANDROID_API_M__,
   3571                               "Text-Relocations-Enforced-for-API-level-23",
   3572                               "\"%s\" has text relocations",
   3573                               get_realpath());
   3574     add_dlwarning(get_realpath(), "text relocations");
   3575     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
   3576       DL_ERR("can't unprotect loadable segments for \"%s\": %s", get_realpath(), strerror(errno));
   3577       return false;
   3578     }
   3579   }
   3580 #endif
   3581 
   3582   if (android_relocs_ != nullptr) {
   3583     // check signature
   3584     if (android_relocs_size_ > 3 &&
   3585         android_relocs_[0] == 'A' &&
   3586         android_relocs_[1] == 'P' &&
   3587         android_relocs_[2] == 'S' &&
   3588         android_relocs_[3] == '2') {
   3589       DEBUG("[ android relocating %s ]", get_realpath());
   3590 
   3591       bool relocated = false;
   3592       const uint8_t* packed_relocs = android_relocs_ + 4;
   3593       const size_t packed_relocs_size = android_relocs_size_ - 4;
   3594 
   3595       relocated = relocate(
   3596           version_tracker,
   3597           packed_reloc_iterator<sleb128_decoder>(
   3598             sleb128_decoder(packed_relocs, packed_relocs_size)),
   3599           global_group, local_group);
   3600 
   3601       if (!relocated) {
   3602         return false;
   3603       }
   3604     } else {
   3605       DL_ERR("bad android relocation header.");
   3606       return false;
   3607     }
   3608   }
   3609 
   3610   if (relr_ != nullptr) {
   3611     DEBUG("[ relocating %s relr ]", get_realpath());
   3612     if (!relocate_relr()) {
   3613       return false;
   3614     }
   3615   }
   3616 
   3617 #if defined(USE_RELA)
   3618   if (rela_ != nullptr) {
   3619     DEBUG("[ relocating %s rela ]", get_realpath());
   3620     if (!relocate(version_tracker,
   3621             plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
   3622       return false;
   3623     }
   3624   }
   3625   if (plt_rela_ != nullptr) {
   3626     DEBUG("[ relocating %s plt rela ]", get_realpath());
   3627     if (!relocate(version_tracker,
   3628             plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
   3629       return false;
   3630     }
   3631   }
   3632 #else
   3633   if (rel_ != nullptr) {
   3634     DEBUG("[ relocating %s rel ]", get_realpath());
   3635     if (!relocate(version_tracker,
   3636             plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
   3637       return false;
   3638     }
   3639   }
   3640   if (plt_rel_ != nullptr) {
   3641     DEBUG("[ relocating %s plt rel ]", get_realpath());
   3642     if (!relocate(version_tracker,
   3643             plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
   3644       return false;
   3645     }
   3646   }
   3647 #endif
   3648 
   3649 #if defined(__mips__)
   3650   if (!mips_relocate_got(version_tracker, global_group, local_group)) {
   3651     return false;
   3652   }
   3653 #endif
   3654 
   3655   DEBUG("[ finished linking %s ]", get_realpath());
   3656 
   3657 #if !defined(__LP64__)
   3658   if (has_text_relocations) {
   3659     // All relocations are done, we can protect our segments back to read-only.
   3660     if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
   3661       DL_ERR("can't protect segments for \"%s\": %s",
   3662              get_realpath(), strerror(errno));
   3663       return false;
   3664     }
   3665   }
   3666 #endif
   3667 
   3668   // We can also turn on GNU RELRO protection if we're not linking the dynamic linker
   3669   // itself --- it can't make system calls yet, and will have to call protect_relro later.
   3670   if (!is_linker() && !protect_relro()) {
   3671     return false;
   3672   }
   3673 
   3674   /* Handle serializing/sharing the RELRO segment */
   3675   if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
   3676     if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
   3677                                        extinfo->relro_fd) < 0) {
   3678       DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
   3679              get_realpath(), strerror(errno));
   3680       return false;
   3681     }
   3682   } else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
   3683     if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
   3684                                  extinfo->relro_fd) < 0) {
   3685       DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
   3686              get_realpath(), strerror(errno));
   3687       return false;
   3688     }
   3689   }
   3690 
   3691   notify_gdb_of_load(this);
   3692   set_image_linked();
   3693   return true;
   3694 }
   3695 
   3696 bool soinfo::protect_relro() {
   3697   if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
   3698     DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
   3699            get_realpath(), strerror(errno));
   3700     return false;
   3701   }
   3702   return true;
   3703 }
   3704 
   3705 static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
   3706   g_default_namespace.set_isolated(false);
   3707   auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
   3708 
   3709   char real_path[PATH_MAX];
   3710   std::vector<std::string> ld_default_paths;
   3711   for (size_t i = 0; default_ld_paths[i] != nullptr; ++i) {
   3712     if (realpath(default_ld_paths[i], real_path) != nullptr) {
   3713       ld_default_paths.push_back(real_path);
   3714     } else {
   3715       ld_default_paths.push_back(default_ld_paths[i]);
   3716     }
   3717   }
   3718 
   3719   g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
   3720 
   3721   std::vector<android_namespace_t*> namespaces;
   3722   namespaces.push_back(&g_default_namespace);
   3723   return namespaces;
   3724 }
   3725 
   3726 static std::string get_ld_config_file_vndk_path() {
   3727   if (android::base::GetBoolProperty("ro.vndk.lite", false)) {
   3728     return kLdConfigVndkLiteFilePath;
   3729   }
   3730 
   3731   std::string ld_config_file_vndk = kLdConfigFilePath;
   3732   size_t insert_pos = ld_config_file_vndk.find_last_of('.');
   3733   if (insert_pos == std::string::npos) {
   3734     insert_pos = ld_config_file_vndk.length();
   3735   }
   3736   ld_config_file_vndk.insert(insert_pos, Config::get_vndk_version_string('.'));
   3737   return ld_config_file_vndk;
   3738 }
   3739 
   3740 static std::string get_ld_config_file_path() {
   3741 #ifdef USE_LD_CONFIG_FILE
   3742   // This is a debugging/testing only feature. Must not be available on
   3743   // production builds.
   3744   const char* ld_config_file_env = getenv("LD_CONFIG_FILE");
   3745   if (ld_config_file_env != nullptr && file_exists(ld_config_file_env)) {
   3746     return ld_config_file_env;
   3747   }
   3748 #endif
   3749 
   3750   if (file_exists(kLdConfigArchFilePath)) {
   3751     return kLdConfigArchFilePath;
   3752   }
   3753 
   3754   std::string ld_config_file_vndk = get_ld_config_file_vndk_path();
   3755   if (file_exists(ld_config_file_vndk.c_str())) {
   3756     return ld_config_file_vndk;
   3757   }
   3758 
   3759   return kLdConfigFilePath;
   3760 }
   3761 
   3762 std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
   3763   g_default_namespace.set_name("(default)");
   3764 
   3765   soinfo* somain = solist_get_somain();
   3766 
   3767   const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
   3768                                                        somain->load_bias);
   3769   const char* bname = (interp != nullptr) ? basename(interp) : nullptr;
   3770 
   3771   g_is_asan = bname != nullptr &&
   3772               (strcmp(bname, "linker_asan") == 0 ||
   3773                strcmp(bname, "linker_asan64") == 0);
   3774 
   3775   const Config* config = nullptr;
   3776 
   3777   std::string error_msg;
   3778 
   3779   std::string ld_config_file_path = get_ld_config_file_path();
   3780 
   3781   if (!Config::read_binary_config(ld_config_file_path.c_str(),
   3782                                   executable_path,
   3783                                   g_is_asan,
   3784                                   &config,
   3785                                   &error_msg)) {
   3786     if (!error_msg.empty()) {
   3787       DL_WARN("Warning: couldn't read \"%s\" for \"%s\" (using default configuration instead): %s",
   3788               ld_config_file_path.c_str(),
   3789               executable_path,
   3790               error_msg.c_str());
   3791     }
   3792     config = nullptr;
   3793   }
   3794 
   3795   if (config == nullptr) {
   3796     return init_default_namespace_no_config(g_is_asan);
   3797   }
   3798 
   3799   const auto& namespace_configs = config->namespace_configs();
   3800   std::unordered_map<std::string, android_namespace_t*> namespaces;
   3801 
   3802   // 1. Initialize default namespace
   3803   const NamespaceConfig* default_ns_config = config->default_namespace_config();
   3804 
   3805   g_default_namespace.set_isolated(default_ns_config->isolated());
   3806   g_default_namespace.set_default_library_paths(default_ns_config->search_paths());
   3807   g_default_namespace.set_permitted_paths(default_ns_config->permitted_paths());
   3808 
   3809   namespaces[default_ns_config->name()] = &g_default_namespace;
   3810   if (default_ns_config->visible()) {
   3811     g_exported_namespaces[default_ns_config->name()] = &g_default_namespace;
   3812   }
   3813 
   3814   // 2. Initialize other namespaces
   3815 
   3816   for (auto& ns_config : namespace_configs) {
   3817     if (namespaces.find(ns_config->name()) != namespaces.end()) {
   3818       continue;
   3819     }
   3820 
   3821     android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
   3822     ns->set_name(ns_config->name());
   3823     ns->set_isolated(ns_config->isolated());
   3824     ns->set_default_library_paths(ns_config->search_paths());
   3825     ns->set_permitted_paths(ns_config->permitted_paths());
   3826 
   3827     namespaces[ns_config->name()] = ns;
   3828     if (ns_config->visible()) {
   3829       g_exported_namespaces[ns_config->name()] = ns;
   3830     }
   3831   }
   3832 
   3833   // 3. Establish links between namespaces
   3834   for (auto& ns_config : namespace_configs) {
   3835     auto it_from = namespaces.find(ns_config->name());
   3836     CHECK(it_from != namespaces.end());
   3837     android_namespace_t* namespace_from = it_from->second;
   3838     for (const NamespaceLinkConfig& ns_link : ns_config->links()) {
   3839       auto it_to = namespaces.find(ns_link.ns_name());
   3840       CHECK(it_to != namespaces.end());
   3841       android_namespace_t* namespace_to = it_to->second;
   3842       if (ns_link.allow_all_shared_libs()) {
   3843         link_namespaces_all_libs(namespace_from, namespace_to);
   3844       } else {
   3845         link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
   3846       }
   3847     }
   3848   }
   3849   // we can no longer rely on the fact that libdl.so is part of default namespace
   3850   // this is why we want to add ld-android.so to all namespaces from ld.config.txt
   3851   soinfo* ld_android_so = solist_get_head();
   3852 
   3853   // we also need vdso to be available for all namespaces (if present)
   3854   soinfo* vdso = solist_get_vdso();
   3855   for (auto it : namespaces) {
   3856     it.second->add_soinfo(ld_android_so);
   3857     if (vdso != nullptr) {
   3858       it.second->add_soinfo(vdso);
   3859     }
   3860     // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked
   3861   }
   3862 
   3863   set_application_target_sdk_version(config->target_sdk_version());
   3864 
   3865   std::vector<android_namespace_t*> created_namespaces;
   3866   created_namespaces.reserve(namespaces.size());
   3867   for (auto kv : namespaces) {
   3868     created_namespaces.push_back(kv.second);
   3869   }
   3870   return created_namespaces;
   3871 }
   3872 
   3873 // This function finds a namespace exported in ld.config.txt by its name.
   3874 // A namespace can be exported by setting .visible property to true.
   3875 android_namespace_t* get_exported_namespace(const char* name) {
   3876   if (name == nullptr) {
   3877     return nullptr;
   3878   }
   3879   auto it = g_exported_namespaces.find(std::string(name));
   3880   if (it == g_exported_namespaces.end()) {
   3881     return nullptr;
   3882   }
   3883   return it->second;
   3884 }
   3885