summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libexec/rtld-elf/rtld.15
-rw-r--r--libexec/rtld-elf/rtld.c8
-rw-r--r--usr.bin/ldd/ldd.18
-rw-r--r--usr.bin/ldd/ldd.c16
4 files changed, 30 insertions, 7 deletions
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index b32b08d..dad1a63 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -107,6 +107,11 @@ When set to a nonempty string, causes
.Nm
to exit after loading the shared objects and printing a summary which includes
the absolute pathnames of all objects, to standard output.
+.It Ev LD_TRACE_LOADED_OBJECTS_ALL
+When set to a nonempty string, causes
+.Nm
+to expand the summary to indicate which objects caused each object to
+be loaded.
.It Ev LD_TRACE_LOADED_OBJECTS_FMT1
.It Ev LD_TRACE_LOADED_OBJECTS_FMT2
When set, these variables are interpreted as format strings a la
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 100f011..abc95e8 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2010,7 +2010,7 @@ symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
static void
trace_loaded_objects(Obj_Entry *obj)
{
- char *fmt1, *fmt2, *fmt, *main_local;
+ char *fmt1, *fmt2, *fmt, *main_local, *list_containers;
int c;
if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
@@ -2022,14 +2022,18 @@ trace_loaded_objects(Obj_Entry *obj)
if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
fmt2 = "\t%o (%x)\n";
+ list_containers = getenv("LD_TRACE_LOADED_OBJECTS_ALL");
+
for (; obj; obj = obj->next) {
Needed_Entry *needed;
char *name, *path;
bool is_lib;
+ if (list_containers && obj->needed != NULL)
+ printf("%s:\n", obj->path);
for (needed = obj->needed; needed; needed = needed->next) {
if (needed->obj != NULL) {
- if (needed->obj->traced)
+ if (needed->obj->traced && !list_containers)
continue;
needed->obj->traced = true;
path = needed->obj->path;
diff --git a/usr.bin/ldd/ldd.1 b/usr.bin/ldd/ldd.1
index 470fd42..a631df2 100644
--- a/usr.bin/ldd/ldd.1
+++ b/usr.bin/ldd/ldd.1
@@ -8,6 +8,7 @@
.Nd list dynamic object dependencies
.Sh SYNOPSIS
.Nm
+.Op Fl a
.Op Fl v
.Op Fl f Ar format
.Ar program ...
@@ -35,6 +36,13 @@ See
for a list of recognized conversion characters.
.Pp
The
+.Fl a
+option displays the list of all objects that are needed by each loaded
+object. This option does not work with
+.Xr a.out 5
+binaries.
+.Pp
+The
.Fl v
option displays an verbose listing of the dynamic linking headers
encoded in the executable. See the source code and include
diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c
index fc20467..19db2f1 100644
--- a/usr.bin/ldd/ldd.c
+++ b/usr.bin/ldd/ldd.c
@@ -49,7 +49,7 @@ extern int error_count;
void
usage()
{
- fprintf(stderr, "usage: ldd [-v] [-f format] program ...\n");
+ fprintf(stderr, "usage: ldd [-a] [-v] [-f format] program ...\n");
exit(1);
}
@@ -61,10 +61,15 @@ char *argv[];
char *fmt1 = NULL, *fmt2 = NULL;
int rval;
int c;
- int vflag = 0;
+ int aflag, vflag;
- while ((c = getopt(argc, argv, "vf:")) != -1) {
+ aflag = vflag = 0;
+
+ while ((c = getopt(argc, argv, "avf:")) != -1) {
switch (c) {
+ case 'a':
+ aflag++;
+ break;
case 'v':
vflag++;
break;
@@ -101,7 +106,7 @@ char *argv[];
#endif
/* ld.so magic */
- setenv("LD_TRACE_LOADED_OBJECTS", "1", 1);
+ setenv("LD_TRACE_LOADED_OBJECTS", "yes", 1);
if (fmt1)
setenv("LD_TRACE_LOADED_OBJECTS_FMT1", fmt1, 1);
if (fmt2)
@@ -190,7 +195,8 @@ char *argv[];
}
setenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", *argv, 1);
- if (fmt1 == NULL && fmt2 == NULL)
+ if (aflag) setenv("LD_TRACE_LOADED_OBJECTS_ALL", "1", 1);
+ else if (fmt1 == NULL && fmt2 == NULL)
/* Default formats */
printf("%s:\n", *argv);
OpenPOWER on IntegriCloud