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