Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright 1995-1998 by Metro Link, Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Metro Link, Inc. not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Metro Link, Inc. makes no | |
11 | * representations about the suitability of this software for any purpose. | |
12 | * It is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | /* | |
23 | * Copyright (c) 1997-2003 by The XFree86 Project, Inc. | |
24 | * | |
25 | * Permission is hereby granted, free of charge, to any person obtaining a | |
26 | * copy of this software and associated documentation files (the "Software"), | |
27 | * to deal in the Software without restriction, including without limitation | |
28 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
29 | * and/or sell copies of the Software, and to permit persons to whom the | |
30 | * Software is furnished to do so, subject to the following conditions: | |
31 | * | |
32 | * The above copyright notice and this permission notice shall be included in | |
33 | * all copies or substantial portions of the Software. | |
34 | * | |
35 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
36 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
37 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
38 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
39 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
40 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
41 | * OTHER DEALINGS IN THE SOFTWARE. | |
42 | * | |
43 | * Except as contained in this notice, the name of the copyright holder(s) | |
44 | * and author(s) shall not be used in advertising or otherwise to promote | |
45 | * the sale, use or other dealings in this Software without prior written | |
46 | * authorization from the copyright holder(s) and author(s). | |
47 | */ | |
48 | ||
49 | #ifdef HAVE_XORG_CONFIG_H | |
50 | #include <xorg-config.h> | |
51 | #endif | |
52 | ||
53 | #include <errno.h> | |
54 | #include <stdio.h> | |
55 | #include <stdlib.h> | |
56 | #include <sys/types.h> | |
57 | #include <unistd.h> | |
58 | #include <sys/stat.h> | |
59 | #include <fcntl.h> | |
60 | #include <string.h> | |
61 | #include <stdarg.h> | |
62 | ||
63 | #include "os.h" | |
64 | #include "loader.h" | |
65 | #include "loaderProcs.h" | |
66 | #include "xf86.h" | |
67 | #include "xf86Priv.h" | |
68 | #include "compiler.h" | |
69 | ||
70 | #ifdef HAVE_DLFCN_H | |
71 | ||
72 | #include <dlfcn.h> | |
73 | #include <X11/Xos.h> | |
74 | ||
75 | #if defined(DL_LAZY) | |
76 | #define DLOPEN_LAZY DL_LAZY | |
77 | #elif defined(RTLD_LAZY) | |
78 | #define DLOPEN_LAZY RTLD_LAZY | |
79 | #elif defined(__FreeBSD__) | |
80 | #define DLOPEN_LAZY 1 | |
81 | #else | |
82 | #define DLOPEN_LAZY 0 | |
83 | #endif | |
84 | ||
85 | #if defined(LD_GLOBAL) | |
86 | #define DLOPEN_GLOBAL LD_GLOBAL | |
87 | #elif defined(RTLD_GLOBAL) | |
88 | #define DLOPEN_GLOBAL RTLD_GLOBAL | |
89 | #else | |
90 | #define DLOPEN_GLOBAL 0 | |
91 | #endif | |
92 | ||
93 | #else | |
94 | #error i have no dynamic linker and i must scream | |
95 | #endif | |
96 | ||
97 | extern void *xorg_symbols[]; | |
98 | ||
99 | void | |
100 | LoaderInit(void) | |
101 | { | |
102 | xf86MsgVerb(X_INFO, 2, "Loader magic: %p\n", (void *) xorg_symbols); | |
103 | xf86MsgVerb(X_INFO, 2, "Module ABI versions:\n"); | |
104 | xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_ANSIC, | |
105 | GET_ABI_MAJOR(LoaderVersionInfo.ansicVersion), | |
106 | GET_ABI_MINOR(LoaderVersionInfo.ansicVersion)); | |
107 | xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_VIDEODRV, | |
108 | GET_ABI_MAJOR(LoaderVersionInfo.videodrvVersion), | |
109 | GET_ABI_MINOR(LoaderVersionInfo.videodrvVersion)); | |
110 | xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_XINPUT, | |
111 | GET_ABI_MAJOR(LoaderVersionInfo.xinputVersion), | |
112 | GET_ABI_MINOR(LoaderVersionInfo.xinputVersion)); | |
113 | xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_EXTENSION, | |
114 | GET_ABI_MAJOR(LoaderVersionInfo.extensionVersion), | |
115 | GET_ABI_MINOR(LoaderVersionInfo.extensionVersion)); | |
116 | ||
117 | } | |
118 | ||
119 | /* Public Interface to the loader. */ | |
120 | ||
121 | void * | |
122 | LoaderOpen(const char *module, int *errmaj, int *errmin) | |
123 | { | |
124 | void *ret; | |
125 | ||
126 | #if defined(DEBUG) | |
127 | ErrorF("LoaderOpen(%s)\n", module); | |
128 | #endif | |
129 | ||
130 | xf86Msg(X_INFO, "Loading %s\n", module); | |
131 | ||
132 | if (!(ret = dlopen(module, DLOPEN_LAZY | DLOPEN_GLOBAL))) { | |
133 | xf86Msg(X_ERROR, "Failed to load %s: %s\n", module, dlerror()); | |
134 | if (errmaj) | |
135 | *errmaj = LDR_NOLOAD; | |
136 | if (errmin) | |
137 | *errmin = LDR_NOLOAD; | |
138 | return NULL; | |
139 | } | |
140 | ||
141 | return ret; | |
142 | } | |
143 | ||
144 | void * | |
145 | LoaderSymbol(const char *name) | |
146 | { | |
147 | static void *global_scope = NULL; | |
148 | void *p; | |
149 | ||
150 | p = dlsym(RTLD_DEFAULT, name); | |
151 | if (p != NULL) | |
152 | return p; | |
153 | ||
154 | if (!global_scope) | |
155 | global_scope = dlopen(NULL, DLOPEN_LAZY | DLOPEN_GLOBAL); | |
156 | ||
157 | if (global_scope) | |
158 | return dlsym(global_scope, name); | |
159 | ||
160 | return NULL; | |
161 | } | |
162 | ||
163 | void * | |
164 | LoaderSymbolFromModule(void *handle, const char *name) | |
165 | { | |
166 | return dlsym(handle, name); | |
167 | } | |
168 | ||
169 | void | |
170 | LoaderUnload(const char *name, void *handle) | |
171 | { | |
172 | LogMessageVerbSigSafe(X_INFO, 1, "Unloading %s\n", name); | |
173 | if (handle) | |
174 | dlclose(handle); | |
175 | } | |
176 | ||
177 | unsigned long LoaderOptions = 0; | |
178 | ||
179 | void | |
180 | LoaderSetOptions(unsigned long opts) | |
181 | { | |
182 | LoaderOptions |= opts; | |
183 | } | |
184 | ||
185 | Bool | |
186 | LoaderShouldIgnoreABI(void) | |
187 | { | |
188 | return (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) != 0; | |
189 | } | |
190 | ||
191 | int | |
192 | LoaderGetABIVersion(const char *abiclass) | |
193 | { | |
194 | struct { | |
195 | const char *name; | |
196 | int version; | |
197 | } classes[] = { | |
198 | {ABI_CLASS_ANSIC, LoaderVersionInfo.ansicVersion}, | |
199 | {ABI_CLASS_VIDEODRV, LoaderVersionInfo.videodrvVersion}, | |
200 | {ABI_CLASS_XINPUT, LoaderVersionInfo.xinputVersion}, | |
201 | {ABI_CLASS_EXTENSION, LoaderVersionInfo.extensionVersion}, | |
202 | {ABI_CLASS_FONT, LoaderVersionInfo.fontVersion}, | |
203 | {NULL, 0} | |
204 | }; | |
205 | int i; | |
206 | ||
207 | for (i = 0; classes[i].name; i++) { | |
208 | if (!strcmp(classes[i].name, abiclass)) { | |
209 | return classes[i].version; | |
210 | } | |
211 | } | |
212 | ||
213 | return 0; | |
214 | } |