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 45e19d702b8e330cef87e0983733c427b5f7842144Pavel Chupinpthread_mutex_t dl_lock = PTHREAD_RECURSIVE_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 { 6316084168111cd7d2ac8a6b92e6fa6df5696928a5David 'Digit' Turner soinfo_call_constructors(ret); 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ret->refcount++; 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return ret; 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectconst char *dlerror(void) 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 722e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin const char *tmp = dl_err_str; 732e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin dl_err_str = NULL; 742e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin return (const char *)tmp; 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid *dlsym(void *handle, const char *symbol) 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 799ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev soinfo *found; 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Elf32_Sym *sym; 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project unsigned bind; 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock(&dl_lock); 842e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 85bedfe38b8ba512dd6236c00e8b4a9b01c2bd1281Elliott Hughes if(unlikely(handle == 0)) { 862e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE); 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto err; 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(unlikely(symbol == 0)) { 902e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_BAD_SYMBOL_NAME); 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto err; 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 932e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(handle == RTLD_DEFAULT) { 951698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = lookup(symbol, &found, NULL); 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if(handle == RTLD_NEXT) { 971698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer void *ret_addr = __builtin_return_address(0); 981698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer soinfo *si = find_containing_library(ret_addr); 991698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer 1001698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = NULL; 1011698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer if(si && si->next) { 1021698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer sym = lookup(symbol, &found, si->next); 1031698d9ebfc7e27271852a1fdf305a2ac37b3ebe4Matt Fischer } 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1059ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev found = (soinfo*)handle; 10616084168111cd7d2ac8a6b92e6fa6df5696928a5David 'Digit' Turner sym = soinfo_lookup(found, symbol); 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(likely(sym != 0)) { 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bind = ELF32_ST_BIND(sym->st_info); 1112e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { 1139ea64da6c511e8f9f4edae4c10c20879957631abIliyan Malchev unsigned ret = sym->st_value + found->base; 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (void*)ret; 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1182e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL); 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1202e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin else 1212e85579c34047c305caf15fb0ebe02bf3d001d0eDima Zavin set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecterr: 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 128bda5da074eab4bdf374e1f4a19d480c62c72f5ffMathias Agopianint dladdr(const void *addr, Dl_info *info) 129e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer{ 130e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer int ret = 0; 131e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 132e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer pthread_mutex_lock(&dl_lock); 133e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 134e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer /* Determine if this address can be found in any library currently mapped */ 135e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer soinfo *si = find_containing_library(addr); 136e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 137e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer if(si) { 138e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer memset(info, 0, sizeof(Dl_info)); 139e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 140e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_fname = si->name; 141e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_fbase = (void*)si->base; 142e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 143e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer /* Determine if any symbol in the library contains the specified address */ 14416084168111cd7d2ac8a6b92e6fa6df5696928a5David 'Digit' Turner Elf32_Sym *sym = soinfo_find_symbol(si, addr); 145e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 146e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer if(sym != NULL) { 147e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_sname = si->strtab + sym->st_name; 148e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer info->dli_saddr = (void*)(si->base + sym->st_value); 149e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer } 150e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 151e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer ret = 1; 152e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer } 153e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 154e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer pthread_mutex_unlock(&dl_lock); 155e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 156e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer return ret; 157e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer} 158e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer 159bedfe38b8ba512dd6236c00e8b4a9b01c2bd1281Elliott Hughesint dlclose(void* handle) { 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock(&dl_lock); 161bedfe38b8ba512dd6236c00e8b4a9b01c2bd1281Elliott Hughes int result = soinfo_unload((soinfo*)handle); 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock(&dl_lock); 163bedfe38b8ba512dd6236c00e8b4a9b01c2bd1281Elliott Hughes return result; 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 172d7daacb46372132ae3f0121647074936c304b572Raghu Gandham#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_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" 177177a77067b6d3326dbcf88fd93d0664e48e27f9fDavid 'Digit' Turner#else 178d7daacb46372132ae3f0121647074936c304b572Raghu Gandham#error Unsupported architecture. Only ARM, MIPS, and x86 are presently supported. 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic Elf32_Sym libdl_symtab[] = { 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // total length of libdl_info.strtab, including trailing 0 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // This is actually the the STH_UNDEF entry. Technically, it's 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // supposed to have st_name == 0, but instead, it points to an index 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // in the strtab with a \0 to make iterating through the symtab easier. 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1, 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 0, // starting index of the name in libdl_info.strtab 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlopen, 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 7, 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlclose, 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 15, 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlsym, 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 21, 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dlerror, 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { st_name: 29, 210e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_value: (Elf32_Addr) &dladdr, 211e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_info: STB_GLOBAL << 4, 212e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer st_shndx: 1, 213e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer }, 214e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer#ifdef ANDROID_ARM_LINKER 215e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer { st_name: 36, 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dl_unwind_find_exidx, 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 220d7daacb46372132ae3f0121647074936c304b572Raghu Gandham#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER) 221e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer { st_name: 36, 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_value: (Elf32_Addr) &dl_iterate_phdr, 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_info: STB_GLOBAL << 4, 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project st_shndx: 1, 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project }, 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Fake out a hash table with a single bucket. 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A search of the hash table will look through 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * libdl_symtab starting with index [1], then 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * use libdl_chains to find the next index to 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * look at. libdl_chains should be set up to 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * walk through every element in libdl_symtab, 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * and then end with 0 (sentinel value). 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * I.e., libdl_chains should look like 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * { 0, 2, 3, ... N, 0 } where N is the number 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * of actual symbols, or nelems(libdl_symtab)-1 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (since the first element of libdl_symtab is not 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a real symbol). 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (see _elf_lookup()) 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that adding any new symbols here requires 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * stubbing them out in libdl. 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic unsigned libdl_buckets[1] = { 1 }; 249e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischerstatic unsigned libdl_chains[7] = { 0, 2, 3, 4, 5, 6, 0 }; 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsoinfo libdl_info = { 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project name: "libdl.so", 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project flags: FLAG_LINKED, 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strtab: ANDROID_LIBDL_STRTAB, 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project symtab: libdl_symtab, 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nbucket: 1, 259e2a8b1fd19fb3a8ead2ba28ddba27be19fa978b5Matt Fischer nchain: 7, 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bucket: libdl_buckets, 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project chain: libdl_chains, 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 263