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