diff options
author | Adam Jackson <ajax@redhat.com> | 2010-09-17 07:32:17 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2010-09-22 10:55:55 -0400 |
commit | 2a24a013bf3f554bb03c0f5af155d23dbb27b599 (patch) | |
tree | 3977d894eef4b905cf42a4fa795e9324bcc36bf7 /hw/xfree86/loader | |
parent | c768cdda92696b636c10bb2df64167d5274b4b99 (diff) |
loader: Merge dlloader directly into the loader
This lets us drop some double-tracking of loaded modules too. If your
OS is too lame to have libdl, fix that first.
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'hw/xfree86/loader')
-rw-r--r-- | hw/xfree86/loader/Makefile.am | 2 | ||||
-rw-r--r-- | hw/xfree86/loader/dlloader.c | 178 | ||||
-rw-r--r-- | hw/xfree86/loader/dlloader.h | 33 | ||||
-rw-r--r-- | hw/xfree86/loader/loader.c | 76 | ||||
-rw-r--r-- | hw/xfree86/loader/loader.h | 3 |
5 files changed, 72 insertions, 220 deletions
diff --git a/hw/xfree86/loader/Makefile.am b/hw/xfree86/loader/Makefile.am index d3c17d173..2bac89ac9 100644 --- a/hw/xfree86/loader/Makefile.am +++ b/hw/xfree86/loader/Makefile.am @@ -8,7 +8,6 @@ INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(top_srcdir)/miext/cw \ AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) EXTRA_DIST = \ - dlloader.h \ loader.h \ loaderProcs.h \ sdksyms.sh @@ -18,7 +17,6 @@ libloader_la_SOURCES = \ loaderProcs.h \ loadext.c \ loadmod.c \ - dlloader.c \ os.c \ sdksyms.c libloader_la_LIBADD = $(DLOPEN_LIBS) diff --git a/hw/xfree86/loader/dlloader.c b/hw/xfree86/loader/dlloader.c deleted file mode 100644 index 18dcb76c6..000000000 --- a/hw/xfree86/loader/dlloader.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 1997 The XFree86 Project, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of the - * XFree86 Project, Inc. not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The Xfree86 Project, Inc. makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE XFREE86 PROJECT, INC. BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Once upon a time, X had multiple loader backends, three of which were - * essentially libdl reimplementations. This was nonsense so we chucked - * it, but we still retain the factorization between loader API and - * platform implementation. This file is the libdl implementation, and - * currently the only backend. If you find yourself porting to a platform - * without working libdl - hpux, win32, some forsaken a.out host, etc. - - * make a new backend rather than hacking up this file. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <dlfcn.h> - -#include <X11/Xos.h> -#include "os.h" - -#include "loader.h" -#include "dlloader.h" - -#if defined(DL_LAZY) -#define DLOPEN_LAZY DL_LAZY -#elif defined(RTLD_LAZY) -#define DLOPEN_LAZY RTLD_LAZY -#elif defined(__FreeBSD__) -#define DLOPEN_LAZY 1 -#else -#define DLOPEN_LAZY 0 -#endif - -#if defined(LD_GLOBAL) -#define DLOPEN_GLOBAL LD_GLOBAL -#elif defined(RTLD_GLOBAL) -#define DLOPEN_GLOBAL RTLD_GLOBAL -#else -#define DLOPEN_GLOBAL 0 -#endif - -#if defined(CSRG_BASED) && !defined(__ELF__) -#define DLSYM_PREFIX "_" -#else -#define DLSYM_PREFIX "" -#endif - -/* Hooray, yet another open coded linked list! FIXME */ -typedef struct DLModuleList { - void *module; - struct DLModuleList *next; -} DLModuleList; - -static DLModuleList *dlModuleList = NULL; - -static void * -DLFindSymbolLocal(pointer module, const char *name) -{ - void *p; - char *n; - - static const char symPrefix[] = DLSYM_PREFIX; - - if (sizeof(symPrefix) > 1) { - n = malloc(strlen(symPrefix) + strlen(name) + 1); - sprintf(n, "%s%s", symPrefix, name); - name = n; - } - - p = dlsym(module, name); - - if (sizeof(symPrefix) > 1) - free(n); - - return p; -} - -static void *global_scope = NULL; - -void * -DLFindSymbol(const char *name) -{ - DLModuleList *l; - void *p; - - p = dlsym(RTLD_DEFAULT, name); - if (p != NULL) - return p; - - for (l = dlModuleList; l != NULL; l = l->next) { - p = DLFindSymbolLocal(l->module, name); - if (p) - return p; - } - - if (!global_scope) - global_scope = dlopen(NULL, DLOPEN_LAZY | DLOPEN_GLOBAL); - - if (global_scope) - return DLFindSymbolLocal(global_scope, name); - - return NULL; -} - -void * -DLLoadModule(loaderPtr modrec, int flags) -{ - void * dlfile; - DLModuleList *l; - int dlopen_flags; - - if (flags & LD_FLAG_GLOBAL) - dlopen_flags = DLOPEN_LAZY | DLOPEN_GLOBAL; - else - dlopen_flags = DLOPEN_LAZY; - dlfile = dlopen(modrec->name, dlopen_flags); - if (dlfile == NULL) { - ErrorF("dlopen: %s\n", dlerror()); - return NULL; - } - - l = malloc(sizeof(DLModuleList)); - l->module = dlfile; - l->next = dlModuleList; - dlModuleList = l; - - return (void *)dlfile; -} - -void -DLUnloadModule(void *modptr) -{ - DLModuleList *l, *p; - - /* remove it from dlModuleList. */ - if (dlModuleList->module == modptr) { - l = dlModuleList; - dlModuleList = l->next; - free(l); - } else { - p = dlModuleList; - for (l = dlModuleList->next; l != NULL; l = l->next) { - if (l->module == modptr) { - p->next = l->next; - free(l); - break; - } - p = l; - } - } - dlclose(modptr); -} diff --git a/hw/xfree86/loader/dlloader.h b/hw/xfree86/loader/dlloader.h deleted file mode 100644 index 8ae610f02..000000000 --- a/hw/xfree86/loader/dlloader.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 1997 Metro Link, Inc. - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Metro Link, Inc. not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Metro Link, Inc. makes no - * representations about the suitability of this software for any purpose. - * It is provided "as is" without express or implied warranty. - * - * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#ifndef _DLLOADER_H -#define _DLLOADER_H - -extern void *DLLoadModule(loaderPtr, int flags); -extern void DLUnloadModule(void *); -extern void *DLFindSymbol(const char *name); - -#endif diff --git a/hw/xfree86/loader/loader.c b/hw/xfree86/loader/loader.c index e043bb233..d51ea928f 100644 --- a/hw/xfree86/loader/loader.c +++ b/hw/xfree86/loader/loader.c @@ -75,6 +75,33 @@ #include "xf86Priv.h" #include "compiler.h" +#ifdef HAVE_DLFCN_H + +#include <dlfcn.h> +#include <X11/Xos.h> + +#if defined(DL_LAZY) +#define DLOPEN_LAZY DL_LAZY +#elif defined(RTLD_LAZY) +#define DLOPEN_LAZY RTLD_LAZY +#elif defined(__FreeBSD__) +#define DLOPEN_LAZY 1 +#else +#define DLOPEN_LAZY 0 +#endif + +#if defined(LD_GLOBAL) +#define DLOPEN_GLOBAL LD_GLOBAL +#elif defined(RTLD_GLOBAL) +#define DLOPEN_GLOBAL RTLD_GLOBAL +#else +#define DLOPEN_GLOBAL 0 +#endif + +#else +#error i have no dynamic linker and i must scream +#endif + extern void *xorg_symbols[]; #define MAX_HANDLE 256 @@ -154,6 +181,27 @@ LoaderInit(void) #endif } +static void * +do_dlopen(loaderPtr modrec, int flags) +{ + void *dlfile; + int dlopen_flags; + + if (flags & LD_FLAG_GLOBAL) + dlopen_flags = DLOPEN_LAZY | DLOPEN_GLOBAL; + else + dlopen_flags = DLOPEN_LAZY; + + dlfile = dlopen(modrec->name, dlopen_flags); + + if (dlfile == NULL) { + ErrorF("dlopen: %s\n", dlerror()); + return NULL; + } + + return dlfile; +} + /* Public Interface to the loader. */ int @@ -217,7 +265,7 @@ LoaderOpen(const char *module, const char *cname, int handle, tmp->handle = new_handle; tmp->module = moduleseq++; - if ((tmp->private = DLLoadModule(tmp, flags)) == NULL) { + if ((tmp->private = do_dlopen(tmp, flags)) == NULL) { xf86Msg(X_ERROR, "Failed to load %s\n", module); _LoaderListPop(new_handle); refCount[new_handle] = 0; @@ -245,9 +293,29 @@ LoaderHandleOpen(int handle) } void * -LoaderSymbol(const char *sym) +LoaderSymbol(const char *name) { - return (DLFindSymbol(sym)); + static void *global_scope = NULL; + loaderPtr l; + void *p; + + p = dlsym(RTLD_DEFAULT, name); + if (p != NULL) + return p; + + for (l = listHead; l != NULL; l = l->next) { + p = dlsym(l->private, name); + if (p) + return p; + } + + if (!global_scope) + global_scope = dlopen(NULL, DLOPEN_LAZY | DLOPEN_GLOBAL); + + if (global_scope) + return dlsym(global_scope, name); + + return NULL; } int @@ -270,7 +338,7 @@ LoaderUnload(int handle) while ((tmp = _LoaderListPop(handle)) != NULL) { xf86Msg(X_INFO, "Unloading %s\n", tmp->name); - DLUnloadModule(tmp->private); + dlclose(tmp->private); free(tmp->name); free(tmp->cname); free(tmp); diff --git a/hw/xfree86/loader/loader.h b/hw/xfree86/loader/loader.h index 6121e02c6..9695c6c59 100644 --- a/hw/xfree86/loader/loader.h +++ b/hw/xfree86/loader/loader.h @@ -91,7 +91,4 @@ extern unsigned long LoaderOptions; int LoaderOpen(const char *, const char *, int, int *, int *, int *, int); int LoaderHandleOpen(int); -/* Loader backends. */ -#include "dlloader.h" - #endif /* _LOADER_H */ |