dlfcn.cpp revision 22d629211d72adaf46f3fc48f59540f8e5798b1e
13b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes/* 23b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * Copyright (C) 2007 The Android Open Source Project 33b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * 43b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 53b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * you may not use this file except in compliance with the License. 63b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * You may obtain a copy of the License at 73b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * 83b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 93b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * 103b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * Unless required by applicable law or agreed to in writing, software 113b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 123b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * See the License for the specific language governing permissions and 143b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes * limitations under the License. 153b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes */ 163b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 173b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <dlfcn.h> 183b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <pthread.h> 193b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <stdio.h> 203b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 213b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include <private/ScopedPthreadMutexLocker.h> 223b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 233b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include "linker.h" 243b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#include "linker_format.h" 253b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 263b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes/* This file hijacks the symbols stubbed out in libdl.so. */ 273b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 283b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic char dl_err_buf[1024]; 293b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic const char* dl_err_str; 303b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 313b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#define likely(expr) __builtin_expect (expr, 1) 323b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#define unlikely(expr) __builtin_expect (expr, 0) 333b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 3422d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughesstatic pthread_mutex_t gDlMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; 353b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 363b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic void set_dlerror(const char* msg, const char* detail) { 373b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (detail != NULL) { 383b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes format_buffer(dl_err_buf, sizeof(dl_err_buf), "%s: %s", msg, detail); 393b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } else { 403b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes format_buffer(dl_err_buf, sizeof(dl_err_buf), "%s", msg); 413b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 423b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes dl_err_str = (const char*) &dl_err_buf[0]; 433b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 443b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 453b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesvoid *dlopen(const char* filename, int flag) { 4622d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes ScopedPthreadMutexLocker locker(&gDlMutex); 473b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes soinfo* result = find_library(filename); 483b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (result == NULL) { 493b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes set_dlerror("dlopen failed", linker_get_error()); 503b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return NULL; 513b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 523b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes soinfo_call_constructors(result); 533b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes result->refcount++; 543b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return result; 553b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 563b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 573b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesconst char* dlerror() { 583b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes const char* old_value = dl_err_str; 593b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes dl_err_str = NULL; 603b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return (const char*) old_value; 613b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 623b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 633b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesvoid* dlsym(void* handle, const char* symbol) { 6422d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes ScopedPthreadMutexLocker locker(&gDlMutex); 653b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 663b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (unlikely(handle == 0)) { 673b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes set_dlerror("dlsym library handle is null", NULL); 683b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return NULL; 693b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 703b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (unlikely(symbol == 0)) { 713b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes set_dlerror("dlsym symbol name is null", NULL); 723b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return NULL; 733b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 743b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 753b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes soinfo* found = NULL; 763b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes Elf32_Sym* sym = NULL; 773b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (handle == RTLD_DEFAULT) { 783b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes sym = lookup(symbol, &found, NULL); 793b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } else if (handle == RTLD_NEXT) { 803b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes void* ret_addr = __builtin_return_address(0); 813b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes soinfo* si = find_containing_library(ret_addr); 823b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 833b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes sym = NULL; 843b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (si && si->next) { 853b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes sym = lookup(symbol, &found, si->next); 863b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 873b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } else { 883b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes found = (soinfo*) handle; 893b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes sym = soinfo_lookup(found, symbol); 903b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 913b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 923b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (likely(sym != 0)) { 933b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes unsigned bind = ELF32_ST_BIND(sym->st_info); 943b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 953b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { 963b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes unsigned ret = sym->st_value + found->load_bias; 973b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return (void*) ret; 983b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 993b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1003b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes set_dlerror("symbol found but not global", symbol); 1013b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return NULL; 1023b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } else { 1033b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes set_dlerror("undefined symbol", symbol); 1043b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return NULL; 1053b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 1063b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 1073b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1083b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesint dladdr(const void* addr, Dl_info* info) { 10922d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes ScopedPthreadMutexLocker locker(&gDlMutex); 1103b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1113b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // Determine if this address can be found in any library currently mapped. 1123b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes soinfo* si = find_containing_library(addr); 1133b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (si == NULL) { 1143b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return 0; 1153b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 1163b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1173b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes memset(info, 0, sizeof(Dl_info)); 1183b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1193b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes info->dli_fname = si->name; 1203b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // Address at which the shared object is loaded. 1213b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes info->dli_fbase = (void*) si->base; 1223b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1233b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // Determine if any symbol in the library contains the specified address. 1243b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes Elf32_Sym *sym = soinfo_find_symbol(si, addr); 1253b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes if (sym != NULL) { 1263b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes info->dli_sname = si->strtab + sym->st_name; 1273b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes info->dli_saddr = (void*)(si->load_bias + sym->st_value); 1283b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes } 1293b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1303b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return 1; 1313b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 1323b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1333b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesint dlclose(void* handle) { 13422d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes ScopedPthreadMutexLocker locker(&gDlMutex); 1353b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes return soinfo_unload((soinfo*) handle); 1363b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes} 1373b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1383b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#if defined(ANDROID_ARM_LINKER) 1393b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes// 0000000 00011111 111112 22222222 2333333 333344444444445555555 1403b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes// 0123456 78901234 567890 12345678 9012345 678901234567890123456 1413b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#define ANDROID_LIBDL_STRTAB \ 1423b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_unwind_find_exidx\0" 1433b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1443b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER) 1453b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes// 0000000 00011111 111112 22222222 2333333 3333444444444455 1463b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes// 0123456 78901234 567890 12345678 9012345 6789012345678901 1473b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#define ANDROID_LIBDL_STRTAB \ 1483b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0dl_iterate_phdr\0" 1493b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#else 1503b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#error Unsupported architecture. Only ARM, MIPS, and x86 are presently supported. 1513b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#endif 1523b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1533b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes// name_offset: starting index of the name in libdl_info.strtab 1543b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#define ELF32_SYM_INITIALIZER(name_offset, value, shndx) \ 1553b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes { name_offset, \ 1563b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes reinterpret_cast<Elf32_Addr>(reinterpret_cast<void*>(value)), \ 1573b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes /* st_size */ 0, \ 1583b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes (shndx == 0) ? 0 : (STB_GLOBAL << 4), \ 1593b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes /* st_other */ 0, \ 1603b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes shndx } 1613b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 1623b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic Elf32_Sym libdl_symtab[] = { 1633b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // Total length of libdl_info.strtab, including trailing 0. 1643b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // This is actually the STH_UNDEF entry. Technically, it's 1653b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // supposed to have st_name == 0, but instead, it points to an index 1663b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes // in the strtab with a \0 to make iterating through the symtab easier. 1673b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(sizeof(ANDROID_LIBDL_STRTAB) - 1, NULL, 0), 1683b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER( 0, &dlopen, 1), 1693b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER( 7, &dlclose, 1), 1703b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(15, &dlsym, 1), 1713b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(21, &dlerror, 1), 1723b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(29, &dladdr, 1), 1733b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#if defined(ANDROID_ARM_LINKER) 1743b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(36, &dl_unwind_find_exidx, 1), 1753b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#elif defined(ANDROID_X86_LINKER) || defined(ANDROID_MIPS_LINKER) 1763b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ELF32_SYM_INITIALIZER(36, &dl_iterate_phdr, 1), 1773b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#endif 1783b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}; 1793b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 18022d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// Fake out a hash table with a single bucket. 18122d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// A search of the hash table will look through 18222d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// libdl_symtab starting with index [1], then 18322d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// use libdl_chains to find the next index to 18422d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// look at. libdl_chains should be set up to 18522d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// walk through every element in libdl_symtab, 18622d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// and then end with 0 (sentinel value). 18722d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// 18822d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// That is, libdl_chains should look like 18922d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// { 0, 2, 3, ... N, 0 } where N is the number 19022d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// of actual symbols, or nelems(libdl_symtab)-1 19122d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// (since the first element of libdl_symtab is not 19222d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// a real symbol). 19322d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// 19422d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// (see soinfo_elf_lookup()) 19522d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// 19622d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// Note that adding any new symbols here requires 19722d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// stubbing them out in libdl. 1983b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic unsigned libdl_buckets[1] = { 1 }; 1993b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughesstatic unsigned libdl_chains[7] = { 0, 2, 3, 4, 5, 6, 0 }; 2003b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 20122d629211d72adaf46f3fc48f59540f8e5798b1eElliott Hughes// This is used by the dynamic linker. Every process gets these symbols for free. 2023b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughessoinfo libdl_info = { 2033b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes name: "libdl.so", 2043b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2053b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes phdr: 0, phnum: 0, 2063b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes entry: 0, base: 0, size: 0, 2073b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes unused: 0, dynamic: 0, unused2: 0, unused3: 0, 2083b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes next: 0, 2093b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2103b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes flags: FLAG_LINKED, 2113b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2123b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes strtab: ANDROID_LIBDL_STRTAB, 2133b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes symtab: libdl_symtab, 2143b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2153b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes nbucket: 1, 2163b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes nchain: 7, 2173b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes bucket: libdl_buckets, 2183b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes chain: libdl_chains, 2193b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2203b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes plt_got: 0, plt_rel: 0, plt_rel_count: 0, rel: 0, rel_count: 0, 2213b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes preinit_array: 0, preinit_array_count: 0, init_array: 0, init_array_count: 0, 2223b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes fini_array: 0, fini_array_count: 0, init_func: 0, fini_func: 0, 2233b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2243b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#if defined(ANDROID_ARM_LINKER) 2253b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes ARM_exidx: 0, ARM_exidx_count: 0, 2263b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#elif defined(ANDROID_MIPS_LINKER) 2273b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes mips_symtabno: 0, mips_local_gotno: 0, mips_gotsym: 0, 2283b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes#endif 2293b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes 2303b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes refcount: 0, 2313b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes { l_addr: 0, l_name: 0, l_ld: 0, l_next: 0, l_prev: 0, }, 2323b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes constructors_called: 0, load_bias: 0, has_text_relocations: 0, 2333b297c40794b23d50cb5240f9b03f6ef25fd98dbElliott Hughes}; 234