diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c index b331cdec7513..342ed74be07c 100644 --- a/gnu/usr.bin/ld/rtld/rtld.c +++ b/gnu/usr.bin/ld/rtld/rtld.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: rtld.c,v 1.50 1997/11/29 03:32:47 jdp Exp $ + * $Id: rtld.c,v 1.51 1997/12/05 02:06:37 jdp Exp $ */ #include @@ -174,6 +174,8 @@ struct somap_private { #define RELOC_PCREL_P(s) ((s)->r_pcrel) #endif +#define END_SYM "_end" + static char __main_progname[] = "main"; static char *main_progname = __main_progname; static char us[] = "/usr/libexec/ld.so"; @@ -205,9 +207,10 @@ static void *__dlsym __P((void *, const char *)); static const char *__dlerror __P((void)); static void __dlexit __P((void)); static void *__dlsym3 __P((void *, const char *, void *)); +static int __dladdr __P((const void *, Dl_info *)); static struct ld_entry ld_entry = { - __dlopen, __dlclose, __dlsym, __dlerror, __dlexit, __dlsym3 + __dlopen, __dlclose, __dlsym, __dlerror, __dlexit, __dlsym3, __dladdr }; void xprintf __P((char *, ...)); @@ -302,11 +305,13 @@ struct _dynamic *dp; struct so_map *main_map; struct so_map *smp; char *add_paths; + char *main_path; /* Check version */ if (version != CRT_VERSION_BSD_2 && version != CRT_VERSION_BSD_3 && version != CRT_VERSION_BSD_4 && + version != CRT_VERSION_BSD_5 && version != CRT_VERSION_SUN) return -1; @@ -335,6 +340,8 @@ struct _dynamic *dp; __progname = crtp->crt_ldso; if (version >= CRT_VERSION_BSD_3) main_progname = crtp->crt_prog; + main_path = version >= CRT_VERSION_BSD_5 ? crtp->crt_argv[0] : + main_progname; /* Some buggy versions of crt0.o have crt_ldso filled in as NULL. */ if (__progname == NULL) @@ -363,7 +370,7 @@ struct _dynamic *dp; anon_open(); /* Make a link map entry for the main program */ - main_map = alloc_link_map(main_progname, + main_map = alloc_link_map(main_path, (struct sod *) NULL, (struct so_map *) NULL, (caddr_t) 0, crtp->crt_dp); LM_PRIVATE(main_map)->spd_refcount++; @@ -453,7 +460,7 @@ struct _dynamic *dp; (void)close(crtp->crt_ldfd); anon_close(); - return LDSO_VERSION_HAS_DLSYM3; + return LDSO_VERSION_HAS_DLADDR; } void @@ -2024,6 +2031,89 @@ resolvesym(fd, sym, retaddr) return (void *)addr; } +static int +__dladdr(addr, dlip) + const void *addr; + Dl_info *dlip; +{ + struct _dynamic *dp; + struct so_map *smp; + char *stringbase; + long numsyms; + int symsize; + int i; + + /* Find the shared object that contains the address. */ + for (smp = link_map_head; smp != NULL; smp = smp->som_next) { + struct so_map *src_map; + struct somap_private *smpp; + struct nzlist *np; + + smpp = LM_PRIVATE(smp); + if (smpp->spd_flags & RTLD_RTLD) + continue; + + if ((void *)smp->som_addr > addr) + continue; + + src_map = smp; + if ((np = lookup(END_SYM, &src_map, 1)) == NULL) + continue; /* No "_end" symbol?! */ + if (addr < (void *)(smp->som_addr + np->nz_value)) + break; + } + if (smp == NULL) { + generror("No shared object contains address"); + return 0; + } + dlip->dli_fname = smp->som_path; + dlip->dli_fbase = smp->som_addr; + dlip->dli_saddr = (void *) 0; + dlip->dli_sname = NULL; + + dp = smp->som_dynamic; + symsize = LD_VERSION_NZLIST_P(dp->d_version) ? + sizeof(struct nzlist) : sizeof(struct nlist); + numsyms = LD_STABSZ(dp) / symsize; + stringbase = LM_STRINGS(smp); + + for (i = 0; i < numsyms; i++) { + struct nzlist *symp = LM_SYMBOL(smp, i); + unsigned long value; + + /* Reject all except definitions. */ + if (symp->nz_type != N_EXT + N_ABS && + symp->nz_type != N_EXT + N_TEXT && + symp->nz_type != N_EXT + N_DATA && + symp->nz_type != N_EXT + N_BSS) + continue; + + /* + * If the symbol is greater than the specified address, or + * if it is further away from addr than the current nearest + * symbol, then reject it. + */ + value = (unsigned long) (smp->som_addr + symp->nz_value); + if (value > (unsigned long) addr || + value < (unsigned long) dlip->dli_saddr) + continue; + + /* Update our idea of the nearest symbol. */ + dlip->dli_sname = stringbase + symp->nz_strx; + dlip->dli_saddr = (void *) value; + + if (dlip->dli_saddr == addr) /* Can't get any closer. */ + break; + } + /* + * Remove any leading underscore from the symbol name, to hide + * our a.out-ness. + */ + if (dlip->dli_sname != NULL && dlip->dli_sname[0] == '_') + dlip->dli_sname++; + return 1; +} + static void * __dlsym3(fd, sym, retaddr) void *fd; diff --git a/include/link.h b/include/link.h index 5ff1f7857b1f..9d80d45d7505 100644 --- a/include/link.h +++ b/include/link.h @@ -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: link.h,v 1.16 1997/11/28 19:05:11 jdp Exp $ + * $Id: link.h,v 1.17 1997/12/06 17:59:52 jdp Exp $ */ /* @@ -41,6 +41,8 @@ #ifndef _LINK_H_ #define _LINK_H_ +struct dl_info; + /* * A `Shared Object Descriptor' describes a shared object that is needed * to complete the link edit process of the object containing it. @@ -158,6 +160,7 @@ struct so_debug { #define LDSO_VERSION_NONE 0 /* FreeBSD2.0, 2.0.5 */ #define LDSO_VERSION_HAS_DLEXIT 1 /* includes dlexit in ld_entry */ #define LDSO_VERSION_HAS_DLSYM3 2 /* includes 3-argument dlsym */ +#define LDSO_VERSION_HAS_DLADDR 3 /* includes dladdr in ld_entry */ /* * Entry points into ld.so - user interface to the run-time linker. @@ -171,6 +174,8 @@ struct ld_entry { const char *(*dlerror) __P((void)); /* NONE */ void (*dlexit) __P((void)); /* HAS_DLEXIT */ void *(*dlsym3) __P((void *, const char *, void *)); /* HAS_DLSYM3 */ + int (*dladdr) __P((const void *, + struct dl_info *)); /* HAS_DLADDR */ }; /* @@ -229,6 +234,7 @@ struct crt_ldso { char *crt_prog; /* Program name (v3) */ char *crt_ldso; /* Link editor name (v4) */ struct ld_entry *crt_ldentry; /* dl*() access (v4) */ + char **crt_argv; /* argument strings (v5) */ }; /* @@ -238,6 +244,7 @@ struct crt_ldso { #define CRT_VERSION_BSD_2 2 #define CRT_VERSION_BSD_3 3 #define CRT_VERSION_BSD_4 4 +#define CRT_VERSION_BSD_5 5 /* * Maximum number of recognized shared object version numbers. diff --git a/lib/csu/i386/Makefile b/lib/csu/i386/Makefile index 15d18923c86a..42907dcde33a 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 b3884e47fa3b..80759cf902ca 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 @@ -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 000000000000..97af8cec5456 --- /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 +.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 e167ef2c1929..ba61ebfd4953 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_ */ diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c index b331cdec7513..342ed74be07c 100644 --- a/libexec/rtld-aout/rtld.c +++ b/libexec/rtld-aout/rtld.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: rtld.c,v 1.50 1997/11/29 03:32:47 jdp Exp $ + * $Id: rtld.c,v 1.51 1997/12/05 02:06:37 jdp Exp $ */ #include @@ -174,6 +174,8 @@ struct somap_private { #define RELOC_PCREL_P(s) ((s)->r_pcrel) #endif +#define END_SYM "_end" + static char __main_progname[] = "main"; static char *main_progname = __main_progname; static char us[] = "/usr/libexec/ld.so"; @@ -205,9 +207,10 @@ static void *__dlsym __P((void *, const char *)); static const char *__dlerror __P((void)); static void __dlexit __P((void)); static void *__dlsym3 __P((void *, const char *, void *)); +static int __dladdr __P((const void *, Dl_info *)); static struct ld_entry ld_entry = { - __dlopen, __dlclose, __dlsym, __dlerror, __dlexit, __dlsym3 + __dlopen, __dlclose, __dlsym, __dlerror, __dlexit, __dlsym3, __dladdr }; void xprintf __P((char *, ...)); @@ -302,11 +305,13 @@ struct _dynamic *dp; struct so_map *main_map; struct so_map *smp; char *add_paths; + char *main_path; /* Check version */ if (version != CRT_VERSION_BSD_2 && version != CRT_VERSION_BSD_3 && version != CRT_VERSION_BSD_4 && + version != CRT_VERSION_BSD_5 && version != CRT_VERSION_SUN) return -1; @@ -335,6 +340,8 @@ struct _dynamic *dp; __progname = crtp->crt_ldso; if (version >= CRT_VERSION_BSD_3) main_progname = crtp->crt_prog; + main_path = version >= CRT_VERSION_BSD_5 ? crtp->crt_argv[0] : + main_progname; /* Some buggy versions of crt0.o have crt_ldso filled in as NULL. */ if (__progname == NULL) @@ -363,7 +370,7 @@ struct _dynamic *dp; anon_open(); /* Make a link map entry for the main program */ - main_map = alloc_link_map(main_progname, + main_map = alloc_link_map(main_path, (struct sod *) NULL, (struct so_map *) NULL, (caddr_t) 0, crtp->crt_dp); LM_PRIVATE(main_map)->spd_refcount++; @@ -453,7 +460,7 @@ struct _dynamic *dp; (void)close(crtp->crt_ldfd); anon_close(); - return LDSO_VERSION_HAS_DLSYM3; + return LDSO_VERSION_HAS_DLADDR; } void @@ -2024,6 +2031,89 @@ resolvesym(fd, sym, retaddr) return (void *)addr; } +static int +__dladdr(addr, dlip) + const void *addr; + Dl_info *dlip; +{ + struct _dynamic *dp; + struct so_map *smp; + char *stringbase; + long numsyms; + int symsize; + int i; + + /* Find the shared object that contains the address. */ + for (smp = link_map_head; smp != NULL; smp = smp->som_next) { + struct so_map *src_map; + struct somap_private *smpp; + struct nzlist *np; + + smpp = LM_PRIVATE(smp); + if (smpp->spd_flags & RTLD_RTLD) + continue; + + if ((void *)smp->som_addr > addr) + continue; + + src_map = smp; + if ((np = lookup(END_SYM, &src_map, 1)) == NULL) + continue; /* No "_end" symbol?! */ + if (addr < (void *)(smp->som_addr + np->nz_value)) + break; + } + if (smp == NULL) { + generror("No shared object contains address"); + return 0; + } + dlip->dli_fname = smp->som_path; + dlip->dli_fbase = smp->som_addr; + dlip->dli_saddr = (void *) 0; + dlip->dli_sname = NULL; + + dp = smp->som_dynamic; + symsize = LD_VERSION_NZLIST_P(dp->d_version) ? + sizeof(struct nzlist) : sizeof(struct nlist); + numsyms = LD_STABSZ(dp) / symsize; + stringbase = LM_STRINGS(smp); + + for (i = 0; i < numsyms; i++) { + struct nzlist *symp = LM_SYMBOL(smp, i); + unsigned long value; + + /* Reject all except definitions. */ + if (symp->nz_type != N_EXT + N_ABS && + symp->nz_type != N_EXT + N_TEXT && + symp->nz_type != N_EXT + N_DATA && + symp->nz_type != N_EXT + N_BSS) + continue; + + /* + * If the symbol is greater than the specified address, or + * if it is further away from addr than the current nearest + * symbol, then reject it. + */ + value = (unsigned long) (smp->som_addr + symp->nz_value); + if (value > (unsigned long) addr || + value < (unsigned long) dlip->dli_saddr) + continue; + + /* Update our idea of the nearest symbol. */ + dlip->dli_sname = stringbase + symp->nz_strx; + dlip->dli_saddr = (void *) value; + + if (dlip->dli_saddr == addr) /* Can't get any closer. */ + break; + } + /* + * Remove any leading underscore from the symbol name, to hide + * our a.out-ness. + */ + if (dlip->dli_sname != NULL && dlip->dli_sname[0] == '_') + dlip->dli_sname++; + return 1; +} + static void * __dlsym3(fd, sym, retaddr) void *fd; diff --git a/sys/sys/link_aout.h b/sys/sys/link_aout.h index 5ff1f7857b1f..9d80d45d7505 100644 --- a/sys/sys/link_aout.h +++ b/sys/sys/link_aout.h @@ -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: link.h,v 1.16 1997/11/28 19:05:11 jdp Exp $ + * $Id: link.h,v 1.17 1997/12/06 17:59:52 jdp Exp $ */ /* @@ -41,6 +41,8 @@ #ifndef _LINK_H_ #define _LINK_H_ +struct dl_info; + /* * A `Shared Object Descriptor' describes a shared object that is needed * to complete the link edit process of the object containing it. @@ -158,6 +160,7 @@ struct so_debug { #define LDSO_VERSION_NONE 0 /* FreeBSD2.0, 2.0.5 */ #define LDSO_VERSION_HAS_DLEXIT 1 /* includes dlexit in ld_entry */ #define LDSO_VERSION_HAS_DLSYM3 2 /* includes 3-argument dlsym */ +#define LDSO_VERSION_HAS_DLADDR 3 /* includes dladdr in ld_entry */ /* * Entry points into ld.so - user interface to the run-time linker. @@ -171,6 +174,8 @@ struct ld_entry { const char *(*dlerror) __P((void)); /* NONE */ void (*dlexit) __P((void)); /* HAS_DLEXIT */ void *(*dlsym3) __P((void *, const char *, void *)); /* HAS_DLSYM3 */ + int (*dladdr) __P((const void *, + struct dl_info *)); /* HAS_DLADDR */ }; /* @@ -229,6 +234,7 @@ struct crt_ldso { char *crt_prog; /* Program name (v3) */ char *crt_ldso; /* Link editor name (v4) */ struct ld_entry *crt_ldentry; /* dl*() access (v4) */ + char **crt_argv; /* argument strings (v5) */ }; /* @@ -238,6 +244,7 @@ struct crt_ldso { #define CRT_VERSION_BSD_2 2 #define CRT_VERSION_BSD_3 3 #define CRT_VERSION_BSD_4 4 +#define CRT_VERSION_BSD_5 5 /* * Maximum number of recognized shared object version numbers. diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h index 5ff1f7857b1f..9d80d45d7505 100644 --- a/sys/sys/link_elf.h +++ b/sys/sys/link_elf.h @@ -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: link.h,v 1.16 1997/11/28 19:05:11 jdp Exp $ + * $Id: link.h,v 1.17 1997/12/06 17:59:52 jdp Exp $ */ /* @@ -41,6 +41,8 @@ #ifndef _LINK_H_ #define _LINK_H_ +struct dl_info; + /* * A `Shared Object Descriptor' describes a shared object that is needed * to complete the link edit process of the object containing it. @@ -158,6 +160,7 @@ struct so_debug { #define LDSO_VERSION_NONE 0 /* FreeBSD2.0, 2.0.5 */ #define LDSO_VERSION_HAS_DLEXIT 1 /* includes dlexit in ld_entry */ #define LDSO_VERSION_HAS_DLSYM3 2 /* includes 3-argument dlsym */ +#define LDSO_VERSION_HAS_DLADDR 3 /* includes dladdr in ld_entry */ /* * Entry points into ld.so - user interface to the run-time linker. @@ -171,6 +174,8 @@ struct ld_entry { const char *(*dlerror) __P((void)); /* NONE */ void (*dlexit) __P((void)); /* HAS_DLEXIT */ void *(*dlsym3) __P((void *, const char *, void *)); /* HAS_DLSYM3 */ + int (*dladdr) __P((const void *, + struct dl_info *)); /* HAS_DLADDR */ }; /* @@ -229,6 +234,7 @@ struct crt_ldso { char *crt_prog; /* Program name (v3) */ char *crt_ldso; /* Link editor name (v4) */ struct ld_entry *crt_ldentry; /* dl*() access (v4) */ + char **crt_argv; /* argument strings (v5) */ }; /* @@ -238,6 +244,7 @@ struct crt_ldso { #define CRT_VERSION_BSD_2 2 #define CRT_VERSION_BSD_3 3 #define CRT_VERSION_BSD_4 4 +#define CRT_VERSION_BSD_5 5 /* * Maximum number of recognized shared object version numbers.