11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * you may not use this file except in compliance with the License. 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * You may obtain a copy of the License at 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * See the License for the specific language governing permissions and 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * limitations under the License. 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <dlfcn.h> 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h> 182e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin#include <stdio.h> 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "linker.h" 205c734644eebf8d01be1e86cbe20a111a5c5a2738David 'Digit' Turner#include "linker_format.h" 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* This file hijacks the symbols stubbed out in libdl.so. */ 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DL_SUCCESS 0 252e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin#define DL_ERR_CANNOT_LOAD_LIBRARY 1 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DL_ERR_INVALID_LIBRARY_HANDLE 2 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DL_ERR_BAD_SYMBOL_NAME 3 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DL_ERR_SYMBOL_NOT_FOUND 4 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DL_ERR_SYMBOL_NOT_GLOBAL 5 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 312e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavinstatic char dl_err_buf[1024]; 322e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavinstatic const char *dl_err_str; 332e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char *dl_errors[] = { 352e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin [DL_ERR_CANNOT_LOAD_LIBRARY] = "Cannot load library", 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project [DL_ERR_INVALID_LIBRARY_HANDLE] = "Invalid library handle", 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project [DL_ERR_BAD_SYMBOL_NAME] = "Invalid symbol name", 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project [DL_ERR_SYMBOL_NOT_FOUND] = "Symbol not found", 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project [DL_ERR_SYMBOL_NOT_GLOBAL] = "Symbol is not global", 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define likely(expr) __builtin_expect (expr, 1) 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define unlikely(expr) __builtin_expect (expr, 0) 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic pthread_mutex_t dl_lock = PTHREAD_MUTEX_INITIALIZER; 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 472e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavinstatic void set_dlerror(int err) 482e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin{ 495c734644eebf8d01be1e86cbe20a111a5c5a2738David 'Digit' Turner format_buffer(dl_err_buf, sizeof(dl_err_buf), "%s: %s", dl_errors[err], 502e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin linker_get_error()); 512e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin dl_err_str = (const char *)&dl_err_buf[0]; 522e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin}; 532e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 542e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavinvoid *dlopen(const char *filename, int flag) 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project soinfo *ret; 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock(&dl_lock); 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret = find_library(filename); 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (unlikely(ret == NULL)) { 612e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_CANNOT_LOAD_LIBRARY); 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret->refcount++; 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return ret; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectconst char *dlerror(void) 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 712e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin const char *tmp = dl_err_str; 722e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin dl_err_str = NULL; 732e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin return (const char *)tmp; 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid *dlsym(void *handle, const char *symbol) 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 789ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev soinfo *found; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Elf32_Sym *sym; 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned bind; 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock(&dl_lock); 832e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(unlikely(handle == 0)) { 852e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE); 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto err; 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(unlikely(symbol == 0)) { 892e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_BAD_SYMBOL_NAME); 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto err; 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 922e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(handle == RTLD_DEFAULT) { 941698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = lookup(symbol, &found, NULL); 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if(handle == RTLD_NEXT) { 961698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer void *ret_addr = __builtin_return_address(0); 971698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer soinfo *si = find_containing_library(ret_addr); 981698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer 991698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = NULL; 1001698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer if(si && si->next) { 1011698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = lookup(symbol, &found, si->next); 1021698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer } 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1049ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev found = (soinfo*)handle; 1059ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev sym = lookup_in_library(found, symbol); 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(likely(sym != 0)) { 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bind = ELF32_ST_BIND(sym->st_info); 1102e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { 1129ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev unsigned ret = sym->st_value + found->base; 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (void*)ret; 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1172e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL); 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1192e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin else 1202e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterr: 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 127bda5da074eab4bdf374e1f4a19d480c62c72f5ffMathias Agopianint dladdr(const void *addr, Dl_info *info) 128e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer{ 129e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer int ret = 0; 130e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 131e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer pthread_mutex_lock(&dl_lock); 132e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 133e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer /* Determine if this address can be found in any library currently mapped */ 134e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer soinfo *si = find_containing_library(addr); 135e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 136e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer if(si) { 137e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer memset(info, 0, sizeof(Dl_info)); 138e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 139e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_fname = si->name; 140e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_fbase = (void*)si->base; 141e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 142e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer /* Determine if any symbol in the library contains the specified address */ 143e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer Elf32_Sym *sym = find_containing_symbol(addr, si); 144e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 145e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer if(sym != NULL) { 146e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_sname = si->strtab + sym->st_name; 147e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_saddr = (void*)(si->base + sym->st_value); 148e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer } 149e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 150e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer ret = 1; 151e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer } 152e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 153e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer pthread_mutex_unlock(&dl_lock); 154e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 155e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer return ret; 156e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer} 157e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint dlclose(void *handle) 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock(&dl_lock); 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (void)unload_library((soinfo*)handle); 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(ANDROID_ARM_LINKER) 167e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0000000 00011111 111112 22222222 2333333 333344444444445555555 168e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0123456 78901234 567890 12345678 9012345 678901234567890123456 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ANDROID_LIBDL_STRTAB \ 170e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_unwind_find_exidx\0" 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#elif defined(ANDROID_X86_LINKER) 173e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0000000 00011111 111112 22222222 2333333 3333444444444455 174e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0123456 78901234 567890 12345678 9012345 6789012345678901 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define ANDROID_LIBDL_STRTAB \ 176e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0" 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 178ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI#elif defined(ANDROID_SH_LINKER) 179e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0000000 00011111 111112 22222222 2333333 3333444444444455 180e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer// 0123456 78901234 567890 12345678 9012345 6789012345678901 181ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI#define ANDROID_LIBDL_STRTAB \ 182e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0" 183ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined(ANDROID_ARM_LINKER) && !defined(ANDROID_X86_LINKER) */ 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#error Unsupported architecture. Only ARM and x86 are presently supported. 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic Elf32_Sym libdl_symtab[] = { 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // total length of libdl_info.strtab, including trailing 0 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // This is actually the the STH_UNDEF entry. Technically, it's 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // supposed to have st_name == 0, but instead, it points to an index 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // in the strtab with a \0 to make iterating through the symtab easier. 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1, 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 0, // starting index of the name in libdl_info.strtab 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlopen, 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 7, 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlclose, 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 15, 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlsym, 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 21, 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlerror, 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 29, 217e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_value: (Elf32_Addr) &dladdr, 218e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_info: STB_GLOBAL << 4, 219e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_shndx: 1, 220e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer }, 221e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer#ifdef ANDROID_ARM_LINKER 222e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer { st_name: 36, 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dl_unwind_find_exidx, 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#elif defined(ANDROID_X86_LINKER) 228e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer { st_name: 36, 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dl_iterate_phdr, 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 231ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI st_shndx: 1, 232ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI }, 233ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI#elif defined(ANDROID_SH_LINKER) 234e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer { st_name: 36, 235ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI st_value: (Elf32_Addr) &dl_iterate_phdr, 236ad13c57298e57d33c130fb03a2c6494da573408cShin-ichiro KAWASAKI st_info: STB_GLOBAL << 4, 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Fake out a hash table with a single bucket. 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A search of the hash table will look through 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * libdl_symtab starting with index [1], then 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * use libdl_chains to find the next index to 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * look at. libdl_chains should be set up to 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * walk through every element in libdl_symtab, 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * and then end with 0 (sentinel value). 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * I.e., libdl_chains should look like 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * { 0, 2, 3, ... N, 0 } where N is the number 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * of actual symbols, or nelems(libdl_symtab)-1 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (since the first element of libdl_symtab is not 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a real symbol). 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (see _elf_lookup()) 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that adding any new symbols here requires 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * stubbing them out in libdl. 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic unsigned libdl_buckets[1] = { 1 }; 262e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischerstatic unsigned libdl_chains[7] = { 0, 2, 3, 4, 5, 6, 0 }; 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsoinfo libdl_info = { 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project name: "libdl.so", 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags: FLAG_LINKED, 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strtab: ANDROID_LIBDL_STRTAB, 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project symtab: libdl_symtab, 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nbucket: 1, 272e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer nchain: 7, 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bucket: libdl_buckets, 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project chain: libdl_chains, 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 277