13b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes/*
23b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * Copyright (C) 2007 The Android Open Source Project
3bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * All rights reserved.
43b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes *
5bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * Redistribution and use in source and binary forms, with or without
6bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * modification, are permitted provided that the following conditions
7bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * are met:
8bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *  * Redistributions of source code must retain the above copyright
9bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    notice, this list of conditions and the following disclaimer.
10bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *  * Redistributions in binary form must reproduce the above copyright
11bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    notice, this list of conditions and the following disclaimer in
12bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    the documentation and/or other materials provided with the
13bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov *    distribution.
143b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes *
15bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bcc4da9b752f0def46d63ed7b31f3f49cc2435adDimitry Ivanov * SUCH DAMAGE.
273b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes */
283b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
295419b9474753d25dff947c7740532f86d130c0beElliott Hughes#include "linker.h"
300a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov#include "linker_cfi.h"
3148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#include "linker_globals.h"
32769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov#include "linker_dlwarning.h"
335419b9474753d25dff947c7740532f86d130c0beElliott Hughes
343b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <pthread.h>
353b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <stdio.h>
365419b9474753d25dff947c7740532f86d130c0beElliott Hughes#include <stdlib.h>
3705fc1d7050d5451aea08dc5f504d2670287b2d43Elliott Hughes#include <string.h>
381913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov#include <android/api-level.h>
393b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
405419b9474753d25dff947c7740532f86d130c0beElliott Hughes#include <bionic/pthread_internal.h>
41eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/bionic_tls.h"
42eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/ScopedPthreadMutexLocker.h"
433b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
447abea57ba599b9b114031ae33699b5d7fba8cc97dimitry#define __LINKER_PUBLIC__ __attribute__((visibility("default")))
457abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
467abea57ba599b9b114031ae33699b5d7fba8cc97dimitryextern "C" {
477abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
487abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_create_namespace(const char* name,
497abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       const char* ld_library_path,
507abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       const char* default_library_path,
517abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       uint64_t type,
527abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       const char* permitted_when_isolated_path,
537abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       android_namespace_t* parent_namespace,
547abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                                       const void* caller_addr) __LINKER_PUBLIC__;
557abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_android_dlopen_ext(const char* filename,
567abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                           int flags,
577abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                           const android_dlextinfo* extinfo,
587abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                           const void* caller_addr) __LINKER_PUBLIC__;
597abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) __LINKER_PUBLIC__;
607abea57ba599b9b114031ae33699b5d7fba8cc97dimitryuint32_t __loader_android_get_application_target_sdk_version() __LINKER_PUBLIC__;
617abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) __LINKER_PUBLIC__;
627abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_get_exported_namespace(const char* name) __LINKER_PUBLIC__;
637abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
647abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                               const char* library_search_path) __LINKER_PUBLIC__;
657abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_link_namespaces(android_namespace_t* namespace_from,
667abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      android_namespace_t* namespace_to,
677abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      const char* shared_libs_sonames) __LINKER_PUBLIC__;
689ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chienbool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
699ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien                                               android_namespace_t* namespace_to) __LINKER_PUBLIC__;
707abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_set_application_target_sdk_version(uint32_t target) __LINKER_PUBLIC__;
717abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__;
727abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_cfi_fail(uint64_t CallSiteTypeId,
737abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void* Ptr,
747abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void *DiagData,
757abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void *CallerPc) __LINKER_PUBLIC__;
767abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data),
777abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                             void* data) __LINKER_PUBLIC__;
787abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dladdr(const void* addr, Dl_info* info) __LINKER_PUBLIC__;
797abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dlclose(void* handle) __LINKER_PUBLIC__;
807abea57ba599b9b114031ae33699b5d7fba8cc97dimitrychar* __loader_dlerror() __LINKER_PUBLIC__;
817abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlopen(const char* filename, int flags, const void* caller_addr) __LINKER_PUBLIC__;
827abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) __LINKER_PUBLIC__;
837abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlvsym(void* handle,
847abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const char* symbol,
857abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const char* version,
867abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const void* caller_addr) __LINKER_PUBLIC__;
8706016f226efe7aff2736643cb8e719c513948eccdimitryvoid __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
8806016f226efe7aff2736643cb8e719c513948eccdimitryvoid __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
897abea57ba599b9b114031ae33699b5d7fba8cc97dimitry#if defined(__arm__)
907abea57ba599b9b114031ae33699b5d7fba8cc97dimitry_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
917abea57ba599b9b114031ae33699b5d7fba8cc97dimitry#endif
927abea57ba599b9b114031ae33699b5d7fba8cc97dimitry}
937abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
94212e0e38248860b151b28877225629a988d95b58Elliott Hughesstatic pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
953b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
965e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughesstatic char* __bionic_set_dlerror(char* new_value) {
972a0b873065edb304fa2d1c54f8de663ea638b8abElliott Hughes  char** dlerror_slot = &reinterpret_cast<char**>(__get_tls())[TLS_SLOT_DLERROR];
983b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
995e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughes  char* old_value = *dlerror_slot;
1005419b9474753d25dff947c7740532f86d130c0beElliott Hughes  *dlerror_slot = new_value;
101295082b3af2042e52ce44aa75c90755ac97bc4aaElliott Hughes  if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value);
1025419b9474753d25dff947c7740532f86d130c0beElliott Hughes  return old_value;
1035419b9474753d25dff947c7740532f86d130c0beElliott Hughes}
1043b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1055419b9474753d25dff947c7740532f86d130c0beElliott Hughesstatic void __bionic_format_dlerror(const char* msg, const char* detail) {
1065419b9474753d25dff947c7740532f86d130c0beElliott Hughes  char* buffer = __get_thread()->dlerror_buffer;
1075419b9474753d25dff947c7740532f86d130c0beElliott Hughes  strlcpy(buffer, msg, __BIONIC_DLERROR_BUFFER_SIZE);
108851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov  if (detail != nullptr) {
1095419b9474753d25dff947c7740532f86d130c0beElliott Hughes    strlcat(buffer, ": ", __BIONIC_DLERROR_BUFFER_SIZE);
1105419b9474753d25dff947c7740532f86d130c0beElliott Hughes    strlcat(buffer, detail, __BIONIC_DLERROR_BUFFER_SIZE);
1113b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1125419b9474753d25dff947c7740532f86d130c0beElliott Hughes
1135419b9474753d25dff947c7740532f86d130c0beElliott Hughes  __bionic_set_dlerror(buffer);
1145419b9474753d25dff947c7740532f86d130c0beElliott Hughes}
1155419b9474753d25dff947c7740532f86d130c0beElliott Hughes
1167abea57ba599b9b114031ae33699b5d7fba8cc97dimitrychar* __loader_dlerror() {
1175e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughes  char* old_value = __bionic_set_dlerror(nullptr);
1185419b9474753d25dff947c7740532f86d130c0beElliott Hughes  return old_value;
1193b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1203b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1217abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
1221728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
123a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes  do_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
124a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes}
125a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes
1267abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
1271728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
128cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes  do_android_update_LD_LIBRARY_PATH(ld_library_path);
129cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes}
130cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes
131d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovstatic void* dlopen_ext(const char* filename,
132d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        int flags,
133d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        const android_dlextinfo* extinfo,
134d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        const void* caller_addr) {
1351728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
136b996d60493a2e501655f23523b31fe34a63edd5cDimitry Ivanov  g_linker_logger.ResetState();
137d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  void* result = do_dlopen(filename, flags, extinfo, caller_addr);
138851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov  if (result == nullptr) {
139650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes    __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
140851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov    return nullptr;
1413b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1423b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  return result;
1433b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1443b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1457abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_android_dlopen_ext(const char* filename,
146d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           int flags,
147d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           const android_dlextinfo* extinfo,
148d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           const void* caller_addr) {
149e5cfafe3446a33b0c77416061d598bf76d580ee0Dmitriy Ivanov  return dlopen_ext(filename, flags, extinfo, caller_addr);
150b648a8a57ee42533a5bf127225a252f73ca2cbbcDmitriy Ivanov}
151b648a8a57ee42533a5bf127225a252f73ca2cbbcDmitriy Ivanov
1527abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlopen(const char* filename, int flags, const void* caller_addr) {
153e5cfafe3446a33b0c77416061d598bf76d580ee0Dmitriy Ivanov  return dlopen_ext(filename, flags, nullptr, caller_addr);
154012cb4583a5f8564059142bb1900ea3a31e7cfa9Torne (Richard Coles)}
155012cb4583a5f8564059142bb1900ea3a31e7cfa9Torne (Richard Coles)
156d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovvoid* dlsym_impl(void* handle, const char* symbol, const char* version, const void* caller_addr) {
1571728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
158b996d60493a2e501655f23523b31fe34a63edd5cDimitry Ivanov  g_linker_logger.ResetState();
1594a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  void* result;
1609cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
1614a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov    __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
162851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov    return nullptr;
1633b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1643b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1654a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  return result;
1663b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1673b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1687abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) {
1699cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  return dlsym_impl(handle, symbol, nullptr, caller_addr);
1709cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov}
1719cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov
1727abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlvsym(void* handle, const char* symbol, const char* version, const void* caller_addr) {
1739cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  return dlsym_impl(handle, symbol, version, caller_addr);
1749cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov}
1759cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov
1767abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dladdr(const void* addr, Dl_info* info) {
1771728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
1784a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  return do_dladdr(addr, info);
1793b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1803b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1817abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dlclose(void* handle) {
1821728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
183d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  int result = do_dlclose(handle);
184d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  if (result != 0) {
185d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov    __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
186d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  }
187d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  return result;
1883b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1893b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1907abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
1917271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
1927271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov  return do_dl_iterate_phdr(cb, data);
1937271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov}
1947271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov
1957abea57ba599b9b114031ae33699b5d7fba8cc97dimitry// This function is needed by libgcc.a
1967abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
1977abea57ba599b9b114031ae33699b5d7fba8cc97dimitry  return __loader_dl_iterate_phdr(cb, data);
1987abea57ba599b9b114031ae33699b5d7fba8cc97dimitry}
1997abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
200d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#if defined(__arm__)
2017abea57ba599b9b114031ae33699b5d7fba8cc97dimitry_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
202d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
203d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov  return do_dl_unwind_find_exidx(pc, pcount);
204d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov}
205d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#endif
206d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov
2077abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_set_application_target_sdk_version(uint32_t target) {
208d974e8804689058714dc4fe9adcb57ee9a6996a8Dmitriy Ivanov  // lock to avoid modification in the middle of dlopen.
209d974e8804689058714dc4fe9adcb57ee9a6996a8Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
21079fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov  set_application_target_sdk_version(target);
21179fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov}
21279fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov
2137abea57ba599b9b114031ae33699b5d7fba8cc97dimitryuint32_t __loader_android_get_application_target_sdk_version() {
21479fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov  return get_application_target_sdk_version();
21579fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov}
21679fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov
2177abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) {
218769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
219769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov  get_dlwarning(obj, f);
220769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov}
221769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov
2227abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
2237abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                               const char* library_search_path) {
22442d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
2257a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  bool success = init_anonymous_namespace(shared_libs_sonames, library_search_path);
22642d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  if (!success) {
2277a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov    __bionic_format_dlerror("android_init_anonymous_namespace failed", linker_get_error_buffer());
22842d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  }
22942d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
23042d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  return success;
23142d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov}
23242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
2337abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_create_namespace(const char* name,
234d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* ld_library_path,
235d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* default_library_path,
236d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                uint64_t type,
237d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* permitted_when_isolated_path,
238d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                android_namespace_t* parent_namespace,
239d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const void* caller_addr) {
24042d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
24142d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
242fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov  android_namespace_t* result = create_namespace(caller_addr,
243fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 name,
244fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 ld_library_path,
245fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 default_library_path,
246fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 type,
247fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 permitted_when_isolated_path,
248fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 parent_namespace);
24942d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
25042d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  if (result == nullptr) {
25142d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov    __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
25242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  }
25342d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
25442d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  return result;
25542d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov}
25642d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
2577abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_link_namespaces(android_namespace_t* namespace_from,
2587abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      android_namespace_t* namespace_to,
2597abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      const char* shared_libs_sonames) {
2607a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
2617a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2627a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  bool success = link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
2637a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2647a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  if (!success) {
2657a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov    __bionic_format_dlerror("android_link_namespaces failed", linker_get_error_buffer());
2667a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  }
2677a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2687a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  return success;
2697a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov}
2707a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2719ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chienbool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
2729ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien                                               android_namespace_t* namespace_to) {
2739ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien  ScopedPthreadMutexLocker locker(&g_dl_mutex);
2749ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien
2759ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien  bool success = link_namespaces_all_libs(namespace_from, namespace_to);
2769ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien
2779ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien  if (!success) {
2789ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien    __bionic_format_dlerror("android_link_namespaces_all_libs failed", linker_get_error_buffer());
2799ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien  }
2809ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien
2819ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien  return success;
2829ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien}
2839ee4591cb4a23b3c1a899f5ae3e4d769d0ba5a15Logan Chien
2847abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_get_exported_namespace(const char* name) {
28501de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park  return get_exported_namespace(name);
28601de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park}
28701de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park
2887abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *CallerPc) {
2890a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov  CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc);
2900a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov}
2910a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov
29206016f226efe7aff2736643cb8e719c513948eccdimitryvoid __loader_add_thread_local_dtor(void* dso_handle) {
29306016f226efe7aff2736643cb8e719c513948eccdimitry  ScopedPthreadMutexLocker locker(&g_dl_mutex);
29406016f226efe7aff2736643cb8e719c513948eccdimitry  increment_dso_handle_reference_counter(dso_handle);
29506016f226efe7aff2736643cb8e719c513948eccdimitry}
29606016f226efe7aff2736643cb8e719c513948eccdimitry
29706016f226efe7aff2736643cb8e719c513948eccdimitryvoid __loader_remove_thread_local_dtor(void* dso_handle) {
29806016f226efe7aff2736643cb8e719c513948eccdimitry  ScopedPthreadMutexLocker locker(&g_dl_mutex);
29906016f226efe7aff2736643cb8e719c513948eccdimitry  decrement_dso_handle_reference_counter(dso_handle);
30006016f226efe7aff2736643cb8e719c513948eccdimitry}
30106016f226efe7aff2736643cb8e719c513948eccdimitry
302aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanovstatic uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
303aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanovstatic soinfo* __libdl_info = nullptr;
304c00f2cb587630d5e954c7f548749f1e3170b3cb1Elliott Hughes
305d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov// This is used by the dynamic linker. Every process gets these symbols for free.
3067abea57ba599b9b114031ae33699b5d7fba8cc97dimitrysoinfo* get_libdl_info(const char* linker_path,
3077abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       const soinfo& linker_si,
3087abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       const link_map& linker_map) {
3097abea57ba599b9b114031ae33699b5d7fba8cc97dimitry  CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0);
3107abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
311aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  if (__libdl_info == nullptr) {
312d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov    __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, linker_path, nullptr, 0, 0);
3137abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->flags_ |= (FLAG_LINKED | FLAG_GNU_HASH);
3147abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->strtab_ = linker_si.strtab_;
3157abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->symtab_ = linker_si.symtab_;
3167abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->load_bias = linker_si.load_bias;
3177abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
3187abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_nbucket_ = linker_si.gnu_nbucket_;
3197abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_maskwords_ = linker_si.gnu_maskwords_;
3207abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_shift2_ = linker_si.gnu_shift2_;
3217abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_;
3227abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_bucket_ = linker_si.gnu_bucket_;
3237abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_chain_ = linker_si.gnu_chain_;
3247abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
325aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    __libdl_info->ref_count_ = 1;
3267abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->strtab_size_ = linker_si.strtab_size_;
327aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    __libdl_info->local_group_root_ = __libdl_info;
3288e8c2c001380ad98f2e239c0c840dad80ebec35cdimitry    __libdl_info->soname_ = linker_si.soname_;
3291913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov    __libdl_info->target_sdk_version_ = __ANDROID_API__;
330d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov    __libdl_info->generate_handle();
331cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_addr = linker_map.l_addr;
332cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_name = linker_map.l_name;
333cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_ld = linker_map.l_ld;
334747d30ebf368be8c4ec0455324bdac53204eb179Mike Frysinger#if defined(__work_around_b_24465209__)
335aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
336aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#endif
337d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  }
3383b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
339aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  return __libdl_info;
340d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov}
341