xref: /haiku/src/system/libroot/posix/dlfcn.c (revision e7e3b6c14af93058fc5aab68ffa695bbcdd77053)
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