Author: kib
Date: Mon Aug 23 15:27:03 2010
New Revision: 211705
URL: http://svn.freebsd.org/changeset/base/211705

Log:
  Introduce implementation-private rtld interface _rtld_addr_phdr, which
  fills struct dl_phdr_info for the shared object that contains the
  specified address, if any.
  
  Idea and reviewed by: kan
  MFC after:    3 weeks

Modified:
  head/lib/libc/gen/Symbol.map
  head/lib/libc/gen/dlfcn.c
  head/libexec/rtld-elf/Symbol.map
  head/libexec/rtld-elf/rtld.c
  head/sys/sys/link_elf.h

Modified: head/lib/libc/gen/Symbol.map
==============================================================================
--- head/lib/libc/gen/Symbol.map        Mon Aug 23 15:18:35 2010        
(r211704)
+++ head/lib/libc/gen/Symbol.map        Mon Aug 23 15:27:03 2010        
(r211705)
@@ -446,6 +446,7 @@ FBSDprivate_1.0 {
        _spinlock;
        _spinlock_debug;
        _spinunlock;
+       _rtld_addr_phdr;
        _rtld_atfork_pre;
        _rtld_atfork_post;
        _rtld_error;            /* for private use */

Modified: head/lib/libc/gen/dlfcn.c
==============================================================================
--- head/lib/libc/gen/dlfcn.c   Mon Aug 23 15:18:35 2010        (r211704)
+++ head/lib/libc/gen/dlfcn.c   Mon Aug 23 15:27:03 2010        (r211705)
@@ -157,3 +157,11 @@ void
 _rtld_atfork_post(int *locks)
 {
 }
+
+#pragma weak _rtld_addr_phdr
+int
+_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info)
+{
+
+       return (0);
+}

Modified: head/libexec/rtld-elf/Symbol.map
==============================================================================
--- head/libexec/rtld-elf/Symbol.map    Mon Aug 23 15:18:35 2010        
(r211704)
+++ head/libexec/rtld-elf/Symbol.map    Mon Aug 23 15:27:03 2010        
(r211705)
@@ -27,4 +27,5 @@ FBSDprivate_1.0 {
     _rtld_free_tls;
     _rtld_atfork_pre;
     _rtld_atfork_post;
+    _rtld_addr_phdr;
 };

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c        Mon Aug 23 15:18:35 2010        
(r211704)
+++ head/libexec/rtld-elf/rtld.c        Mon Aug 23 15:27:03 2010        
(r211705)
@@ -147,6 +147,8 @@ static int  rtld_verify_object_versions(
 static void object_add_name(Obj_Entry *, const char *);
 static int  object_match_name(const Obj_Entry *, const char *);
 static void ld_utrace_log(int, void *, void *, size_t, int, const char *);
+static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
+    struct dl_phdr_info *phdr_info);
 
 void r_debug_state(struct r_debug *, struct link_map *);
 
@@ -220,6 +222,7 @@ static func_ptr_type exports[] = {
     (func_ptr_type) &dl_iterate_phdr,
     (func_ptr_type) &_rtld_atfork_pre,
     (func_ptr_type) &_rtld_atfork_post,
+    (func_ptr_type) &_rtld_addr_phdr,
     NULL
 };
 
@@ -2261,6 +2264,24 @@ dlvsym(void *handle, const char *name, c
 }
 
 int
+_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info)
+{
+    const Obj_Entry *obj;
+    int lockstate;
+
+    lockstate = rlock_acquire(rtld_bind_lock);
+    obj = obj_from_addr(addr);
+    if (obj == NULL) {
+        _rtld_error("No shared object contains address");
+       rlock_release(rtld_bind_lock, lockstate);
+        return (0);
+    }
+    rtld_fill_dl_phdr_info(obj, phdr_info);
+    rlock_release(rtld_bind_lock, lockstate);
+    return (1);
+}
+
+int
 dladdr(const void *addr, Dl_info *info)
 {
     const Obj_Entry *obj;
@@ -2362,6 +2383,21 @@ dlinfo(void *handle, int request, void *
     return (error);
 }
 
+static void
+rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
+{
+
+       phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
+       phdr_info->dlpi_name = STAILQ_FIRST(&obj->names) ?
+           STAILQ_FIRST(&obj->names)->name : obj->path;
+       phdr_info->dlpi_phdr = obj->phdr;
+       phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
+       phdr_info->dlpi_tls_modid = obj->tlsindex;
+       phdr_info->dlpi_tls_data = obj->tlsinit;
+       phdr_info->dlpi_adds = obj_loads;
+       phdr_info->dlpi_subs = obj_loads - obj_count;
+}
+
 int
 dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
 {
@@ -2375,16 +2411,7 @@ dl_iterate_phdr(__dl_iterate_hdr_callbac
     error = 0;
 
     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
-       phdr_info.dlpi_addr = (Elf_Addr)obj->relocbase;
-       phdr_info.dlpi_name = STAILQ_FIRST(&obj->names) ?
-           STAILQ_FIRST(&obj->names)->name : obj->path;
-       phdr_info.dlpi_phdr = obj->phdr;
-       phdr_info.dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
-       phdr_info.dlpi_tls_modid = obj->tlsindex;
-       phdr_info.dlpi_tls_data = obj->tlsinit;
-       phdr_info.dlpi_adds = obj_loads;
-       phdr_info.dlpi_subs = obj_loads - obj_count;
-
+       rtld_fill_dl_phdr_info(obj, &phdr_info);
        if ((error = callback(&phdr_info, sizeof phdr_info, param)) != 0)
                break;
 

Modified: head/sys/sys/link_elf.h
==============================================================================
--- head/sys/sys/link_elf.h     Mon Aug 23 15:18:35 2010        (r211704)
+++ head/sys/sys/link_elf.h     Mon Aug 23 15:27:03 2010        (r211705)
@@ -92,6 +92,7 @@ __BEGIN_DECLS
 
 typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void 
*);
 extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
+int _rtld_addr_phdr(const void *, struct dl_phdr_info *);
 
 __END_DECLS
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to