summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1999-03-24 23:37:35 +0000
committernate <nate@FreeBSD.org>1999-03-24 23:37:35 +0000
commit49744ae917b1d49bd77a6009a2afa719abc35c55 (patch)
tree01e42078cb287500f5592cf8cbfe187e52a8677a /libexec
parentc42abfb1fe46d89d8c6bffc17aa69c778f17e2b4 (diff)
downloadFreeBSD-src-49744ae917b1d49bd77a6009a2afa719abc35c55.zip
FreeBSD-src-49744ae917b1d49bd77a6009a2afa719abc35c55.tar.gz
- Added dladdr(3) support.
Reviewed by: jdp@FreeBSD.org
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 9b4a9cf..02f9c20 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -22,7 +22,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.12 1998/10/13 03:31:59 jdp Exp $
+ * $Id: rtld.c,v 1.13 1998/11/27 21:19:52 dfr Exp $
*/
/*
@@ -148,6 +148,7 @@ static func_ptr_type exports[] = {
(func_ptr_type) &dlerror,
(func_ptr_type) &dlopen,
(func_ptr_type) &dlsym,
+ (func_ptr_type) &dladdr,
NULL
};
@@ -1259,6 +1260,51 @@ dlsym(void *handle, const char *name)
return NULL;
}
+int
+dladdr(const void *addr, Dl_info *info)
+{
+ const Obj_Entry *obj;
+ const Elf_Sym *def;
+ void *symbol_addr;
+ unsigned long symoffset;
+
+ obj = obj_from_addr(addr);
+ if (obj == NULL) {
+ _rtld_error("No shared object contains address");
+ return 0;
+ }
+ info->dli_fname = obj->path;
+ info->dli_fbase = obj->relocbase;
+ info->dli_saddr = (void *)0;
+ info->dli_sname = NULL;
+
+ /*
+ * Walk the symbol list looking for the symbol whosse address is
+ * closest to the address sent in.
+ */
+ for (symoffset = 0; symoffset < obj->nchains; symoffset++) {
+ def = obj->symtab + symoffset;
+ symbol_addr = obj->relocbase + def->st_value;
+ /*
+ *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.
+ */
+ if (symbol_addr > addr ||
+ symbol_addr < info->dli_saddr)
+ continue;
+
+ /* Update our idea of the nearest symbol. */
+ info->dli_sname = obj->strtab + def->st_name;
+ info->dli_saddr = symbol_addr;
+
+ /* Exact match? */
+ if (info->dli_saddr == addr)
+ break;
+ }
+ return 1;
+}
+
static void
linkmap_add(Obj_Entry *obj)
{
OpenPOWER on IntegriCloud