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