loader.c revision f7df2e56
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/*#ifdef HAVE_DIX_CONFIG_H*/
54#include <dix-config.h>
55/*#endif*/
56
57#include <errno.h>
58#include <stdio.h>
59#include <stdlib.h>
60#include <sys/types.h>
61#include <unistd.h>
62#include <sys/stat.h>
63#include <fcntl.h>
64#include <string.h>
65#include <stdarg.h>
66
67#include "os.h"
68#include "loader.h"
69#include "loaderProcs.h"
70#include "xf86.h"
71#include "xf86Priv.h"
72
73#ifdef HAVE_DLFCN_H
74
75#include <dlfcn.h>
76#include <X11/Xos.h>
77
78#else
79#error i have no dynamic linker and i must scream
80#endif
81
82extern void *xorg_symbols[];
83
84void
85LoaderInit(void)
86{
87    xf86MsgVerb(X_INFO, 2, "Loader magic: %p\n", (void *) xorg_symbols);
88    xf86MsgVerb(X_INFO, 2, "Module ABI versions:\n");
89    xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_ANSIC,
90                   GET_ABI_MAJOR(LoaderVersionInfo.ansicVersion),
91                   GET_ABI_MINOR(LoaderVersionInfo.ansicVersion));
92    xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_VIDEODRV,
93                   GET_ABI_MAJOR(LoaderVersionInfo.videodrvVersion),
94                   GET_ABI_MINOR(LoaderVersionInfo.videodrvVersion));
95    xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_XINPUT,
96                   GET_ABI_MAJOR(LoaderVersionInfo.xinputVersion),
97                   GET_ABI_MINOR(LoaderVersionInfo.xinputVersion));
98    xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_EXTENSION,
99                   GET_ABI_MAJOR(LoaderVersionInfo.extensionVersion),
100                   GET_ABI_MINOR(LoaderVersionInfo.extensionVersion));
101
102}
103
104/* Public Interface to the loader. */
105
106void *
107LoaderOpen(const char *module, int *errmaj, int *errmin)
108{
109    void *ret;
110
111#if defined(DEBUG)
112    ErrorF("LoaderOpen(%s)\n", module);
113#endif
114
115    xf86Msg(X_INFO, "Loading %s\n", module);
116
117    if (!(ret = dlopen(module, RTLD_LAZY | RTLD_GLOBAL))) {
118        xf86Msg(X_ERROR, "Failed to load %s: %s\n", module, dlerror());
119        if (errmaj)
120            *errmaj = LDR_NOLOAD;
121        if (errmin)
122            *errmin = LDR_NOLOAD;
123        return NULL;
124    }
125
126    return ret;
127}
128
129void *
130LoaderSymbol(const char *name)
131{
132    static void *global_scope = NULL;
133    void *p;
134
135    p = dlsym(RTLD_DEFAULT, name);
136    if (p != NULL)
137        return p;
138
139    if (!global_scope)
140        global_scope = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
141
142    if (global_scope)
143        return dlsym(global_scope, name);
144
145    return NULL;
146}
147
148void *
149LoaderSymbolFromModule(void *handle, const char *name)
150{
151    return dlsym(handle, name);
152}
153
154void
155LoaderUnload(const char *name, void *handle)
156{
157    LogMessageVerbSigSafe(X_INFO, 1, "Unloading %s\n", name);
158    if (handle)
159        dlclose(handle);
160}
161
162unsigned long LoaderOptions = 0;
163
164void
165LoaderSetOptions(unsigned long opts)
166{
167    LoaderOptions |= opts;
168}
169
170Bool
171LoaderShouldIgnoreABI(void)
172{
173    return (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) != 0;
174}
175
176int
177LoaderGetABIVersion(const char *abiclass)
178{
179    struct {
180        const char *name;
181        int version;
182    } classes[] = {
183        {ABI_CLASS_ANSIC, LoaderVersionInfo.ansicVersion},
184        {ABI_CLASS_VIDEODRV, LoaderVersionInfo.videodrvVersion},
185        {ABI_CLASS_XINPUT, LoaderVersionInfo.xinputVersion},
186        {ABI_CLASS_EXTENSION, LoaderVersionInfo.extensionVersion},
187        {ABI_CLASS_FONT, LoaderVersionInfo.fontVersion},
188        {NULL, 0}
189    };
190    int i;
191
192    for (i = 0; classes[i].name; i++) {
193        if (!strcmp(classes[i].name, abiclass)) {
194            return classes[i].version;
195        }
196    }
197
198    return 0;
199}
200