git: 0913953c9ed0 - main - rtld: trace preloaded objects

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 01 Apr 2022 00:51:32 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=0913953c9ed0f6ac3dd57aa06e1d7c8a1a6c5530

commit 0913953c9ed0f6ac3dd57aa06e1d7c8a1a6c5530
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-03-30 21:01:54 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-04-01 00:51:22 +0000

    rtld: trace preloaded objects
    
    Before, preloaded objects, if not listed as needed for any normally
    linked objects, were silently ignored.
    
    Preloaded objects are printed with the `[preloaded]` herald. The list
    includes the objects not listed explicitly as recursive dependencies of
    the main object, effectively dsos loaded by LD_PRELOAD mechanism.
    vdso is listed as well, since it is not needed by anything.
    
    Since there is no DT_NEEDED entry for LD_PRELOADed objects, they are
    usually printed using LD_TRACE_LOADED_OBJECTS_FTM2 format due to the
    failure of the heuristic based on the presence of the 'lib' prefix.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D34716
---
 libexec/rtld-elf/rtld.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 3860e1dba3eb..6e499ebc5208 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -172,7 +172,7 @@ static int symlook_needed(SymLook *, const Needed_Entry *, DoneList *);
 static int symlook_obj1_sysv(SymLook *, const Obj_Entry *);
 static int symlook_obj1_gnu(SymLook *, const Obj_Entry *);
 static void *tls_get_addr_slow(Elf_Addr **, int, size_t, bool) __noinline;
-static void trace_loaded_objects(Obj_Entry *);
+static void trace_loaded_objects(Obj_Entry *, bool);
 static void unlink_object(Obj_Entry *);
 static void unload_object(Obj_Entry *, RtldLockState *lockstate);
 static void unref_dag(Obj_Entry *);
@@ -872,7 +872,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
        dump_auxv(aux_info);
 
     if (ld_tracing) {		/* We're done */
-	trace_loaded_objects(obj_main);
+	trace_loaded_objects(obj_main, true);
 	exit(0);
     }
 
@@ -3834,7 +3834,7 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
 	lock_release(rtld_bind_lock, lockstate);
     return (obj);
 trace:
-    trace_loaded_objects(obj);
+    trace_loaded_objects(obj, false);
     if (lockstate == &mlockstate)
 	lock_release(rtld_bind_lock, lockstate);
     exit(0);
@@ -4992,17 +4992,17 @@ trace_print_obj(Obj_Entry *obj, const char *name, const char *path,
 }
 
 static void
-trace_loaded_objects(Obj_Entry *obj)
+trace_loaded_objects(Obj_Entry *obj, bool show_preload)
 {
 	const char *fmt1, *fmt2, *main_local;
-	bool list_containers;
+	const char *name, *path;
+	bool first_spurious, list_containers;
 
 	trace_calc_fmts(&main_local, &fmt1, &fmt2);
 	list_containers = ld_get_env_var(LD_TRACE_LOADED_OBJECTS_ALL) != NULL;
 
 	for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
 		Needed_Entry *needed;
-		const char *name, *path;
 
 		if (obj->marker)
 			continue;
@@ -5022,6 +5022,23 @@ trace_loaded_objects(Obj_Entry *obj)
 			    fmt1, fmt2);
 		}
 	}
+
+	if (show_preload) {
+		first_spurious = true;
+		TAILQ_FOREACH(obj, &obj_list, next) {
+			if (obj->marker || obj == obj_main || obj->traced)
+				continue;
+
+			if (first_spurious) {
+				rtld_printf("[preloaded]\n");
+				first_spurious = false;
+			}
+			Name_Entry *fname = STAILQ_FIRST(&obj->names);
+			name = fname == NULL ? "<unknown>" : fname->name;
+			trace_print_obj(obj, name, obj->path, main_local,
+			    fmt1, fmt2);
+		}
+	}
 }
 
 /*