summaryrefslogtreecommitdiffstats
path: root/lib/csu
diff options
context:
space:
mode:
authorjdp <jdp@FreeBSD.org>1998-02-06 16:46:46 +0000
committerjdp <jdp@FreeBSD.org>1998-02-06 16:46:46 +0000
commitd5b09c81eced1f16f3f4629fb7fbafca071830c8 (patch)
treea5dbf2df17b8cae687037c9d85532424638e9a9d /lib/csu
parenta339af109edf459ef1479a6db4d42adcd4e8c89f (diff)
downloadFreeBSD-src-d5b09c81eced1f16f3f4629fb7fbafca071830c8.zip
FreeBSD-src-d5b09c81eced1f16f3f4629fb7fbafca071830c8.tar.gz
Implement dladdr.
Diffstat (limited to 'lib/csu')
-rw-r--r--lib/csu/i386/Makefile4
-rw-r--r--lib/csu/i386/crt0.c42
-rw-r--r--lib/csu/i386/dladdr.3121
-rw-r--r--lib/csu/i386/dlfcn.h15
4 files changed, 169 insertions, 13 deletions
diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile
index 15d1892..42907dc 100644
--- a/lib/csu/i386/Makefile
+++ b/lib/csu/i386/Makefile
@@ -1,10 +1,10 @@
# from: @(#)Makefile 5.6 (Berkeley) 5/22/91
-# $Id: Makefile,v 1.32 1997/10/11 02:37:42 asami Exp $
+# $Id: Makefile,v 1.33 1998/01/12 18:29:02 eivind Exp $
CFLAGS+= -DLIBC_SCCS -fno-omit-frame-pointer -I${.CURDIR}
OBJS= crt0.o c++rt0.o gcrt0.o scrt0.o sgcrt0.o
CLEANFILES+= a.out
-MAN3+= dlopen.3
+MAN3+= dladdr.3 dlopen.3
MLINKS+= dlopen.3 dlsym.3 \
dlopen.3 dlerror.3 \
dlopen.3 dlclose.3
diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c
index b3884e4..80759cf 100644
--- a/lib/csu/i386/crt0.c
+++ b/lib/csu/i386/crt0.c
@@ -27,7 +27,7 @@
* (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: crt0.c,v 1.30 1997/08/02 04:56:33 jdp Exp $
+ * $Id: crt0.c,v 1.31 1997/11/22 03:34:45 brian Exp $
*/
#include <sys/param.h>
@@ -85,7 +85,7 @@ static int _strncmp();
extern struct _dynamic _DYNAMIC;
static struct ld_entry *ld_entry;
-static void __do_dynamic_link ();
+static void __do_dynamic_link(char **argv);
#endif /* DYNAMIC */
int _callmain();
@@ -174,7 +174,7 @@ start()
/* sometimes GCC is too smart/stupid for its own good */
x = (caddr_t)&_DYNAMIC;
if (x)
- __do_dynamic_link();
+ __do_dynamic_link(argv);
#endif /* DYNAMIC */
asm("eprol:");
@@ -190,7 +190,8 @@ asm ("__callmain:"); /* Defined for the benefit of debuggers */
#ifdef DYNAMIC
static void
-__do_dynamic_link ()
+__do_dynamic_link(argv)
+ char **argv;
{
struct crt_ldso crt;
struct exec hdr;
@@ -253,14 +254,20 @@ __do_dynamic_link ()
crt.crt_prog = __progname;
crt.crt_ldso = ldso;
crt.crt_ldentry = NULL;
+ crt.crt_argv = argv;
entry = (int (*)())(crt.crt_ba + sizeof hdr);
- ldso_version = (*entry)(CRT_VERSION_BSD_4, &crt);
+ ldso_version = (*entry)(CRT_VERSION_BSD_5, &crt);
ld_entry = crt.crt_ldentry;
if (ldso_version == -1 && ld_entry == NULL) {
- /* if version 4 not recognised, try version 3 */
- ldso_version = (*entry)(CRT_VERSION_BSD_3, &crt);
- ld_entry = _DYNAMIC.d_entry;
+ /* If version 5 not recognised, try version 4 */
+ ldso_version = (*entry)(CRT_VERSION_BSD_4, &crt);
+ ld_entry = crt.crt_ldentry;
+ if (ldso_version == -1 && ld_entry == NULL) {
+ /* if version 4 not recognised, try version 3 */
+ ldso_version = (*entry)(CRT_VERSION_BSD_3, &crt);
+ ld_entry = _DYNAMIC.d_entry;
+ }
}
if (ldso_version == -1) {
_PUTMSG("ld.so failed");
@@ -334,6 +341,16 @@ dlerror()
return (ld_entry->dlerror)();
}
+int
+dladdr(addr, dlip)
+ const void *addr;
+ Dl_info *dlip;
+{
+ if (ld_entry == NULL || ldso_version < LDSO_VERSION_HAS_DLADDR)
+ return 0;
+ return (ld_entry->dladdr)(addr, dlip);
+}
+
/*
* Support routines
@@ -419,12 +436,19 @@ const char *name;
return NULL;
}
-
const char *
dlerror()
{
return "Service unavailable";
}
+
+int
+dladdr(addr, dlip)
+ const void *addr;
+ Dl_info *dlip;
+{
+ return 0;
+}
#endif /* DYNAMIC */
diff --git a/lib/csu/i386/dladdr.3 b/lib/csu/i386/dladdr.3
new file mode 100644
index 0000000..97af8ce
--- /dev/null
+++ b/lib/csu/i386/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$
+.\"
+.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/csu/i386/dlfcn.h b/lib/csu/i386/dlfcn.h
index e167ef2..ba61ebf 100644
--- a/lib/csu/i386/dlfcn.h
+++ b/lib/csu/i386/dlfcn.h
@@ -50,11 +50,22 @@
*/
#define RTLD_NEXT ((void *) -1)
+/*
+ * Structure filled in by dladdr().
+ */
+typedef struct dl_info {
+ const char *dli_fname; /* Pathname of shared object */
+ void *dli_fbase; /* Base address of shared object */
+ const char *dli_sname; /* Name of nearest symbol */
+ void *dli_saddr; /* Address of nearest symbol */
+} Dl_info;
+
__BEGIN_DECLS
+int dladdr __P((const void *, Dl_info *));
+int dlclose __P((void *));
+const char *dlerror __P((void));
void *dlopen __P((const char *, int));
void *dlsym __P((void *, const char *));
-const char *dlerror __P((void));
-int dlclose __P((void *));
__END_DECLS
#endif /* !_DLFCN_H_ */
OpenPOWER on IntegriCloud