diff options
Diffstat (limited to 'src/lib/libdll')
-rw-r--r-- | src/lib/libdll/Makefile | 17 | ||||
-rw-r--r-- | src/lib/libdll/Mamfile | 319 | ||||
-rw-r--r-- | src/lib/libdll/RELEASE | 52 | ||||
-rw-r--r-- | src/lib/libdll/dlfcn.c | 536 | ||||
-rw-r--r-- | src/lib/libdll/dll_lib.c | 183 | ||||
-rw-r--r-- | src/lib/libdll/dllcheck.c | 85 | ||||
-rw-r--r-- | src/lib/libdll/dllerror.c | 52 | ||||
-rw-r--r-- | src/lib/libdll/dllfind.c | 46 | ||||
-rw-r--r-- | src/lib/libdll/dlllib.h | 34 | ||||
-rw-r--r-- | src/lib/libdll/dlllook.c | 46 | ||||
-rw-r--r-- | src/lib/libdll/dllnext.c | 223 | ||||
-rw-r--r-- | src/lib/libdll/dllopen.c | 93 | ||||
-rw-r--r-- | src/lib/libdll/dllplug.c | 126 | ||||
-rw-r--r-- | src/lib/libdll/dllscan.c | 525 | ||||
-rw-r--r-- | src/lib/libdll/features/dll | 263 |
15 files changed, 2600 insertions, 0 deletions
diff --git a/src/lib/libdll/Makefile b/src/lib/libdll/Makefile new file mode 100644 index 0000000..1fdde57 --- /dev/null +++ b/src/lib/libdll/Makefile @@ -0,0 +1,17 @@ +:PACKAGE: ast + +LICENSE = since=1997,author=gsf + +CCFLAGS = $(CC.OPTIMIZE) $(CC.DLL) + +dll 1.0 :LIBRARY: dlfcn.c dllopen.c dllfind.c dllplug.c dll_lib.c \ + dllnext.c dlllook.c dllscan.c dllcheck.c dllerror.c \ + -ldl -ldld + +win32.i386-64 :NOOPTIMIZE: dllscan.c + +$(INCLUDEDIR) :INSTALLPROTO: dlldefs.h + +dlldefs.h :COPY: FEATURE/dll + +:: RELEASE diff --git a/src/lib/libdll/Mamfile b/src/lib/libdll/Mamfile new file mode 100644 index 0000000..198ac1e --- /dev/null +++ b/src/lib/libdll/Mamfile @@ -0,0 +1,319 @@ +info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-02-29 +setv INSTALLROOT ../../.. +setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast +setv PACKAGE_ast_LIB ${INSTALLROOT}/lib +setv PACKAGEROOT ../../../../.. +setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS} +setv ARFLAGS rc +setv AS as +setv ASFLAGS +setv CC cc +setv mam_cc_FLAGS ${mam_cc_DLL} +setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?} +setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??} +setv COTEMP $$ +setv CPIO cpio +setv CPIOFLAGS +setv CPP "${CC} -E" +setv F77 f77 +setv HOSTCC ${CC} +setv IGNORE +setv LD ld +setv LDFLAGS +setv LEX lex +setv LEXFLAGS +setv LPR lpr +setv LPRFLAGS +setv M4FLAGS +setv NMAKE nmake +setv NMAKEFLAGS +setv PR pr +setv PRFLAGS +setv SHELL /bin/sh +setv SILENT +setv TAR tar +setv YACC yacc +setv YACCFLAGS -d +make ${PACKAGEROOT}/lib/package/ast.lic +done ${PACKAGEROOT}/lib/package/ast.lic +make install +make dll +make libdll.a archive +make dll.req +exec - set - +exec - echo 'int main(){return 0;}' > 1.${COTEMP}.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -c 1.${COTEMP}.c && +exec - x=`${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l'*' 2>&1 | sed -e 's/[][()+@?]/#/g' || :` && +exec - { +exec - case "" in +exec - *?) echo " " ;; +exec - esac +exec - for i in dll dl dld ast +exec - do case $i in +exec - "dll"|dll) +exec - ;; +exec - *) if test -f ${INSTALLROOT}/lib/lib/$i +exec - then y=`cat ${INSTALLROOT}/lib/lib/$i` +exec - case $y in +exec - *-?*) echo "" $y ;; +exec - esac +exec - continue +exec - elif test ! -f ${INSTALLROOT}/lib/lib$i.a +exec - then case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -L${INSTALLROOT}/lib ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in +exec - *$x*) case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in +exec - *$x*) continue ;; +exec - esac +exec - ;; +exec - esac +exec - fi +exec - ;; +exec - esac +exec - echo " -l$i" +exec - done +exec - } > dll.req +exec - rm -f 1.${COTEMP}.* +done dll.req generated +make dlfcn.o +make dlfcn.c +make dll.h implicit +done dll.h dontcare virtual +make xcoff.h implicit +done xcoff.h dontcare virtual +make dl.h implicit +done dl.h dontcare virtual +make ${PACKAGE_ast_INCLUDE}/error.h implicit +make ${PACKAGE_ast_INCLUDE}/option.h implicit +make ${PACKAGE_ast_INCLUDE}/ast.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare +make ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare +make ${PACKAGE_ast_INCLUDE}/endian.h implicit +make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare +done ${PACKAGE_ast_INCLUDE}/endian.h dontcare +done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare +make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +make ${PACKAGE_ast_INCLUDE}/regex.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit +make ${PACKAGE_ast_INCLUDE}/wctype.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit +prev ${PACKAGE_ast_INCLUDE}/endian.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare +done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare +make ${PACKAGE_ast_INCLUDE}/stdio.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit +make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit +done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare +done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare +prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +make ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +make ${INSTALLROOT}/include/prototyped.h implicit +done ${INSTALLROOT}/include/prototyped.h dontcare +done ${PACKAGE_ast_INCLUDE}/prototyped.h dontcare +done ${PACKAGE_ast_INCLUDE}/regex.h dontcare +make ${PACKAGE_ast_INCLUDE}/getopt.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare +make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare +make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare +done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit +prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit +prev ${PACKAGE_ast_INCLUDE}/endian.h implicit +prev ${PACKAGE_ast_INCLUDE}/endian.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare +make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare +done ${PACKAGE_ast_INCLUDE}/vmalloc.h dontcare +make ${PACKAGE_ast_INCLUDE}/sfio.h implicit +prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/ast.h dontcare +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/option.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/error.h +make dlldefs.h implicit +make FEATURE/dll +meta FEATURE/dll features/%>FEATURE/% features/dll dll +make features/dll +done features/dll +bind -ldl dontcare +bind -last +exec - iffe -v -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdl} ${mam_libast} : run features/dll +done FEATURE/dll generated +exec - cmp 2>/dev/null -s FEATURE/dll dlldefs.h || { rm -f dlldefs.h; silent test -d . || mkdir .; cp FEATURE/dll dlldefs.h; } +done dlldefs.h generated +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dlfcn.c +meta dlfcn.o %.c>%.o dlfcn.c dlfcn +prev dlfcn.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dlfcn.c +done dlfcn.o generated +make dllopen.o +make dllopen.c +make dlllib.h implicit +prev ${PACKAGE_ast_INCLUDE}/error.h implicit +prev dlldefs.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dlllib.h +done dllopen.c +meta dllopen.o %.c>%.o dllopen.c dllopen +prev dllopen.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllopen.c +done dllopen.o generated +make dllfind.o +make dllfind.c +prev ${PACKAGE_ast_INCLUDE}/error.h implicit +prev dlldefs.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dllfind.c +meta dllfind.o %.c>%.o dllfind.c dllfind +prev dllfind.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllfind.c +done dllfind.o generated +make dllplug.o +make dllplug.c +prev dlllib.h implicit +done dllplug.c +meta dllplug.o %.c>%.o dllplug.c dllplug +prev dllplug.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllplug.c +done dllplug.o generated +make dll_lib.o +make dll_lib.c +prev dlllib.h implicit +done dll_lib.c +meta dll_lib.o %.c>%.o dll_lib.c dll_lib +prev dll_lib.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dll_lib.c +done dll_lib.o generated +make dllnext.o +make dllnext.c +make rld_interface.h implicit +done rld_interface.h dontcare virtual +prev dlldefs.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dllnext.c +meta dllnext.o %.c>%.o dllnext.c dllnext +prev dllnext.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllnext.c +done dllnext.o generated +make dlllook.o +make dlllook.c +prev dlldefs.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dlllook.c +meta dlllook.o %.c>%.o dlllook.c dlllook +prev dlllook.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dlllook.c +done dlllook.o generated +make dllscan.o +make dllscan.c +prev dlldefs.h implicit +prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit +make ${PACKAGE_ast_INCLUDE}/fts.h implicit +make ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit +done ${PACKAGE_ast_INCLUDE}/ast_mode.h dontcare +prev ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit +done ${PACKAGE_ast_INCLUDE}/fts.h +prev ${PACKAGE_ast_INCLUDE}/error.h implicit +prev ${PACKAGE_ast_INCLUDE}/endian.h implicit +make ${PACKAGE_ast_INCLUDE}/cdt.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit +prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit +done ${PACKAGE_ast_INCLUDE}/cdt.h +prev ${PACKAGE_ast_INCLUDE}/ast.h implicit +done dllscan.c +meta dllscan.o %.c>%.o dllscan.c dllscan +prev dllscan.c +exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllscan.c +done dllscan.o generated +make dllcheck.o +make dllcheck.c +prev dlllib.h implicit +done dllcheck.c +meta dllcheck.o %.c>%.o dllcheck.c dllcheck +prev dllcheck.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllcheck.c +done dllcheck.o generated +make dllerror.o +make dllerror.c +prev dlllib.h implicit +done dllerror.c +meta dllerror.o %.c>%.o dllerror.c dllerror +prev dllerror.c +exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllerror.c +done dllerror.o generated +exec - ${AR} rc libdll.a dlfcn.o dllopen.o dllfind.o dllplug.o dll_lib.o dllnext.o dlllook.o dllscan.o dllcheck.o dllerror.o +exec - (ranlib libdll.a) >/dev/null 2>&1 || true +done libdll.a generated +done dll virtual +prev libdll.a archive +make ${INSTALLROOT}/lib +exec - if silent test ! -d ${INSTALLROOT}/lib +exec - then mkdir -p ${INSTALLROOT}/lib +exec - fi +done ${INSTALLROOT}/lib generated +make ${INSTALLROOT}/lib/libdll.a archive +prev ${INSTALLROOT}/lib +prev libdll.a archive +exec - test '' = 'libdll.a' || ${STDCMP} 2>/dev/null -s libdll.a ${INSTALLROOT}/lib/libdll.a || { ${STDMV} ${INSTALLROOT}/lib/libdll.a ${INSTALLROOT}/lib/libdll.a.old 2>/dev/null || true; ${STDCP} libdll.a ${INSTALLROOT}/lib/libdll.a ;} +exec - (ranlib ${INSTALLROOT}/lib/libdll.a) >/dev/null 2>&1 || true +done ${INSTALLROOT}/lib/libdll.a generated +make ${INSTALLROOT}/lib/lib +exec - if silent test ! -d ${INSTALLROOT}/lib/lib +exec - then mkdir -p ${INSTALLROOT}/lib/lib +exec - fi +done ${INSTALLROOT}/lib/lib generated +make ${INSTALLROOT}/lib/lib/dll +prev ${INSTALLROOT}/lib/lib +prev dll.req +exec - test '' = 'dll.req' || ${STDCMP} 2>/dev/null -s dll.req ${INSTALLROOT}/lib/lib/dll || { ${STDMV} ${INSTALLROOT}/lib/lib/dll ${INSTALLROOT}/lib/lib/dll.old 2>/dev/null || true; ${STDCP} dll.req ${INSTALLROOT}/lib/lib/dll ;} +done ${INSTALLROOT}/lib/lib/dll generated +make ${PACKAGE_ast_INCLUDE} +exec - if silent test ! -d ${PACKAGE_ast_INCLUDE} +exec - then mkdir -p ${PACKAGE_ast_INCLUDE} +exec - fi +done ${PACKAGE_ast_INCLUDE} generated +make ${PACKAGE_ast_INCLUDE}/dlldefs.h +prev ${PACKAGE_ast_INCLUDE} +prev dlldefs.h +exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1997,author=gsf' dlldefs.h > 1.${COTEMP}.x +exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/dlldefs.h 1.${COTEMP}.x +exec - then rm -f 1.${COTEMP}.x +exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/dlldefs.h +exec - fi +done ${PACKAGE_ast_INCLUDE}/dlldefs.h generated +done install virtual +make test +done test dontcare virtual diff --git a/src/lib/libdll/RELEASE b/src/lib/libdll/RELEASE new file mode 100644 index 0000000..516c866 --- /dev/null +++ b/src/lib/libdll/RELEASE @@ -0,0 +1,52 @@ +11-10-11 dll_lib.c: add { dllnames() dll_lib() } +10-10-20 dllscan.c: version arg "-" => 0 +10-10-19 dllplug.c: fix bug that wiped out dlopen() error message +10-10-19 dllplug.c: un-localize lookup names (happens with cut and paste) +10-10-19 dllscan.c: still no code for implicit libs missed by dlopen() +10-08-02 dllplug.c: fix local path dllcheck() call +10-05-28 dllplug.c: add dllplugin() with dllcheck() version check +10-05-28 dllcheck.c: add dllcheck() to do plugin_version() checks +10-05-28 dllerror.c: add dllerror(int retain) for dll*() and dl*() messages +09-11-17 dllscan.c: handle name[-.]version in dlsopen() +09-04-15 dllopen.c: add, use dllopen() internally to wrap dlopen() +08-05-12 dllscan.c: LIBSUFFIX==.dylib => default plugin version match 0.0 +06-10-11 dllscan.c: check sfstruse() return values -- doh +06-01-25 dllplug.c: add errorf() library message for dlopen() error +05-02-14 dllscan.c: "" || "-" => NiL +04-10-01 dllfind.c: drop ksh "builtin" workaround + dllscan.c: directory prefix in name limits search to dir and siblings +04-07-22 dllscan.c: access() => eaccess() +04-01-30 dllfind.c: dllplug(error_info.id) then dllplug(0) +04-01-28 dllscan.c: update for new plugin scheme: lib/foo/bar.xxx + dllplug.c: add dllplug() for plugin dllfind() +03-03-12 dllfind.c: dlopen() with RTLD_GLOBAL|RTLD_PARENT defaults +03-02-11 dllscan.c: change LIBPATH to <dir>[:<env>[:<pat>]][,...] +03-01-08 dllscan.c: hack version logic again -- is consistency rocket science? +03-01-07 dlfcn.c: fix darwin.ppc dlopen/dlsym/dlclose +02-11-18 dllfind.c: add path,size args (with backwards compatibility checks) +02-11-15 dllfind.c: check for ./path if '.' in path but no '/' +02-08-30 dllfind.c: fix a bug that returned uninitialized value on not found +02-08-28 dllscan.c: handle and display bin as a sibling dir +02-07-31 dllscan.c: add dllsopen,dllsread,dllsclose + dllfind.c: use dllsopen,dllsread,dllsclose +02-07-26 dllfind.c: add dllinfo() +02-06-27 dllnext.c: define _GNU_SOURCE to enable RTLD_NEXT +02-03-17 dllfind.c: fix dll prefix search (for cygwin) +02-01-11 features/dll: include <dlfcn.h> only if _hdr_dlfcn&&_lib_dlopen +01-10-31 dlfcn.c: change hp.pa dlopen() prototype (<dlfcn.h> but no -ldl!) +01-09-25 dllfind: add LIBSUFFIX +01-07-17 dllfind: do at least one dlopen() to prime dlerror() +01-05-29 dlopen: fix dlopen(0,0) for HP +01-04-20 dllfind: use getconf HOSTTYPE LIBPATH LIBSUFFIX +01-02-14 features/dll: fix unbalanced ' quote and ancient hostinfo reference +00-01-26 dlllook: add -- dlsym() with `_' weak prefix fallback +99-04-01 features/dll: drop <stdio.h> -- iffe protos printf +99-03-19 static=1 for all but win32.* +98-06-01 dllfind: fix version search +98-03-11 features/dll: probe for _DLL_RLD_SYM +98-03-01 dllnext: fix to work! +98-01-23 -ldl test moved to lib0ast +98-01-11 update for astconf("LIBPATH") + add dllnext(flags) to uncover next layer + dllfind() and dllnext() in separate files (for 3d) +97-10-11 move from libast so libast can link static diff --git a/src/lib/libdll/dlfcn.c b/src/lib/libdll/dlfcn.c new file mode 100644 index 0000000..810be1b --- /dev/null +++ b/src/lib/libdll/dlfcn.c @@ -0,0 +1,536 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * provide dlopen/dlsym/dlerror interface + * + * David Korn + * Glenn Fowler + * AT&T Research + */ + +static const char id[] = "\n@(#)$Id: dll library (AT&T Research) 2010-10-20 $\0\n"; + +#include <ast.h> +#include <dlldefs.h> +#include <error.h> + +#define T(x) ERROR_dictionary(x) + +#if _BLD_dll && defined(__EXPORT__) +#define extern __EXPORT__ +#endif + +#if _hdr_dlfcn && _lib_dlopen + + /* + * standard + */ + +# include <dlfcn.h> + +#else +#if _hdr_dl + + /* + * HP-UX + */ + +# include <dl.h> +# ifndef BIND_FIRST +# define BIND_FIRST 0x4 +# endif +# ifndef BIND_NOSTART +# define BIND_NOSTART 0x10 +# endif + + static shl_t all; + static int err; + + extern void* dlopen(const char* path, int mode) + { + void* dll; + + if (!path) + return (void*)&all; + if (mode) + mode = (BIND_IMMEDIATE|BIND_FIRST|BIND_NOSTART); + if (!(dll = (void*)shl_load(path, mode, 0L))) + err = errno; + return dll; + } + + extern int dlclose(void* dll) + { + return 0; + } + + extern void* dlsym(void* dll, const char* name) + { + shl_t handle; + long addr; + + handle = dll == (void*)&all ? (shl_t)0 : (shl_t)dll; + if (shl_findsym(&handle, name, TYPE_UNDEFINED, &addr)) + { + err = errno; + return 0; + } + return (void*)addr; + } + + extern char* dlerror(void) + { + char* msg; + + if (!err) + return 0; + msg = fmterror(err); + err = 0; + return msg; + } + +#else +#if _sys_ldr && _lib_loadbind + + /* + * rs6000 + */ + +# include <sys/ldr.h> +# include <xcoff.h> + + /* xcoff module header */ + struct hdr + { + struct filehdr f; + struct aouthdr a; + struct scnhdr s[1]; + }; + + static struct ld_info* ld_info; + static unsigned int ld_info_size = 1024; + static void* last_module; + static int err; + + extern void* dlopen(const char* path, int mode) + { + void* dll; + + if (!(dll = (void*)load((char*)path, mode, getenv("LIBPATH")))) + err = errno; + return dll; + } + + extern int dlclose(void* dll) + { + return 0; + } + + static int getquery(void) + { + if (!ld_info) + ld_info = malloc(ld_info_size); + for (;;) + { + if (!ld_info) + return 1; + if (!loadquery(L_GETINFO, ld_info, ld_info_size)) + return 0; + if (errno != ENOMEM) + return 1; + ld_info = realloc(ld_info, ld_info_size *= 2); + } + } + + /* find the loaded module whose data area contains the + * address passed in. Remember that procedure pointers + * are implemented as pointers to descriptors in the + * data area of the module defining the procedure + */ + static struct ld_info* getinfo(void* module) + { + struct ld_info* info = ld_info; + register int n = 1; + + if (!ld_info || module != last_module) + { + last_module = module; + if (getquery()) + return 0; + info = ld_info; + } + while (n) + { + if ((char*)(info->ldinfo_dataorg) <= (char*)module && + (char*)module <= ((char*)(info->ldinfo_dataorg) + + (unsigned)(info->ldinfo_datasize))) + return info; + if (n=info->ldinfo_next) + info = (void*)((char*)info + n); + } + return 0; + } + + static char* getloc(struct hdr* hdr, char* data, char* name) + { + struct ldhdr* ldhdr; + struct ldsym* ldsym; + ulong datareloc; + ulong textreloc; + int i; + + /* data is relocated by the difference between + * its virtual origin and where it was + * actually placed + */ + /*N.B. o_sndata etc. are one based */ + datareloc = (ulong)data - hdr->s[hdr->a.o_sndata-1].s_vaddr; + /*hdr is address of header, not text, so add text s_scnptr */ + textreloc = (ulong)hdr + hdr->s[hdr->a.o_sntext-1].s_scnptr + - hdr->s[hdr->a.o_sntext-1].s_vaddr; + ldhdr = (void*)((char*)hdr+ hdr->s[hdr->a.o_snloader-1].s_scnptr); + ldsym = (void*) (ldhdr+1); + /* search the exports symbols */ + for(i=0; i < ldhdr->l_nsyms;ldsym++,i++) + { + char *symname,symbuf[9]; + char *loc; + /* the symbol name representation is a nuisance since + * 8 character names appear in l_name but may + * not be null terminated. This code works around + * that by brute force + */ + if (ldsym->l_zeroes) + { + symname = symbuf; + memcpy(symbuf,ldsym->l_name,8); + symbuf[8] = 0; + } + else + symname = (void*)(ldsym->l_offset + (ulong)ldhdr + ldhdr->l_stoff); + if (strcmp(symname,name)) + continue; + loc = (char*)ldsym->l_value; + if ((ldsym->l_scnum==hdr->a.o_sndata) || + (ldsym->l_scnum==hdr->a.o_snbss)) + loc += datareloc; + else if (ldsym->l_scnum==hdr->a.o_sntext) + loc += textreloc; + return loc; + } + return 0; + } + + extern void* dlsym(void* handle, const char* name) + { + void* addr; + struct ld_info* info; + + if (!(info = getinfo(handle)) || !(addr = getloc(info->ldinfo_textorg,info->ldinfo_dataorg,(char*)name))) + { + err = errno; + return 0; + } + return addr; + } + + extern char* dlerror(void) + { + char* msg; + + if (!err) + return 0; + msg = fmterror(err); + err = 0; + return msg; + } + +#else +#if _hdr_dll && _lib_dllload + + /* + * MVS + */ + +# include <dll.h> + + static int err; + + extern void* dlopen(const char* path, int mode) + { + void* dll; + + NoP(mode); + if (!(dll = (void*)dllload(path))) + err = errno; + return dll; + } + + extern int dlclose(void* dll) + { + return 0; + } + + extern void* dlsym(void* handle, const char* name) + { + void* addr; + + if (!(addr = (void*)dllqueryfn(handle, (char*)name))) + err = errno; + return addr; + } + + extern char* dlerror(void) + { + char* msg; + + if (!err) + return 0; + msg = fmterror(err); + err = 0; + return msg; + } + +#else +#if _hdr_mach_o_dyld + + /* + * mac[h] + */ + +# include <mach-o/dyld.h> + + typedef const struct mach_header* NSImage; + + typedef struct Dll_s + { + unsigned long magic; + NSImage image; + NSModule module; + char path[1]; + } Dll_t; + + #define DL_MAGIC 0x04190c04 + #define DL_NEXT ((Dll_t*)RTLD_NEXT) + + static const char* dlmessage = "no error"; + + static const char e_cover[] = T("cannot access covered library"); + static const char e_handle[] = T("invalid handle"); + static const char e_space[] = T("out of space"); + static const char e_static[] = T("image statically linked"); + static const char e_undefined[] = T("undefined symbol"); + + static Dll_t global = { DL_MAGIC }; + + static void undefined(const char* name) + { + } + + static NSModule multiple(NSSymbol sym, NSModule om, NSModule nm) + { + return om; + } + + static void linkedit(NSLinkEditErrors c, int n, const char* f, const char* m) + { + dlmessage = m; + } + + static NSLinkEditErrorHandlers handlers = + { + undefined, multiple, linkedit + }; + + extern void* dlopen(const char* path, int mode) + { + Dll_t* dll; + int i; + NSObjectFileImage image; + + static int init = 0; + + if (!_dyld_present()) + { + dlmessage = e_static; + return 0; + } + if (!init) + { + init = 1; + NSInstallLinkEditErrorHandlers(&handlers); + } + if (!path) + dll = &global; + else if (!(dll = newof(0, Dll_t, 1, strlen(path)))) + { + dlmessage = e_space; + return 0; + } + else + { + switch (NSCreateObjectFileImageFromFile(path, &image)) + { + case NSObjectFileImageSuccess: + dll->module = NSLinkModule(image, path, (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(image); + if (!dll->module) + { + free(dll); + return 0; + } + break; + case NSObjectFileImageInappropriateFile: + dll->image = NSAddImage(path, 0); + if (!dll->image) + { + free(dll); + return 0; + } + break; + default: + free(dll); + return 0; + } + strcpy(dll->path, path); + dll->magic = DL_MAGIC; + } + return (void*)dll; + } + + extern int dlclose(void* handle) + { + Dll_t* dll = (Dll_t*)handle; + + if (!dll || dll == DL_NEXT || dll->magic != DL_MAGIC) + { + dlmessage = e_handle; + return -1; + } + if (dll->module) + NSUnLinkModule(dll->module, 0); + free(dll); + return 0; + } + + static NSSymbol + lookup(Dll_t* dll, const char* name) + { + unsigned long pun; + void* address; + + if (dll == DL_NEXT) + { + if (!_dyld_func_lookup(name, &pun)) + return 0; + address = (NSSymbol)pun; + } + else if (dll->module) + address = NSLookupSymbolInModule(dll->module, name); + else if (dll->image) + { + if (!NSIsSymbolNameDefinedInImage(dll->image, name)) + return 0; + address = NSLookupSymbolInImage(dll->image, name, 0); + } + else + { + if (!NSIsSymbolNameDefined(name)) + return 0; + address = NSLookupAndBindSymbol(name); + } + if (address) + address = NSAddressOfSymbol(address); + return address; + } + + extern void* dlsym(void* handle, const char* name) + { + Dll_t* dll = (Dll_t*)handle; + NSSymbol address; + char buf[1024]; + + if (!dll || dll != DL_NEXT && (dll->magic != DL_MAGIC || !dll->image && !dll->module)) + { + dlmessage = e_handle; + return 0; + } + if (!(address = lookup(dll, name)) && name[0] != '_' && strlen(name) < (sizeof(buf) - 1)) + { + buf[0] = '_'; + strcpy(buf + 1, name); + address = lookup(dll, buf); + } + if (!address) + { + dlmessage = dll == DL_NEXT ? e_cover : e_undefined; + return 0; + } + return (void*)address; + } + + extern char* dlerror(void) + { + char* msg; + + msg = (char*)dlmessage; + dlmessage = 0; + return msg; + } + +#else + /* + * punt + */ + + static int err; + + extern void* dlopen(const char* path, int mode) + { + err = 1; + return 0; + } + + extern int dlclose(void* dll) + { + err = 1; + return 0; + } + + extern void* dlsym(void* handle, const char* name) + { + err = 1; + return 0; + } + + extern char* dlerror(void) + { + if (!err) + return 0; + err = 0; + return "dynamic linking not supported"; + } + +#endif +#endif +#endif +#endif +#endif diff --git a/src/lib/libdll/dll_lib.c b/src/lib/libdll/dll_lib.c new file mode 100644 index 0000000..29e4cd8 --- /dev/null +++ b/src/lib/libdll/dll_lib.c @@ -0,0 +1,183 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include "dlllib.h" + +typedef void* (*Dll_lib_f)(const char*, void*, const char*); + +typedef struct Dll_lib_s +{ + struct Dll_lib_s* next; + Dll_lib_f libf; + char* path; + char base[1]; +} Dll_lib_t; + +/* + * split <name,base,type,opts> from name into names + */ + +Dllnames_t* +dllnames(const char* id, const char* name, Dllnames_t* names) +{ + char* s; + char* t; + char* b; + char* e; + size_t n; + + n = strlen(id); + if (strneq(name, id, n) && (streq(name + n, "_s") || streq(name + n, "_t"))) + return 0; + if (!names) + { + s = fmtbuf(sizeof(Dllnames_t*) + sizeof(names) - 1); + if (n = (s - (char*)0) % sizeof(names)) + s += sizeof(names) - n; + names = (Dllnames_t*)s; + } + + /* + * determine the base name + */ + + if ((s = strrchr(name, '/')) || (s = strrchr(name, '\\'))) + s++; + else + s = (char*)name; + if (strneq(s, "lib", 3)) + s += 3; + b = names->base = names->data; + e = b + sizeof(names->data) - 1; + t = s; + while (b < e && *t && *t != '.' && *t != '-' && *t != ':') + *b++ = *t++; + *b++ = 0; + + /* + * determine the optional type + */ + + if (t = strrchr(s, ':')) + { + names->name = b; + while (b < e && s < t) + *b++ = *s++; + *b++ = 0; + names->type = b; + while (b < e && *++t) + *b++ = *t; + *b++ = 0; + } + else + { + names->name = (char*)name; + names->type = 0; + } + *(names->path = b) = 0; + names->opts = 0; + names->id = (char*)id; + return names; +} + +/* + * return method pointer for <id,version> in names + */ + +void* +dll_lib(Dllnames_t* names, unsigned long version, Dllerror_f errorf, void* disc) +{ + void* dll; + Dll_lib_t* lib; + Dll_lib_f libf; + int n; + char sym[64]; + + static Dll_lib_t* loaded; + + if (!names) + return 0; + + /* + * check if plugin already loaded + */ + + for (lib = loaded; lib; lib = lib->next) + if (streq(names->base, lib->base)) + { + libf = lib->libf; + goto init; + } + + /* + * load + */ + + if (!(dll = dllplugin(names->id, names->name, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path)) && (streq(names->name, names->base) || !(dll = dllplugin(names->id, names->base, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path)))) + { + if (errorf) + (*errorf)(NiL, disc, 2, "%s: library not found", names->name); + return 0; + } + + /* + * init + */ + + sfsprintf(sym, sizeof(sym), "%s_lib", names->id); + if (!(libf = (Dll_lib_f)dlllook(dll, sym))) + { + if (errorf) + (*errorf)(NiL, disc, 2, "%s: %s: initialization function not found in library", names->path, sym); + return 0; + } + + /* + * add to the loaded list + */ + + if (lib = newof(0, Dll_lib_t, 1, (n = strlen(names->base)) + strlen(names->path) + 1)) + { + lib->libf = libf; + strcpy(lib->base, names->base); + strcpy(lib->path = lib->base + n + 1, names->path); + lib->next = loaded; + loaded = lib; + } + init: + return (*libf)(names->path, disc, names->type); +} + +/* + * return method pointer for <id,name,version> + */ + +void* +dllmeth(const char* id, const char* name, unsigned long version) +{ + Dllnames_t names; + + return dll_lib(dllnames(id, name, &names), version, 0, 0); +} diff --git a/src/lib/libdll/dllcheck.c b/src/lib/libdll/dllcheck.c new file mode 100644 index 0000000..c18f83e --- /dev/null +++ b/src/lib/libdll/dllcheck.c @@ -0,0 +1,85 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include "dlllib.h" + +/* + * return plugin version for dll + * 0 if there is none + * path!=0 enables library level diagnostics + */ + +extern unsigned long +dllversion(void* dll, const char* path) +{ + Dll_plugin_version_f pvf; + + if (pvf = (Dll_plugin_version_f)dlllook(dll, "plugin_version")) + return (*pvf)(); + if (path) + { + state.error = 1; + sfsprintf(state.errorbuf, sizeof(state.errorbuf), "plugin_version() not found"); + errorf("dll", NiL, 1, "%s: %s", path, state.errorbuf); + } + return 0; +} + +/* + * check if dll on path has plugin version >= ver + * 1 returned on success, 0 on failure + * path!=0 enables library level diagnostics + * cur!=0 gets actual version + */ + +extern int +dllcheck(void* dll, const char* path, unsigned long ver, unsigned long* cur) +{ + unsigned long v; + Dll_plugin_version_f pvf; + + state.error = 0; + if (ver || cur) + { + v = dllversion(dll, path); + if (cur) + *cur = v; + } + if (!ver) + return 1; + if (!v) + return 0; + if (v < ver) + { + if (path) + { + state.error = 1; + sfsprintf(state.errorbuf, sizeof(state.errorbuf), "plugin version %lu older than caller %lu", v, ver); + errorf("dll", NiL, 1, "%s: %s", path, state.errorbuf); + } + return 0; + } + return 1; +} diff --git a/src/lib/libdll/dllerror.c b/src/lib/libdll/dllerror.c new file mode 100644 index 0000000..dd0278d --- /dev/null +++ b/src/lib/libdll/dllerror.c @@ -0,0 +1,52 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include "dlllib.h" + +Dllstate_t state; + +/* + * return error message from last failed dl*() call + * retain==0 resets the last dl*() error + */ + +extern char* +dllerror(int retain) +{ + char* s; + + if (state.error) + { + state.error = retain; + return state.errorbuf; + } + s = dlerror(); + if (retain) + { + state.error = retain; + sfsprintf(state.errorbuf, sizeof(state.errorbuf), "%s", s); + } + return s; +} diff --git a/src/lib/libdll/dllfind.c b/src/lib/libdll/dllfind.c new file mode 100644 index 0000000..6446663 --- /dev/null +++ b/src/lib/libdll/dllfind.c @@ -0,0 +1,46 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include <ast.h> +#include <dlldefs.h> +#include <error.h> + +/* + * find and load library name with optional version ver and dlopen() flags + * at least one dlopen() is called to initialize dlerror() + * if path!=0 then library path up to size chars copied to path with trailing 0 + * if name contains a directory prefix then library search is limited to the dir and siblings + */ + +extern void* +dllfind(const char* lib, const char* ver, int flags, char* path, size_t size) +{ + char* id; + void* dll; + + if ((id = error_info.id) && (dll = dllplug(id, lib, ver, flags, path, size))) + return dll; + return dllplug(NiL, lib, ver, flags, path, size); +} diff --git a/src/lib/libdll/dlllib.h b/src/lib/libdll/dlllib.h new file mode 100644 index 0000000..c5fb1ab --- /dev/null +++ b/src/lib/libdll/dlllib.h @@ -0,0 +1,34 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped + +#include <ast.h> +#include <dlldefs.h> +#include <error.h> + +#define state _dll_state + +typedef struct Dllstate_s +{ + int error; + char errorbuf[128]; +} Dllstate_t; + +extern Dllstate_t state; diff --git a/src/lib/libdll/dlllook.c b/src/lib/libdll/dlllook.c new file mode 100644 index 0000000..10928a6 --- /dev/null +++ b/src/lib/libdll/dlllook.c @@ -0,0 +1,46 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include <ast.h> +#include <dlldefs.h> + +/* + * dlsym() with `_' weak fallback + */ + +void* +dlllook(void* dll, const char* name) +{ + register void* addr; + char buf[256]; + + if (!(addr = dlsym(dll, name)) && strlen(name) < (sizeof(buf) - 2)) + { + buf[0] = '_'; + strcpy(buf + 1, name); + addr = dlsym(dll, buf); + } + return addr; +} diff --git a/src/lib/libdll/dllnext.c b/src/lib/libdll/dllnext.c new file mode 100644 index 0000000..9e81c4a --- /dev/null +++ b/src/lib/libdll/dllnext.c @@ -0,0 +1,223 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ 1 +#endif + +#include <ast.h> +#include <dlldefs.h> + +#if _hdr_rld_interface +#include <rld_interface.h> +#endif + +/* + * return a handle for the next layer down, + * i.e., the next layer that has symbols covered + * by the main prog and dll's loaded so far + * + * intentionally light on external lib calls + * so this routine can be used early in process + * startup + */ + +#ifdef _DLL_RLD_SYM + +#define DEBUG 1 + +#if DEBUG + +typedef ssize_t (*Write_f)(int, const void*, size_t); + +#endif + +#undef dllnext + +void* +_dll_next(int flags, _DLL_RLD_SYM_TYPE* here) +{ + register char* vp; + register void* lp; + register int found = 0; + char* s; + char* b; + char* e; + char dummy[256]; +#if DEBUG + Write_f wr = 0; + Write_f xr; + char buf[1024]; +#endif + +#if DEBUG + if (getenv("DLL_DEBUG") && (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME))) + { + do + { + if (strcmp(vp, "MAIN") && (lp = dllopen(vp, flags))) + { + if (xr = (Write_f)dlsym(lp, "write")) + wr = xr; + } + } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME)); + } +#endif + if (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME)) + { + do + { + if (lp = dllopen(strcmp(vp, "MAIN") ? vp : (char*)0, flags)) + { + if (found) + { + b = e = 0; + s = vp; + for (;;) + { + switch (*s++) + { + case 0: + break; + case '/': + b = s; + e = 0; + continue; + case '.': + if (!e) + e = s - 1; + continue; + default: + continue; + } + break; + } + if (b && e) + { + s = dummy; + *s++ = '_'; + *s++ = '_'; + while (b < e) + *s++ = *b++; + b = "_dummy"; + while (*s++ = *b++); + if (dlsym(lp, dummy)) + { + dlclose(lp); + lp = 0; + } + } + if (lp) + { +#if DEBUG + if (wr) + (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: next %s\n", vp)); +#endif + return lp; + } +#if DEBUG + else if (wr) + (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: skip %s\n", vp)); +#endif + } + else if ((_DLL_RLD_SYM_TYPE*)dlsym(lp, _DLL_RLD_SYM_STR) == here) + { +#if DEBUG + if (wr) + (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: this %s\n", vp)); +#endif + found = 1; + } + } + } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME)); + } + return dllnext(flags); +} + +#endif + +#ifndef RTLD_NEXT +#if _dll_DYNAMIC + +#include <link.h> + +extern struct link_dynamic _DYNAMIC; + +#endif +#endif + +void* +dllnext(int flags) +{ + register void* dll; +#ifndef RTLD_NEXT +#if _dll_DYNAMIC + register struct link_map* map; + register char* s; + register char* b; +#endif + register char* ver; + char* path; + + static char next[] = { _DLL_NEXT_PATH }; +#endif + +#ifdef RTLD_NEXT + dll = RTLD_NEXT; +#else + path = next; +#if _dll_DYNAMIC + for (map = _DYNAMIC.ld_un.ld_1->ld_loaded; map; map = map->lm_next) + { + b = 0; + s = map->lm_name; + while (*s) + if (*s++ == '/') + b = s; + if (b && b[0] == 'l' && b[1] == 'i' && b[2] == 'b' && b[3] == 'c' && b[4] == '.') + { + path = map->lm_name; + break; + } + } +#endif + ver = path + strlen(path); + while (!(dll = dllopen(path, flags))) + { + do + { + if (ver <= path) + return 0; + } while (*--ver != '.'); + if (*(ver + 1) <= '0' || *(ver + 1) >= '9') + return 0; + *ver = 0; + } +#endif + return dll; +} diff --git a/src/lib/libdll/dllopen.c b/src/lib/libdll/dllopen.c new file mode 100644 index 0000000..0fac2d0 --- /dev/null +++ b/src/lib/libdll/dllopen.c @@ -0,0 +1,93 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * at&t research + */ + +#include "dlllib.h" + +#if 0 + +/* + * dlopen() wrapper that properly initializes LIBPATH + * with the path of the dll to be opened + * + * 2009-04-15 -- if ld.so re-checked the env this would work ... + */ + +void* +dllopen(const char* name, int mode) +{ + void* dll; + Dllinfo_t* info; + char* olibpath; + char* path; + char* oenv; + char* nenv[2]; + char* dir; + char* base; + int len; + + if (!environ) + { + nenv[0] = nenv[1] = 0; + environ = nenv; + } + info = dllinfo(); + oenv = environ[0]; + olibpath = getenv(info->env); + if (base = strrchr(name, '/')) + { + dir = (char*)name; + len = ++base - dir; + } + else + { + dir = "./"; + len = 2; + base = (char*)name; + } + path = sfprints("%-.*s%s%c%s=%-.*s%s%s", len, dir, base, 0, info->env, len, dir, olibpath ? ":" : "", olibpath ? olibpath : ""); + environ[0] = path + strlen(path) + 1; + state.error = 0; + dll = dlopen(path, mode); + if (environ == nenv) + environ = 0; + else + environ[0] = oenv; + return dll; +} + +#else + +/* + * dlopen() wrapper -- waiting for prestidigitaions + */ + +void* +dllopen(const char* name, int mode) +{ + state.error = 0; + return dlopen(name, mode); +} + +#endif diff --git a/src/lib/libdll/dllplug.c b/src/lib/libdll/dllplug.c new file mode 100644 index 0000000..3854762 --- /dev/null +++ b/src/lib/libdll/dllplug.c @@ -0,0 +1,126 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#include "dlllib.h" + +/* + * find and load lib plugin/module library name with optional version ver and dlopen() flags + * at least one dlopen() is called to initialize dlerror() + * if path!=0 then library path up to size chars copied to path with trailing 0 + * if name contains a directory prefix then library search is limited to the dir and siblings + */ + +extern void* +dllplugin(const char* lib, const char* name, const char* ver, unsigned long rel, unsigned long* cur, int flags, char* path, size_t size) +{ + void* dll; + int err; + int hit; + Dllscan_t* dls; + Dllent_t* dle; + + err = hit = 0; + for (;;) + { + if (dls = dllsopen(lib, name, ver)) + { + while (dle = dllsread(dls)) + { + hit = 1; +#if 0 + again: +#endif + if (dll = dllopen(dle->path, flags|RTLD_GLOBAL|RTLD_PARENT)) + { + if (!dllcheck(dll, dle->path, rel, cur)) + { + err = state.error; + dlclose(dll); + dll = 0; + continue; + } + if (path && size) + strlcpy(path, dle->path, size); + break; + } + else + { +#if 0 + /* + * dlopen() should load implicit libraries + * this code does that + * but it doesn't help on galadriel + */ + + char* s; + char* e; + + if ((s = dllerror(1)) && (e = strchr(s, ':'))) + { + *e = 0; + error(1, "AHA %s implicit", s); + dll = dllplugin(lib, s, 0, 0, 0, flags, path, size); + *e = ':'; + if (dll) + { + error(1, "AHA implicit %s => %s", s, path); + goto again; + } + } +#endif + errorf("dll", NiL, 1, "%s: dlopen failed: %s", dle->path, dllerror(1)); + err = state.error; + } + } + dllsclose(dls); + } + if (hit) + { + if (!dll) + state.error = err; + return dll; + } + if (!lib) + break; + lib = 0; + } + if (dll = dllopen(name, flags)) + { + if (!dllcheck(dll, name, rel, cur)) + { + dlclose(dll); + dll = 0; + } + else if (path && size) + strlcpy(path, name, size); + } + return dll; +} + +extern void* +dllplug(const char* lib, const char* name, const char* ver, int flags, char* path, size_t size) +{ + return dllplugin(lib, name, ver, 0, NiL, flags, path, size); +} diff --git a/src/lib/libdll/dllscan.c b/src/lib/libdll/dllscan.c new file mode 100644 index 0000000..1c8f5a5 --- /dev/null +++ b/src/lib/libdll/dllscan.c @@ -0,0 +1,525 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1997-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + */ + +#define _DLLINFO_PRIVATE_ \ + char* sib[3]; \ + char sibbuf[64]; \ + char envbuf[64]; + +#define _DLLSCAN_PRIVATE_ \ + Dllent_t entry; \ + Uniq_t* uniq; \ + int flags; \ + Vmalloc_t* vm; \ + Dt_t* dict; \ + Dtdisc_t disc; \ + FTS* fts; \ + FTSENT* ent; \ + Sfio_t* tmp; \ + char** sb; \ + char** sp; \ + char* pb; \ + char* pp; \ + char* pe; \ + int off; \ + int prelen; \ + int suflen; \ + char** lib; \ + char nam[64]; \ + char pat[64]; \ + char buf[64]; + +#define DLL_MATCH_DONE 0x8000 +#define DLL_MATCH_NAME 0x4000 +#define DLL_MATCH_VERSION 0x2000 + +#include <ast.h> +#include <cdt.h> +#include <ctype.h> +#include <error.h> +#include <fts.h> +#include <vmalloc.h> + +typedef struct Uniq_s +{ + Dtlink_t link; + char name[1]; +} Uniq_t; + +#include <dlldefs.h> + +static char bin[] = "bin"; +static char lib[] = "lib"; + +/* + * we need a sibling dir in PATH to search for dlls + * the confstr LIBPATH provides the local info + * + * <sibling-dir>[:<env-var>[:<host-pattern>]][,...] + * + * if <host-pattern> is present then it must match confstr HOSTTYPE + */ + +Dllinfo_t* +dllinfo(void) +{ + register char* s; + register char* h; + char* d; + char* v; + char* p; + int dn; + int vn; + int pn; + char pat[256]; + + static Dllinfo_t info; + + if (!info.sibling) + { + info.sibling = info.sib; + if (*(s = astconf("LIBPATH", NiL, NiL))) + { + while (*s == ':' || *s == ',') + s++; + if (*s) + { + h = 0; + for (;;) + { + for (d = s; *s && *s != ':' && *s != ','; s++); + if (!(dn = s - d)) + d = 0; + if (*s == ':') + { + for (v = ++s; *s && *s != ':' && *s != ','; s++); + if (!(vn = s - v)) + v = 0; + if (*s == ':') + { + for (p = ++s; *s && *s != ':' && *s != ','; s++); + if (!(pn = s - p)) + p = 0; + } + else + p = 0; + } + else + { + v = 0; + p = 0; + } + while (*s && *s++ != ','); + if (!*s || !p || !h && !*(h = astconf("HOSTTYPE", NiL, NiL))) + break; + if (pn >= sizeof(pat)) + pn = sizeof(pat) - 1; + memcpy(pat, p, pn); + pat[pn] = 0; + if (strmatch(h, pat)) + break; + } + if (d && dn < sizeof(info.sibbuf)) + { + memcpy(info.sibbuf, d, dn); + info.sibling[0] = info.sibbuf; + } + if (v && vn < sizeof(info.envbuf)) + { + memcpy(info.envbuf, v, vn); + info.env = info.envbuf; + } + } + } + if (!info.sibling[0] || streq(info.sibling[0], bin)) + info.sibling[0] = bin; + if (!streq(info.sibling[0], lib)) + info.sibling[1] = lib; + if (!info.env) + info.env = "LD_LIBRARY_PATH"; + info.prefix = astconf("LIBPREFIX", NiL, NiL); + info.suffix = astconf("LIBSUFFIX", NiL, NiL); + if (streq(info.suffix, ".dll")) + info.flags |= DLL_INFO_PREVER; + else + info.flags |= DLL_INFO_DOTVER; + } + return &info; +} + +/* + * fts version sort order + * higher versions appear first + */ + +static int +vercmp(FTSENT* const* ap, FTSENT* const* bp) +{ + register unsigned char* a = (unsigned char*)(*ap)->fts_name; + register unsigned char* b = (unsigned char*)(*bp)->fts_name; + register int n; + register int m; + char* e; + + for (;;) + { + if (isdigit(*a) && isdigit(*b)) + { + m = strtol((char*)a, &e, 10); + a = (unsigned char*)e; + n = strtol((char*)b, &e, 10); + b = (unsigned char*)e; + if (n -= m) + return n; + } + if (n = *a - *b) + return n; + if (!*a++) + return *b ? 0 : -1; + if (!*b++) + return 1; + } + /*NOTREACHED*/ +} + +/* + * open a scan stream + */ + +Dllscan_t* +dllsopen(const char* lib, const char* name, const char* version) +{ + register char* s; + register char* t; + Dllscan_t* scan; + Dllinfo_t* info; + Vmalloc_t* vm; + int i; + int j; + int k; + char buf[32]; + + if (!(vm = vmopen(Vmdcheap, Vmlast, 0))) + return 0; + if (lib && *lib && (*lib != '-' || *(lib + 1))) + { + /* + * grab the local part of the library id + */ + + if (s = strrchr(lib, ':')) + lib = (const char*)(s + 1); + i = 2 * sizeof(char**) + strlen(lib) + 5; + } + else + { + lib = 0; + i = 0; + } + if (version && (!*version || *version == '-' && !*(version + 1))) + version = 0; + if (!(scan = vmnewof(vm, 0, Dllscan_t, 1, i)) || !(scan->tmp = sfstropen())) + { + vmclose(vm); + return 0; + } + scan->vm = vm; + info = dllinfo(); + scan->flags = info->flags; + if (lib) + { + scan->lib = (char**)(scan + 1); + s = *scan->lib = (char*)(scan->lib + 2); + sfsprintf(s, i, "lib/%s", lib); + if (!version && streq(info->suffix, ".dylib")) + version = "0.0"; + } + if (!name || !*name || *name == '-' && !*(name + 1)) + { + name = (const char*)"?*"; + scan->flags |= DLL_MATCH_NAME; + } + else if (t = strrchr(name, '/')) + { + if (!(scan->pb = vmnewof(vm, 0, char, t - (char*)name, 2))) + goto bad; + memcpy(scan->pb, name, t - (char*)name); + name = (const char*)(t + 1); + } + if (name) + { + i = strlen(name); + j = strlen(info->prefix); + if (!j || i > j && strneq(name, info->prefix, j)) + { + k = strlen(info->suffix); + if (i > k && streq(name + i - k, info->suffix)) + { + i -= j + k; + if (!(t = vmnewof(vm, 0, char, i, 1))) + goto bad; + memcpy(t, name + j, i); + t[i] = 0; + name = (const char*)t; + } + } + if (!version) + for (t = (char*)name; *t; t++) + if ((*t == '-' || *t == '.' || *t == '?') && isdigit(*(t + 1))) + { + if (*t != '-') + scan->flags |= DLL_MATCH_VERSION; + version = t + 1; + if (!(s = vmnewof(vm, 0, char, t - (char*)name, 1))) + goto bad; + memcpy(s, name, t - (char*)name); + name = (const char*)s; + break; + } + } + if (!version) + { + scan->flags |= DLL_MATCH_VERSION; + sfsprintf(scan->nam, sizeof(scan->nam), "%s%s%s", info->prefix, name, info->suffix); + } + else if (scan->flags & DLL_INFO_PREVER) + { + sfprintf(scan->tmp, "%s%s", info->prefix, name); + for (s = (char*)version; *s; s++) + if (isdigit(*s)) + sfputc(scan->tmp, *s); + sfprintf(scan->tmp, "%s", info->suffix); + if (!(s = sfstruse(scan->tmp))) + goto bad; + sfsprintf(scan->nam, sizeof(scan->nam), "%s", s); + } + else + sfsprintf(scan->nam, sizeof(scan->nam), "%s%s%s.%s", info->prefix, name, info->suffix, version); + if (scan->flags & (DLL_MATCH_NAME|DLL_MATCH_VERSION)) + { + if (scan->flags & DLL_INFO_PREVER) + { + if (!version) + version = "*([0-9_])"; + else + { + t = buf; + for (s = (char*)version; *s; s++) + if (isdigit(*s) && t < &buf[sizeof(buf)-1]) + *t++ = *s; + *t = 0; + version = (const char*)buf; + } + sfsprintf(scan->pat, sizeof(scan->pat), "%s%s%s%s", info->prefix, name, version, info->suffix); + } + else if (version) + sfsprintf(scan->pat, sizeof(scan->pat), "%s%s@(%s([-.])%s%s|%s.%s)", info->prefix, name, strchr(version, '.') ? "@" : "?", version, info->suffix, info->suffix, version); + else + { + version = "*([0-9.])"; + sfsprintf(scan->pat, sizeof(scan->pat), "%s%s@(?([-.])%s%s|%s%s)", info->prefix, name, version, info->suffix, info->suffix, version); + } + } + scan->sp = scan->sb = (scan->lib ? scan->lib : info->sibling); + scan->prelen = strlen(info->prefix); + scan->suflen = strlen(info->suffix); + return scan; + bad: + dllsclose(scan); + return 0; +} + +/* + * close a scan stream + */ + +int +dllsclose(Dllscan_t* scan) +{ + if (!scan) + return -1; + if (scan->fts) + fts_close(scan->fts); + if (scan->dict) + dtclose(scan->dict); + if (scan->tmp) + sfclose(scan->tmp); + if (scan->vm) + vmclose(scan->vm); + return 0; +} + +/* + * return the next scan stream entry + */ + +Dllent_t* +dllsread(register Dllscan_t* scan) +{ + register char* p; + register char* b; + register char* t; + register Uniq_t* u; + register int n; + register int m; + + if (scan->flags & DLL_MATCH_DONE) + return 0; + again: + do + { + while (!scan->ent || !(scan->ent = scan->ent->fts_link)) + { + if (scan->fts) + { + fts_close(scan->fts); + scan->fts = 0; + } + if (!scan->pb) + scan->pb = pathbin(); + else if (!*scan->sp) + { + scan->sp = scan->sb; + if (!*scan->pe++) + return 0; + scan->pb = scan->pe; + } + for (p = scan->pp = scan->pb; *p && *p != ':'; p++) + if (*p == '/') + scan->pp = p; + scan->pe = p; + if (*scan->sp == bin) + scan->off = sfprintf(scan->tmp, "%-.*s", scan->pe - scan->pb, scan->pb); + else + scan->off = sfprintf(scan->tmp, "%-.*s/%s", scan->pp - scan->pb, scan->pb, *scan->sp); + scan->sp++; + if (!(scan->flags & DLL_MATCH_NAME)) + { + sfprintf(scan->tmp, "/%s", scan->nam); + if (!(p = sfstruse(scan->tmp))) + return 0; + if (!eaccess(p, R_OK)) + { + b = scan->nam; + goto found; + } + if (errno != ENOENT) + continue; + } + if (scan->flags & (DLL_MATCH_NAME|DLL_MATCH_VERSION)) + { + sfstrseek(scan->tmp, scan->off, SEEK_SET); + if (!(t = sfstruse(scan->tmp))) + return 0; + if ((scan->fts = fts_open((char**)t, FTS_LOGICAL|FTS_NOPOSTORDER|FTS_ONEPATH, vercmp)) && (scan->ent = fts_read(scan->fts)) && (scan->ent = fts_children(scan->fts, FTS_NOSTAT))) + break; + } + } + } while (!strmatch(scan->ent->fts_name, scan->pat)); + b = scan->ent->fts_name; + sfstrseek(scan->tmp, scan->off, SEEK_SET); + sfprintf(scan->tmp, "/%s", b); + if (!(p = sfstruse(scan->tmp))) + return 0; + found: + b = scan->buf + sfsprintf(scan->buf, sizeof(scan->buf), "%s", b + scan->prelen); + if (!(scan->flags & DLL_INFO_PREVER)) + while (b > scan->buf) + { + if (!isdigit(*(b - 1)) && *(b - 1) != '.') + break; + b--; + } + b -= scan->suflen; + if (b > (scan->buf + 2) && (*(b - 1) == 'g' || *(b - 1) == 'O') && *(b - 2) == '-') + b -= 2; + n = m = 0; + for (t = b; t > scan->buf; t--) + if (isdigit(*(t - 1))) + n = 1; + else if (*(t - 1) != m) + { + if (*(t - 1) == '.' || *(t - 1) == '-' || *(t - 1) == '_') + { + n = 1; + if (m) + { + m = -1; + t--; + break; + } + m = *(t - 1); + } + else + break; + } + if (n) + { + if (isdigit(t[0]) && isdigit(t[1]) && !isdigit(t[2])) + n = (t[0] - '0') * 10 + (t[1] - '0'); + else if (isdigit(t[1]) && isdigit(t[2]) && !isdigit(t[3])) + n = (t[1] - '0') * 10 + (t[2] - '0'); + else + n = 0; + if (n && !(n & (n - 1))) + { + if (!isdigit(t[0])) + t++; + m = *(t += 2); + } + if (m || (scan->flags & DLL_INFO_PREVER)) + b = t; + } + *b = 0; + if (!*(b = scan->buf)) + goto again; + if (scan->uniq) + { + if (!scan->dict) + { + scan->disc.key = offsetof(Uniq_t, name); + scan->disc.size = 0; + scan->disc.link = offsetof(Uniq_t, link); + if (!(scan->dict = dtopen(&scan->disc, Dtset))) + return 0; + dtinsert(scan->dict, scan->uniq); + } + if (dtmatch(scan->dict, b)) + goto again; + if (!(u = vmnewof(scan->vm, 0, Uniq_t, 1, strlen(b)))) + return 0; + strcpy(u->name, b); + dtinsert(scan->dict, u); + } + else if (!(scan->flags & DLL_MATCH_NAME)) + scan->flags |= DLL_MATCH_DONE; + else if (!(scan->uniq = vmnewof(scan->vm, 0, Uniq_t, 1, strlen(b)))) + return 0; + else + strcpy(scan->uniq->name, b); + scan->entry.name = b; + scan->entry.path = p; + return &scan->entry; +} diff --git a/src/lib/libdll/features/dll b/src/lib/libdll/features/dll new file mode 100644 index 0000000..691012f --- /dev/null +++ b/src/lib/libdll/features/dll @@ -0,0 +1,263 @@ +set prototyped +hdr dl,dlfcn,dll,rld_interface,mach-o/dyld +sys ldr +lib dlopen -ldl +lib dllload,loadbind,shl_load -ldl +tst dll_DYNAMIC link{ + #include <sys/types.h> + #include <link.h> + extern struct link_dynamic _DYNAMIC; + int + main() + { + return _DYNAMIC.ld_version; + } +}end +tst run{ + lib= + for d in /shlib /usr/shlib /lib /usr/lib + do if test -d $d + then for s in "*.*" "*[!a]*" + do for b in libc + do for i in $d/$b.$s + do if test -f $i + then lib=$i + fi + done + case $lib in + ?*) break 3 ;; + esac + done + done + fi + done + case $lib in + *.[0-9]*.[0-9]*) + i=`echo $lib | sed 's,\([^0-9]*[0-9]*\).*,\1,'` + if test -f $i + then lib=$i + fi + ;; + esac + # some run time linkers barf with /lib/xxx if + # /usr/lib/xxx is there + case $lib in + /usr*) ;; + *) if test -f /usr$lib + then lib=/usr$lib + fi + ;; + esac + case $lib in + "") lib=/lib/libc.so.1 ;; + esac + case $lib in + /usr/lib/*) + case `package` in + sgi.mips3) + abi=/lib32 + ;; + sgi.mips4) + abi=/lib64 + ;; + *) abi= + ;; + esac + case $abi in + ?*) if test -d $abi + then lib=`echo $lib | sed 's,/usr/lib/,,'` + lib=$abi/$lib + fi + ;; + esac + ;; + esac + echo "#define _DLL_NEXT_PATH \"$lib\"" +}end +tst - output{ + #if defined(__MVS__) && !defined(__SUSV3) + #define __SUSV3 1 + #endif + #if _hdr_dlfcn && _lib_dlopen + #include <dlfcn.h> + #endif + #if _hdr_rld_interface + #include <rld_interface.h> + #endif + int + main() + { + int i; + #if _hdr_rld_interface + void* dll; + static char* local[] = { "__elf_header", "_call_add_gp_range", "_etext" }; + #endif + printf("\n"); + printf("#if defined(__MVS__) && !defined(__SUSV3)\n"); + printf("#define __SUSV3 1\n"); + printf("#endif\n"); + #if _hdr_dlfcn && _lib_dlopen + printf("#include <dlfcn.h>\n"); + #endif + #ifndef RTLD_LAZY + i = 0; + printf("\n"); + printf("#define RTLD_LAZY 1\n"); + #else + i = 1; + #endif + #ifndef RTLD_NOW + if (i) + { + i = 0; + printf("\n"); + } + printf("#define RTLD_NOW 2\n"); + #endif + #ifndef RTLD_GLOBAL + if (i) + { + i = 0; + printf("\n"); + } + printf("#define RTLD_GLOBAL 0\n"); + #endif + #ifndef RTLD_LOCAL + if (i) + { + i = 0; + printf("\n"); + } + printf("#define RTLD_LOCAL 0\n"); + #endif + #ifndef RTLD_PARENT + if (i) + { + i = 0; + printf("\n"); + } + printf("#define RTLD_PARENT 0\n"); + #endif + #if defined(_hdr_mach_o_dyld) && !defined(RTLD_NEXT) + if (i) + { + i = 0; + printf("\n"); + } + printf("#define RTLD_NEXT ((void*)16)\n"); + #endif + #if _hdr_rld_interface + if (!(dll = dlopen(0, RTLD_LAZY))) + i = -1; + else + { + for (i = 0; i < sizeof(local) / sizeof(local[0]); i++) + if (dlsym(dll, local[i])) + break; + if (i >= sizeof(local) / sizeof(local[0])) + i = -1; + } + if (i >= 0) + { + printf("\n"); + printf("#define _DLL_RLD_SYM %s\n", local[i]); + printf("#define _DLL_RLD_SYM_STR \"%s\"\n", local[i]); + printf("#define _DLL_RLD_SYM_TYPE void*\n"); + } + #endif + printf("\n"); + printf("#define DLL_INFO_PREVER 0x0001 /* pre-suffix style version */\n"); + printf("#define DLL_INFO_DOTVER 0x0002 /* post-suffix style version */\n"); + printf("\n"); + printf("typedef unsigned long (*Dll_plugin_version_f)(void);\n"); + printf("typedef int (*Dllerror_f)(void*, void*, int, ...);\n"); + printf("\n"); + printf("typedef struct Dllinfo_s\n"); + printf("{\n"); + printf(" char** sibling; /* sibling dirs on $PATH */\n"); + printf(" char* prefix; /* library name prefix */\n"); + printf(" char* suffix; /* library name suffix */\n"); + printf(" char* env; /* library path env var */\n"); + printf(" int flags; /* DLL_INFO_* flags */\n"); + printf("#ifdef _DLLINFO_PRIVATE_\n"); + printf(" _DLLINFO_PRIVATE_\n"); + printf("#endif\n"); + printf("} Dllinfo_t;\n"); + printf("\n"); + printf("typedef struct Dllnames_s\n"); + printf("{\n"); + printf(" char* id;\n"); + printf(" char* name;\n"); + printf(" char* base;\n"); + printf(" char* type;\n"); + printf(" char* opts;\n"); + printf(" char* path;\n"); + printf(" char data[1024];\n"); + printf("} Dllnames_t;\n"); + printf("\n"); + printf("typedef struct Dllent_s\n"); + printf("{\n"); + printf(" char* path;\n"); + printf(" char* name;\n"); + printf("#ifdef _DLLENT_PRIVATE_\n"); + printf(" _DLLENT_PRIVATE_\n"); + printf("#endif\n"); + printf("} Dllent_t;\n"); + printf("\n"); + printf("typedef struct Dllscan_s\n"); + printf("{\n"); + printf(" void* pad;\n"); + printf("#ifdef _DLLSCAN_PRIVATE_\n"); + printf(" _DLLSCAN_PRIVATE_\n"); + printf("#endif\n"); + printf("} Dllscan_t;\n"); + #if !_hdr_dlfcn || !_lib_dlopen + printf("\n"); + printf("extern void* dlopen(const char*, int);\n"); + printf("extern void* dlsym(void*, const char*);\n"); + printf("extern int dlclose(void*);\n"); + printf("extern char* dlerror(void);\n"); + #endif + printf("\n"); + printf("#if _BLD_dll && defined(__EXPORT__)\n"); + printf("#define extern __EXPORT__\n"); + printf("#endif\n"); + printf("\n"); + printf("extern Dllinfo_t* dllinfo(void);\n"); + printf("extern void* dllplugin(const char*, const char*, const char*, unsigned long, unsigned long*, int, char*, size_t);\n"); + printf("extern void* dllplug(const char*, const char*, const char*, int, char*, size_t);\n"); + printf("extern void* dllfind(const char*, const char*, int, char*, size_t);\n"); + printf("extern Dllnames_t* dllnames(const char*, const char*, Dllnames_t*);\n"); + printf("extern void* dll_lib(Dllnames_t*, unsigned long, Dllerror_f, void*);\n"); + printf("extern void* dllmeth(const char*, const char*, unsigned long);\n"); + printf("extern void* dllopen(const char*, int);\n"); + printf("extern void* dllnext(int);\n"); + printf("extern void* dlllook(void*, const char*);\n"); + printf("extern int dllcheck(void*, const char*, unsigned long, unsigned long*);\n"); + printf("extern unsigned long dllversion(void*, const char*);\n"); + printf("extern char* dllerror(int);\n"); + #if _hdr_rld_interface + if (i >= 0) + { + printf("\n"); + printf("extern void* _dll_next(int, _DLL_RLD_SYM_TYPE*);\n"); + printf("#define dllnext(f) _dll_next(f, &_DLL_RLD_SYM)\n"); + } + #endif + printf("\n"); + printf("extern Dllscan_t* dllsopen(const char*, const char*, const char*);\n"); + printf("extern Dllent_t* dllsread(Dllscan_t*);\n"); + printf("extern int dllsclose(Dllscan_t*);\n"); + printf("\n"); + printf("#undef extern\n"); + #if _hdr_rld_interface + if (i >= 0) + { + printf("\n"); + printf("extern _DLL_RLD_SYM_TYPE _DLL_RLD_SYM;\n"); + } + #endif + printf("\n"); + return 0; + } +}end |