summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2007-04-03 18:31:20 +0000
committerkan <kan@FreeBSD.org>2007-04-03 18:31:20 +0000
commit0dd97e2c183c4064e9883accc0097616edb73c80 (patch)
tree2f24e02761b238e127c61dd19755bf947aa24006 /libexec/rtld-elf/rtld.c
parent34c2527aa4837fb3920e7a6fa68ac03a68012223 (diff)
downloadFreeBSD-src-0dd97e2c183c4064e9883accc0097616edb73c80.zip
FreeBSD-src-0dd97e2c183c4064e9883accc0097616edb73c80.tar.gz
Implement dl_iterate_phdr function.
Convert boolean flags in internal Obj_Entry structure into bitfields. Properly check for loaded segment alignment in map_object.
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index e8e31c5..174c6ea 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -164,6 +164,7 @@ static Obj_Entry **obj_tail; /* Link field of last object in list */
static Obj_Entry *obj_main; /* The main program shared object */
static Obj_Entry obj_rtld; /* The dynamic linker shared object */
static unsigned int obj_count; /* Number of objects in obj_list */
+static unsigned int obj_loads; /* Number of objects in obj_list */
static Objlist list_global = /* Objects dlopened with RTLD_GLOBAL */
STAILQ_HEAD_INITIALIZER(list_global);
@@ -204,6 +205,7 @@ static func_ptr_type exports[] = {
(func_ptr_type) &__tls_get_addr,
(func_ptr_type) &_rtld_allocate_tls,
(func_ptr_type) &_rtld_free_tls,
+ (func_ptr_type) &dl_iterate_phdr,
NULL
};
@@ -423,6 +425,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
*obj_tail = obj_main;
obj_tail = &obj_main->next;
obj_count++;
+ obj_loads++;
/* Make sure we don't call the main program's init and fini functions. */
obj_main->init = obj_main->fini = (Elf_Addr)NULL;
@@ -1387,6 +1390,7 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp)
*obj_tail = obj;
obj_tail = &obj->next;
obj_count++;
+ obj_loads++;
linkmap_add(obj); /* for GDB & dlinfo() */
dbg(" %p .. %p: %s", obj->mapbase,
@@ -2079,6 +2083,37 @@ dlinfo(void *handle, int request, void *p)
return (error);
}
+int
+dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
+{
+ struct dl_phdr_info phdr_info;
+ const Obj_Entry *obj;
+ int error, lockstate;
+
+ lockstate = rlock_acquire(rtld_bind_lock);
+
+ 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;
+
+ if ((error = callback(&phdr_info, sizeof phdr_info, param)) != 0)
+ break;
+
+ }
+ rlock_release(rtld_bind_lock, lockstate);
+
+ return (error);
+}
+
struct fill_search_info_args {
int request;
unsigned int flags;
OpenPOWER on IntegriCloud