Remove dlfcn implementation for AIX since nowadays AIX have dlopen()

Also drop license and copyright statement
This commit is contained in:
Love Hornquist Astrand
2009-07-24 04:25:39 +02:00
parent 1dd94e44ba
commit de0ae78c4e
5 changed files with 2 additions and 902 deletions

View File

@@ -409,23 +409,6 @@ Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
(GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
@end verbatim
@copynext
@heading Jens-Uwe Mager, Helios Software GmbH
AIX dlfcn in libkafs
@verbatim
Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH
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.
@end verbatim

View File

@@ -24,11 +24,7 @@ AFS_EXTRA_LD = -e _nostart
endif
if AIX_DYNAMIC_AFS
if HAVE_DLOPEN
AIX_SRC =
else
AIX_SRC = dlfcn.c
endif
AFS_EXTRA_LIBS = afslib.so
AFS_EXTRA_DEFS =
else
@@ -73,9 +69,9 @@ dist_libkafs_la_SOURCES = \
nodist_libkafs_la_SOURCES = $(ROKEN_SRCS)
EXTRA_libkafs_la_SOURCES = afskrb5.c dlfcn.c afslib.c dlfcn.h
EXTRA_libkafs_la_SOURCES = afskrb5.c afslib.c
EXTRA_DIST = README.dlfcn afsl.exp afslib.exp $(man_MANS)
EXTRA_DIST = afsl.exp afslib.exp $(man_MANS)
man_MANS = kafs.3

View File

@@ -1,246 +0,0 @@
Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH
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.
libdl.a
-------
This is an emulation library to emulate the SunOS/System V.4 functions
to access the runtime linker. The functions are emulated by using the
AIX load() function and by reading the .loader section of the loaded
module to find the exports. The to be loaded module should be linked as
follows (if using AIX 3):
cc -o module.so -bM:SRE -bE:module.exp -e _nostart $(OBJS)
For AIX 4:
cc -o module.so -bM:SRE -bE:module.exp -bnoentry $(OBJS)
If you want to reference symbols from the main part of the program in a
loaded module, you will have to link against the export file of the
main part:
cc -o main -bE:main.exp $(MAIN_OBJS)
cc -o module.so -bM:SRE -bI:main.exp -bE:module.exp -bnoentry $(OBJS)
Note that you explicitely have to specify what functions are supposed
to be accessible from your loaded modules, this is different from
SunOS/System V.4 where any global is automatically exported. If you
want to export all globals, the following script might be of help:
#!/bin/sh
/usr/ucb/nm -g $* | awk '$2 == "B" || $2 == "D" { print $3 }'
The module export file contains the symbols to be exported. Because
this library uses the loader section, the final module.so file can be
stripped. C++ users should build their shared objects using the script
makeC++SharedLib (part of the IBM C++ compiler), this will make sure
that constructors and destructors for static and global objects will be
called upon loading and unloading the module. GNU C++ users should use
the -shared option to g++ to link the shared object:
g++ -o module.so -shared $(OBJS)
If the shared object does have permissions for anybody, the shared
object will be loaded into the shared library segment and it will stay
there even if the main application terminates. If you rebuild your
shared object after a bugfix and you want to make sure that you really
get the newest version you will have to use the "slibclean" command
before starting the application again to garbage collect the shared
library segment. If the performance utilities (bosperf) are installed
you can use the following command to see what shared objects are
loaded:
/usr/lpp/bosperf/genkld | sort | uniq
For easier debugging you can avoid loading the shared object into the
shared library segment alltogether by removing permissions for others
from the module.so file:
chmod o-rwx module.so
This will ensure you get a fresh copy of the shared object for every
dlopen() call which is loaded into the application's data segment.
Usage
-----
void *dlopen(const char *path, int mode);
This routine loads the module pointed to by path and reads its export
table. If the path does not contain a '/' character, dlopen will search
for the module using the LIBPATH environment variable. It returns an
opaque handle to the module or NULL on error. The mode parameter can be
either RTLD_LAZY (for lazy function binding) or RTLD_NOW for immediate
function binding. The AIX implementation currently does treat RTLD_NOW
the same as RTLD_LAZY. The flag RTLD_GLOBAL might be or'ed into the
mode parameter to allow loaded modules to bind to global variables or
functions in other loaded modules loaded by dlopen(). If RTLD_GLOBAL is
not specified, only globals from the main part of the executable or
shared libraries are used to look for undefined symbols in loaded
modules.
void *dlsym(void *handle, const char *symbol);
This routine searches for the symbol in the module referred to by
handle and returns its address. If the symbol could not be found, the
function returns NULL. The return value must be casted to a proper
function pointer before it can be used. SunOS/System V.4 allows handle
to be a NULL pointer to refer to the module the call is made from, this
is not implemented.
int dlclose(void *handle);
This routine unloads the module referred to by the handle and disposes
of any local storage. this function returns -1 on failure. Any function
pointers obtained through dlsym() should be considered invalid after
closing a module.
As AIX caches shared objects in the shared library segment, function
pointers obtained through dlsym() might still work even though the
module has been unloaded. This can introduce subtle bugs that will
segment fault later if AIX garbage collects or immediatly on
SunOS/System V.4 as the text segment is unmapped.
char *dlerror(void);
This routine can be used to retrieve a text message describing the most
recent error that occured on on of the above routines. This function
returns NULL if there is no error information.
Initialization and termination handlers
---------------------------------------
The emulation provides for an initialization and a termination
handler. The dlfcn.h file contains a structure declaration named
dl_info with following members:
void (*init)(void);
void (*fini)(void);
The init function is called upon first referencing the library. The
fini function is called at dlclose() time or when the process exits.
The module should declare a variable named dl_info that contains this
structure which must be exported. These functions correspond to the
documented _init() and _fini() functions of SunOS 4.x, but these are
appearently not implemented in SunOS. When using SunOS 5.0, these
correspond to #pragma init and #pragma fini respectively. At the same
time any static or global C++ object's constructors or destructors will
be called.
BUGS
----
Please note that there is currently a problem with implicitely loaded
shared C++ libaries: if you refer to a shared C++ library from a loaded
module that is not yet used by the main program, the dlopen() emulator
does not notice this and does not call the static constructors for the
implicitely loaded library. This can be easily demonstrated by
referencing the C++ standard streams from a loaded module if the main
program is a plain C program.
Jens-Uwe Mager
HELIOS Software GmbH
Lavesstr. 80
30159 Hannover
Germany
Phone: +49 511 36482-0
FAX: +49 511 36482-69
AppleLink: helios.de/jum
Internet: jum@helios.de
Revison History
---------------
SCCS/s.dlfcn.h:
D 1.4 95/04/25 09:36:52 jum 4 3 00018/00004/00028
MRs:
COMMENTS:
added RTLD_GLOBAL, include and C++ guards
D 1.3 92/12/27 20:58:32 jum 3 2 00001/00001/00031
MRs:
COMMENTS:
we always have prototypes on RS/6000
D 1.2 92/08/16 17:45:11 jum 2 1 00009/00000/00023
MRs:
COMMENTS:
added dl_info structure to implement initialize and terminate functions
D 1.1 92/08/02 18:08:45 jum 1 0 00023/00000/00000
MRs:
COMMENTS:
Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum
SCCS/s.dlfcn.c:
D 1.11 96/04/10 20:12:51 jum 13 12 00037/00000/00533
MRs:
COMMENTS:
Integrated the changes from John W. Eaton <jwe@bevo.che.wisc.edu> to initialize
g++ generated shared objects.
D 1.10 96/02/15 17:42:44 jum 12 10 00012/00007/00521
MRs:
COMMENTS:
the C++ constructor and destructor chains are now called properly for either
xlC 2 or xlC 3 (CSet++).
D 1.9 95/09/22 11:09:38 markus 10 9 00001/00008/00527
MRs:
COMMENTS:
Fix version number
D 1.8 95/09/22 10:14:34 markus 9 8 00008/00001/00527
MRs:
COMMENTS:
Added version number for dl lib
D 1.7 95/08/14 19:08:38 jum 8 6 00026/00004/00502
MRs:
COMMENTS:
Integrated the fixes from Kirk Benell (kirk@rsinc.com) to allow loading of
shared objects generated under AIX 4. Fixed bug that symbols with exactly
8 characters would use garbage characters from the following symbol value.
D 1.6 95/04/25 09:38:03 jum 6 5 00046/00006/00460
MRs:
COMMENTS:
added handling of C++ static constructors and destructors, added RTLD_GLOBAL to bind against other loaded modules
D 1.5 93/02/14 20:14:17 jum 5 4 00002/00000/00464
MRs:
COMMENTS:
added path to dlopen error message to make clear where there error occured.
D 1.4 93/01/03 19:13:56 jum 4 3 00061/00005/00403
MRs:
COMMENTS:
to allow calling symbols in the main module call load with L_NOAUTODEFER and
do a loadbind later with the main module.
D 1.3 92/12/27 20:59:55 jum 3 2 00066/00008/00342
MRs:
COMMENTS:
added search by L_GETINFO if module got loaded by LIBPATH
D 1.2 92/08/16 17:45:43 jum 2 1 00074/00006/00276
MRs:
COMMENTS:
implemented initialize and terminate functions, added reference counting to avoid multiple loads of the same library
D 1.1 92/08/02 18:08:45 jum 1 0 00282/00000/00000
MRs:
COMMENTS:
Erstellungsdatum und -uhrzeit 92/08/02 18:08:45 von jum

View File

@@ -1,584 +0,0 @@
/*
* See README.dlfcn for license
*/
/*
* @(#)dlfcn.c 1.11 revision of 96/04/10 20:12:51
* This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
* 30159 Hannover, Germany
*/
/*
* Changes marked with `--jwe' were made on April 7 1996 by John W. Eaton
* <jwe@bevo.che.wisc.edu> to support g++ and/or use with Octave.
*/
/*
* This makes my life easier with Octave. --jwe
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ldr.h>
#include <a.out.h>
#include <ldfcn.h>
#include "dlfcn.h"
/*
* 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
*/
#ifndef HAVE_STRDUP
extern char *strdup(const char *);
#endif
static void caterr(char *);
static int readExports(ModulePtr);
static void terminate(void);
static void *findMain(void);
void *dlopen(const char *path, int mode)
{
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++;
snprintf (errbuf, sizeof(errbuf), "calloc: %s", strerror(errno));
return NULL;
}
if ((mp->name = strdup(path)) == NULL) {
errvalid++;
snprintf (errbuf, sizeof(errbuf), "strdup: %s", 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++;
snprintf (errbuf, sizeof(errbuf),
"dlopen: %s: ", path);
/*
* 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)
strlcpy(errbuf,
strerror(errno),
sizeof(errbuf));
else {
char **p;
for (p = tmp; *p; p++)
caterr(*p);
}
} else
strlcat(errbuf,
strerror(errno),
sizeof(errbuf));
return NULL;
}
mp->refCnt = 1;
mp->next = modList;
modList = mp;
if (loadbind(0, mainModule, mp->entry) == -1) {
dlclose(mp);
errvalid++;
snprintf (errbuf, sizeof(errbuf),
"loadbind: %s", strerror(errno));
return NULL;
}
/*
* If the user wants global binding, loadbind against all other
* loaded modules.
*/
if (mode & RTLD_GLOBAL) {
ModulePtr mp1;
for (mp1 = mp->next; mp1; mp1 = mp1->next)
if (loadbind(0, mp1->entry, mp->entry) == -1) {
dlclose(mp);
errvalid++;
snprintf (errbuf, sizeof(errbuf),
"loadbind: %s",
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)
{
char *p = s;
while (*p >= '0' && *p <= '9')
p++;
switch(atoi(s)) {
case L_ERROR_TOOMANY:
strlcat(errbuf, "to many errors", sizeof(errbuf));
break;
case L_ERROR_NOLIB:
strlcat(errbuf, "can't load library", sizeof(errbuf));
strlcat(errbuf, p, sizeof(errbuf));
break;
case L_ERROR_UNDEF:
strlcat(errbuf, "can't find symbol", sizeof(errbuf));
strlcat(errbuf, p, sizeof(errbuf));
break;
case L_ERROR_RLDBAD:
strlcat(errbuf, "bad RLD", sizeof(errbuf));
strlcat(errbuf, p, sizeof(errbuf));
break;
case L_ERROR_FORMAT:
strlcat(errbuf, "bad exec format in", sizeof(errbuf));
strlcat(errbuf, p, sizeof(errbuf));
break;
case L_ERROR_ERRNO:
strlcat(errbuf, strerror(atoi(++p)), sizeof(errbuf));
break;
default:
strlcat(errbuf, s, sizeof(errbuf));
break;
}
}
void *dlsym(void *handle, const char *symbol)
{
ModulePtr mp = (ModulePtr)handle;
ExportPtr ep;
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++;
snprintf (errbuf, sizeof(errbuf),
"dlsym: undefined symbol %s", symbol);
return NULL;
}
char *dlerror(void)
{
if (errvalid) {
errvalid = 0;
return errbuf;
}
return NULL;
}
int dlclose(void *handle)
{
ModulePtr mp = (ModulePtr)handle;
int result;
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++;
snprintf (errbuf, sizeof(errbuf),
"%s", strerror(errno));
}
if (mp->exports) {
ExportPtr ep;
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;
if ((ldp = ldopen(mp->name, ldp)) == NULL) {
struct ld_info *lp;
char *buf;
int size = 4*1024;
if (errno != ENOENT) {
errvalid++;
snprintf(errbuf, sizeof(errbuf),
"readExports: %s",
strerror(errno));
return -1;
}
/*
* 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++;
snprintf(errbuf, sizeof(errbuf),
"readExports: %s",
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++;
snprintf(errbuf, sizeof(errbuf),
"readExports: %s",
strerror(errno));
return -1;
}
}
if (i == -1) {
errvalid++;
snprintf(errbuf, sizeof(errbuf),
"readExports: %s",
strerror(errno));
free(buf);
return -1;
}
/*
* Traverse the list of loaded modules. The entry point
* returned by load() does actually point to the data
* segment origin.
*/
lp = (struct ld_info *)buf;
while (lp) {
if (lp->ldinfo_dataorg == mp->entry) {
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++;
snprintf (errbuf, sizeof(errbuf),
"readExports: %s", strerror(errno));
return -1;
}
}
if (TYPE(ldp) != U802TOCMAGIC) {
errvalid++;
snprintf(errbuf, sizeof(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++;
snprintf(errbuf, sizeof(errbuf),
"readExports: cannot read data section header");
while(ldclose(ldp) == FAILURE)
;
return -1;
}
if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {
errvalid++;
snprintf(errbuf, sizeof(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++;
snprintf (errbuf, sizeof(errbuf),
"readExports: %s", strerror(errno));
while(ldclose(ldp) == FAILURE)
;
return -1;
}
if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {
errvalid++;
snprintf(errbuf, sizeof(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++;
snprintf(errbuf, sizeof(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++;
snprintf (errbuf, sizeof(errbuf),
"readExports: %s", strerror(errno));
free(ldbuf);
while(ldclose(ldp) == FAILURE)
;
return -1;
}
/*
* Fill in the export table. All entries are relative to
* the entry point we got from load.
*/
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.
*/
strlcpy (tmpsym, ls->l_name,
SYMNMLEN + 1);
symname = tmpsym;
}
ep->name = strdup(symname);
ep->addr = (void *)((unsigned long)mp->entry +
ls->l_value - shdata.s_vaddr);
ep++;
}
free(ldbuf);
while(ldclose(ldp) == FAILURE)
;
return 0;
}
/*
* Find the main modules entry point. 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++;
snprintf (errbuf, sizeof(errbuf),
"findMail: %s", 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++;
snprintf (errbuf, sizeof(errbuf),
"findMail: %s", strerror(errno));
return NULL;
}
}
if (i == -1) {
errvalid++;
snprintf (errbuf, sizeof(errbuf),
"findMail: %s", strerror(errno));
free(buf);
return NULL;
}
/*
* The first entry is the main module. The entry point
* returned by load() does actually point to the data
* segment origin.
*/
lp = (struct ld_info *)buf;
ret = lp->ldinfo_dataorg;
free(buf);
return ret;
}

View File

@@ -1,49 +0,0 @@
/*
* See README.dlfcn for license
*/
/*
* @(#)dlfcn.h 1.4 revision of 95/04/25 09:36:52
* This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
* 30159 Hannover, Germany
*/
#ifndef __dlfcn_h__
#define __dlfcn_h__
#ifdef __cplusplus
extern "C" {
#endif
/*
* Mode flags for the dlopen routine.
*/
#define RTLD_LAZY 1 /* lazy function call binding */
#define RTLD_NOW 2 /* immediate function call binding */
#define RTLD_GLOBAL 0x100 /* allow symbols to be global */
/*
* To be able to initialize, 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);
};
#if __STDC__ || defined(_IBMR2)
void *dlopen(const char *path, int mode);
void *dlsym(void *handle, const char *symbol);
char *dlerror(void);
int dlclose(void *handle);
#else
void *dlopen();
void *dlsym();
char *dlerror();
int dlclose();
#endif
#ifdef __cplusplus
}
#endif
#endif /* __dlfcn_h__ */