Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Implement dl_iterate_phdr.



details:   https://anonhg.NetBSD.org/src/rev/8f65861d7be1
branches:  trunk
changeset: 758063:8f65861d7be1
user:      skrll <skrll%NetBSD.org@localhost>
date:      Sat Oct 16 10:27:06 2010 +0000

description:
Implement dl_iterate_phdr.

Somewhat taken from FreeBSD. Manual page from OpenBSD.

diffstat:

 distrib/sets/lists/comp/mi       |   5 +-
 include/link_elf.h               |  24 ++++++++++-
 lib/libc/dlfcn/dlfcn_elf.c       |  16 ++++++-
 libexec/ld.elf_so/headers.c      |  28 ++++++++-----
 libexec/ld.elf_so/load.c         |   5 +-
 libexec/ld.elf_so/map_object.c   |  63 +++++++++++++++++++++++++++++-
 libexec/ld.elf_so/rtld.c         |  41 ++++++++++++++++++-
 libexec/ld.elf_so/rtld.h         |  30 ++++++++++----
 libexec/ld.elf_so/symbol.c       |   5 +-
 rescue/list.ldd                  |   5 +-
 share/man/man3/Makefile          |   5 +-
 share/man/man3/dl_iterate_phdr.3 |  84 ++++++++++++++++++++++++++++++++++++++++
 sys/sys/exec_elf.h               |  24 +++++++----
 usr.bin/ldd/ldd.c                |   8 ++-
 14 files changed, 292 insertions(+), 51 deletions(-)

diffs (truncated from 768 to 300 lines):

diff -r 9c497e50730d -r 8f65861d7be1 distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi        Sat Oct 16 06:31:49 2010 +0000
+++ b/distrib/sets/lists/comp/mi        Sat Oct 16 10:27:06 2010 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: mi,v 1.1511 2010/10/15 12:29:17 skrll Exp $
+#      $NetBSD: mi,v 1.1512 2010/10/16 10:27:06 skrll Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -5588,6 +5588,7 @@
 ./usr/share/man/cat3/disklabel_dkcksum.0       comp-c-catman           .cat
 ./usr/share/man/cat3/disklabel_scan.0          comp-c-catman           .cat
 ./usr/share/man/cat3/div.0                     comp-c-catman           .cat
+./usr/share/man/cat3/dl_iterate_phdr.0         comp-c-catman           .cat
 ./usr/share/man/cat3/dladdr.0                  comp-c-catman           .cat
 ./usr/share/man/cat3/dlclose.0                 comp-c-catman           .cat
 ./usr/share/man/cat3/dlctl.0                   comp-c-catman           .cat
@@ -11541,6 +11542,7 @@
 ./usr/share/man/html3/dlclose.html             comp-c-htmlman          html
 ./usr/share/man/html3/dlctl.html               comp-c-htmlman          html
 ./usr/share/man/html3/dlerror.html             comp-c-htmlman          html
+./usr/share/man/html3/dl_iterate_phdr.html     comp-c-htmlman          html
 ./usr/share/man/html3/dlfcn.html               comp-c-htmlman          html
 ./usr/share/man/html3/dlopen.html              comp-c-htmlman          html
 ./usr/share/man/html3/dlsym.html               comp-c-htmlman          html
@@ -17394,6 +17396,7 @@
 ./usr/share/man/man3/disklabel_dkcksum.3       comp-c-man              .man
 ./usr/share/man/man3/disklabel_scan.3          comp-c-man              .man
 ./usr/share/man/man3/div.3                     comp-c-man              .man
+./usr/share/man/man3/dl_iterate_phdr.3         comp-c-man              .man
 ./usr/share/man/man3/dladdr.3                  comp-c-man              .man
 ./usr/share/man/man3/dlclose.3                 comp-c-man              .man
 ./usr/share/man/man3/dlctl.3                   comp-c-man              .man
diff -r 9c497e50730d -r 8f65861d7be1 include/link_elf.h
--- a/include/link_elf.h        Sat Oct 16 06:31:49 2010 +0000
+++ b/include/link_elf.h        Sat Oct 16 10:27:06 2010 +0000
@@ -1,11 +1,10 @@
-/*     $NetBSD: link_elf.h,v 1.9 2010/10/14 07:51:21 skrll Exp $       */
+/*     $NetBSD: link_elf.h,v 1.10 2010/10/16 10:27:06 skrll Exp $      */
 
 #ifndef _LINK_ELF_H_
 #define        _LINK_ELF_H_
 
 #include <sys/types.h>
-
-#include <machine/elf_machdep.h>
+#include <sys/exec_elf.h>
 
 typedef struct link_map {
        caddr_t          l_addr;        /* Base Address of library */
@@ -32,4 +31,23 @@
        } r_state;
 };
 
