--- 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 > > Dri-devel@lists.sourceforge.net > > 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 > Dri-devel@lists.sourceforge.net > 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); }