Module Name:    src
Committed By:   kamil
Date:           Sun Sep 15 13:40:46 UTC 2019

Modified Files:
        src/libexec/ld.elf_so: rtld.c

Log Message:
Return the ELF loader dl_phdr_info information for dl_iterate_phdr(3)

Sync the behavior of dl_iterate_phdr(3) with Linux/FreeBSD/OpenBSD.


To generate a diff of this commit:
cvs rdiff -u -r1.197 -r1.198 src/libexec/ld.elf_so/rtld.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.197 src/libexec/ld.elf_so/rtld.c:1.198
--- src/libexec/ld.elf_so/rtld.c:1.197	Sun Apr 14 19:21:37 2019
+++ src/libexec/ld.elf_so/rtld.c	Sun Sep 15 13:40:46 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.c,v 1.197 2019/04/14 19:21:37 christos Exp $	 */
+/*	$NetBSD: rtld.c,v 1.198 2019/09/15 13:40:46 kamil Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.197 2019/04/14 19:21:37 christos Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.198 2019/09/15 13:40:46 kamil Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -134,6 +134,7 @@ static void _rtld_objlist_clear(Objlist 
 static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool);
 static void _rtld_unref_dag(Obj_Entry *);
 static Obj_Entry *_rtld_obj_from_addr(const void *);
+static void _rtld_fill_dl_phdr_info(const Obj_Entry *, struct dl_phdr_info *);
 
 static inline void
 _rtld_call_initfini_function(const Obj_Entry *obj, Elf_Addr func, sigset_t *mask)
@@ -344,6 +345,7 @@ restart:
 static void
 _rtld_init(caddr_t mapbase, caddr_t relocbase, const char *execname)
 {
+	const Elf_Ehdr *ehdr;
 
 	/* Conjure up an Obj_Entry structure for the dynamic linker. */
 	_rtld_objself.path = __UNCONST(_rtld_path);
@@ -394,6 +396,10 @@ _rtld_init(caddr_t mapbase, caddr_t relo
 
 	_rtld_debug.r_brk = _rtld_debug_state;
 	_rtld_debug.r_state = RT_CONSISTENT;
+
+	ehdr = (Elf_Ehdr *)mapbase;
+	_rtld_objself.phdr = (Elf_Phdr *)((char *)mapbase + ehdr->e_phoff);
+	_rtld_objself.phsize = ehdr->e_phnum * sizeof(_rtld_objself.phdr[0]);
 }
 
 /*
@@ -1433,6 +1439,26 @@ dlinfo(void *handle, int req, void *v)
 	return 0;
 }
 
+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;
+	/* XXX: wrong but not fixing it yet */
+	phdr_info->dlpi_name = obj->path;
+	phdr_info->dlpi_phdr = obj->phdr;
+	phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
+#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
+	phdr_info->dlpi_tls_modid = obj->tlsindex;
+	phdr_info->dlpi_tls_data = obj->tlsinit;
+#else
+	phdr_info->dlpi_tls_modid = 0;
+	phdr_info->dlpi_tls_data = 0;
+#endif
+	phdr_info->dlpi_adds = _rtld_objloads;
+	phdr_info->dlpi_subs = _rtld_objloads - _rtld_objcount;
+}
+
 __strong_alias(__dl_iterate_phdr,dl_iterate_phdr);
 int
 dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *param)
@@ -1446,20 +1472,7 @@ dl_iterate_phdr(int (*callback)(struct d
 	_rtld_shared_enter();
 
 	for (obj = _rtld_objlist;  obj != NULL;  obj = obj->next) {
-		phdr_info.dlpi_addr = (Elf_Addr)obj->relocbase;
-		/* XXX: wrong but not fixing it yet */
-		phdr_info.dlpi_name = obj->path;
-		phdr_info.dlpi_phdr = obj->phdr;
-		phdr_info.dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
-#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
-		phdr_info.dlpi_tls_modid = obj->tlsindex;
-		phdr_info.dlpi_tls_data = obj->tlsinit;
-#else
-		phdr_info.dlpi_tls_modid = 0;
-		phdr_info.dlpi_tls_data = 0;
-#endif
-		phdr_info.dlpi_adds = _rtld_objloads;
-		phdr_info.dlpi_subs = _rtld_objloads - _rtld_objcount;
+		_rtld_fill_dl_phdr_info(obj, &phdr_info);
 
 		/* XXXlocking: exit point */
 		error = callback(&phdr_info, sizeof(phdr_info), param);
@@ -1467,6 +1480,13 @@ dl_iterate_phdr(int (*callback)(struct d
 			break;
 	}
 
+	if (error == 0) {
+		_rtld_fill_dl_phdr_info(&_rtld_objself, &phdr_info);
+
+		/* XXXlocking: exit point */
+		error = callback(&phdr_info, sizeof(phdr_info), param);
+	}
+
 	_rtld_shared_exit();
 	return error;
 }

Reply via email to