1/* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2003-2010, Axel D��rfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2002, Manuel J. Petit. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11#include <libroot_private.h> 12 13#include <dlfcn.h> 14#include <string.h> 15 16#include <runtime_loader.h> 17#include <user_runtime.h> 18 19 20static status_t sStatus; 21 // Note, this is not thread-safe 22 23 24void * 25dlopen(char const *name, int mode) 26{ 27 void* handle; 28 void* caller = __builtin_return_address(0); 29 image_id imageID = __gRuntimeLoader->load_library(name, mode, caller, 30 &handle); 31 32 sStatus = imageID >= 0 ? B_OK : imageID; 33 34 return imageID >= 0 ? handle : NULL; 35} 36 37 38void * 39dlsym(void *handle, char const *name) 40{ 41 void* location; 42 status_t status; 43 void* caller = NULL; 44 45 if (handle == RTLD_NEXT) { 46 caller = __builtin_return_address(0); 47 } 48 49 status = __gRuntimeLoader->get_library_symbol(handle, caller, name, 50 &location); 51 sStatus = status; 52 53 if (status < B_OK) 54 return NULL; 55 56 return location; 57} 58 59 60int 61dlclose(void *handle) 62{ 63 return sStatus = __gRuntimeLoader->unload_library(handle); 64} 65 66 67char * 68dlerror(void) 69{ 70 if (sStatus < B_OK) 71 return strerror(sStatus); 72 73 return NULL; 74} 75 76 77int 78dladdr(const void *address, Dl_info *info) 79{ 80 image_id image; 81 char* imagePath; 82 char* symbolName; 83 void* location; 84 image_info imageInfo; 85 86 sStatus = __gRuntimeLoader->get_nearest_symbol_at_address(address, &image, 87 &imagePath, NULL, &symbolName, NULL, &location, NULL); 88 if (sStatus != B_OK) 89 return 0; 90 91 sStatus = get_image_info(image, &imageInfo); 92 if (sStatus != B_OK) 93 return 0; 94 95 info->dli_fname = imagePath; 96 info->dli_fbase = imageInfo.text; 97 info->dli_sname = symbolName; 98 info->dli_saddr = location; 99 100 return 1; 101} 102 103 104// __libc_dl*** wrappers 105// We use a mixed glibc / bsd libc, and glibc wants these 106void *__libc_dlopen(const char *name); 107void *__libc_dlsym(void *handle, const char *name); 108void __libc_dlclose(void *handle); 109 110void * 111__libc_dlopen(const char *name) 112{ 113 return dlopen(name, 0); 114} 115 116 117void * 118__libc_dlsym(void *handle, const char *name) 119{ 120 return dlsym(handle, name); 121} 122 123 124void 125__libc_dlclose(void *handle) 126{ 127 dlclose(handle); 128} 129