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