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 image_id imageID = __gRuntimeLoader->load_library(name, mode, &handle); 29 30 sStatus = imageID >= 0 ? B_OK : imageID; 31 32 return imageID >= 0 ? handle : NULL; 33 } 34 35 36 void * 37 dlsym(void *handle, char const *name) 38 { 39 void* location; 40 status_t status; 41 void* caller = NULL; 42 43 if (handle == RTLD_NEXT) { 44 caller = __builtin_return_address(0); 45 } 46 47 status = __gRuntimeLoader->get_library_symbol(handle, caller, name, 48 &location); 49 sStatus = status; 50 51 if (status < B_OK) 52 return NULL; 53 54 return location; 55 } 56 57 58 int 59 dlclose(void *handle) 60 { 61 return sStatus = __gRuntimeLoader->unload_library(handle); 62 } 63 64 65 char * 66 dlerror(void) 67 { 68 if (sStatus < B_OK) 69 return strerror(sStatus); 70 71 return NULL; 72 } 73 74 75 int 76 dladdr(const void *address, Dl_info *info) 77 { 78 image_id image; 79 char* imagePath; 80 char* symbolName; 81 void* location; 82 image_info imageInfo; 83 84 sStatus = __gRuntimeLoader->get_nearest_symbol_at_address(address, &image, 85 &imagePath, NULL, &symbolName, NULL, &location, NULL); 86 if (sStatus != B_OK) 87 return 0; 88 89 sStatus = get_image_info(image, &imageInfo); 90 if (sStatus != B_OK) 91 return 0; 92 93 info->dli_fname = imagePath; 94 info->dli_fbase = imageInfo.text; 95 info->dli_sname = symbolName; 96 info->dli_saddr = location; 97 98 return 1; 99 } 100 101 102 // __libc_dl*** wrappers 103 // We use a mixed glibc / bsd libc, and glibc wants these 104 void *__libc_dlopen(const char *name); 105 void *__libc_dlsym(void *handle, const char *name); 106 void __libc_dlclose(void *handle); 107 108 void * 109 __libc_dlopen(const char *name) 110 { 111 return dlopen(name, 0); 112 } 113 114 115 void * 116 __libc_dlsym(void *handle, const char *name) 117 { 118 return dlsym(handle, name); 119 } 120 121 122 void 123 __libc_dlclose(void *handle) 124 { 125 dlclose(handle); 126 } 127