--- Mike Mestnik <[EMAIL PROTECTED]> wrote:
>
>
> --- Felix K�hling <[EMAIL PROTECTED]> wrote:
>
> > It looks like adding indirect acceleration added a new function to
> the
> > loader that is used by libglx.so. So the new libglx won't work with
> > older Xservers and I will have to build a new Xserver binary for
> > snapshots/extras or add the Xserver to the snapshots. Yay!
> >
> I came up with two workable solutions for this problem. The first one
> can be implemented in multiple ways.
> Make this function available as/in a module. I understand that this
> is
> part of the loader, but it should not be needed to boot-strap itself.
> The second implementation is to put this function in libglx.so, where
> it
> is used.
>
I have a source file that can build a ".o", so now all I have to do is
link it with something. Build instructions are currently: replace
loadmod.c in an xorg tree with this one and "make loadmod.o". Here is a
dependancy list for thoes interested.
LoadSubModuleLocal
Static marked with '*':
* doLoadModule
* InitPatterns
* LoaderGetCanonicalName
* InitPathList
* FindModule
* CheckVersion
* FreePathList
* FreePatterns
* PatternPtr
* stdPatterns
* PatternRec
* defaultPathList
* FreeStringList
* InitSubdirs
* FreeSubdirs
* stdSubdirs
Unresolved:
U AddSibling
U ErrorF
U FatalError
U LoaderGetOS
U LoaderOpen
U LoaderOptions
U LoaderSymbol
U LoaderVersionInfo
U NewModuleDesc
U UnloadModule
U Xalloc
U Xfree
U Xstrdup
U __xstat
U regcomp
U regerror
U regexec
U snprintf
U sprintf
U strcat
U strchr
U strcmp
U strcpy
U strlen
U strncpy
U strrchr
U strstr
U xf86ErrorF
U xf86ErrorFVerb
U xf86Msg
U xf86MsgVerb
> My other solution is to include an xorg-additions.c into the snapshots
> that can be built and then linked against the installed xorg binary.
> This would need a configure script that detects what symbols are
> missing
> . Should not be too hard.
>
I missed Jeopardy last night...
What is an "absolute file".
Dose some one know the answer, specificaly how can I introduce(link in)
more object data?
> I would gladly put forth the effort to bring any solution to life, I
> just would like to know what will/will-not be accepted.
>
> > The problem with that is that the default ModulePath, RgbPath etc. I
> > build with will only work with either one of Xorg 6.9 or 7.0, but
> not
> > both. Hmm ... testing the latest and greatest stuff is getting
> > messier.
> >
> > Regards,
> > Felix
> >
> > Am Donnerstag, den 23.03.2006, 16:34 +0100 schrieb Michal Suchanek:
> > > Hello
> > >
> > > I tried installing the dri snapshots common-2006032[12]-linux.i386
> > > with r200-2006032[12]-linux.i386, and I get undefined symbol in
> > > libglx.so.
> > >
> > > After reinstalling xorg-server 1.0.2 the problem goes away but it
> is
> > > because the library is overwritten with the older version.
> > >
> > > Using the X server and modules from
> > > http://dri.freedesktop.org/wiki/Download does not help either.
> > >
> > > Attaching the X server output. I do not see the error in the
> > /var/log/X* files.
> > >
> > > Thanks
> > >
> > > Michal
> > --
> > | Felix K�hling <[EMAIL PROTECTED]>
> http://fxk.de.vu
> > |
> > | PGP Fingerprint: 6A3C 9566 5B30 DDED 73C3 B152 151C 5CC1 D888
> E595
> > |
> >
> >
> >
> > -------------------------------------------------------
> > This SF.Net email is sponsored by xPML, a groundbreaking scripting
> > language
> > that extends applications into web and mobile media. Attend the live
> > webcast
> > and join the prime developer group breaking into this new coding
> > territory!
> > http://sel.as-us.falkag.net/sel?cmd=lnk&kid0944&bid$1720&dat1642
> > --
> > _______________________________________________
> > Dri-devel mailing list
> > [email protected]
> > https://lists.sourceforge.net/lists/listinfo/dri-devel
> >
>
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by xPML, a groundbreaking scripting
> language
> that extends applications into web and mobile media. Attend the live
> webcast
> and join the prime developer group breaking into this new coding
> territory!
>
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
> --
> _______________________________________________
> Dri-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/dri-devel
>
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com /* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.73 2003/11/03 05:11:51 tsi Exp $ */
/*
*
* Copyright 1995-1998 by 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.
*/
/*
* Copyright (c) 1997-2002 by The XFree86 Project, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "os.h"
/* For stat() and related stuff */
#define NO_OSLIB_PROTOTYPES
#include "xf86_OSlib.h"
#define LOADERDECLARATIONS
#include "loaderProcs.h"
#include "misc.h"
#include "xf86.h"
#include "xf86Priv.h"
#ifdef XINPUT
#include "xf86Xinput.h"
#endif
#include "loader.h"
#include "xf86Optrec.h"
#include <sys/types.h>
#include <regex.h>
#include <dirent.h>
#include <limits.h>
typedef struct _pattern {
const char *pattern;
regex_t rex;
} PatternRec, *PatternPtr;
static char *FindModule(const char *, const char *, const char **,
PatternPtr);
static Bool CheckVersion(const char *, XF86ModuleVersionInfo *,
const XF86ModReqInfo *);
static char *LoaderGetCanonicalName(const char *, PatternPtr);
static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
const char **, pointer,
const XF86ModReqInfo *, int *, int *,
int flags);
/* Standard set of module subdirectories to search, in order of preference */
static const char *stdSubdirs[] = {
"",
"fonts/",
"input/",
"drivers/",
"multimedia/",
"extensions/",
"internal/",
NULL
};
/*
* Standard set of module name patterns to check, in order of preference
* These are regular expressions (suitable for use with POSIX regex(3)).
*/
static PatternRec stdPatterns[] = {
{"^lib(.*)\\.so$",},
{"^lib(.*)\\.a$",},
{"(.*)_drv\\.so$",},
{"(.*)_drv\\.o$",},
{"(.*)\\.so$",},
{"(.*)\\.a$",},
{"(.*)\\.o$",},
{NULL,}
};
static const char **
InitSubdirs(const char **subdirlist)
{
int i;
const char **tmp_subdirlist = NULL;
char **subdirs = NULL;
const char **s, **stmp = NULL;
const char *osname;
const char *slash;
int oslen = 0, len;
Bool indefault;
if (subdirlist == NULL) {
subdirlist = tmp_subdirlist = xalloc(2 * sizeof(char *));
if (subdirlist == NULL)
return NULL;
subdirlist[0] = DEFAULT_LIST;
subdirlist[1] = NULL;
}
LoaderGetOS(&osname, NULL, NULL, NULL);
oslen = strlen(osname);
{
/* Count number of entries and check for invalid paths */
for (i = 0, s = subdirlist; *s; i++, s++) {
if (*s == DEFAULT_LIST) {
i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
} else {
/*
* Path validity check. Don't allow absolute paths, or
* paths containing "..". To catch absolute paths on
* platforms that use driver letters, don't allow the ':'
* character to appear at all.
*/
if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
strstr(*s, "..")) {
xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
if (tmp_subdirlist)
xfree(tmp_subdirlist);
return NULL;
}
}
}
subdirs = xalloc((i * 2 + 1) * sizeof(char *));
if (!subdirs) {
if (tmp_subdirlist)
xfree(tmp_subdirlist);
return NULL;
}
i = 0;
s = subdirlist;
indefault = FALSE;
while (*s) {
if (*s == DEFAULT_LIST) {
/* Divert to the default list */
indefault = TRUE;
stmp = ++s;
s = stdSubdirs;
}
len = strlen(*s);
if (**s && (*s)[len - 1] != '/') {
slash = "/";
len++;
} else
slash = "";
len += oslen + 2;
if (!(subdirs[i] = xalloc(len))) {
while (--i >= 0)
xfree(subdirs[i]);
xfree(subdirs);
if (tmp_subdirlist)
xfree(tmp_subdirlist);
return NULL;
}
/* tack on the OS name */
sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
i++;
/* path as given */
subdirs[i] = xstrdup(*s);
i++;
s++;
if (indefault && !s) {
/* revert back to the main list */
indefault = FALSE;
s = stmp;
}
}
subdirs[i] = NULL;
}
if (tmp_subdirlist)
xfree(tmp_subdirlist);
return (const char **)subdirs;
}
static void
FreeSubdirs(const char **subdirs)
{
const char **s;
if (subdirs) {
for (s = subdirs; *s; s++)
xfree(*s);
xfree(subdirs);
}
}
static void
FreeStringList(char **paths)
{
char **p;
if (!paths)
return;
for (p = paths; *p; p++)
xfree(*p);
xfree(paths);
}
static char **defaultPathList = NULL;
static PatternPtr
InitPatterns(const char **patternlist)
{
char errmsg[80];
int i, e;
PatternPtr patterns = NULL;
PatternPtr p = NULL;
static int firstTime = 1;
const char **s;
if (firstTime) {
/* precompile stdPatterns */
firstTime = 0;
for (p = stdPatterns; p->pattern; p++)
if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
regerror(e, &p->rex, errmsg, sizeof(errmsg));
FatalError("InitPatterns: regcomp error for `%s': %s\n",
p->pattern, errmsg);
}
}
if (patternlist) {
for (i = 0, s = patternlist; *s; i++, s++)
if (*s == DEFAULT_LIST)
i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
patterns = xalloc((i + 1) * sizeof(PatternRec));
if (!patterns) {
return NULL;
}
for (i = 0, s = patternlist; *s; i++, s++)
if (*s != DEFAULT_LIST) {
p = patterns + i;
p->pattern = *s;
if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
regerror(e, &p->rex, errmsg, sizeof(errmsg));
ErrorF("InitPatterns: regcomp error for `%s': %s\n",
p->pattern, errmsg);
i--;
}
} else {
for (p = stdPatterns; p->pattern; p++, i++)
patterns[i] = *p;
if (p != stdPatterns)
i--;
}
patterns[i].pattern = NULL;
} else
patterns = stdPatterns;
return patterns;
}
static void
FreePatterns(PatternPtr patterns)
{
if (patterns && patterns != stdPatterns)
xfree(patterns);
}
/*
* Convert a comma-separated path into a NULL-terminated array of path
* elements, rejecting any that are not full absolute paths, and appending
* a '/' when it isn't already present.
*/
static char **
InitPathList(const char *path)
{
char *fullpath = NULL;
char *elem = NULL;
char **list = NULL, **save = NULL;
int len;
int addslash;
int n = 0;
if (!path)
return defaultPathList;
fullpath = xstrdup(path);
if (!fullpath)
return NULL;
elem = strtok(fullpath, ",");
while (elem) {
/* Only allow fully specified paths */
#ifndef __UNIXOS2__
if (*elem == '/')
#else
if (*elem == '/' || (strlen(elem) > 2 && isalpha(elem[0]) &&
elem[1] == ':' && elem[2] == '/'))
#endif
{
len = strlen(elem);
addslash = (elem[len - 1] != '/');
if (addslash)
len++;
save = list;
list = xrealloc(list, (n + 2) * sizeof(char *));
if (!list) {
if (save) {
save[n] = NULL;
FreeStringList(save);
}
xfree(fullpath);
return NULL;
}
list[n] = xalloc(len + 1);
if (!list[n]) {
FreeStringList(list);
xfree(fullpath);
return NULL;
}
strcpy(list[n], elem);
if (addslash) {
list[n][len - 1] = '/';
list[n][len] = '\0';
}
n++;
}
elem = strtok(NULL, ",");
}
if (list)
list[n] = NULL;
return list;
}
static void
FreePathList(char **pathlist)
{
if (pathlist && pathlist != defaultPathList)
FreeStringList(pathlist);
}
ModuleDescPtr
LoadSubModuleLocal(ModuleDescPtr parent, const char *module,
const char **subdirlist, const char **patternlist,
pointer options, const XF86ModReqInfo * modreq,
int *errmaj, int *errmin)
{
ModuleDescPtr submod;
xf86MsgVerb(X_INFO, 3, "Loading local sub module \"%s\"\n", module);
/* Absolute module paths are not allowed here */
#ifndef __UNIXOS2__
if (module[0] == '/')
#else
if (isalpha(module[0]) && module[1] == ':' && module[2] == '/')
#endif
{
xf86Msg(X_ERROR,
"LoadSubModule: Absolute module path not permitted: \"%s\"\n",
module);
if (errmaj)
*errmaj = LDR_BADUSAGE;
if (errmin)
*errmin = 0;
return NULL;
}
submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
modreq, errmaj, errmin, 0);
if (submod) {
parent->child = AddSibling(parent->child, submod);
submod->parent = parent;
}
return submod;
}
static ModuleDescPtr
doLoadModule(const char *module, const char *path, const char **subdirlist,
const char **patternlist, pointer options,
const XF86ModReqInfo * modreq,
int *errmaj, int *errmin, int flags)
{
XF86ModuleData *initdata = NULL;
char **pathlist = NULL;
char *found = NULL;
char *name = NULL;
char **path_elem = NULL;
char *p = NULL;
ModuleDescPtr ret = NULL;
int wasLoaded = 0;
PatternPtr patterns = NULL;
int noncanonical = 0;
char *m = NULL;
/*xf86Msg(X_INFO,"OS2DIAG: LoadModule: %s\n",module); */
xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
patterns = InitPatterns(patternlist);
name = LoaderGetCanonicalName(module, patterns);
noncanonical = (name && strcmp(module, name) != 0);
if (noncanonical) {
xf86ErrorFVerb(3, " (%s)\n", name);
xf86MsgVerb(X_WARNING, 1,
"LoadModule: given non-canonical module name \"%s\"\n",
module);
m = name;
} else {
xf86ErrorFVerb(3, "\n");
m = (char *)module;
}
if (!name) {
if (errmaj)
*errmaj = LDR_BADUSAGE;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
ret = NewModuleDesc(name);
if (!ret) {
if (errmaj)
*errmaj = LDR_NOMEM;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
pathlist = InitPathList(path);
if (!pathlist) {
/* This could be a malloc failure too */
if (errmaj)
*errmaj = LDR_BADUSAGE;
if (errmin)
*errmin = 1;
goto LoadModule_fail;
}
/*
* if the module name is not a full pathname, we need to
* check the elements in the path
*/
#ifndef __UNIXOS2__
if (module[0] == '/')
found = xstrdup(module);
#else
/* accept a drive name here */
if (isalpha(module[0]) && module[1] == ':' && module[2] == '/')
found = xstrdup(module);
#endif
path_elem = pathlist;
while (!found && *path_elem != NULL) {
found = FindModule(m, *path_elem, subdirlist, patterns);
path_elem++;
/*
* When the module name isn't the canonical name, search for the
* former if no match was found for the latter.
*/
if (!*path_elem && m == name) {
path_elem = pathlist;
m = (char *)module;
}
}
/*
* did we find the module?
*/
if (!found) {
xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module);
if (errmaj)
*errmaj = LDR_NOENT;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
ret->handle = LoaderOpen(found, name, 0,
errmaj, errmin, &wasLoaded, flags);
if (ret->handle < 0)
goto LoadModule_fail;
ret->filename = xstrdup(found);
/* drop any explicit suffix from the module name */
p = strchr(name, '.');
if (p)
*p = '\0';
/*
* now check if the special data object <modulename>ModuleData is
* present.
*/
p = xalloc(strlen(name) + strlen("ModuleData") + 1);
if (!p) {
if (errmaj)
*errmaj = LDR_NOMEM;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
strcpy(p, name);
strcat(p, "ModuleData");
initdata = LoaderSymbol(p);
if (initdata) {
ModuleSetupProc setup;
ModuleTearDownProc teardown;
XF86ModuleVersionInfo *vers;
vers = initdata->vers;
setup = initdata->setup;
teardown = initdata->teardown;
if (!wasLoaded) {
if (vers) {
if (!CheckVersion(module, vers, modreq)) {
if (errmaj)
*errmaj = LDR_MISMATCH;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
} else {
xf86Msg(X_ERROR,
"LoadModule: Module %s does not supply"
" version information\n", module);
if (errmaj)
*errmaj = LDR_INVALID;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
}
if (setup)
ret->SetupProc = setup;
if (teardown)
ret->TearDownProc = teardown;
ret->path = path;
ret->VersionInfo = vers;
} else {
/* No initdata is OK for external modules */
if (options == EXTERN_MODULE)
goto LoadModule_exit;
/* no initdata, fail the load */
xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s "
"data object.\n", module, p);
if (errmaj)
*errmaj = LDR_INVALID;
if (errmin)
*errmin = 0;
goto LoadModule_fail;
}
if (ret->SetupProc) {
ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);
if (!ret->TearDownData) {
goto LoadModule_fail;
}
} else if (options) {
xf86Msg(X_WARNING, "Module Options present, but no SetupProc "
"available for %s\n", module);
}
goto LoadModule_exit;
LoadModule_fail:
UnloadModule(ret);
ret = NULL;
LoadModule_exit:
FreePathList(pathlist);
FreePatterns(patterns);
TestFree(found);
TestFree(name);
TestFree(p);
/*
* If you need to do something to keep the
* instruction cache in sync with the main
* memory before jumping to that code, you may
* do it here.
*/
#ifdef __alpha__
istream_mem_barrier();
#endif
return ret;
}
static char *
FindModule(const char *module, const char *dir, const char **subdirlist,
PatternPtr patterns)
{
char buf[PATH_MAX + 1], tmpBuf[PATH_MAX + 1];
char *dirpath = NULL;
char *name = NULL;
struct stat stat_buf;
int dirlen;
const char **subdirs = NULL;
const char **s;
#ifdef DLOPEN_HACK
const char suffix[3][3] = { "so", "a", "o" };
#else
const char suffix[3][3] = { "a", "o", "so" };
#endif
#ifndef __EMX__
dirpath = (char *)dir;
#else
dirpath = xalloc(strlen(dir) + 10);
strcpy(dirpath, (char *)__XOS2RedirRoot(dir));
#endif
if (strlen(dirpath) > PATH_MAX)
return NULL;
subdirs = InitSubdirs(subdirlist);
if (!subdirs)
return NULL;
for (s = subdirs; *s; s++) {
if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX)
continue;
strcpy(buf, dirpath);
strcat(buf, *s);
/*xf86Msg(X_INFO,"OS2DIAG: FindModule: buf=%s\n",buf); */
if ((stat(buf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
int i;
if (buf[dirlen - 1] != '/') {
buf[dirlen++] = '/';
}
for (i = 0; i < 3 && !name; i++) {
snprintf(tmpBuf, PATH_MAX, "%slib%s.%s", buf, module,
suffix[i]);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break;
}
snprintf(tmpBuf, PATH_MAX, "%s%s_drv.%s", buf, module,
suffix[i]);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break;
}
snprintf(tmpBuf, PATH_MAX, "%s%s.%s", buf, module,
suffix[i]);
if (stat(tmpBuf, &stat_buf) == 0) {
name = tmpBuf;
break;
}
}
if (name)
break;
}
}
FreeSubdirs(subdirs);
if (dirpath != dir)
xfree(dirpath);
if (name) {
return xstrdup(name);
}
return NULL;
}
static Bool
CheckVersion(const char *module, XF86ModuleVersionInfo * data,
const XF86ModReqInfo * req)
{
int vercode[4];
char verstr[4];
long ver = data->xf86version;
MessageType errtype;
xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n",
data->modname ? data->modname : "UNKNOWN!",
data->vendor ? data->vendor : "UNKNOWN!");
/* Check for the different scheme used in XFree86 4.0.x releases:
* ((((((((major << 7) | minor) << 7) | subminor) << 5) | beta) << 5) | alpha)
* Since it wasn't used in 4.1.0 or later, limit to versions in the 4.0.x
* range, which limits the overlap with the new version scheme to conflicts
* with 6.71.8.764 through 6.72.39.934.
*/
if ((ver > (4 << 24)) && (ver < ( (4 << 24) + (1 << 17)))) {
/* 4.0.x and earlier */
verstr[1] = verstr[3] = 0;
verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
ver >>= 5;
verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
ver >>= 5;
vercode[2] = ver & 0x7f;
ver >>= 7;
vercode[1] = ver & 0x7f;
ver >>= 7;
vercode[0] = ver;
xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
if (vercode[2] != 0)
xf86ErrorF(".%d", vercode[2]);
xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
data->majorversion, data->minorversion, data->patchlevel);
} else {
vercode[0] = ver / 10000000;
vercode[1] = (ver / 100000) % 100;
vercode[2] = (ver / 1000) % 100;
vercode[3] = ver % 1000;
xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1],
vercode[2]);
if (vercode[3] != 0)
xf86ErrorF(".%d", vercode[3]);
xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion,
data->minorversion, data->patchlevel);
}
if (data->moduleclass)
xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
ver = -1;
if (data->abiclass) {
int abimaj, abimin;
int vermaj, vermin;
if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
ver = LoaderVersionInfo.ansicVersion;
else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
ver = LoaderVersionInfo.videodrvVersion;
else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
ver = LoaderVersionInfo.xinputVersion;
else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
ver = LoaderVersionInfo.extensionVersion;
else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
ver = LoaderVersionInfo.fontVersion;
abimaj = GET_ABI_MAJOR(data->abiversion);
abimin = GET_ABI_MINOR(data->abiversion);
xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
data->abiclass, abimaj, abimin);
if (ver != -1) {
vermaj = GET_ABI_MAJOR(ver);
vermin = GET_ABI_MINOR(ver);
if (abimaj != vermaj) {
if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
errtype = X_WARNING;
else
errtype = X_ERROR;
xf86MsgVerb(errtype, 0,
"module ABI major version (%d) doesn't"
" match the server's version (%d)\n",
abimaj, vermaj);
if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
return FALSE;
} else if (abimin > vermin) {
if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
errtype = X_WARNING;
else
errtype = X_ERROR;
xf86MsgVerb(errtype, 0,
"module ABI minor version (%d) is "
"newer than the server's version "
"(%d)\n", abimin, vermin);
if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
return FALSE;
}
}
}
/* Check against requirements that the caller has specified */
if (req) {
if (req->majorversion != MAJOR_UNSPEC) {
if (data->majorversion != req->majorversion) {
xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
"doesn't match required major version (%d)\n",
data->majorversion, req->majorversion);
return FALSE;
} else if (req->minorversion != MINOR_UNSPEC) {
if (data->minorversion < req->minorversion) {
xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
"is less than the required minor version (%d)\n",
data->minorversion, req->minorversion);
return FALSE;
} else if (data->minorversion == req->minorversion &&
req->patchlevel != PATCH_UNSPEC) {
if (data->patchlevel < req->patchlevel) {
xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
"is less than the required patch level (%d)\n",
data->patchlevel, req->patchlevel);
return FALSE;
}
}
}
}
if (req->moduleclass) {
if (!data->moduleclass ||
strcmp(req->moduleclass, data->moduleclass)) {
xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
"the required class (%s)\n",
data->moduleclass ? data->moduleclass : "<NONE>",
req->moduleclass);
return FALSE;
}
} else if (req->abiclass != ABI_CLASS_NONE) {
if (!data->abiclass || strcmp(req->abiclass, data->abiclass)) {
xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
"required ABI class (%s)\n",
data->abiclass ? data->abiclass : "<NONE>",
req->abiclass);
return FALSE;
}
}
if ((req->abiclass != ABI_CLASS_NONE) &&
req->abiversion != ABI_VERS_UNSPEC) {
int reqmaj, reqmin, maj, min;
reqmaj = GET_ABI_MAJOR(req->abiversion);
reqmin = GET_ABI_MINOR(req->abiversion);
maj = GET_ABI_MAJOR(data->abiversion);
min = GET_ABI_MINOR(data->abiversion);
if (maj != reqmaj) {
xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
"match the required ABI major version (%d)\n",
maj, reqmaj);
return FALSE;
}
/* XXX Maybe this should be the other way around? */
if (min > reqmin) {
xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
"is new than that available (%d)\n", min, reqmin);
return FALSE;
}
}
}
#ifdef NOTYET
if (data->checksum) {
/* verify the checksum field */
/* TO BE DONE */
} else {
ErrorF("\t*** Checksum field is 0 - this module is untrusted!\n");
}
#endif
return TRUE;
}
/* Given a module path or file name, return the module's canonical name */
static char *
LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
{
char *str;
const char *s;
int len;
PatternPtr p;
regmatch_t match[2];
/* Strip off any leading path */
s = strrchr(modname, '/');
if (s == NULL)
s = modname;
else
s++;
/* Find the first regex that is matched */
for (p = patterns; p->pattern; p++)
if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) {
len = match[1].rm_eo - match[1].rm_so;
str = xalloc(len + 1);
if (!str)
return NULL;
strncpy(str, s + match[1].rm_so, len);
str[len] = '\0';
return str;
}
/* If there is no match, return the whole name minus the leading path */
return xstrdup(s);
}