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(void *address, Dl_info *info) 76 { 77 static char sImageName[MAXPATHLEN]; 78 static char sSymbolName[NAME_MAX]; 79 80 image_id image; 81 int32 nameLength = sizeof(sSymbolName); 82 void* location; 83 image_info imageInfo; 84 sStatus = __gRuntimeLoader->get_symbol_at_address(address, &image, 85 sSymbolName, &nameLength, NULL, &location); 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 strlcpy(sImageName, imageInfo.name, MAXPATHLEN); 94 info->dli_fname = sImageName; 95 info->dli_fbase = imageInfo.text; 96 info->dli_sname = sSymbolName; 97 info->dli_saddr = location; 98 99 return 1; 100 } 101 102 103 // __libc_dl*** wrappers 104 // We use a mixed glibc / bsd libc, and glibc wants these 105 void *__libc_dlopen(const char *name); 106 void *__libc_dlsym(void *handle, const char *name); 107 void __libc_dlclose(void *handle); 108 109 void * 110 __libc_dlopen(const char *name) 111 { 112 return dlopen(name, 0); 113 } 114 115 116 void * 117 __libc_dlsym(void *handle, const char *name) 118 { 119 return dlsym(handle, name); 120 } 121 122 123 void 124 __libc_dlclose(void *handle) 125 { 126 dlclose(handle); 127 } 128