rse 98/04/28 01:42:13
Modified: . STATUS INSTALL src CHANGES Configure README.DSO src/modules/standard mod_so.c src/os/unix os.c Added: src/os/unix os-aix-dso.c src/support httpd.exp Log: After the third interaction now we have it: Dynamic Shared Object (DSO) support for IBM's AIX. This is accomplished by using DSO emulation code because AIX <= 4.2 don't have dlopen() and AIX 4.2 has a broken one. But with the emulation code it works great. Revision Changes Path 1.341 +1 -0 apache-1.3/STATUS Index: STATUS =================================================================== RCS file: /export/home/cvs/apache-1.3/STATUS,v retrieving revision 1.340 retrieving revision 1.341 diff -u -r1.340 -r1.341 --- STATUS 1998/04/28 08:19:47 1.340 +++ STATUS 1998/04/28 08:42:06 1.341 @@ -75,6 +75,7 @@ * Roy's bugfixes for select() handling * Martin's suppress "error(0)" messages for ap_log_error() * Ralf's fixes for compiler warnings under AIX 4.2 (NET_SIZE_T is size_t) + * Ralf's DSO support for AIX Available Patches: 1.22 +5 -4 apache-1.3/INSTALL Index: INSTALL =================================================================== RCS file: /export/home/cvs/apache-1.3/INSTALL,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- INSTALL 1998/04/27 16:11:40 1.21 +++ INSTALL 1998/04/28 08:42:06 1.22 @@ -75,13 +75,14 @@ platform-dependend. The current state is this: o Out-of-the-box supported platforms are: - - Linux - SunOS - IRIX - - FreeBSD - Solaris - HPUX - - OpenBSD - OSF1 - UnixWare + - Linux - IRIX + - FreeBSD - HPUX + - OpenBSD - OSF1 + - SunOS - UnixWare + - Solaris - AIX o Entirely unsupported platforms are: - Ultrix (because no dlopen-style interface) - - AIX (although it has dlopen it is a braindead one) If your system is not on these lists but has the dlopen-style interface, you either have to provide the appropriate compiler and 1.803 +6 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.802 retrieving revision 1.803 diff -u -r1.802 -r1.803 --- CHANGES 1998/04/28 08:19:47 1.802 +++ CHANGES 1998/04/28 08:42:07 1.803 @@ -1,4 +1,10 @@ Changes with Apache 1.3b7 + + *) Add Dynamic Shared Object (DSO) support for AIX (at least 4.2 but older + AIX variants should work fine, too. Even AIX 3.x should work). This is + accomplished by using the free DSO emulation code from Jens-Uwe Mager + which we put into a os/unix/os-dso-aix.c file. + [Ralf S. Engelschall] *) PORT: Fix compiler warnings under AIX >= 4.2 where the manual pages imply that we should use NET_SIZE_T == int but the include files force size_t. 1.249 +24 -0 apache-1.3/src/Configure Index: Configure =================================================================== RCS file: /export/home/cvs/apache-1.3/src/Configure,v retrieving revision 1.248 retrieving revision 1.249 diff -u -r1.248 -r1.249 --- Configure 1998/04/28 08:19:48 1.248 +++ Configure 1998/04/28 08:42:08 1.249 @@ -763,6 +763,7 @@ if [ "x$using_shlib" = "x1" ] ; then DEF_SHARED_CORE=no SHLIB_SUFFIX_DEPTH=all + SHLIB_EXPORT_FILES=no case "$PLAT" in *-linux1) CFLAGS_SHLIB="-fpic" @@ -899,6 +900,25 @@ LDFLAGS_SHLIB="-b" LDFLAGS_SHLIB_EXPORT="-Wl,-E -Wl,-B,deferred" ;; + *-ibm-aix*) + case $CC in + */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; + */cc|cc ) CFLAGS_SHLIB="" ;; + esac + case $PLAT in + *-ibm-aix4*) + LDFLAGS_SHLIB="-H512 -T512 -bhalt:4 -bM:SRE -bnoentry" + ;; + *-ibm-aix*) + LDFLAGS_SHLIB="-H512 -T512 -bhalt:4 -bM:SRE -e _nostart" + ;; + esac + LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bI:\$(SRCDIR)/support/httpd.exp " + LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bE:\`echo \$@|sed -e 's:\.so\$\$:.exp:'\`" + LDFLAGS_SHLIB="$LDFLAGS_SHLIB -lc" + LDFLAGS_SHLIB_EXPORT="-Wl,-bE:\$(SRCDIR)/support/httpd.exp" + SHLIB_EXPORT_FILES=yes + ;; *) ## ok, no known explict support for shared objects ## on this platform, but we give not up immediately. @@ -1248,6 +1268,10 @@ fi if [ $ext != so ]; then echo "Module $modname $modbase.$ext" >>$tmpfile + fi + # optionally generate export file for some linkers + if [ $ext = so -a .$SHLIB_EXPORT_FILES = .yes ]; then + echo "$modname" >$modbase.exp fi done # $tmpfile now contains Module lines for all the modules we want 1.6 +1 -4 apache-1.3/src/README.DSO Index: README.DSO =================================================================== RCS file: /export/home/cvs/apache-1.3/src/README.DSO,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- README.DSO 1998/04/27 16:11:41 1.5 +++ README.DSO 1998/04/28 08:42:08 1.6 @@ -150,6 +150,7 @@ o IRIX (6.2) o HP/UX (10.20) o UnixWare (2.01, 2.1.2) + o AIX (4.2) o ReliantUNIX/SINIX (5.43) o SVR4 (-) @@ -157,10 +158,6 @@ o Ultrix: There is no dlopen-style interface under this platform. - o AIX: Under AIX 3.x there is no dlopen-style interface and under AIX 4.2 - although there is one the linker (ld) is such braindead that it is a - horrible mess to get the DSO mechanism working. - Usage Summary ------------- 1.23 +12 -5 apache-1.3/src/modules/standard/mod_so.c Index: mod_so.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_so.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- mod_so.c 1998/04/14 10:58:24 1.22 +++ mod_so.c 1998/04/28 08:42:10 1.23 @@ -135,11 +135,18 @@ : else DL_LIB="" - if ./helpers/TestCompile lib dl; then - DL_LIB="-ldl" - fi - LIBS="$LIBS $DL_LIB" - if [ "X$DL_LIB" != "X" ]; then + case $PLAT in + *-ibm-aix* ) + DL_LIB="-lld" + ;; + * ) + if ./helpers/TestCompile lib dl; then + DL_LIB="-ldl" + fi + ;; + esac + if [ ".$DL_LIB" != . ]; then + LIBS="$LIBS $DL_LIB" echo " + using $DL_LIB for DSO support" fi fi 1.11 +7 -0 apache-1.3/src/os/unix/os.c Index: os.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/os/unix/os.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- os.c 1998/04/19 12:25:22 1.10 +++ os.c 1998/04/28 08:42:11 1.11 @@ -14,6 +14,13 @@ void ap_is_not_here(void) {} /* + * Insert the DSO emulation code for AIX + */ +#ifdef AIX +#include "os-aix-dso.c" +#endif + +/* * Abstraction layer for loading * Apache modules under run-time via * dynamic shared object (DSO) mechanism 1.1 apache-1.3/src/os/unix/os-aix-dso.c Index: os-aix-dso.c =================================================================== /* ==================================================================== * Copyright (c) 1998 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ /* ** os-aix-dso.c -- DSO system function emulation for AIX */ /* ** Based on libdl (dlfcn.c/dlfcn.h) which is ** Copyright (c) 1992,1993,1995,1996,1997,1988 ** Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany. ** ** Not derived from licensed software. ** ** Permission is granted to freely use, copy, modify, and redistribute ** this software, provided that the author is not construed to be liable ** for any results of using the software, alterations are clearly marked ** as such, and this notice is not modified. ** ** Changes marked with `--jwe' were made on April 7 1996 by ** John W. Eaton <[EMAIL PROTECTED]> to support g++ ** ** Bundled, stripped and adjusted on April 1998 as one single source file ** for inclusion into the Apache HTTP server by ** Ralf S. Engelschall <[EMAIL PROTECTED]> */ #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ldr.h> #include <a.out.h> #undef FREAD #undef FWRITE #include <ldfcn.h> /* * Mode flags for the dlopen routine. */ #undef RTLD_LAZY #define RTLD_LAZY 1 /* lazy function call binding */ #undef RTLD_NOW #define RTLD_NOW 2 /* immediate function call binding */ #undef RTLD_GLOBAL #define RTLD_GLOBAL 0x100 /* allow symbols to be global */ /* * To be able to intialize, a library may provide a dl_info structure * that contains functions to be called to initialize and terminate. */ struct dl_info { void (*init) (void); void (*fini) (void); }; /* * Forward declarations */ void *dlopen(const char *path, int mode); void *dlsym(void *handle, const char *symbol); const char *dlerror(void); int dlclose(void *handle); /* * We simulate dlopen() et al. through a call to load. Because AIX has * no call to find an exported symbol we read the loader section of the * loaded module and build a list of exported symbols and their virtual * address. */ typedef struct { char *name; /* the symbols's name */ void *addr; /* its relocated virtual address */ } Export, *ExportPtr; /* * xlC uses the following structure to list its constructors and * destructors. This is gleaned from the output of munch. */ typedef struct { void (*init) (void); /* call static constructors */ void (*term) (void); /* call static destructors */ } Cdtor, *CdtorPtr; typedef void (*GccCDtorPtr) (void); /* * The void * handle returned from dlopen is actually a ModulePtr. */ typedef struct Module { struct Module *next; char *name; /* module name for refcounting */ int refCnt; /* the number of references */ void *entry; /* entry point from load */ struct dl_info *info; /* optional init/terminate functions */ CdtorPtr cdtors; /* optional C++ constructors */ GccCDtorPtr gcc_ctor; /* g++ constructors --jwe */ GccCDtorPtr gcc_dtor; /* g++ destructors --jwe */ int nExports; /* the number of exports found */ ExportPtr exports; /* the array of exports */ } Module, *ModulePtr; /* * We keep a list of all loaded modules to be able to call the fini * handlers and destructors at atexit() time. */ static ModulePtr modList; /* * The last error from one of the dl* routines is kept in static * variables here. Each error is returned only once to the caller. */ static char errbuf[BUFSIZ]; static int errvalid; /* * The `fixed' gcc header files on AIX 3.2.5 provide a prototype for * strdup(). --jwe */ extern char *strdup(const char *); static void caterr(char *); static int readExports(ModulePtr); static void terminate(void); static void *findMain(void); void *dlopen(const char *path, int mode) { register ModulePtr mp; static void *mainModule; /* * Upon the first call register a terminate handler that will * close all libraries. Also get a reference to the main module * for use with loadbind. */ if (!mainModule) { if ((mainModule = findMain()) == NULL) return NULL; atexit(terminate); } /* * Scan the list of modules if we have the module already loaded. */ for (mp = modList; mp; mp = mp->next) if (strcmp(mp->name, path) == 0) { mp->refCnt++; return mp; } if ((mp = (ModulePtr) calloc(1, sizeof(*mp))) == NULL) { errvalid++; strcpy(errbuf, "calloc: "); strcat(errbuf, strerror(errno)); return NULL; } if ((mp->name = strdup(path)) == NULL) { errvalid++; strcpy(errbuf, "strdup: "); strcat(errbuf, strerror(errno)); free(mp); return NULL; } /* * load should be declared load(const char *...). Thus we * cast the path to a normal char *. Ugly. */ if ((mp->entry = (void *) load((char *) path, L_NOAUTODEFER, NULL)) == NULL) { free(mp->name); free(mp); errvalid++; strcpy(errbuf, "dlopen: "); strcat(errbuf, path); strcat(errbuf, ": "); /* * If AIX says the file is not executable, the error * can be further described by querying the loader about * the last error. */ if (errno == ENOEXEC) { char *tmp[BUFSIZ / sizeof(char *)]; if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1) strcpy(errbuf, strerror(errno)); else { char **p; for (p = tmp; *p; p++) caterr(*p); } } else strcat(errbuf, strerror(errno)); return NULL; } mp->refCnt = 1; mp->next = modList; modList = mp; if (loadbind(0, mainModule, mp->entry) == -1) { dlclose(mp); errvalid++; strcpy(errbuf, "loadbind: "); strcat(errbuf, strerror(errno)); return NULL; } /* * If the user wants global binding, loadbind against all other * loaded modules. */ if (mode & RTLD_GLOBAL) { register ModulePtr mp1; for (mp1 = mp->next; mp1; mp1 = mp1->next) if (loadbind(0, mp1->entry, mp->entry) == -1) { dlclose(mp); errvalid++; strcpy(errbuf, "loadbind: "); strcat(errbuf, strerror(errno)); return NULL; } } if (readExports(mp) == -1) { dlclose(mp); return NULL; } /* * If there is a dl_info structure, call the init function. */ if (mp->info = (struct dl_info *) dlsym(mp, "dl_info")) { if (mp->info->init) (*mp->info->init) (); } else errvalid = 0; /* * If the shared object was compiled using xlC we will need * to call static constructors (and later on dlclose destructors). */ if (mp->cdtors = (CdtorPtr) dlsym(mp, "__cdtors")) { CdtorPtr cp = mp->cdtors; while (cp->init || cp->term) { if (cp->init && cp->init != (void (*)(void)) 0xffffffff) (*cp->init) (); cp++; } /* * If the shared object was compiled using g++, we will need * to call global constructors using the _GLOBAL__DI function, * and later, global destructors using the _GLOBAL_DD * funciton. --jwe */ } else if (mp->gcc_ctor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DI")) { (*mp->gcc_ctor) (); mp->gcc_dtor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DD"); } else errvalid = 0; return mp; } /* * Attempt to decipher an AIX loader error message and append it * to our static error message buffer. */ static void caterr(char *s) { register char *p = s; while (*p >= '0' && *p <= '9') p++; switch (atoi(s)) { case L_ERROR_TOOMANY: strcat(errbuf, "to many errors"); break; case L_ERROR_NOLIB: strcat(errbuf, "can't load library"); strcat(errbuf, p); break; case L_ERROR_UNDEF: strcat(errbuf, "can't find symbol"); strcat(errbuf, p); break; case L_ERROR_RLDBAD: strcat(errbuf, "bad RLD"); strcat(errbuf, p); break; case L_ERROR_FORMAT: strcat(errbuf, "bad exec format in"); strcat(errbuf, p); break; case L_ERROR_ERRNO: strcat(errbuf, strerror(atoi(++p))); break; default: strcat(errbuf, s); break; } } void *dlsym(void *handle, const char *symbol) { register ModulePtr mp = (ModulePtr) handle; register ExportPtr ep; register int i; /* * Could speed up the search, but I assume that one assigns * the result to function pointers anyways. */ for (ep = mp->exports, i = mp->nExports; i; i--, ep++) if (strcmp(ep->name, symbol) == 0) return ep->addr; errvalid++; strcpy(errbuf, "dlsym: undefined symbol "); strcat(errbuf, symbol); return NULL; } const char *dlerror(void) { if (errvalid) { errvalid = 0; return errbuf; } return NULL; } int dlclose(void *handle) { register ModulePtr mp = (ModulePtr) handle; int result; register ModulePtr mp1; if (--mp->refCnt > 0) return 0; if (mp->info && mp->info->fini) (*mp->info->fini) (); if (mp->cdtors) { CdtorPtr cp = mp->cdtors; while (cp->init || cp->term) { if (cp->term && cp->init != (void (*)(void)) 0xffffffff) (*cp->term) (); cp++; } /* * If the function to handle global destructors for g++ * exists, call it. --jwe */ } else if (mp->gcc_dtor) { (*mp->gcc_dtor) (); } result = unload(mp->entry); if (result == -1) { errvalid++; strcpy(errbuf, strerror(errno)); } if (mp->exports) { register ExportPtr ep; register int i; for (ep = mp->exports, i = mp->nExports; i; i--, ep++) if (ep->name) free(ep->name); free(mp->exports); } if (mp == modList) modList = mp->next; else { for (mp1 = modList; mp1; mp1 = mp1->next) if (mp1->next == mp) { mp1->next = mp->next; break; } } free(mp->name); free(mp); return result; } static void terminate(void) { while (modList) dlclose(modList); } /* * Build the export table from the XCOFF .loader section. */ static int readExports(ModulePtr mp) { LDFILE *ldp = NULL; SCNHDR sh, shdata; LDHDR *lhp; char *ldbuf; LDSYM *ls; int i; ExportPtr ep; struct ld_info *lp; char *buf; int size = 4 * 1024; void *dataorg; /* * The module might be loaded due to the LIBPATH * environment variable. Search for the loaded * module using L_GETINFO. */ if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) { free(buf); size += 4 * 1024; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } } if (i == -1) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); free(buf); return -1; } /* * Traverse the list of loaded modules. The entry point * returned by load() does actually point to the TOC * entry contained in the data segment. */ lp = (struct ld_info *) buf; while (lp) { if ((unsigned long) mp->entry >= (unsigned long) lp->ldinfo_dataorg && (unsigned long) mp->entry < (unsigned long) lp->ldinfo_dataorg + lp->ldinfo_datasize) { dataorg = lp->ldinfo_dataorg; ldp = ldopen(lp->ldinfo_filename, ldp); break; } if (lp->ldinfo_next == 0) lp = NULL; else lp = (struct ld_info *) ((char *) lp + lp->ldinfo_next); } free(buf); if (!ldp) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } if (TYPE(ldp) != U802TOCMAGIC) { errvalid++; strcpy(errbuf, "readExports: bad magic"); while (ldclose(ldp) == FAILURE); return -1; } /* * Get the padding for the data section. This is needed for * AIX 4.1 compilers. This is used when building the final * function pointer to the exported symbol. */ if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) { errvalid++; strcpy(errbuf, "readExports: cannot read data section header"); while (ldclose(ldp) == FAILURE); return -1; } if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) { errvalid++; strcpy(errbuf, "readExports: cannot read loader section header"); while (ldclose(ldp) == FAILURE); return -1; } /* * We read the complete loader section in one chunk, this makes * finding long symbol names residing in the string table easier. */ if ((ldbuf = (char *) malloc(sh.s_size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); while (ldclose(ldp) == FAILURE); return -1; } if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) { errvalid++; strcpy(errbuf, "readExports: cannot seek to loader section"); free(ldbuf); while (ldclose(ldp) == FAILURE); return -1; } if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) { errvalid++; strcpy(errbuf, "readExports: cannot read loader section"); free(ldbuf); while (ldclose(ldp) == FAILURE); return -1; } lhp = (LDHDR *) ldbuf; ls = (LDSYM *) (ldbuf + LDHDRSZ); /* * Count the number of exports to include in our export table. */ for (i = lhp->l_nsyms; i; i--, ls++) { if (!LDR_EXPORT(*ls)) continue; mp->nExports++; } if ((mp->exports = (ExportPtr) calloc(mp->nExports, sizeof(*mp->exports))) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); free(ldbuf); while (ldclose(ldp) == FAILURE); return -1; } /* * Fill in the export table. All entries are relative to * the beginning of the data origin. */ ep = mp->exports; ls = (LDSYM *) (ldbuf + LDHDRSZ); for (i = lhp->l_nsyms; i; i--, ls++) { char *symname; char tmpsym[SYMNMLEN + 1]; if (!LDR_EXPORT(*ls)) continue; if (ls->l_zeroes == 0) symname = ls->l_offset + lhp->l_stoff + ldbuf; else { /* * The l_name member is not zero terminated, we * must copy the first SYMNMLEN chars and make * sure we have a zero byte at the end. */ strncpy(tmpsym, ls->l_name, SYMNMLEN); tmpsym[SYMNMLEN] = '\0'; symname = tmpsym; } ep->name = strdup(symname); ep->addr = (void *) ((unsigned long) dataorg + ls->l_value - shdata.s_vaddr); ep++; } free(ldbuf); while (ldclose(ldp) == FAILURE); return 0; } /* * Find the main modules data origin. This is used as export pointer * for loadbind() to be able to resolve references to the main part. */ static void *findMain(void) { struct ld_info *lp; char *buf; int size = 4 * 1024; int i; void *ret; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); return NULL; } while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) { free(buf); size += 4 * 1024; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); return NULL; } } if (i == -1) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); free(buf); return NULL; } /* * The first entry is the main module. The data segment * starts with the TOC entries for all exports, so the * data segment origin works as argument for loadbind. */ lp = (struct ld_info *) buf; ret = lp->ldinfo_dataorg; free(buf); return ret; } 1.1 apache-1.3/src/support/httpd.exp Index: httpd.exp =================================================================== #! ap_MD5Final ap_MD5Init ap_MD5Update ap_add_cgi_vars ap_add_common_vars ap_add_module ap_add_named_module ap_add_per_dir_conf ap_add_per_url_conf ap_allow_options ap_allow_overrides ap_append_arrays ap_array_cat ap_auth_name ap_auth_type ap_basic_http_header ap_bclose ap_bcreate ap_bfilbuf ap_bfileno ap_bflsbuf ap_bflush ap_bgetopt ap_bgets ap_bhalfduplex ap_bind_address ap_block_alarms ap_blookc ap_bnonblock ap_bonerror ap_bprintf ap_bpushfd ap_bputs ap_bread ap_bsetflag ap_bsetopt ap_bskiplf ap_bvputs ap_bwrite ap_bytes_in_free_blocks ap_bytes_in_pool ap_call_exec ap_can_exec ap_cfg_closefile ap_cfg_getc ap_cfg_getline ap_chdir_file ap_check_access ap_check_auth ap_check_cmd_context ap_check_user_id ap_checkmask ap_child_exit_modules ap_child_init_modules ap_child_terminate ap_cleanup_for_exec ap_clear_module_list ap_clear_pool ap_clear_table ap_close_piped_log ap_construct_server ap_construct_url ap_copy_array ap_copy_array_hdr ap_copy_table ap_core_reorder_directories ap_coredump_dir ap_count_dirs ap_cpystrn ap_create_environment ap_create_per_dir_config ap_create_request_config ap_daemons_limit ap_daemons_max_free ap_daemons_min_free ap_daemons_to_start ap_day_snames ap_default_port_for_request ap_default_port_for_scheme ap_default_type ap_destroy_pool ap_destroy_sub_req ap_die ap_discard_request_body ap_document_root ap_dummy_mutex ap_each_byterange ap_error_log2stderr ap_escape_html ap_escape_path_segment ap_escape_quotes ap_escape_shell_cmd ap_excess_requests_per_child ap_exists_scoreboard_image ap_finalize_request_protocol ap_finalize_sub_req_protocol ap_find_command ap_find_command_in_modules ap_find_last_token ap_find_linked_module ap_find_module_name ap_find_path_info ap_find_token ap_find_types ap_fini_vhost_config ap_fnmatch ap_force_library_loading ap_get_basic_auth_pw ap_get_client_block ap_get_gmtoff ap_get_local_host ap_get_module_config ap_get_remote_host ap_get_remote_logname ap_get_server_built ap_get_server_name ap_get_server_port ap_get_server_version ap_get_time ap_get_token ap_get_virthost_addr ap_getparents ap_getword ap_getword_conf ap_getword_conf_nc ap_getword_nc ap_getword_nulls ap_getword_nulls_nc ap_getword_white ap_getword_white_nc ap_gm_timestr_822 ap_gname2id ap_group_id ap_handle_command ap_hard_timeout ap_header_parse ap_ht_time ap_ind ap_index_of_response ap_init_alloc ap_init_modules ap_init_vhost_config ap_init_virtual_host ap_internal_redirect ap_internal_redirect_handler ap_invoke_handler ap_is_directory ap_is_fnmatch ap_is_initial_req ap_is_matchexp ap_is_url ap_keepalive_timeout ap_kill_cleanup ap_kill_cleanups_for_fd ap_kill_cleanups_for_socket ap_kill_timeout ap_limit_section ap_listenbacklog ap_listeners ap_lock_fname ap_log_assert ap_log_error ap_log_error_old ap_log_pid ap_log_printf ap_log_reason ap_log_transaction ap_log_unixerr ap_make_array ap_make_dirstr ap_make_dirstr_parent ap_make_dirstr_prefix ap_make_full_path ap_make_sub_pool ap_make_table ap_matches_request_vhost ap_max_requests_per_child ap_md5 ap_md5contextTo64 ap_md5digest ap_meets_conditions ap_merge_per_dir_configs ap_month_snames ap_no2slash ap_note_auth_failure ap_note_basic_auth_failure ap_note_cleanups_for_fd ap_note_cleanups_for_file ap_note_cleanups_for_socket ap_note_digest_auth_failure ap_note_subprocess ap_null_cleanup ap_open_logs ap_open_piped_log ap_os_escape_path ap_os_is_path_absolute ap_overlay_tables ap_palloc ap_parseHTTPdate ap_parse_hostinfo_components ap_parse_htaccess ap_parse_uri ap_parse_uri_components ap_parse_vhost_addrs ap_pcalloc ap_pcfg_open_custom ap_pcfg_openfile ap_pclosedir ap_pclosef ap_pclosesocket ap_pduphostent ap_pfclose ap_pfdopen ap_pfopen ap_pgethostbyname ap_pid_fname ap_popendir ap_popenf ap_pregcomp ap_pregfree ap_pregsub ap_prelinked_modules ap_preloaded_modules ap_process_request ap_process_resource_config ap_psignature ap_psocket ap_psprintf ap_pstrcat ap_pstrdup ap_pstrndup ap_push_array ap_pvsprintf ap_rationalize_mtime ap_read_config ap_read_request ap_register_cleanup ap_register_other_child ap_remove_module ap_requires ap_reset_timeout ap_response_code_string ap_restart_time ap_rfc1413 ap_rfc1413_timeout ap_rflush ap_rind ap_rprintf ap_rputc ap_rputs ap_run_cleanup ap_run_fixups ap_run_post_read_request ap_run_sub_req ap_rvputs ap_rwrite ap_satisfies ap_scan_script_header_err ap_scan_script_header_err_buff ap_scoreboard_fname ap_scoreboard_image ap_send_error_response ap_send_fb ap_send_fb_length ap_send_fd ap_send_fd_length ap_send_header_field ap_send_http_header ap_send_http_options ap_send_http_trace ap_send_mmap ap_send_size ap_server_argv0 ap_server_confname ap_server_post_read_config ap_server_pre_read_config ap_server_root ap_server_root_relative ap_set_byterange ap_set_callback_and_alarm ap_set_content_length ap_set_etag ap_set_file_slot ap_set_flag_slot ap_set_keepalive ap_set_last_modified ap_set_module_config ap_set_name_virtual_host ap_set_string_slot ap_set_string_slot_lower ap_set_sub_req_protocol ap_setup_client_block ap_setup_prelinked_modules ap_should_client_block ap_show_directives ap_show_modules ap_signal ap_slack ap_snprintf ap_soft_timeout ap_some_auth_required ap_spawn_child_err ap_spawn_child_err_buff ap_srm_command_loop ap_standalone ap_start_restart ap_start_shutdown ap_str_tolower ap_strcasecmp_match ap_strcmp_match ap_sub_req_lookup_file ap_sub_req_lookup_uri ap_suexec_enabled ap_sync_scoreboard_image ap_table_add ap_table_addn ap_table_do ap_table_get ap_table_merge ap_table_mergen ap_table_set ap_table_setn ap_table_unset ap_threads_per_child ap_tm2sec ap_translate_name ap_uname2id ap_unblock_alarms ap_unescape_url ap_unparse_uri_components ap_unregister_other_child ap_update_child_status ap_update_mtime ap_update_vhost_from_headers ap_update_vhost_given_ip ap_user_id ap_user_name ap_util_init ap_util_uri_init ap_uudecode ap_vbprintf ap_vformatter ap_vsnprintf core_module top_module