dlfcn.cpp revision 8e8c2c001380ad98f2e239c0c840dad80ebec35c
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__;
687abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_set_application_target_sdk_version(uint32_t target) __LINKER_PUBLIC__;
697abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__;
707abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_cfi_fail(uint64_t CallSiteTypeId,
717abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void* Ptr,
727abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void *DiagData,
737abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       void *CallerPc) __LINKER_PUBLIC__;
747abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data),
757abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                             void* data) __LINKER_PUBLIC__;
767abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dladdr(const void* addr, Dl_info* info) __LINKER_PUBLIC__;
777abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dlclose(void* handle) __LINKER_PUBLIC__;
787abea57ba599b9b114031ae33699b5d7fba8cc97dimitrychar* __loader_dlerror() __LINKER_PUBLIC__;
797abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlopen(const char* filename, int flags, const void* caller_addr) __LINKER_PUBLIC__;
807abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) __LINKER_PUBLIC__;
817abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlvsym(void* handle,
827abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const char* symbol,
837abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const char* version,
847abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                      const void* caller_addr) __LINKER_PUBLIC__;
857abea57ba599b9b114031ae33699b5d7fba8cc97dimitry#if defined(__arm__)
867abea57ba599b9b114031ae33699b5d7fba8cc97dimitry_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
877abea57ba599b9b114031ae33699b5d7fba8cc97dimitry#endif
887abea57ba599b9b114031ae33699b5d7fba8cc97dimitry}
897abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
90212e0e38248860b151b28877225629a988d95b58Elliott Hughesstatic pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
913b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
925e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughesstatic char* __bionic_set_dlerror(char* new_value) {
932a0b873065edb304fa2d1c54f8de663ea638b8abElliott Hughes  char** dlerror_slot = &reinterpret_cast<char**>(__get_tls())[TLS_SLOT_DLERROR];
943b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
955e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughes  char* old_value = *dlerror_slot;
965419b9474753d25dff947c7740532f86d130c0beElliott Hughes  *dlerror_slot = new_value;
97295082b3af2042e52ce44aa75c90755ac97bc4aaElliott Hughes  if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value);
985419b9474753d25dff947c7740532f86d130c0beElliott Hughes  return old_value;
995419b9474753d25dff947c7740532f86d130c0beElliott Hughes}
1003b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1015419b9474753d25dff947c7740532f86d130c0beElliott Hughesstatic void __bionic_format_dlerror(const char* msg, const char* detail) {
1025419b9474753d25dff947c7740532f86d130c0beElliott Hughes  char* buffer = __get_thread()->dlerror_buffer;
1035419b9474753d25dff947c7740532f86d130c0beElliott Hughes  strlcpy(buffer, msg, __BIONIC_DLERROR_BUFFER_SIZE);
104851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov  if (detail != nullptr) {
1055419b9474753d25dff947c7740532f86d130c0beElliott Hughes    strlcat(buffer, ": ", __BIONIC_DLERROR_BUFFER_SIZE);
1065419b9474753d25dff947c7740532f86d130c0beElliott Hughes    strlcat(buffer, detail, __BIONIC_DLERROR_BUFFER_SIZE);
1073b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1085419b9474753d25dff947c7740532f86d130c0beElliott Hughes
1095419b9474753d25dff947c7740532f86d130c0beElliott Hughes  __bionic_set_dlerror(buffer);
1105419b9474753d25dff947c7740532f86d130c0beElliott Hughes}
1115419b9474753d25dff947c7740532f86d130c0beElliott Hughes
1127abea57ba599b9b114031ae33699b5d7fba8cc97dimitrychar* __loader_dlerror() {
1135e071a18ce88d93fcffaebb9e0f62524ae504908Elliott Hughes  char* old_value = __bionic_set_dlerror(nullptr);
1145419b9474753d25dff947c7740532f86d130c0beElliott Hughes  return old_value;
1153b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1163b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1177abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
1181728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
119a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes  do_android_get_LD_LIBRARY_PATH(buffer, buffer_size);
120a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes}
121a4aafd156068ee174012f28cd894dbecf0e4ab90Elliott Hughes
1227abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
1231728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
124cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes  do_android_update_LD_LIBRARY_PATH(ld_library_path);
125cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes}
126cade4c36e7c9c62db3f476a0f9cfc329bac9acb7Elliott Hughes
127d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovstatic void* dlopen_ext(const char* filename,
128d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        int flags,
129d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        const android_dlextinfo* extinfo,
130d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                        const void* caller_addr) {
1311728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
132b996d60493a2e501655f23523b31fe34a63edd5cDimitry Ivanov  g_linker_logger.ResetState();
133d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  void* result = do_dlopen(filename, flags, extinfo, caller_addr);
134851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov  if (result == nullptr) {
135650be4e584eeab3591b9e273bfd6d169eea60853Elliott Hughes    __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());
136851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov    return nullptr;
1373b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1383b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  return result;
1393b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1403b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1417abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_android_dlopen_ext(const char* filename,
142d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           int flags,
143d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           const android_dlextinfo* extinfo,
144d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                           const void* caller_addr) {
145e5cfafe3446a33b0c77416061d598bf76d580ee0Dmitriy Ivanov  return dlopen_ext(filename, flags, extinfo, caller_addr);
146b648a8a57ee42533a5bf127225a252f73ca2cbbcDmitriy Ivanov}
147b648a8a57ee42533a5bf127225a252f73ca2cbbcDmitriy Ivanov
1487abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlopen(const char* filename, int flags, const void* caller_addr) {
149e5cfafe3446a33b0c77416061d598bf76d580ee0Dmitriy Ivanov  return dlopen_ext(filename, flags, nullptr, caller_addr);
150012cb4583a5f8564059142bb1900ea3a31e7cfa9Torne (Richard Coles)}
151012cb4583a5f8564059142bb1900ea3a31e7cfa9Torne (Richard Coles)
152d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanovvoid* dlsym_impl(void* handle, const char* symbol, const char* version, const void* caller_addr) {
1531728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
154b996d60493a2e501655f23523b31fe34a63edd5cDimitry Ivanov  g_linker_logger.ResetState();
1554a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  void* result;
1569cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  if (!do_dlsym(handle, symbol, version, caller_addr, &result)) {
1574a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov    __bionic_format_dlerror(linker_get_error_buffer(), nullptr);
158851135bf9941b3813adb9b4f43d76e040c4ba157Dmitriy Ivanov    return nullptr;
1593b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes  }
1603b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1614a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  return result;
1623b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1633b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1647abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) {
1659cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  return dlsym_impl(handle, symbol, nullptr, caller_addr);
1669cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov}
1679cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov
1687abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid* __loader_dlvsym(void* handle, const char* symbol, const char* version, const void* caller_addr) {
1699cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov  return dlsym_impl(handle, symbol, version, caller_addr);
1709cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov}
1719cf99cbad89c8495828788ce693a99ced434f66fDimitry Ivanov
1727abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dladdr(const void* addr, Dl_info* info) {
1731728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
1744a2c5aa30ceea2aaf8dcaee2feb4879978af4fceDimitry Ivanov  return do_dladdr(addr, info);
1753b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1763b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1777abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dlclose(void* handle) {
1781728b2396591853345507a063ed6075dfd251706Elliott Hughes  ScopedPthreadMutexLocker locker(&g_dl_mutex);
179d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  int result = do_dlclose(handle);
180d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  if (result != 0) {
181d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov    __bionic_format_dlerror("dlclose failed", linker_get_error_buffer());
182d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  }
183d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov  return result;
1843b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}
1853b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
1867abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
1877271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
1887271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov  return do_dl_iterate_phdr(cb, data);
1897271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov}
1907271caf93db6897cdbcfca169441045bb52de61bDmitriy Ivanov
1917abea57ba599b9b114031ae33699b5d7fba8cc97dimitry// This function is needed by libgcc.a
1927abea57ba599b9b114031ae33699b5d7fba8cc97dimitryint dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) {
1937abea57ba599b9b114031ae33699b5d7fba8cc97dimitry  return __loader_dl_iterate_phdr(cb, data);
1947abea57ba599b9b114031ae33699b5d7fba8cc97dimitry}
1957abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
196d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#if defined(__arm__)
1977abea57ba599b9b114031ae33699b5d7fba8cc97dimitry_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) {
198d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
199d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov  return do_dl_unwind_find_exidx(pc, pcount);
200d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov}
201d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov#endif
202d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov
2037abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_set_application_target_sdk_version(uint32_t target) {
204d974e8804689058714dc4fe9adcb57ee9a6996a8Dmitriy Ivanov  // lock to avoid modification in the middle of dlopen.
205d974e8804689058714dc4fe9adcb57ee9a6996a8Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
20679fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov  set_application_target_sdk_version(target);
20779fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov}
20879fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov
2097abea57ba599b9b114031ae33699b5d7fba8cc97dimitryuint32_t __loader_android_get_application_target_sdk_version() {
21079fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov  return get_application_target_sdk_version();
21179fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov}
21279fd668bb4ddb22432eeda2ebd8d10359013d9a8Dmitriy Ivanov
2137abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) {
214769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
215769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov  get_dlwarning(obj, f);
216769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov}
217769b33fadf45a039741f932672ac2c4f901d7d4aDimitry Ivanov
2187abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames,
2197abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                               const char* library_search_path) {
22042d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
2217a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  bool success = init_anonymous_namespace(shared_libs_sonames, library_search_path);
22242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  if (!success) {
2237a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov    __bionic_format_dlerror("android_init_anonymous_namespace failed", linker_get_error_buffer());
22442d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  }
22542d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
22642d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  return success;
22742d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov}
22842d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
2297abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_create_namespace(const char* name,
230d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* ld_library_path,
231d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* default_library_path,
232d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                uint64_t type,
233d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const char* permitted_when_isolated_path,
234d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                android_namespace_t* parent_namespace,
235d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov                                                const void* caller_addr) {
23642d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
23742d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
238fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov  android_namespace_t* result = create_namespace(caller_addr,
239fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 name,
240fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 ld_library_path,
241fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 default_library_path,
242fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 type,
243fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 permitted_when_isolated_path,
244fc2da53440383fe1026e0eb287d643b577c2707dDimitry Ivanov                                                 parent_namespace);
24542d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
24642d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  if (result == nullptr) {
24742d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov    __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer());
24842d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  }
24942d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
25042d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov  return result;
25142d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov}
25242d5fcb9f494eb45de3b6bf759f4a18076e84728Dmitriy Ivanov
2537abea57ba599b9b114031ae33699b5d7fba8cc97dimitrybool __loader_android_link_namespaces(android_namespace_t* namespace_from,
2547abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      android_namespace_t* namespace_to,
2557abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                                      const char* shared_libs_sonames) {
2567a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  ScopedPthreadMutexLocker locker(&g_dl_mutex);
2577a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2587a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  bool success = link_namespaces(namespace_from, namespace_to, shared_libs_sonames);
2597a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2607a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  if (!success) {
2617a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov    __bionic_format_dlerror("android_link_namespaces failed", linker_get_error_buffer());
2627a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  }
2637a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2647a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov  return success;
2657a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov}
2667a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov
2677abea57ba599b9b114031ae33699b5d7fba8cc97dimitryandroid_namespace_t* __loader_android_get_exported_namespace(const char* name) {
26801de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park  return get_exported_namespace(name);
26901de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park}
27001de74e76d1131b5c5b0120d07e8f468ac5f8facJiyong Park
2717abea57ba599b9b114031ae33699b5d7fba8cc97dimitryvoid __loader_cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *CallerPc) {
2720a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov  CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc);
2730a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov}
2740a3637d3eb2424d8e825ad1825f843450a888406Evgenii Stepanov
275aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanovstatic uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
276aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanovstatic soinfo* __libdl_info = nullptr;
277c00f2cb587630d5e954c7f548749f1e3170b3cb1Elliott Hughes
278d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov// This is used by the dynamic linker. Every process gets these symbols for free.
2797abea57ba599b9b114031ae33699b5d7fba8cc97dimitrysoinfo* get_libdl_info(const char* linker_path,
2807abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       const soinfo& linker_si,
2817abea57ba599b9b114031ae33699b5d7fba8cc97dimitry                       const link_map& linker_map) {
2827abea57ba599b9b114031ae33699b5d7fba8cc97dimitry  CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0);
2837abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
284aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  if (__libdl_info == nullptr) {
285d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov    __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, linker_path, nullptr, 0, 0);
2867abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->flags_ |= (FLAG_LINKED | FLAG_GNU_HASH);
2877abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->strtab_ = linker_si.strtab_;
2887abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->symtab_ = linker_si.symtab_;
2897abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->load_bias = linker_si.load_bias;
2907abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
2917abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_nbucket_ = linker_si.gnu_nbucket_;
2927abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_maskwords_ = linker_si.gnu_maskwords_;
2937abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_shift2_ = linker_si.gnu_shift2_;
2947abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_;
2957abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_bucket_ = linker_si.gnu_bucket_;
2967abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->gnu_chain_ = linker_si.gnu_chain_;
2977abea57ba599b9b114031ae33699b5d7fba8cc97dimitry
298aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    __libdl_info->ref_count_ = 1;
2997abea57ba599b9b114031ae33699b5d7fba8cc97dimitry    __libdl_info->strtab_size_ = linker_si.strtab_size_;
300aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    __libdl_info->local_group_root_ = __libdl_info;
3018e8c2c001380ad98f2e239c0c840dad80ebec35cdimitry    __libdl_info->soname_ = linker_si.soname_;
3021913352c6b3501893dfb45189754970f9dc6e7bbDmitriy Ivanov    __libdl_info->target_sdk_version_ = __ANDROID_API__;
303d88e1f350111b3dfd71c6492321f0503cb5540dbDimitry Ivanov    __libdl_info->generate_handle();
304cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_addr = linker_map.l_addr;
305cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_name = linker_map.l_name;
306cd510cbed9dc1e1b65b9d34676fdf6d85101f22cDimitry Ivanov    __libdl_info->link_map_head.l_ld = linker_map.l_ld;
307747d30ebf368be8c4ec0455324bdac53204eb179Mike Frysinger#if defined(__work_around_b_24465209__)
308aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov    strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
309aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov#endif
310d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov  }
3113b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes
312aae859cc3ca127d890e853cbf12b731e05624a22Dmitriy Ivanov  return __libdl_info;
313d59e50063ad708509f3ad83350be33f5612c4f54Dmitriy Ivanov}
314