Module Name: src
Committed By: skrll
Date: Sat Oct 16 10:27:08 UTC 2010
Modified Files:
src/distrib/sets/lists/comp: mi
src/include: link_elf.h
src/lib/libc/dlfcn: dlfcn_elf.c
src/libexec/ld.elf_so: headers.c load.c map_object.c rtld.c rtld.h
symbol.c
src/rescue: list.ldd
src/share/man/man3: Makefile
src/sys/sys: exec_elf.h
src/usr.bin/ldd: ldd.c
Added Files:
src/share/man/man3: dl_iterate_phdr.3
Log Message:
Implement dl_iterate_phdr.
Somewhat taken from FreeBSD. Manual page from OpenBSD.
To generate a diff of this commit:
cvs rdiff -u -r1.1511 -r1.1512 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.9 -r1.10 src/include/link_elf.h
cvs rdiff -u -r1.6 -r1.7 src/lib/libc/dlfcn/dlfcn_elf.c
cvs rdiff -u -r1.35 -r1.36 src/libexec/ld.elf_so/headers.c
cvs rdiff -u -r1.37 -r1.38 src/libexec/ld.elf_so/load.c
cvs rdiff -u -r1.40 -r1.41 src/libexec/ld.elf_so/map_object.c
cvs rdiff -u -r1.130 -r1.131 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.94 -r1.95 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.53 -r1.54 src/libexec/ld.elf_so/symbol.c
cvs rdiff -u -r1.3 -r1.4 src/rescue/list.ldd
cvs rdiff -u -r1.55 -r1.56 src/share/man/man3/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man3/dl_iterate_phdr.3
cvs rdiff -u -r1.105 -r1.106 src/sys/sys/exec_elf.h
cvs rdiff -u -r1.14 -r1.15 src/usr.bin/ldd/ldd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/comp/mi
diff -u src/distrib/sets/lists/comp/mi:1.1511 src/distrib/sets/lists/comp/mi:1.1512
--- src/distrib/sets/lists/comp/mi:1.1511 Fri Oct 15 12:29:17 2010
+++ src/distrib/sets/lists/comp/mi Sat Oct 16 10:27:06 2010
@@ -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
Index: src/include/link_elf.h
diff -u src/include/link_elf.h:1.9 src/include/link_elf.h:1.10
--- src/include/link_elf.h:1.9 Thu Oct 14 07:51:21 2010
+++ src/include/link_elf.h Sat Oct 16 10:27:06 2010
@@ -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_ */
Index: src/lib/libc/dlfcn/dlfcn_elf.c
diff -u src/lib/libc/dlfcn/dlfcn_elf.c:1.6 src/lib/libc/dlfcn/dlfcn_elf.c:1.7
--- src/lib/libc/dlfcn/dlfcn_elf.c:1.6 Thu Sep 24 21:21:33 2009
+++ src/lib/libc/dlfcn/dlfcn_elf.c Sat Oct 16 10:27:07 2010
@@ -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;
+}
Index: src/libexec/ld.elf_so/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.35 src/libexec/ld.elf_so/headers.c:1.36
--- src/libexec/ld.elf_so/headers.c:1.35 Fri Oct 15 15:08:05 2010
+++ src/libexec/ld.elf_so/headers.c Sat Oct 16 10:27:07 2010
@@ -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) {
+ 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 = ph->p_vaddr + relocoffs;
+ 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 */
Index: src/libexec/ld.elf_so/load.c
diff -u src/libexec/ld.elf_so/load.c:1.37 src/libexec/ld.elf_so/load.c:1.38
--- src/libexec/ld.elf_so/load.c:1.37 Sat Feb 27 11:16:38 2010
+++ src/libexec/ld.elf_so/load.c Sat Oct 16 10:27:07 2010
@@ -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
Index: src/libexec/ld.elf_so/map_object.c
diff -u src/libexec/ld.elf_so/map_object.c:1.40 src/libexec/ld.elf_so/map_object.c:1.41
--- src/libexec/ld.elf_so/map_object.c:1.40 Sat Sep 11 11:11:52 2010
+++ src/libexec/ld.elf_so/map_object.c Sat Oct 16 10:27:07 2010
@@ -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;
+
case PT_DYNAMIC:
obj->dynamic = (void *)(uintptr_t)phdr->p_vaddr;
+ dbg(("%s: PT_DYNAMIC %p", obj->path, obj->dynamic));
break;
}
++phdr;
}
+ phdr = (Elf_Phdr *) ((caddr_t)ehdr + ehdr->e_phoff);
obj->entry = (void *)(uintptr_t)ehdr->e_entry;
if (!obj->dynamic) {
_rtld_error("%s: not dynamically linked", path);
@@ -216,6 +238,39 @@
obj->vaddrbase = base_vaddr;
obj->isdynamic = ehdr->e_type == ET_DYN;
+ obj->phdr_loaded = false;
+ for (i = 0; i < nsegs; i++) {
+ if (phdr_vaddr != EA_UNDEF &&
+ segs[i]->p_vaddr <= phdr_vaddr &&
+ segs[i]->p_memsz >= phdr_memsz) {
+ obj->phdr_loaded = true;
+ break;
+ }
+ if (segs[i]->p_offset <= ehdr->e_phoff &&
+ segs[i]->p_memsz >= phsize) {
+ phdr_vaddr = segs[i]->p_vaddr + ehdr->e_phoff;
+ phdr_memsz = phsize;
+ obj->phdr_loaded = true;
+ break;
+ }
+ }
+ if (obj->phdr_loaded) {
+ obj->phdr = (void *)(uintptr_t)phdr_vaddr;
+ obj->phsize = phdr_memsz;
+ } else {
+ Elf_Phdr *buf;
+ buf = xmalloc(phsize);
+ if (buf == NULL) {
+ _rtld_error("%s: cannot allocate program header", path);
+ goto bad;
+ }
+ memcpy(buf, phdr, phsize);
+ obj->phdr = buf;
+ obj->phsize = phsize;
+ }
+ dbg(("%s: phdr %p phsize %zu (%s)", obj->path, obj->phdr, obj->phsize,
+ obj->phdr_loaded ? "loaded" : "allocated"));
+
/* Unmap header if it overlaps the first load section. */
if (base_offset < _rtld_pagesz) {
munmap(ehdr, _rtld_pagesz);
@@ -294,6 +349,8 @@
obj->entry = (void *)(obj->relocbase + (Elf_Addr)(uintptr_t)obj->entry);
if (obj->interp)
obj->interp = (void *)(obj->relocbase + (Elf_Addr)(uintptr_t)obj->interp);
+ if (obj->phdr_loaded)
+ obj->phdr = (void *)(obj->relocbase + (Elf_Addr)(uintptr_t)obj->phdr);
return obj;
@@ -325,6 +382,8 @@
SIMPLEQ_REMOVE_HEAD(&obj->dagmembers, link);
xfree(elm);
}
+ if (!obj->phdr_loaded)
+ xfree((void *)(uintptr_t)obj->phdr);
xfree(obj);
#ifdef COMBRELOC
_rtld_combreloc_reset(obj);
Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.130 src/libexec/ld.elf_so/rtld.c:1.131
--- src/libexec/ld.elf_so/rtld.c:1.130 Thu Mar 18 22:17:55 2010
+++ src/libexec/ld.elf_so/rtld.c Sat Oct 16 10:27:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.130 2010/03/18 22:17:55 roy Exp $ */
+/* $NetBSD: rtld.c,v 1.131 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: rtld.c,v 1.130 2010/03/18 22:17:55 roy Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.131 2010/10/16 10:27:07 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -83,9 +83,10 @@
bool _rtld_trust; /* False for setuid and setgid programs */
Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */
Obj_Entry **_rtld_objtail; /* Link field of last object in list */
-int _rtld_objcount; /* Number of shared objects */
Obj_Entry *_rtld_objmain; /* The main program shared object */
Obj_Entry _rtld_objself; /* The dynamic linker shared object */
+u_int _rtld_objcount; /* Number of objects in _rtld_objlist */
+u_int _rtld_objloads; /* Number of objects loaded in _rtld_objlist */
const char _rtld_path[] = _PATH_RTLD;
/* Initialize a fake symbol for resolving undefined weak references. */
@@ -501,6 +502,8 @@
/* Link the main program into the list of objects. */
*_rtld_objtail = _rtld_objmain;
_rtld_objtail = &_rtld_objmain->next;
+ _rtld_objcount++;
+ _rtld_objloads++;
_rtld_linkmap_add(_rtld_objmain);
_rtld_linkmap_add(&_rtld_objself);
@@ -1042,6 +1045,38 @@
return 0;
}
+__strong_alias(__dl_iterate_phdr,dl_iterate_phdr);
+int
+dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *param)
+{
+ struct dl_phdr_info phdr_info;
+ const Obj_Entry *obj;
+ int error = 0;
+
+ for (obj = _rtld_objlist; 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]);
+#if 1
+ phdr_info.dlpi_tls_modid = 0;
+ phdr_info.dlpi_tls_data = 0;
+#else
+ phdr_info.dlpi_tls_modid = obj->tlsindex;
+ phdr_info.dlpi_tls_data = obj->tlsinit;
+#endif
+ phdr_info.dlpi_adds = _rtld_objloads;
+ phdr_info.dlpi_subs = _rtld_objloads - _rtld_objcount;
+
+ error = callback(&phdr_info, sizeof(phdr_info), param);
+ if (error)
+ break;
+ }
+
+ return error;
+}
+
/*
* Error reporting function. Use it like printf. If formats the message
* into a buffer, and sets things up so that the next call to dlerror()
Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.94 src/libexec/ld.elf_so/rtld.h:1.95
--- src/libexec/ld.elf_so/rtld.h:1.94 Sun Oct 10 21:27:16 2010
+++ src/libexec/ld.elf_so/rtld.h Sat Oct 16 10:27:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.94 2010/10/10 21:27:16 christos Exp $ */
+/* $NetBSD: rtld.h,v 1.95 2010/10/16 10:27:07 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -85,6 +85,11 @@
typedef SIMPLEQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
+typedef struct Struct_Name_Entry {
+ STAILQ_ENTRY(Struct_Name_Entry) link;
+ char name[1];
+} Name_Entry;
+
typedef struct Struct_Needed_Entry {
struct Struct_Needed_Entry *next;
struct Struct_Obj_Entry *obj;
@@ -142,8 +147,8 @@
caddr_t relocbase; /* Reloc const = mapbase - *vaddrbase */
Elf_Dyn *dynamic; /* Dynamic section */
caddr_t entry; /* Entry point */
- const Elf_Phdr *__junk001;
- size_t pathlen; /* Pathname length */
+ const Elf_Phdr *phdr; /* Program header (may be xmalloc'ed) */
+ size_t phsize; /* Size of program header in bytes */
/* Items from the dynamic section. */
Elf_Addr *pltgot; /* PLTGOT table */
@@ -197,8 +202,10 @@
* called */
fini_called:1, /* True if .fini function has been
* called */
- initfirst:1; /* True if object's .init/.fini take
- * priority over others */
+ initfirst:1, /* True if object's .init/.fini take
+ * priority over others */
+ phdr_loaded:1; /* Phdr is loaded and doesn't need to
+ * be freed. */
struct link_map linkmap; /* for GDB */
@@ -215,6 +222,9 @@
uint32_t nbuckets_m; /* Precomputed for fast remainder */
uint8_t nbuckets_s1;
uint8_t nbuckets_s2;
+ size_t pathlen; /* Pathname length */
+ STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we
+ know about. */
} Obj_Entry;
typedef struct Struct_DoneList {
@@ -230,7 +240,8 @@
extern Search_Path *_rtld_default_paths;
extern Obj_Entry *_rtld_objlist;
extern Obj_Entry **_rtld_objtail;
-extern int _rtld_objcount;
+extern u_int _rtld_objcount;
+extern u_int _rtld_objloads;
extern Obj_Entry *_rtld_objmain;
extern Obj_Entry _rtld_objself;
extern Search_Path *_rtld_paths;
@@ -242,16 +253,17 @@
/* rtld.c */
-/*
- * We export these symbols using _rtld_symbol_lookup and is_exported.
- */
+/* We export these symbols using _rtld_symbol_lookup and is_exported. */
char *dlerror(void);
void *dlopen(const char *, int);
void *dlsym(void *, const char *);
int dlclose(void *);
int dladdr(const void *, Dl_info *);
int dlinfo(void *, int, void *);
+int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
+ void *);
+/* These aren't exported */
void _rtld_error(const char *, ...)
__attribute__((__format__(__printf__,1,2)));
void _rtld_die(void) __attribute__((__noreturn__));
Index: src/libexec/ld.elf_so/symbol.c
diff -u src/libexec/ld.elf_so/symbol.c:1.53 src/libexec/ld.elf_so/symbol.c:1.54
--- src/libexec/ld.elf_so/symbol.c:1.53 Mon Apr 5 14:01:26 2010
+++ src/libexec/ld.elf_so/symbol.c Sat Oct 16 10:27:07 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: symbol.c,v 1.53 2010/04/05 14:01:26 joerg Exp $ */
+/* $NetBSD: symbol.c,v 1.54 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: symbol.c,v 1.53 2010/04/05 14:01:26 joerg Exp $");
+__RCSID("$NetBSD: symbol.c,v 1.54 2010/10/16 10:27:07 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -92,6 +92,7 @@
(fptr_t)dlerror,
(fptr_t)dladdr,
(fptr_t)dlinfo,
+ (fptr_t)dl_iterate_phdr,
NULL
};
int i;
Index: src/rescue/list.ldd
diff -u src/rescue/list.ldd:1.3 src/rescue/list.ldd:1.4
--- src/rescue/list.ldd:1.3 Sat Feb 27 11:17:54 2010
+++ src/rescue/list.ldd Sat Oct 16 10:27:07 2010
@@ -1,4 +1,4 @@
-# $NetBSD: list.ldd,v 1.3 2010/02/27 11:17:54 roy Exp $
+# $NetBSD: list.ldd,v 1.4 2010/10/16 10:27:07 skrll Exp $
PROG ldd
@@ -8,5 +8,6 @@
SPECIAL ldd keepsymbols _rtld_pagesz _rtld_error _rtld_trust
SPECIAL ldd keepsymbols _rtld_default_paths _rtld_paths
SPECIAL ldd keepsymbols _rtld_xforms _rtld_objmain
-SPECIAL ldd keepsymbols _rtld_objtail _rtld_objlist _rtld_objcount
+SPECIAL ldd keepsymbols _rtld_objtail _rtld_objlist
+SPECIAL ldd keepsymbols _rtld_objcount _rtld_objloads
SPECIAL ldd keepsymbols print_needed main_local main_progname
Index: src/share/man/man3/Makefile
diff -u src/share/man/man3/Makefile:1.55 src/share/man/man3/Makefile:1.56
--- src/share/man/man3/Makefile:1.55 Tue Jun 8 08:51:09 2010
+++ src/share/man/man3/Makefile Sat Oct 16 10:27:08 2010
@@ -1,8 +1,9 @@
-# $NetBSD: Makefile,v 1.55 2010/06/08 08:51:09 jruoho Exp $
+# $NetBSD: Makefile,v 1.56 2010/10/16 10:27:08 skrll Exp $
# @(#)Makefile 8.2 (Berkeley) 12/13/93
MAN= _DIAGASSERT.3 __CONCAT.3 __UNCONST.3 CMSG_DATA.3 \
- __arraycount.3 assert.3 bits.3 bitstring.3 dirent.3 dlfcn.3 end.3 \
+ __arraycount.3 assert.3 bits.3 bitstring.3 dirent.3 \
+ dlfcn.3 dl_iterate_phdr.3 end.3 \
fast_divide32.3 ffs32.3 gcq.3 \
ilog2.3 intro.3 inttypes.3 iso646.3 \
offsetof.3 queue.3 rb.3 sigevent.3 \
Index: src/sys/sys/exec_elf.h
diff -u src/sys/sys/exec_elf.h:1.105 src/sys/sys/exec_elf.h:1.106
--- src/sys/sys/exec_elf.h:1.105 Thu Oct 14 07:57:34 2010
+++ src/sys/sys/exec_elf.h Sat Oct 16 10:27:08 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_elf.h,v 1.105 2010/10/14 07:57:34 skrll Exp $ */
+/* $NetBSD: exec_elf.h,v 1.106 2010/10/16 10:27:08 skrll Exp $ */
/*-
* Copyright (c) 1994 The NetBSD Foundation, Inc.
@@ -46,14 +46,6 @@
#include <inttypes.h>
#endif /* _KERNEL || _STANDALONE */
-#if defined(ELFSIZE)
-#define CONCAT(x,y) __CONCAT(x,y)
-#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
-#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
-#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
-#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
-#endif
-
#if HAVE_NBTOOL_CONFIG_H
#include <nbinclude/machine/elf_machdep.h>
#else
@@ -842,6 +834,18 @@
int32_t cpi_siglwp; /* LWP target of killing signal */
};
+#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
+#define ELFSIZE ARCH_ELFSIZE
+#endif
+
+#if defined(ELFSIZE)
+#define CONCAT(x,y) __CONCAT(x,y)
+#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
+#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
+#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
+#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
+#endif
+
#if defined(ELFSIZE) && (ELFSIZE == 32)
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Phdr Elf32_Phdr
@@ -852,6 +856,7 @@
#define Elf_Dyn Elf32_Dyn
#define Elf_Word Elf32_Word
#define Elf_Sword Elf32_Sword
+#define Elf_Half Elf32_Half
#define Elf_Addr Elf32_Addr
#define Elf_Off Elf32_Off
#define Elf_SOff Elf32_SOff
@@ -872,6 +877,7 @@
#define Elf_Dyn Elf64_Dyn
#define Elf_Word Elf64_Word
#define Elf_Sword Elf64_Sword
+#define Elf_Half Elf64_Half
#define Elf_Addr Elf64_Addr
#define Elf_Off Elf64_Off
#define Elf_SOff Elf64_SOff
Index: src/usr.bin/ldd/ldd.c
diff -u src/usr.bin/ldd/ldd.c:1.14 src/usr.bin/ldd/ldd.c:1.15
--- src/usr.bin/ldd/ldd.c:1.14 Sat Feb 27 11:17:05 2010
+++ src/usr.bin/ldd/ldd.c Sat Oct 16 10:27:08 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ldd.c,v 1.14 2010/02/27 11:17:05 roy Exp $ */
+/* $NetBSD: ldd.c,v 1.15 2010/10/16 10:27:08 skrll Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ldd.c,v 1.14 2010/02/27 11:17:05 roy Exp $");
+__RCSID("$NetBSD: ldd.c,v 1.15 2010/10/16 10:27:08 skrll Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -92,7 +92,9 @@
Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */
Obj_Entry **_rtld_objtail = &_rtld_objlist;
/* Link field of last object in list */
-int _rtld_objcount; /* Number of shared objects */
+u_int _rtld_objcount; /* Number of shared objects */
+u_int _rtld_objloads; /* Number of objects loaded */
+
Obj_Entry *_rtld_objmain; /* The main program shared object */
size_t _rtld_pagesz;
Added files:
Index: src/share/man/man3/dl_iterate_phdr.3
diff -u /dev/null src/share/man/man3/dl_iterate_phdr.3:1.1
--- /dev/null Sat Oct 16 10:27:09 2010
+++ src/share/man/man3/dl_iterate_phdr.3 Sat Oct 16 10:27:08 2010
@@ -0,0 +1,84 @@
+.\" $NetBSD: dl_iterate_phdr.3,v 1.1 2010/10/16 10:27:08 skrll Exp $
+.\" $OpenBSD: dl_iterate_phdr.3,v 1.3 2007/05/31 19:19:48 jmc Exp $
+.\"
+.\" Copyright (c) 2005 Mark Kettenis
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd October 16, 2010
+.Dt DL_ITERATE_PHDR 3
+.Os
+.Sh NAME
+.Nm dl_iterate_phdr
+.Nd iterate over program headers
+.Sh SYNOPSIS
+.Fd #include <link.h>
+.Ft int
+.Fn dl_iterate_phdr "int (*callback)(struct dl_phdr_info *, size_t, void*)" "void *data"
+.Sh DESCRIPTION
+The
+.Fn dl_iterate_phdr
+function iterates over all shared objects loaded into a process's
+address space, calling
+.Fa callback
+for each shared object, passing it information about the object's
+program headers and the
+.Fa data
+argument.
+The information about the program headers is passed in a structure
+that is defined as:
+.Bd -literal
+struct dl_phdr_info {
+ Elf_Addr dlpi_addr;
+ const char *dlpi_name;
+ const Elf_Phdr *dlpi_phdr;
+ Elf_Half dlpi_phnum;
+ unsigned long long int dlpi_adds;
+ unsigned long long int dlpi_subs;
+ size_t dlpi_tls_modid;
+ void *dlpi_tls_data;
+};
+.Ed
+.Pp
+The members of
+.Li struct dl_phdr_info
+have the following meaning:
+.Bl -tag -width XXXdlpi_phdr
+.It Fa dlpi_addr
+The base address at which the shared object is mapped into the address
+space of the calling process.
+.It Fa dlpi_name
+The name of the shared object.
+.It Fa dlpi_phdr
+A pointer to the shared object's program headers.
+.It Fa dlpi_phnum
+The number of program headers in the shared object.
+.It Fa dlpi_adds
+The number of objects added into the main program.
+.It Fa dlpi_subs
+The number of objects removed from the main program.
+.El
+.Pp
+To make it possible for programs to check whether any new members have
+been added, the size of the structure is passed as an argument to
+.Fa callback .
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr ld.elf_so 1 ,
+.Xr dlfcn 3 ,
+.Xr elf 5
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 6.0 .