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