Hi I've built the project with my proposed fixes and found that it wasn't completely correct; the fp variable is already used for something else.
I also found another problem in the function LoaderGetCanonicalName. You've used lines like "if (sscanf(s, "%s_drv.so", tmpBuf) == 1)". You can't use scanf-functions like this. It fails on a very subtle point: %s reads until whitespace or the end of the input. This function will return "ati_drv.so" instead of "ati" for input like "/some/place/ati_drv.so". I've fixed both points and tested them. The fix work. I've created a patch to 028_loader_speed_hack.diff. It's attached. Sjoerd Hemminga Snow B.V.
--- 028_loader_speed_hack.diff 2005-12-10 11:43:46.000000000 +0100 +++ 028_loader_speed_hack.diff.new 2005-12-11 23:04:22.000000000 +0100 @@ -17,10 +17,14 @@ Author: Daniel Stone <[EMAIL PROTECTED]> +Changed by: Sjoerd Hemminga <[EMAIL PROTECTED]> + - Fixed LoaderListDirs so it returns the list of drivers instead of NULL + - Fixed LoaderGetCanonicalName to return ati instead of ati_drv.so + diff -urN xc/programs/Xserver/hw/xfree86.orig/common/xf86Config.c xc/programs/Xserver/hw/xfree86/common/xf86Config.c ---- xc/programs/Xserver/hw/xfree86.orig/common/xf86Config.c 2005-02-03 09:26:09.738057304 +1100 -+++ xc/programs/Xserver/hw/xfree86/common/xf86Config.c 2005-02-03 09:30:06.446072216 +1100 -@@ -248,6 +248,9 @@ +--- xc/programs/Xserver/hw/xfree86.orig/common/xf86Config.c 2005-12-11 22:35:07.000000000 +0100 ++++ xc/programs/Xserver/hw/xfree86/common/xf86Config.c 2005-12-11 22:36:35.000000000 +0100 +@@ -253,6 +253,9 @@ char **modulearray; pointer *optarray; XF86LoadPtr modp; @@ -30,7 +34,7 @@ /* * make sure the config file has been parsed and that we have a -@@ -282,6 +285,17 @@ +@@ -287,6 +290,17 @@ if (xf86configptr->conf_modules) { modp = xf86configptr->conf_modules->mod_load_lst; while (modp) { @@ -48,11 +52,12 @@ modulearray[count] = modp->load_name; optarray[count] = modp->load_opt; count++; ---- xc/programs/Xserver/hw/xfree86.orig/drivers/cirrus/Imakefile 2005-02-03 09:26:10.458947712 +1100 -+++ xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile 2005-02-03 09:26:15.968110192 +1100 +diff -urN xc/programs/Xserver/hw/xfree86.orig/drivers/cirrus/Imakefile xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile +--- xc/programs/Xserver/hw/xfree86.orig/drivers/cirrus/Imakefile 2005-12-11 22:35:08.000000000 +0100 ++++ xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile 2005-12-11 22:36:35.000000000 +0100 @@ -79,13 +79,13 @@ - InstallObjectModule(cirrus,$(MODULEDIR),drivers) + InstallVideoObjectModule(cirrus,$(MODULEDIR)) -SubDriverObjectModuleTarget(cirrus_alpine,$(AOBJS)) +ObjectModuleTarget(cirrus_alpine,$(AOBJS)) @@ -76,11 +81,12 @@ -InstallDriverSDKObjectSubModule(cirrus_laguna,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(cirrus_alpine,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(cirrus_laguna,$(DRIVERSDKMODULEDIR),drivers) ---- xc/programs/Xserver/hw/xfree86.orig/drivers/nv/Imakefile 2005-02-03 09:26:10.835890408 +1100 -+++ xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile 2005-02-03 09:26:15.968110192 +1100 +diff -urN xc/programs/Xserver/hw/xfree86.orig/drivers/nv/Imakefile xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile +--- xc/programs/Xserver/hw/xfree86.orig/drivers/nv/Imakefile 2005-12-11 22:35:09.000000000 +0100 ++++ xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile 2005-12-11 22:36:35.000000000 +0100 @@ -79,8 +79,8 @@ - InstallObjectModule(nv,$(MODULEDIR),drivers) + InstallVideoObjectModule(nv,$(MODULEDIR)) -SubDriverObjectModuleTarget(riva128,$(R_OBJS)) -InstallSubDriverObjectModule(riva128,$(MODULEDIR),drivers) @@ -96,22 +102,10 @@ -InstallDriverSDKObjectSubModule(riva128,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(riva128,$(DRIVERSDKMODULEDIR),drivers) ---- xc/programs/Xserver/hw/xfree86.orig/loader/loadmod.c 2005-02-03 09:26:11.962719104 +1100 -+++ xc/programs/Xserver/hw/xfree86/loader/loadmod.c 2005-02-03 09:26:16.014103200 +1100 -@@ -204,89 +204,16 @@ - - /* Standard set of module subdirectories to search, in order of preference */ - static const char *stdSubdirs[] = { -- "drivers/", -+ "", -+ "fonts/", - "input/", -+ "drivers/", - "multimedia/", - "extensions/", -- "fonts/", - "internal/", -- "", +diff -urN xc/programs/Xserver/hw/xfree86.orig/loader/loadmod.c xc/programs/Xserver/hw/xfree86/loader/loadmod.c +--- xc/programs/Xserver/hw/xfree86.orig/loader/loadmod.c 2005-12-11 22:35:07.000000000 +0100 ++++ xc/programs/Xserver/hw/xfree86/loader/loadmod.c 2005-12-11 22:36:59.000000000 +0100 +@@ -218,79 +218,6 @@ NULL }; @@ -191,94 +185,7 @@ static const char ** InitSubdirs(const char **subdirlist) { -@@ -396,20 +323,24 @@ - - static char * - FindModule(const char *module, const char *dir, const char **subdirlist, -- PatternPtr patterns) -+ PatternPtr unused) - { -- char buf[PATH_MAX + 1]; -+ char buf[PATH_MAX + 1], tmpBuf[PATH_MAX + 1]; - char *dirpath = NULL; - char *name = NULL; - struct stat stat_buf; - int len, dirlen; -- char *fp; - DIR *d; - const char **subdirs = NULL; -- PatternPtr p = NULL; - const char **s; - struct dirent *dp; -- regmatch_t match[2]; -+ int i = 0; -+ -+#ifdef DLOPEN_HACK -+ char *suffix[] = { "so", "a", "o" }; -+#else -+ char *suffix[] = { "a", "o", "so" }; -+#endif - - subdirs = InitSubdirs(subdirlist); - if (!subdirs) -@@ -431,39 +362,23 @@ - strcpy(buf, dirpath); - strcat(buf, *s); - /*xf86Msg(X_INFO,"OS2DIAG: FindModule: buf=%s\n",buf); */ -- fp = buf + dirlen; -- if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && -- (d = opendir(buf))) { -- if (buf[dirlen - 1] != '/') { -- buf[dirlen++] = '/'; -- fp++; -- } -- while ((dp = readdir(d))) { -- if (dirlen + strlen(dp->d_name) + 1 > PATH_MAX) -- continue; -- strcpy(fp, dp->d_name); -- if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode))) -- continue; -- for (p = patterns; p->pattern; p++) { -- if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 && -- match[1].rm_so != -1) { -- len = match[1].rm_eo - match[1].rm_so; -- if (len == strlen(module) && -- strncmp(module, dp->d_name + match[1].rm_so, -- len) == 0) { -- /*xf86Msg(X_INFO,"OS2DIAG: matching %s\n",buf); */ -- name = buf; -- break; -- } -- } -- } -- if (name) -- break; -- } -- closedir(d); -- if (name) -- break; -- } -+ if ((stat(buf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) { -+ 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; -+ else { -+ snprintf(tmpBuf, PATH_MAX, "%s%s_drv.%s", buf, module, -+ suffix[i]); -+ if (stat(tmpBuf, &stat_buf) == 0) -+ name = tmpBuf; -+ } -+ } -+ } - } - FreeSubdirs(subdirs); - if (dirpath != dir) -@@ -476,18 +391,15 @@ +@@ -479,21 +406,18 @@ } char ** @@ -297,8 +204,12 @@ - regmatch_t match[2]; struct stat stat_buf; int len, dirlen; - char *fp; -@@ -501,11 +413,6 @@ +- char *fp; ++ char *fp, *f; + char **listing = NULL; + char **save; + int n = 0; +@@ -504,11 +428,6 @@ FreePathList(pathlist); return NULL; } @@ -310,22 +221,25 @@ for (elem = pathlist; *elem; elem++) { for (s = subdirs; *s; s++) { -@@ -513,52 +420,24 @@ +@@ -516,52 +435,27 @@ continue; strcpy(buf, *elem); strcat(buf, *s); - fp = buf + dirlen; - if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) && - (d = opendir(buf))) { ++ f = buf + dirlen; + if (d = opendir(buf)) { if (buf[dirlen - 1] != '/') { buf[dirlen++] = '/'; - fp++; ++ f++; } while ((dp = readdir(d))) { if (dirlen + strlen(dp->d_name) > PATH_MAX) continue; - strcpy(fp, dp->d_name); ++ strcpy(f, dp->d_name); if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode))) continue; @@ -372,7 +286,7 @@ } closedir(d); } -@@ -748,7 +627,7 @@ +@@ -757,7 +651,7 @@ ModuleDescPtr LoadSubModule(ModuleDescPtr parent, const char *module, @@ -381,7 +295,7 @@ pointer options, const XF86ModReqInfo * modreq, int *errmaj, int *errmin) { -@@ -773,7 +652,7 @@ +@@ -782,7 +676,7 @@ return NULL; } @@ -390,7 +304,7 @@ modreq, errmaj, errmin); if (submod) { parent->child = AddSibling(parent->child, submod); -@@ -824,12 +703,7 @@ +@@ -833,12 +727,7 @@ * subdirlist A NULL terminated list of subdirectories to search. When * NULL, the default "stdSubdirs" list is used. The default * list is also substituted for entries with value DEFAULT_LIST. @@ -404,7 +318,7 @@ * options A NULL terminated list of Options that are passed to the * module's SetupProc function. * modreq An optional XF86ModReqInfo* containing -@@ -854,7 +728,7 @@ +@@ -863,7 +752,7 @@ ModuleDescPtr LoadModule(const char *module, const char *path, const char **subdirlist, @@ -413,7 +327,7 @@ const XF86ModReqInfo * modreq, int *errmaj, int *errmin) { XF86ModuleData *initdata = NULL; -@@ -865,15 +739,14 @@ +@@ -874,15 +763,14 @@ char *p = NULL; ModuleDescPtr ret = NULL; int wasLoaded = 0; @@ -431,7 +345,7 @@ noncanonical = (name && strcmp(module, name) != 0); if (noncanonical) { xf86ErrorFVerb(3, " (%s)\n", name); -@@ -925,7 +798,7 @@ +@@ -934,7 +822,7 @@ #endif path_elem = pathlist; while (!found && *path_elem != NULL) { @@ -440,7 +354,7 @@ path_elem++; /* * When the module name isn't the canonical name, search for the -@@ -1035,7 +908,6 @@ +@@ -1049,7 +937,6 @@ LoadModule_exit: FreePathList(pathlist); @@ -448,7 +362,7 @@ TestFree(found); TestFree(name); TestFree(p); -@@ -1266,13 +1138,11 @@ +@@ -1282,13 +1169,12 @@ /* Given a module path or file name, return the module's canonical name */ static char * @@ -461,10 +375,11 @@ int len; - PatternPtr p; - regmatch_t match[2]; ++ char *e; /* Strip off any leading path */ s = strrchr(modname, '/'); -@@ -1281,17 +1151,14 @@ +@@ -1297,17 +1183,32 @@ else s++; @@ -479,14 +394,32 @@ - str[len] = '\0'; - return str; - } -+ if (sscanf(s, "lib%s.a", tmpBuf) == 1) -+ return xstrdup(tmpBuf); -+ if (sscanf(s, "%s_drv.o", tmpBuf) == 1) -+ return xstrdup(tmpBuf); -+ if (sscanf(s, "lib%s.so", tmpBuf) == 1) ++ if (sscanf(s, "lib%s", tmpBuf) == 1) { ++ e = tmpBuf + strlen(tmpBuf) - 2; ++ if (strcmp(e, ".a") == 0) { ++ e[0] = '\0'; ++ return xstrdup(tmpBuf); ++ } ++ ++ e = e--; ++ if (strcmp(e, ".so") == 0) { ++ e[0] = '\0'; ++ return xstrdup(tmpBuf); ++ } ++ } ++ ++ strcpy(tmpBuf, s); ++ e = tmpBuf + strlen(tmpBuf) - 6; ++ if (strcmp(e, "_drv.o") == 0) { ++ e[0] = '\0'; + return xstrdup(tmpBuf); -+ if (sscanf(s, "%s_drv.so", tmpBuf) == 1) ++ } ++ ++ e = e--; ++ if (strcmp(e, "_drv.so") == 0) { ++ e[0] = '\0'; + return xstrdup(tmpBuf); ++ } /* If there is no match, return the whole name minus the leading path */ return xstrdup(s);