+struct dl_phdr_info
+{
+       Elf_Addr dlpi_addr;                     /* module relocation base */
+       const char *dlpi_name;                  /* module name */
+       const Elf_Phdr *dlpi_phdr;              /* pointer to module's phdr */
+       Elf_Half dlpi_phnum;                    /* number of entries in phdr */
+       unsigned long long int dlpi_adds;       /* total # of loads */
+       unsigned long long int dlpi_subs;       /* total # of unloads */
+       size_t dlpi_tls_modid;
+       void *dlpi_tls_data;
+};
+
+__BEGIN_DECLS
+
+int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
+    void *);
+
+__END_DECLS
+
 #endif /* _LINK_ELF_H_ */
diff -r 9c497e50730d -r 8f65861d7be1 lib/libc/dlfcn/dlfcn_elf.c
--- a/lib/libc/dlfcn/dlfcn_elf.c        Sat Oct 16 06:31:49 2010 +0000
+++ b/lib/libc/dlfcn/dlfcn_elf.c        Sat Oct 16 10:27:06 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dlfcn_elf.c,v 1.6 2009/09/24 21:21:33 pooka Exp $      */
+/*     $NetBSD: dlfcn_elf.c,v 1.7 2010/10/16 10:27:07 skrll Exp $      */
 
 /*
  * Copyright (c) 2000 Takuya SHIOZAKI
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: dlfcn_elf.c,v 1.6 2009/09/24 21:21:33 pooka Exp $");
+__RCSID("$NetBSD: dlfcn_elf.c,v 1.7 2010/10/16 10:27:07 skrll Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -45,6 +45,7 @@
 #define        dlerror         ___dlerror
 #define        dladdr          ___dladdr
 #define        dlinfo          ___dlinfo
+#define        dl_iterate_phdr         ___dl_iterate_phdr
 
 #define ELFSIZE ARCH_ELFSIZE
 #include "rtld.h"
@@ -56,6 +57,7 @@
 __weak_alias(dlerror,___dlerror)
 __weak_alias(dladdr,___dladdr)
 __weak_alias(dlinfo,___dlinfo)
+__weak_alias(dl_iterate_phdr,___dl_iterate_phdr)
 
 __weak_alias(__dlopen,___dlopen)
 __weak_alias(__dlclose,___dlclose)
@@ -63,6 +65,7 @@
 __weak_alias(__dlerror,___dlerror)
 __weak_alias(__dladdr,___dladdr)
 __weak_alias(__dlinfo,___dlinfo)
+__weak_alias(__dl_iterate_phdr,___dl_iterate_phdr)
 #endif
 
 /*
@@ -124,3 +127,12 @@
 
        return -1;
 }
+
+/*ARGSUSED*/
+int
+dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
+    void *data)
+{
+
+       return 0;
+}
diff -r 9c497e50730d -r 8f65861d7be1 libexec/ld.elf_so/headers.c
--- a/libexec/ld.elf_so/headers.c       Sat Oct 16 06:31:49 2010 +0000
+++ b/libexec/ld.elf_so/headers.c       Sat Oct 16 10:27:06 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: headers.c,v 1.35 2010/10/15 15:08:05 skrll Exp $        */
+/*     $NetBSD: headers.c,v 1.36 2010/10/16 10:27:07 skrll Exp $        */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.35 2010/10/15 15:08:05 skrll Exp $");
+__RCSID("$NetBSD: headers.c,v 1.36 2010/10/16 10:27:07 skrll Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -307,20 +307,27 @@
        const Elf_Phdr *phlimit = phdr + phnum;
        const Elf_Phdr *ph;
        int             nsegs = 0;
-       ptrdiff_t       relocoffs = 0;
        Elf_Addr        vaddr;
 
        obj = _rtld_obj_new();
+
        for (ph = phdr; ph < phlimit; ++ph) {
-               vaddr = ph->p_vaddr + relocoffs;
+               if (ph->p_type != PT_PHDR)
+                       continue;
+               
+               obj->phdr = (void *)(uintptr_t)phdr->p_vaddr;
+               obj->phsize = phdr->p_memsz;
+               obj->relocbase = (caddr_t)((uintptr_t)phdr - (uintptr_t)ph->p_vaddr);
+               dbg(("headers: phdr %p phsize %zu relocbase %lx", obj->phdr,
+                   obj->phsize, (long)obj->relocbase));
+               break;
+       }
+       assert(obj->phdr == phdr);
+       
+       for (ph = phdr; ph < phlimit; ++ph) {
+               vaddr = (Elf_Addr)obj->relocbase + ph->p_vaddr;
                switch (ph->p_type) {
 
-               case PT_PHDR:
-                       relocoffs = (uintptr_t)phdr - (uintptr_t)ph->p_vaddr;
-                       dbg(("headers: phdr %p phsize %zu relocoffs %lx", obj->phdr,
-                           obj->phsize, (long)relocoffs));
-                       break;
-
                case PT_INTERP:
                        obj->interp = (const char *)(uintptr_t)vaddr;
                        break;
@@ -330,7 +337,6 @@
                        if (nsegs == 0) {       /* First load segment */
                                obj->vaddrbase = round_down(vaddr);
                                obj->mapbase = (caddr_t)(uintptr_t)obj->vaddrbase;
-                               obj->relocbase = (void *)relocoffs;
                                obj->textsize = round_up(vaddr + ph->p_memsz) -
                                    obj->vaddrbase;
                        } else {                /* Last load segment */
diff -r 9c497e50730d -r 8f65861d7be1 libexec/ld.elf_so/load.c
--- a/libexec/ld.elf_so/load.c  Sat Oct 16 06:31:49 2010 +0000
+++ b/libexec/ld.elf_so/load.c  Sat Oct 16 10:27:06 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: load.c,v 1.37 2010/02/27 11:16:38 roy Exp $     */
+/*     $NetBSD: load.c,v 1.38 2010/10/16 10:27:07 skrll Exp $   */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: load.c,v 1.37 2010/02/27 11:16:38 roy Exp $");
+__RCSID("$NetBSD: load.c,v 1.38 2010/10/16 10:27:07 skrll Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -156,6 +156,7 @@
                *_rtld_objtail = obj;
                _rtld_objtail = &obj->next;
                _rtld_objcount++;
+               _rtld_objloads++;
 #ifdef RTLD_LOADER
                _rtld_linkmap_add(obj); /* for GDB */
 #endif
diff -r 9c497e50730d -r 8f65861d7be1 libexec/ld.elf_so/map_object.c
--- a/libexec/ld.elf_so/map_object.c    Sat Oct 16 06:31:49 2010 +0000
+++ b/libexec/ld.elf_so/map_object.c    Sat Oct 16 10:27:06 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: map_object.c,v 1.40 2010/09/11 11:11:52 skrll Exp $     */
+/*     $NetBSD: map_object.c,v 1.41 2010/10/16 10:27:07 skrll Exp $     */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.40 2010/09/11 11:11:52 skrll Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.41 2010/10/16 10:27:07 skrll Exp $");
 #endif /* not lint */
 
 #include <errno.h>
@@ -46,10 +46,13 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 
+#include "debug.h"
 #include "rtld.h"
 
 static int protflags(int);     /* Elf flags -> mmap protection */
 
+#define EA_UNDEF               (~(Elf_Addr)0)
+
 /*
  * Map a shared object into memory.  The argument is a file descriptor,
  * which must be open on the object and positioned at its beginning.
@@ -63,6 +66,7 @@
        Obj_Entry       *obj;
        Elf_Ehdr        *ehdr;
        Elf_Phdr        *phdr;
+       size_t           phsize;
        Elf_Phdr        *phlimit;
        Elf_Phdr        *segs[2];
        int              nsegs;
@@ -83,8 +87,11 @@
        Elf_Addr         data_vlimit;
        int              data_flags;
        caddr_t          data_addr;
+       Elf_Addr         phdr_vaddr;
+       size_t           phdr_memsz;
        caddr_t          gap_addr;
        size_t           gap_size;
+       int i;
 #ifdef RTLD_LOADER
        Elf_Addr         clear_vaddr;
        caddr_t          clear_addr;
@@ -152,27 +159,42 @@
          * in that order.
          */
        phdr = (Elf_Phdr *) ((caddr_t)ehdr + ehdr->e_phoff);
+       phsize = ehdr->e_phnum * sizeof(phdr[0]);
+       obj->phdr = NULL;
+       phdr_vaddr = EA_UNDEF;
+       phdr_memsz = 0;
        phlimit = phdr + ehdr->e_phnum;
        nsegs = 0;
        while (phdr < phlimit) {
                switch (phdr->p_type) {
                case PT_INTERP:
                        obj->interp = (void *)(uintptr_t)phdr->p_vaddr;
+                       dbg(("%s: PT_INTERP %p", obj->path, obj->interp));
                        break;
 
                case PT_LOAD:
                        if (nsegs < 2)
                                segs[nsegs] = phdr;
                        ++nsegs;
+                       dbg(("%s: PT_LOAD %p", obj->path, phdr));
                        break;
 
+               case PT_PHDR:
+                       phdr_vaddr = phdr->p_vaddr;
+                       phdr_memsz = phdr->p_memsz;
+                       dbg(("%s: PT_PHDR %p phsize %zu", obj->path,
+                           (void *)(uintptr_t)phdr_vaddr, phdr_memsz));
+                       break;
+               



Home | Main Index | Thread Index | Old Index