summaryrefslogtreecommitdiffstats
path: root/linker/dlfcn.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:13 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:13 -0800
commit1767f908af327fa388b1c66883760ad851267013 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /linker/dlfcn.c
parenta799b53f10e5a6fd51fef4436cfb7ec99836a516 (diff)
downloadbionic-1767f908af327fa388b1c66883760ad851267013.zip
bionic-1767f908af327fa388b1c66883760ad851267013.tar.gz
bionic-1767f908af327fa388b1c66883760ad851267013.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'linker/dlfcn.c')
-rw-r--r--linker/dlfcn.c212
1 files changed, 0 insertions, 212 deletions
diff --git a/linker/dlfcn.c b/linker/dlfcn.c
deleted file mode 100644
index cd73d11..0000000
--- a/linker/dlfcn.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <dlfcn.h>
-#include <pthread.h>
-#include "linker.h"
-
-/* This file hijacks the symbols stubbed out in libdl.so. */
-
-#define DL_SUCCESS 0
-#define DL_ERR_CANNOT_FIND_LIBRARY 1
-#define DL_ERR_INVALID_LIBRARY_HANDLE 2
-#define DL_ERR_BAD_SYMBOL_NAME 3
-#define DL_ERR_SYMBOL_NOT_FOUND 4
-#define DL_ERR_SYMBOL_NOT_GLOBAL 5
-
-static const char *dl_errors[] = {
- [DL_SUCCESS] = NULL,
- [DL_ERR_CANNOT_FIND_LIBRARY] = "Cannot find library",
- [DL_ERR_INVALID_LIBRARY_HANDLE] = "Invalid library handle",
- [DL_ERR_BAD_SYMBOL_NAME] = "Invalid symbol name",
- [DL_ERR_SYMBOL_NOT_FOUND] = "Symbol not found",
- [DL_ERR_SYMBOL_NOT_GLOBAL] = "Symbol is not global",
-};
-
-static int dl_last_err = DL_SUCCESS;
-
-#define likely(expr) __builtin_expect (expr, 1)
-#define unlikely(expr) __builtin_expect (expr, 0)
-
-static pthread_mutex_t dl_lock = PTHREAD_MUTEX_INITIALIZER;
-
-void *dlopen(const char *filename, int flag)
-{
- soinfo *ret;
-
- pthread_mutex_lock(&dl_lock);
- ret = find_library(filename);
- if (unlikely(ret == NULL)) {
- dl_last_err = DL_ERR_CANNOT_FIND_LIBRARY;
- } else {
- ret->refcount++;
- }
- pthread_mutex_unlock(&dl_lock);
- return ret;
-}
-
-const char *dlerror(void)
-{
- const char *err = dl_errors[dl_last_err];
- dl_last_err = DL_SUCCESS;
- return err;
-}
-
-void *dlsym(void *handle, const char *symbol)
-{
- unsigned base;
- Elf32_Sym *sym;
- unsigned bind;
-
- pthread_mutex_lock(&dl_lock);
-
- if(unlikely(handle == 0)) {
- dl_last_err = DL_ERR_INVALID_LIBRARY_HANDLE;
- goto err;
- }
- if(unlikely(symbol == 0)) {
- dl_last_err = DL_ERR_BAD_SYMBOL_NAME;
- goto err;
- }
-
- if(handle == RTLD_DEFAULT) {
- sym = lookup(symbol, &base);
- } else if(handle == RTLD_NEXT) {
- sym = lookup(symbol, &base);
- } else {
- sym = lookup_in_library((soinfo*) handle, symbol);
- base = ((soinfo*) handle)->base;
- }
-
- if(likely(sym != 0)) {
- bind = ELF32_ST_BIND(sym->st_info);
-
- if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) {
- unsigned ret = sym->st_value + base;
- pthread_mutex_unlock(&dl_lock);
- return (void*)ret;
- }
-
- dl_last_err = DL_ERR_SYMBOL_NOT_GLOBAL;
- }
- else dl_last_err = DL_ERR_SYMBOL_NOT_FOUND;
-
-err:
- pthread_mutex_unlock(&dl_lock);
- return 0;
-}
-
-int dlclose(void *handle)
-{
- pthread_mutex_lock(&dl_lock);
- (void)unload_library((soinfo*)handle);
- pthread_mutex_unlock(&dl_lock);
- return 0;
-}
-
-#if defined(ANDROID_ARM_LINKER)
-// 0000000 00011111 111112 22222222 233333333334444444444
-// 0123456 78901234 567890 12345678 901234567890123456789
-#define ANDROID_LIBDL_STRTAB \
- "dlopen\0dlclose\0dlsym\0dlerror\0dl_unwind_find_exidx\0"
-
-#elif defined(ANDROID_X86_LINKER)
-// 0000000 00011111 111112 22222222 2333333333344444
-// 0123456 78901234 567890 12345678 9012345678901234
-#define ANDROID_LIBDL_STRTAB \
- "dlopen\0dlclose\0dlsym\0dlerror\0dl_iterate_phdr\0"
-
-#else /* !defined(ANDROID_ARM_LINKER) && !defined(ANDROID_X86_LINKER) */
-#error Unsupported architecture. Only ARM and x86 are presently supported.
-#endif
-
-
-static Elf32_Sym libdl_symtab[] = {
- // total length of libdl_info.strtab, including trailing 0
- // This is actually the the STH_UNDEF entry. Technically, it's
- // supposed to have st_name == 0, but instead, it points to an index
- // in the strtab with a \0 to make iterating through the symtab easier.
- { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1,
- },
- { st_name: 0, // starting index of the name in libdl_info.strtab
- st_value: (Elf32_Addr) &dlopen,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
- { st_name: 7,
- st_value: (Elf32_Addr) &dlclose,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
- { st_name: 15,
- st_value: (Elf32_Addr) &dlsym,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
- { st_name: 21,
- st_value: (Elf32_Addr) &dlerror,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
-#ifdef ANDROID_ARM_LINKER
- { st_name: 29,
- st_value: (Elf32_Addr) &dl_unwind_find_exidx,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
-#elif defined(ANDROID_X86_LINKER)
- { st_name: 29,
- st_value: (Elf32_Addr) &dl_iterate_phdr,
- st_info: STB_GLOBAL << 4,
- st_shndx: 1,
- },
-#endif
-};
-
-/* Fake out a hash table with a single bucket.
- * A search of the hash table will look through
- * libdl_symtab starting with index [1], then
- * use libdl_chains to find the next index to
- * look at. libdl_chains should be set up to
- * walk through every element in libdl_symtab,
- * and then end with 0 (sentinel value).
- *
- * I.e., libdl_chains should look like
- * { 0, 2, 3, ... N, 0 } where N is the number
- * of actual symbols, or nelems(libdl_symtab)-1
- * (since the first element of libdl_symtab is not
- * a real symbol).
- *
- * (see _elf_lookup())
- *
- * Note that adding any new symbols here requires
- * stubbing them out in libdl.
- */
-static unsigned libdl_buckets[1] = { 1 };
-static unsigned libdl_chains[6] = { 0, 2, 3, 4, 5, 0 };
-
-soinfo libdl_info = {
- name: "libdl.so",
- flags: FLAG_LINKED,
-
- strtab: ANDROID_LIBDL_STRTAB,
- symtab: libdl_symtab,
-
- nbucket: 1,
- nchain: 6,
- bucket: libdl_buckets,
- chain: libdl_chains,
-};
-