diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/Makefile.inc | 10 | ||||
-rw-r--r-- | lib/libc/gen/dladdr.3 | 121 | ||||
-rw-r--r-- | lib/libc/gen/dlfcn.c | 96 | ||||
-rw-r--r-- | lib/libc/gen/dlopen.3 | 236 |
4 files changed, 460 insertions, 3 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index e0b087f..fbf76bd 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -1,5 +1,5 @@ # @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 -# $Id: Makefile.inc,v 1.40 1997/10/15 16:15:24 bde Exp $ +# $Id: Makefile.inc,v 1.41 1997/10/21 08:41:06 bde Exp $ # machine-independent gen sources .PATH: ${.CURDIR}/../libc/${MACHINE}/gen ${.CURDIR}/../libc/gen @@ -7,7 +7,7 @@ SRCS+= _rand48.c alarm.c arc4random.c assert.c \ clock.c closedir.c config.c confstr.c \ crypt.c ctermid.c daemon.c devname.c disklabel.c \ - drand48.c erand48.c err.c errlst.c \ + dlfcn.c drand48.c erand48.c err.c errlst.c \ exec.c fnmatch.c fstab.c fts.c getbootfile.c getbsize.c \ getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \ gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \ @@ -45,7 +45,8 @@ errlst.o errlst.po: .if ${LIB} == "c" MAN3+= alarm.3 arc4random.3 clock.3 config_open.3 \ confstr.3 crypt.3 ctermid.3 daemon.3 \ - devname.3 directory.3 err.3 exec.3 fnmatch.3 frexp.3 fts.3 \ + devname.3 directory.3 dladdr.3 dlopen.3 \ + err.3 exec.3 fnmatch.3 frexp.3 fts.3 \ getbootfile.3 getbsize.3 getcap.3 getcwd.3 \ getdiskbyname.3 getdomainname.3 getfsent.3 \ getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \ @@ -69,6 +70,9 @@ MLINKS+=crypt.3 des_cipher.3 crypt.3 des_setkey.3 crypt.3 encrypt.3 \ MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ directory.3 readdir.3 directory.3 rewinddir.3 directory.3 seekdir.3 \ directory.3 telldir.3 +MLINKS+=dlopen.3 dlsym.3 \ + dlopen.3 dlerror.3 \ + dlopen.3 dlclose.3 MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \ exec.3 execv.3 exec.3 execvp.3 MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errx.3 err.3 verr.3 \ diff --git a/lib/libc/gen/dladdr.3 b/lib/libc/gen/dladdr.3 new file mode 100644 index 0000000..bb5ab41 --- /dev/null +++ b/lib/libc/gen/dladdr.3 @@ -0,0 +1,121 @@ +.\" +.\" Copyright (c) 1998 John D. Polstra +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS 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 AUTHOR OR 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. +.\" +.\" $Id: dladdr.3,v 1.1 1998/02/06 16:46:34 jdp Exp $ +.\" +.Dd February 5, 1998 +.Os FreeBSD +.Dt DLADDR 3 +.Sh NAME +.Nm dladdr +.Nd find the shared object containing a given address +.Sh SYNOPSIS +.Fd #include <dlfcn.h> +.Ft int +.Fn dladdr "const void *addr" "Dl_info *info" +.Sh DESCRIPTION +.Nm +queries the dynamic linker for information about the shared object +containing the address +.Fa addr . +The information is returned in the structure specified by +.Fa info . +The structure contains at least the following members: +.Bl -tag -width "XXXconst char *dli_fname" +.It Li "const char *dli_fname" +The pathname of the shared object containing the address. +.It Li "void *dli_fbase" +The base address at which the shared object is mapped into the +address space of the calling process. +.It Li "const char *dli_sname" +The name of the nearest run-time symbol with a value less than or +equal to +.Fa addr . +When possible, the symbol name is returned as it would appear in C +source code. +.Pp +If no symbol with a suitable value is found, both this field and +.Va dli_saddr +are set to +.Dv NULL . +.It Li "void *dli_saddr" +The value of the symbol returned in +.Li dli_sname . +.El +.Pp +.Nm +is available only in dynamically linked programs. +.Sh ERRORS +If a mapped shared object containing +.Fa addr +cannot be found, +.Nm +returns 0. +In that case, a message detailing the failure can be retrieved by +calling +.Fn dlerror . +.Pp +On success, a non-zero value is returned. +.Sh SEE ALSO +.Xr dlopen 3 , +.Xr rtld 1 +.Sh HISTORY +The +.Nm +function first appeared in the Solaris operating system. +.Sh BUGS +This implementation is bug-compatible with the Solaris +implementation. In particular, the following bugs are present: +.Bl -bullet +.It +If +.Fa addr +lies in the main executable rather than in a shared library, the +pathname returned in +.Va dli_fname +may not be correct. The pathname is taken directly from +.Va argv[0] +of the calling process. When executing a program specified by its +full pathname, most shells set +.Va argv[0] +to the pathname. But this is not required of shells or guaranteed +by the operating system. +.It +If +.Fa addr +is of the form +.Va &func , +where +.Va func +is a global function, its value may be an unpleasant surprise. In +dynamically linked programs, the address of a global function is +considered to point to its program linkage table entry, rather than to +the entry point of the function itself. This causes most global +functions to appear to be defined within the main executable, rather +than in the shared libraries where the actual code resides. +.It +Returning 0 as an indication of failure goes against long-standing +Unix tradition. +.El diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c new file mode 100644 index 0000000..3f00346 --- /dev/null +++ b/lib/libc/gen/dlfcn.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 1998 John D. Polstra + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * $Id$ + */ + +/* + * Trampolines to services provided by the dynamic linker. + */ + +#include <sys/types.h> +#include <nlist.h> /* XXX - Required by link.h */ +#include <dlfcn.h> +#include <link.h> +#include <stddef.h> + +/* + * These variables are set by code in crt0.o. For compatibility with + * old executables, they must be common, not extern. + */ +struct ld_entry *__ldso_entry; /* Entry points to dynamic linker */ +int __ldso_version; /* Dynamic linker version number */ + +void * +dlopen(name, mode) + const char *name; + int mode; +{ + if (__ldso_entry == NULL) + return NULL; + return (__ldso_entry->dlopen)(name, mode); +} + +int +dlclose(fd) + void *fd; +{ + if (__ldso_entry == NULL) + return -1; + return (__ldso_entry->dlclose)(fd); +} + +void * +dlsym(fd, name) + void *fd; + const char *name; +{ + if (__ldso_entry == NULL) + return NULL; + if (__ldso_version >= LDSO_VERSION_HAS_DLSYM3) { + void *retaddr = *(&fd - 1); /* XXX - ABI/machine dependent */ + return (__ldso_entry->dlsym3)(fd, name, retaddr); + } else + return (__ldso_entry->dlsym)(fd, name); +} + + +const char * +dlerror() +{ + if (__ldso_entry == NULL) + return "Service unavailable"; + return (__ldso_entry->dlerror)(); +} + +int +dladdr(addr, dlip) + const void *addr; + Dl_info *dlip; +{ + if (__ldso_entry == NULL || __ldso_version < LDSO_VERSION_HAS_DLADDR) + return 0; + return (__ldso_entry->dladdr)(addr, dlip); +} diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 new file mode 100644 index 0000000..b9a987c --- /dev/null +++ b/lib/libc/gen/dlopen.3 @@ -0,0 +1,236 @@ +.\" This source code is a product of Sun Microsystems, Inc. and is provided +.\" for unrestricted use provided that this legend is included on all tape +.\" media and as a part of the software program in whole or part. Users +.\" may copy or modify this source code without charge, but are not authorized +.\" to license or distribute it to anyone else except as part of a product or +.\" program developed by the user. +.\" +.\" THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC. +.\" SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY +.\" OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT +.\" EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS +.\" ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +.\" NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT, +.\" INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY. +.\" +.\" This source code is provided with no support and without any obligation on +.\" the part of Sun Microsystems, Inc. to assist in its use, correction, +.\" modification or enhancement. +.\" +.\" SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +.\" INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS +.\" SOURCE CODE OR ANY PART THEREOF. +.\" +.\" Sun Microsystems, Inc. +.\" 2550 Garcia Avenue +.\" Mountain View, California 94043 +.\" +.\" Copyright (c) 1991 Sun Microsystems, Inc. +.\" +.\" @(#) dlopen.3 1.6 90/01/31 SMI +.Dd September 24, 1989 +.Os FreeBSD +.Dt DLOPEN 3 +.Sh NAME +.Nm dlopen, dlsym, dlerror, dlclose +.Nd programmatic interface to the dynamic linker +.Sh SYNOPSIS +.Fd #include <dlfcn.h> +.Ft void * +.Fn dlopen "const char *path" "int mode" +.Ft void * +.Fn dlsym "void *handle" "const char *symbol" +.Ft const char * +.Fn dlerror "void" +.Ft int +.Fn dlclose "void *handle" +.Sh DESCRIPTION +These functions provide a simple programmatic interface to the services of the +dynamic linker. +Operations are provided to add new shared objects to a +program's address space, to obtain the address bindings of symbols +defined by such +objects, and to remove such objects when their use is no longer required. +.Pp +.Fn dlopen +provides access to the shared object in +.Fa path , +returning a descriptor that can be used for later +references to the object in calls to +.Fn dlsym +and +.Fn dlclose . +If +.Fa path +was not in the address space prior to the call to +.Fn dlopen , +it is placed in the address space. +When an object is first loaded into the address space in this way, its +function +.Fn _init , +if any, is called by the dynamic linker. +(Note that +.Ql _init +is the name as expressed in the C language. +From assembly language, the name would appear as +.Ql __init +instead.) +If +.Fa path +has already been placed in the address space in a previous call to +.Fn dlopen , +it is not added a second time, although a reference count of +.Fn dlopen +operations on +.Fa path +is maintained. +A null pointer supplied for +.Fa path +is interpreted as a reference to the main +executable of the process. +.Fa mode +controls the way in which external function references from the +loaded object are bound to their referents. +It must contains one of the following values: +.Bl -tag -width RTLD_LAZYX +.It Dv RTLD_LAZY +Each external function reference is resolved when the function is first +called. +.It Dv RTLD_NOW +All external function references are bound immediately by +.Fn dlopen . +.El +.Pp +.Dv RTLD_LAZY +is normally preferred, for reasons of efficiency. +However, +.Dv RTLD_NOW +is useful to ensure that any undefined symbols are discovered during the +call to +.Fn dlopen . +If +.Fn dlopen +fails, it returns a null pointer, and sets an error condition which may +be interrogated with +.Fn dlerror . +.Pp +.Fn dlsym +returns the address binding of the symbol described in the null-terminated +character string +.Fa symbol , +as it occurs in the shared object identified by +.Fa handle . +Note that +.Fa symbol +is the assembly language representation of the symbol name. +The assembly language representation of a C language symbol contains an +extra underscore at the beginning. +For example, the symbol +.Ql foo +in C would appear as +.Ql _foo +in assembly language, and in the +.Fa symbol +argument to +.Fn dlsym . +The symbols exported by objects added to the address space by +.Fn dlopen +can be accessed only through calls to +.Fn dlsym . +Such symbols do not supersede any definition of those symbols already present +in the address space when the object is loaded, nor are they available to +satisfy normal dynamic linking references. +A null pointer supplied as the value of +.Fa handle +is interpreted as a reference to the executable from which the call to +.Fn dlsym +is being made. Thus a shared object can reference its own symbols. +.Fn dlsym +returns a null pointer if the symbol cannot be found, and sets an error +condition which may be queried with +.Fn dlerror . +.Pp +If +.Fn dlsym +is called with the special +.Fa handle +.Dv RTLD_NEXT , +then the search for the symbol is limited to the shared objects +which were loaded after the one issuing the call to +.Fn dlsym . +Thus, if the function is called from the main program, all +the shared libraries are searched. +If it is called from a shared library, all subsequent shared +libraries are searched. +.Dv RTLD_NEXT +is useful for implementing wrappers around library functions. +For example, a wrapper function +.Fn getpid +could access the +.Dq real +.Fn getpid +with +.Li dlsym(RTLD_NEXT, \&"_getpid\&") . +.Pp +.Fn dlerror +returns a null-terminated character string describing the last error that +occurred during a call to +.Fn dlopen , +.Fn dlsym , +or +.Fn dlclose . +If no such error has occurred, +.Fn dlerror +returns a null pointer. +At each call to +.Fn dlerror , +the error indication is reset. Thus in the case of two calls +to +.Fn dlerror , +where the second call follows the first immediately, the second call +will always return a null pointer. +.Pp +.Fn dlclose +deletes a reference to the shared object referenced by +.Fa handle . +If the reference count drops to 0, the object is removed from the +address space, and +.Fa handle +is rendered invalid. +Just before removing a shared object in this way, the dynamic linker +calls the object's +.Fn _fini +function, if such a function is defined by the object. +As with +.Ql _init , +.Ql _fini +is the C language name of the function. +If +.Fn dlclose +is successful, it returns a value of 0. +Otherwise it returns -1, and sets an error condition that can be +interrogated with +.Fn dlerror . +.Pp +The object-intrinsic functions +.Fn _init +and +.Fn _fini +are called with no arguments, and are not expected to return values. +.Sh ERRORS +.Fn dlopen +and +.Fn dlsym +return the null pointer in the event of errors. +.Fn dlclose +returns 0 on success, or -1 if an error occurred. +Whenever an error has been detected, a message detailing it can be +retrieved via a call to +.Fn dlerror . +.Sh SEE ALSO +.Xr ld 1 , +.Xr rtld 1 , +.Xr link 5 + |