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 20 static status_t sStatus; 21 // Note, this is not thread-safe 22 23 24 void * 25 dlopen(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 38 void * 39 dlsym(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 60 int 61 dlclose(void *handle) 62 { 63 return sStatus = __gRuntimeLoader->unload_library(handle); 64 } 65 66 67 char * 68 dlerror(void) 69 { 70 if (sStatus < B_OK) 71 return strerror(sStatus); 72 73 return NULL; 74 } 75 76 77 int 78 dladdr(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 106 void *__libc_dlopen(const char *name); 107 void *__libc_dlsym(void *handle, const char *name); 108 void __libc_dlclose(void *handle); 109 110 void * 111 __libc_dlopen(const char *name) 112 { 113 return dlopen(name, 0); 114 } 115 116 117 void * 118 __libc_dlsym(void *handle, const char *name) 119 { 120 return dlsym(handle, name); 121 } 122 123 124 void 125 __libc_dlclose(void *handle) 126 { 127 dlclose(handle); 128 } 129