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>
This commit is contained in:
parent
c768cdda92
commit
2a24a013bf
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user