1706f2543Smrg/* 2706f2543Smrg * Copyright 1995-1998 by Metro Link, Inc. 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Metro Link, Inc. not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Metro Link, Inc. makes no 11706f2543Smrg * representations about the suitability of this software for any purpose. 12706f2543Smrg * It is provided "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg */ 22706f2543Smrg/* 23706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 24706f2543Smrg * 25706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 26706f2543Smrg * copy of this software and associated documentation files (the "Software"), 27706f2543Smrg * to deal in the Software without restriction, including without limitation 28706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 29706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 30706f2543Smrg * Software is furnished to do so, subject to the following conditions: 31706f2543Smrg * 32706f2543Smrg * The above copyright notice and this permission notice shall be included in 33706f2543Smrg * all copies or substantial portions of the Software. 34706f2543Smrg * 35706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 38706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 39706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 40706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 41706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE. 42706f2543Smrg * 43706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s) 44706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote 45706f2543Smrg * the sale, use or other dealings in this Software without prior written 46706f2543Smrg * authorization from the copyright holder(s) and author(s). 47706f2543Smrg */ 48706f2543Smrg 49706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 50706f2543Smrg#include <xorg-config.h> 51706f2543Smrg#endif 52706f2543Smrg 53706f2543Smrg/*#ifdef HAVE_DIX_CONFIG_H*/ 54706f2543Smrg#include <dix-config.h> 55706f2543Smrg/*#endif*/ 56706f2543Smrg 57706f2543Smrg#include <errno.h> 58706f2543Smrg#include <stdio.h> 59706f2543Smrg#include <stdlib.h> 60706f2543Smrg#include <sys/types.h> 61706f2543Smrg#include <unistd.h> 62706f2543Smrg#include <sys/stat.h> 63706f2543Smrg#include <fcntl.h> 64706f2543Smrg#include <string.h> 65706f2543Smrg#include <stdarg.h> 66706f2543Smrg 67706f2543Smrg#include "os.h" 68706f2543Smrg#include "loader.h" 69706f2543Smrg#include "loaderProcs.h" 70706f2543Smrg#include "xf86.h" 71706f2543Smrg#include "xf86Priv.h" 72706f2543Smrg#include "compiler.h" 73706f2543Smrg 74706f2543Smrg#ifdef HAVE_DLFCN_H 75706f2543Smrg 76706f2543Smrg#include <dlfcn.h> 77706f2543Smrg#include <X11/Xos.h> 78706f2543Smrg 79706f2543Smrg#if defined(DL_LAZY) 80706f2543Smrg#define DLOPEN_LAZY DL_LAZY 81706f2543Smrg#elif defined(RTLD_LAZY) 82706f2543Smrg#define DLOPEN_LAZY RTLD_LAZY 83706f2543Smrg#elif defined(__FreeBSD__) 84706f2543Smrg#define DLOPEN_LAZY 1 85706f2543Smrg#else 86706f2543Smrg#define DLOPEN_LAZY 0 87706f2543Smrg#endif 88706f2543Smrg 89706f2543Smrg#if defined(LD_GLOBAL) 90706f2543Smrg#define DLOPEN_GLOBAL LD_GLOBAL 91706f2543Smrg#elif defined(RTLD_GLOBAL) 92706f2543Smrg#define DLOPEN_GLOBAL RTLD_GLOBAL 93706f2543Smrg#else 94706f2543Smrg#define DLOPEN_GLOBAL 0 95706f2543Smrg#endif 96706f2543Smrg 97706f2543Smrg#else 98706f2543Smrg#error i have no dynamic linker and i must scream 99706f2543Smrg#endif 100706f2543Smrg 101706f2543Smrgextern void *xorg_symbols[]; 102706f2543Smrg 103706f2543Smrgvoid 104706f2543SmrgLoaderInit(void) 105706f2543Smrg{ 106706f2543Smrg xf86MsgVerb(X_INFO, 2, "Loader magic: %p\n", (void *)xorg_symbols); 107706f2543Smrg xf86MsgVerb(X_INFO, 2, "Module ABI versions:\n"); 108706f2543Smrg xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_ANSIC, 109706f2543Smrg GET_ABI_MAJOR(LoaderVersionInfo.ansicVersion), 110706f2543Smrg GET_ABI_MINOR(LoaderVersionInfo.ansicVersion)); 111706f2543Smrg xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_VIDEODRV, 112706f2543Smrg GET_ABI_MAJOR(LoaderVersionInfo.videodrvVersion), 113706f2543Smrg GET_ABI_MINOR(LoaderVersionInfo.videodrvVersion)); 114706f2543Smrg xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_XINPUT, 115706f2543Smrg GET_ABI_MAJOR(LoaderVersionInfo.xinputVersion), 116706f2543Smrg GET_ABI_MINOR(LoaderVersionInfo.xinputVersion)); 117706f2543Smrg xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_EXTENSION, 118706f2543Smrg GET_ABI_MAJOR(LoaderVersionInfo.extensionVersion), 119706f2543Smrg GET_ABI_MINOR(LoaderVersionInfo.extensionVersion)); 120706f2543Smrg 121706f2543Smrg} 122706f2543Smrg 123706f2543Smrg/* Public Interface to the loader. */ 124706f2543Smrg 125706f2543Smrgvoid * 126706f2543SmrgLoaderOpen(const char *module, int *errmaj, int *errmin) 127706f2543Smrg{ 128706f2543Smrg void *ret; 129706f2543Smrg 130706f2543Smrg#if defined(DEBUG) 131706f2543Smrg ErrorF("LoaderOpen(%s)\n", module); 132706f2543Smrg#endif 133706f2543Smrg 134706f2543Smrg xf86Msg(X_INFO, "Loading %s\n", module); 135706f2543Smrg 136706f2543Smrg if (!(ret = dlopen(module, DLOPEN_LAZY | DLOPEN_GLOBAL))) { 137706f2543Smrg xf86Msg(X_ERROR, "Failed to load %s: %s\n", module, dlerror()); 138706f2543Smrg if (errmaj) 139706f2543Smrg *errmaj = LDR_NOLOAD; 140706f2543Smrg if (errmin) 141706f2543Smrg *errmin = LDR_NOLOAD; 142706f2543Smrg return NULL; 143706f2543Smrg } 144706f2543Smrg 145706f2543Smrg return ret; 146706f2543Smrg} 147706f2543Smrg 148706f2543Smrgvoid * 149706f2543SmrgLoaderSymbol(const char *name) 150706f2543Smrg{ 151706f2543Smrg static void *global_scope = NULL; 152706f2543Smrg void *p; 153706f2543Smrg 154706f2543Smrg p = dlsym(RTLD_DEFAULT, name); 155706f2543Smrg if (p != NULL) 156706f2543Smrg return p; 157706f2543Smrg 158706f2543Smrg if (!global_scope) 159706f2543Smrg global_scope = dlopen(NULL, DLOPEN_LAZY | DLOPEN_GLOBAL); 160706f2543Smrg 161706f2543Smrg if (global_scope) 162706f2543Smrg return dlsym(global_scope, name); 163706f2543Smrg 164706f2543Smrg return NULL; 165706f2543Smrg} 166706f2543Smrg 167706f2543Smrgvoid 168706f2543SmrgLoaderUnload(const char *name, void *handle) 169706f2543Smrg{ 170706f2543Smrg xf86Msg(X_INFO, "Unloading %s\n", name); 171706f2543Smrg if (handle) 172706f2543Smrg dlclose(handle); 173706f2543Smrg} 174706f2543Smrg 175706f2543Smrgunsigned long LoaderOptions = 0; 176706f2543Smrg 177706f2543Smrgvoid 178706f2543SmrgLoaderSetOptions(unsigned long opts) 179706f2543Smrg{ 180706f2543Smrg LoaderOptions |= opts; 181706f2543Smrg} 182706f2543Smrg 183706f2543SmrgBool 184706f2543SmrgLoaderShouldIgnoreABI(void) 185706f2543Smrg{ 186706f2543Smrg return (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL) != 0; 187706f2543Smrg} 188706f2543Smrg 189706f2543Smrgint 190706f2543SmrgLoaderGetABIVersion(const char *abiclass) 191706f2543Smrg{ 192706f2543Smrg struct { 193706f2543Smrg const char *name; 194706f2543Smrg int version; 195706f2543Smrg } classes[] = { 196706f2543Smrg { ABI_CLASS_ANSIC, LoaderVersionInfo.ansicVersion }, 197706f2543Smrg { ABI_CLASS_VIDEODRV, LoaderVersionInfo.videodrvVersion }, 198706f2543Smrg { ABI_CLASS_XINPUT, LoaderVersionInfo.xinputVersion }, 199706f2543Smrg { ABI_CLASS_EXTENSION, LoaderVersionInfo.extensionVersion }, 200706f2543Smrg { ABI_CLASS_FONT, LoaderVersionInfo.fontVersion }, 201706f2543Smrg { NULL, 0 } 202706f2543Smrg }; 203706f2543Smrg int i; 204706f2543Smrg 205706f2543Smrg for(i = 0; classes[i].name; i++) { 206706f2543Smrg if(!strcmp(classes[i].name, abiclass)) { 207706f2543Smrg return classes[i].version; 208706f2543Smrg } 209706f2543Smrg } 210706f2543Smrg 211706f2543Smrg return 0; 212706f2543Smrg} 213