Implement dl_iterate_phdr.
Somewhat taken from FreeBSD. Manual page from OpenBSD.
This commit is contained in:
parent
a00a1fe7ff
commit
e6cdac9c4b
|
@ -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
|
||||
|
|
|
@ -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 @@ struct r_debug {
|
|||
} 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_ */
|
||||
|
|
|
@ -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 @@ __RCSID("$NetBSD: dlfcn_elf.c,v 1.6 2009/09/24 21:21:33 pooka Exp $");
|
|||
#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(dlsym,___dlsym)
|
|||
__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(__dlsym,___dlsym)
|
|||
__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 @@ dlinfo(void *handle, int req, void *v)
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
|
||||
void *data)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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,19 +307,26 @@ _rtld_digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
|
|||
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;
|
||||
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;
|
||||
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 = (Elf_Addr)obj->relocbase + ph->p_vaddr;
|
||||
switch (ph->p_type) {
|
||||
|
||||
case PT_INTERP:
|
||||
obj->interp = (const char *)(uintptr_t)vaddr;
|
||||
|
@ -330,7 +337,6 @@ _rtld_digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
|
|||
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 */
|
||||
|
|
|
@ -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_load_object(const char *filepath, int mode)
|
|||
*_rtld_objtail = obj;
|
||||
_rtld_objtail = &obj->next;
|
||||
_rtld_objcount++;
|
||||
_rtld_objloads++;
|
||||
#ifdef RTLD_LOADER
|
||||
_rtld_linkmap_add(obj); /* for GDB */
|
||||
#endif
|
||||
|
|
|
@ -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 @@ __RCSID("$NetBSD: map_object.c,v 1.40 2010/09/11 11:11:52 skrll Exp $");
|
|||
#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 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
|
|||
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 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
|
|||
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 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
|
|||
* 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 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
|
|||
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 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
|
|||
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 @@ _rtld_obj_free(Obj_Entry *obj)
|
|||
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);
|
||||
|
|
|
@ -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 @@ struct r_debug _rtld_debug; /* for GDB; */
|
|||
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 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
|
|||
/* 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 @@ dlinfo(void *handle, int req, void *v)
|
|||
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()
|
||||
|
|
|
@ -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 struct Struct_Objlist_Entry {
|
|||
|
||||
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 @@ typedef struct Struct_Obj_Entry {
|
|||
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 @@ typedef struct Struct_Obj_Entry {
|
|||
* 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 @@ typedef struct Struct_Obj_Entry {
|
|||
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 struct r_debug _rtld_debug;
|
|||
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 @@ extern Elf_Sym _rtld_sym_zero;
|
|||
|
||||
/* 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__));
|
||||
|
|
|
@ -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 @@ _rtld_is_exported(const Elf_Sym *def)
|
|||
(fptr_t)dlerror,
|
||||
(fptr_t)dladdr,
|
||||
(fptr_t)dlinfo,
|
||||
(fptr_t)dl_iterate_phdr,
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
|
|
@ -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 @@ LIBS ${LDD_ELF64DIR}/libldd_elf64.a
|
|||
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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 .
|
|
@ -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 @@ struct netbsd_elfcore_procinfo {
|
|||
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 @@ struct netbsd_elfcore_procinfo {
|
|||
#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 @@ struct netbsd_elfcore_procinfo {
|
|||
#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
|
||||
|
|
|
@ -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 @@ bool _rtld_trust; /* False for setuid and setgid programs */
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue