summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2002-02-04 10:33:48 +0000
committersobomax <sobomax@FreeBSD.org>2002-02-04 10:33:48 +0000
commit0a68f500fad520bd9e947259f71f0704362cde51 (patch)
tree0f41fb802fc9270b46740b35eb965449205e46a9 /libexec
parentc61b7216e49401a2e8eb5f81218c1fa5a181abbf (diff)
downloadFreeBSD-src-0a68f500fad520bd9e947259f71f0704362cde51.zip
FreeBSD-src-0a68f500fad520bd9e947259f71f0704362cde51.tar.gz
Allow ldd(1) be used on shared libraries in addition to executables.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/rtld.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index a083dea..100f011 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -107,6 +107,7 @@ static void objlist_remove_unref(Objlist *);
static int relocate_objects(Obj_Entry *, bool);
static void rtld_exit(void);
static char *search_library_path(const char *, const char *);
+static const void **get_program_var_addr(const char *name);
static void set_program_var(const char *, const void *);
static const Elf_Sym *symlook_default(const char *, unsigned long hash,
const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt);
@@ -1556,6 +1557,11 @@ dlopen(const char *name, int mode)
Obj_Entry **old_obj_tail;
Obj_Entry *obj;
Objlist initlist;
+ int result;
+
+ ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
+ if (ld_tracing != NULL)
+ environ = (char **)*get_program_var_addr("environ");
objlist_init(&initlist);
@@ -1581,7 +1587,14 @@ dlopen(const char *name, int mode)
if (*old_obj_tail != NULL) { /* We loaded something new. */
assert(*old_obj_tail == obj);
- if (load_needed_objects(obj) == -1 ||
+ result = load_needed_objects(obj);
+ if (result != -1 && ld_tracing) {
+ trace_loaded_objects(obj);
+ wlock_release();
+ exit(0);
+ }
+
+ if (result == -1 ||
(init_dag(obj), relocate_objects(obj, mode == RTLD_NOW)) == -1) {
obj->dl_refcount--;
unref_dag(obj);
@@ -1812,12 +1825,10 @@ r_debug_state(struct r_debug* rd, struct link_map *m)
}
/*
- * Set a pointer variable in the main program to the given value. This
- * is used to set key variables such as "environ" before any of the
- * init functions are called.
+ * Get address of the pointer variable in the main program.
*/
-static void
-set_program_var(const char *name, const void *value)
+static const void **
+get_program_var_addr(const char *name)
{
const Obj_Entry *obj;
unsigned long hash;
@@ -1830,11 +1841,26 @@ set_program_var(const char *name, const void *value)
const void **addr;
addr = (const void **)(obj->relocbase + def->st_value);
- dbg("\"%s\": *%p <-- %p", name, addr, value);
- *addr = value;
- break;
+ return addr;
}
}
+ return NULL;
+}
+
+/*
+ * Set a pointer variable in the main program to the given value. This
+ * is used to set key variables such as "environ" before any of the
+ * init functions are called.
+ */
+static void
+set_program_var(const char *name, const void *value)
+{
+ const void **addr;
+
+ if ((addr = get_program_var_addr(name)) != NULL) {
+ dbg("\"%s\": *%p <-- %p", name, addr, value);
+ *addr = value;
+ }
}
/*
OpenPOWER on IntegriCloud