Home | History | Annotate | Download | only in linker
      1 /*
      2  * Copyright (C) 2007 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 "linker.h"
     30 #include "linker_cfi.h"
     31 #include "linker_globals.h"
     32 #include "linker_dlwarning.h"
     33 
     34 #include <pthread.h>
     35 #include <stdio.h>
     36 #include <stdlib.h>
     37 #include <string.h>
     38 #include <android/api-level.h>
     39 
     40 #include <bionic/pthread_internal.h>
     41 #include "private/bionic_globals.h"
     42 #include "private/bionic_tls.h"
     43 #include "private/ScopedPthreadMutexLocker.h"
     44 
     45 #define __LINKER_PUBLIC__ __attribute__((visibility("default")))
     46 
     47 extern "C" {
     48 
     49 android_namespace_t* __loader_android_create_namespace(const char* name,
     50                                                        const char* ld_library_path,
     51                                                        const char* default_library_path,
     52                                                        uint64_t type,
     53                                                        const char* permitted_when_isolated_path,
     54                                                        android_namespace_t* parent_namespace,
     55                                                        const void* caller_addr) __LINKER_PUBLIC__;
     56 void* __loader_android_dlopen_ext(const char* filename,
     57                            int flags,
     58                            const android_dlextinfo* extinfo,
     59                            const void* caller_addr) __LINKER_PUBLIC__;
     60 void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) __LINKER_PUBLIC__;
     61 int __loader_android_get_application_target_sdk_version() __LINKER_PUBLIC__;
     62 void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) __LINKER_PUBLIC__;
     63 android_namespace_t* __loader_android_get_exported_namespace(const char* name) __LINKER_PUBLIC__;
     64 bool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
     65                                                const char* library_search_path) __LINKER_PUBLIC__;
     66 bool __loader_android_link_namespaces(android_namespace_t* namespace_from,
     67                                       android_namespace_t* namespace_to,
     68                                       const char* shared_libs_sonames) __LINKER_PUBLIC__;
     69 bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
     70                                                android_namespace_t* namespace_to) __LINKER_PUBLIC__;
     71 void __loader_android_set_application_target_sdk_version(int target) __LINKER_PUBLIC__;
     72 void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__;
     73 void __loader_cfi_fail(uint64_t CallSiteTypeId,
     74                        void* Ptr,
     75                        void *DiagData,
     76                        void *CallerPc) __LINKER_PUBLIC__;
     77 int __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data),
     78                              void* data) __LINKER_PUBLIC__;
     79 int __loader_dladdr(const void* addr, Dl_info* info) __LINKER_PUBLIC__;
     80 int __loader_dlclose(void* handle) __LINKER_PUBLIC__;
     81 char* __loader_dlerror() __LINKER_PUBLIC__;
     82 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr) __LINKER_PUBLIC__;
     83 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) __LINKER_PUBLIC__;
     84 void* __loader_dlvsym(void* handle,
     85                       const char* symbol,
     86                       const char* version,
     87                       const void* caller_addr) __LINKER_PUBLIC__;
     88 void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
     89 void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
     90 libc_shared_globals* __loader_shared_globals() __LINKER_PUBLIC__;
     91 #if defined(__arm__)
     92 _Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
     93 #endif
     94 }
     95 
     96 static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
     97 
     98 static char* __bionic_set_dlerror(char* new_value) {
     99   char* old_value = __get_thread()->current_dlerror;
    100   __get_thread()->current_dlerror = new_value;
    101 
    102   if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value);
    103   return old_value;
    104 }
    105 
    106 static void __bionic_format_dlerror(const char* msg, const char* detail) {
    107   char* buffer = __get_thread()->dlerror_buffer;
    108   strlcpy(buffer, msg, __BIONIC_DLERROR_BUFFER_SIZE);
    109   if (detail != nullptr) {
    110     strlcat(buffer, ": ", __BIONIC_DLERROR_BUFFER_SIZE);
    111     strlcat(buffer, detail, __BIONIC_DLERROR_BUFFER_SIZE);
    112   }
    113 
    114   __bionic_set_dlerror(buffer);
    115 }
    116 
    117 char* __loader_dlerror() {
    118   char* old_value = __bionic_set_dlerror(nullptr);
    119   return old_value;
    120 }
    121 
    122 void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
    123   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    124   do_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
    125 }
    126 
    127 void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
    128   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    129   do_android_update_LD_LIBRARY_PATH(ld_library_path);
    130 }
    131 
    132 static void* dlopen_ext(const char* filename,
    133                         int flags,
    134                         const android_dlextinfo* extinfo,
    135                         const void* caller_addr) {
    136   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    137   g_linker_logger.ResetState();
    138   void* result = do_dlopen(filename, flags, extinfo, caller_addr);
    139   if (result == nullptr) {
    140     __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
    141     return nullptr;
    142   }
    143   return result;
    144 }
    145 
    146 void* __loader_android_dlopen_ext(const char* filename,
    147                            int flags,
    148                            const android_dlextinfo* extinfo,
    149                            const void* caller_addr) {
    150   return dlopen_ext(filename, flags, extinfo, caller_addr);
    151 }
    152 
    153 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr) {
    154   return dlopen_ext(filename, flags, nullptr, caller_addr);
    155 }
    156 
    157 void* dlsym_impl(void* handle, const char* symbol, const char* version, const void* caller_addr) {
    158   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    159   g_linker_logger.ResetState();
    160   void* result;
    161   if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
    162     __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
    163     return nullptr;
    164   }
    165 
    166   return result;
    167 }
    168 
    169 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) {
    170   return dlsym_impl(handle, symbol, nullptr, caller_addr);
    171 }
    172 
    173 void* __loader_dlvsym(void* handle, const char* symbol, const char* version, const void* caller_addr) {
    174   return dlsym_impl(handle, symbol, version, caller_addr);
    175 }
    176 
    177 int __loader_dladdr(const void* addr, Dl_info* info) {
    178   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    179   return do_dladdr(addr, info);
    180 }
    181 
    182 int __loader_dlclose(void* handle) {
    183   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    184   int result = do_dlclose(handle);
    185   if (result != 0) {
    186     __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
    187   }
    188   return result;
    189 }
    190 
    191 int __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
    192   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    193   return do_dl_iterate_phdr(cb, data);
    194 }
    195 
    196 // This function is needed by libgcc.a
    197 int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
    198   return __loader_dl_iterate_phdr(cb, data);
    199 }
    200 
    201 #if defined(__arm__)
    202 _Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
    203   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    204   return do_dl_unwind_find_exidx(pc, pcount);
    205 }
    206 #endif
    207 
    208 void __loader_android_set_application_target_sdk_version(int target) {
    209   // lock to avoid modification in the middle of dlopen.
    210   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    211   set_application_target_sdk_version(target);
    212 }
    213 
    214 int __loader_android_get_application_target_sdk_version() {
    215   return get_application_target_sdk_version();
    216 }
    217 
    218 void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) {
    219   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    220   get_dlwarning(obj, f);
    221 }
    222 
    223 bool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
    224                                                const char* library_search_path) {
    225   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    226   bool success = init_anonymous_namespace(shared_libs_sonames, library_search_path);
    227   if (!success) {
    228     __bionic_format_dlerror("android_init_anonymous_namespace failed", linker_get_error_buffer());
    229   }
    230 
    231   return success;
    232 }
    233 
    234 android_namespace_t* __loader_android_create_namespace(const char* name,
    235                                                 const char* ld_library_path,
    236                                                 const char* default_library_path,
    237                                                 uint64_t type,
    238                                                 const char* permitted_when_isolated_path,
    239                                                 android_namespace_t* parent_namespace,
    240                                                 const void* caller_addr) {
    241   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    242 
    243   android_namespace_t* result = create_namespace(caller_addr,
    244                                                  name,
    245                                                  ld_library_path,
    246                                                  default_library_path,
    247                                                  type,
    248                                                  permitted_when_isolated_path,
    249                                                  parent_namespace);
    250 
    251   if (result == nullptr) {
    252     __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
    253   }
    254 
    255   return result;
    256 }
    257 
    258 bool __loader_android_link_namespaces(android_namespace_t* namespace_from,
    259                                       android_namespace_t* namespace_to,
    260                                       const char* shared_libs_sonames) {
    261   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    262 
    263   bool success = link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
    264 
    265   if (!success) {
    266     __bionic_format_dlerror("android_link_namespaces failed", linker_get_error_buffer());
    267   }
    268 
    269   return success;
    270 }
    271 
    272 bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
    273                                                android_namespace_t* namespace_to) {
    274   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    275 
    276   bool success = link_namespaces_all_libs(namespace_from, namespace_to);
    277 
    278   if (!success) {
    279     __bionic_format_dlerror("android_link_namespaces_all_libs failed", linker_get_error_buffer());
    280   }
    281 
    282   return success;
    283 }
    284 
    285 android_namespace_t* __loader_android_get_exported_namespace(const char* name) {
    286   return get_exported_namespace(name);
    287 }
    288 
    289 void __loader_cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *CallerPc) {
    290   CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc);
    291 }
    292 
    293 void __loader_add_thread_local_dtor(void* dso_handle) {
    294   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    295   increment_dso_handle_reference_counter(dso_handle);
    296 }
    297 
    298 void __loader_remove_thread_local_dtor(void* dso_handle) {
    299   ScopedPthreadMutexLocker locker(&g_dl_mutex);
    300   decrement_dso_handle_reference_counter(dso_handle);
    301 }
    302 
    303 libc_shared_globals* __loader_shared_globals() {
    304   return __libc_shared_globals();
    305 }
    306 
    307 static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
    308 static soinfo* __libdl_info = nullptr;
    309 
    310 // This is used by the dynamic linker. Every process gets these symbols for free.
    311 soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si) {
    312   CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0);
    313 
    314   if (__libdl_info == nullptr) {
    315     __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, linker_path, nullptr, 0, 0);
    316     __libdl_info->flags_ |= (FLAG_LINKED | FLAG_GNU_HASH);
    317     __libdl_info->strtab_ = linker_si.strtab_;
    318     __libdl_info->symtab_ = linker_si.symtab_;
    319     __libdl_info->load_bias = linker_si.load_bias;
    320     __libdl_info->phdr = linker_si.phdr;
    321     __libdl_info->phnum = linker_si.phnum;
    322 
    323     __libdl_info->gnu_nbucket_ = linker_si.gnu_nbucket_;
    324     __libdl_info->gnu_maskwords_ = linker_si.gnu_maskwords_;
    325     __libdl_info->gnu_shift2_ = linker_si.gnu_shift2_;
    326     __libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_;
    327     __libdl_info->gnu_bucket_ = linker_si.gnu_bucket_;
    328     __libdl_info->gnu_chain_ = linker_si.gnu_chain_;
    329 
    330     __libdl_info->ref_count_ = 1;
    331     __libdl_info->strtab_size_ = linker_si.strtab_size_;
    332     __libdl_info->local_group_root_ = __libdl_info;
    333     __libdl_info->soname_ = linker_si.soname_;
    334     __libdl_info->target_sdk_version_ = __ANDROID_API__;
    335     __libdl_info->generate_handle();
    336 #if defined(__work_around_b_24465209__)
    337     strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
    338 #endif
    339   }
    340 
    341   return __libdl_info;
    342 }
    343