diff options
author | dfr <dfr@FreeBSD.org> | 1998-05-01 08:39:27 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1998-05-01 08:39:27 +0000 |
commit | ac67dd4e68c1d174836e84ce2b9e319b1230f8ac (patch) | |
tree | 7dff389ffe7e5a3e74232c7d52036e5cec240567 /libexec | |
parent | 1caaf9212f2f49a3053269faa4e579b6daa9b841 (diff) | |
download | FreeBSD-src-ac67dd4e68c1d174836e84ce2b9e319b1230f8ac.zip FreeBSD-src-ac67dd4e68c1d174836e84ce2b9e319b1230f8ac.tar.gz |
Add support for ldd.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 50a392f..e233c51 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.1.1.1 1998/03/07 19:24:35 jdp Exp $ + * $Id: rtld.c,v 1.2 1998/04/30 07:48:00 dfr Exp $ */ /* @@ -93,6 +93,7 @@ static void unref_object_dag(Obj_Entry *); void r_debug_state(void); static void linkmap_add(Obj_Entry *); static void linkmap_delete(Obj_Entry *); +static void trace_loaded_objects(Obj_Entry *obj); void xprintf(const char *, ...); @@ -124,6 +125,7 @@ static bool trust; /* False for setuid and setgid programs */ static char *ld_bind_now; /* Environment variable for immediate binding */ static char *ld_debug; /* Environment variable for debugging */ static char *ld_library_path; /* Environment variable for search path */ +static char *ld_tracing; /* Called from ldd to print libs */ static Obj_Entry *obj_list; /* Head of linked list of shared objects */ static Obj_Entry **obj_tail; /* Link field of last object in list */ static Obj_Entry *obj_main; /* The main program shared object */ @@ -216,6 +218,7 @@ _rtld(Elf32_Word *sp, func_ptr_type *exit_proc) ld_debug = getenv("LD_DEBUG"); ld_library_path = getenv("LD_LIBRARY_PATH"); } + ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS"); if (ld_debug != NULL && *ld_debug != '\0') debug = 1; @@ -266,6 +269,11 @@ _rtld(Elf32_Word *sp, func_ptr_type *exit_proc) if (load_needed_objects(obj_main) == -1) die(); + if (ld_tracing) { /* We're done */ + trace_loaded_objects(obj_main); + exit(0); + } + dbg("relocating objects"); if (relocate_objects(obj_main, ld_bind_now != NULL && *ld_bind_now != '\0') == -1) @@ -831,12 +839,15 @@ load_needed_objects(Obj_Entry *first) const char *name = obj->strtab + needed->name; char *path = find_library(name, obj); - if (path == NULL) + needed->obj = NULL; + if (path == NULL && !ld_tracing) return -1; - needed->obj = load_object(path); - if (needed->obj == NULL) - return -1; /* XXX - cleanup */ + if (path) { + needed->obj = load_object(path); + if (needed->obj == NULL && !ld_tracing) + return -1; /* XXX - cleanup */ + } } } @@ -1366,3 +1377,93 @@ void linkmap_delete(Obj_Entry *obj) if ((l->l_prev->l_next = l->l_next) != NULL) l->l_next->l_prev = l->l_prev; } + +void trace_loaded_objects(Obj_Entry *obj) +{ + char *fmt1, *fmt2, *fmt, *main_local; + int c; + + if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) + main_local = ""; + + if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL) + fmt1 = "\t%o => %p (%x)\n"; + + if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL) + fmt2 = "\t%o (%x)\n"; + + for (; obj; obj = obj->next) { + Needed_Entry *needed; + char *name, *path; + bool is_lib; + + for (needed = obj->needed; needed; needed = needed->next) { + name = (char *)obj->strtab + needed->name; + if (!strncmp(name, "lib", 3)) { + is_lib = true; /* XXX bogus */ + } else { + is_lib = false; + } + + if (needed->obj == NULL) + path = "not found"; + else + path = needed->obj->path; + + fmt = is_lib ? fmt1 : fmt2; + while ((c = *fmt++) != '\0') { + switch (c) { + default: + putchar(c); + continue; + case '\\': + switch (c = *fmt) { + case '\0': + continue; + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + } + break; + case '%': + switch (c = *fmt) { + case '\0': + continue; + case '%': + default: + putchar(c); + break; + case 'A': + printf("%s", main_local); + break; + case 'a': + printf("%s", obj_main->path); + break; + case 'o': + printf("%s", name); + break; +#if 0 + case 'm': + printf("%d", sodp->sod_major); + break; + case 'n': + printf("%d", sodp->sod_minor); + break; +#endif + case 'p': + printf("%s", path); + break; + case 'x': + printf("%p", needed->obj ? needed->obj->mapbase : 0); + break; + } + break; + } + ++fmt; + } + } + } +} |