summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/include/debug.h11
-rw-r--r--usr/src/cmd/sgs/include/rtld.h26
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/files.c17
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/liblddbg.msg20
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/libs.c4
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/llib-llddbg16
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/mapfile-vers4
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/syms.c23
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/unused.c33
-rw-r--r--usr/src/cmd/sgs/librtld/common/dynamic.c2
-rw-r--r--usr/src/cmd/sgs/librtld/common/relocate.c2
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README2
-rw-r--r--usr/src/cmd/sgs/rtld/amd64/amd64_elf.c10
-rw-r--r--usr/src/cmd/sgs/rtld/common/_a.out.h11
-rw-r--r--usr/src/cmd/sgs/rtld/common/_audit.h4
-rw-r--r--usr/src/cmd/sgs/rtld/common/_elf.h16
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h65
-rw-r--r--usr/src/cmd/sgs/rtld/common/a.out.c29
-rw-r--r--usr/src/cmd/sgs/rtld/common/analyze.c258
-rw-r--r--usr/src/cmd/sgs/rtld/common/audit.c48
-rw-r--r--usr/src/cmd/sgs/rtld/common/cap.c26
-rw-r--r--usr/src/cmd/sgs/rtld/common/dlfcns.c207
-rw-r--r--usr/src/cmd/sgs/rtld/common/elf.c75
-rw-r--r--usr/src/cmd/sgs/rtld/common/globals.c32
-rw-r--r--usr/src/cmd/sgs/rtld/common/object.c4
-rw-r--r--usr/src/cmd/sgs/rtld/common/paths.c73
-rw-r--r--usr/src/cmd/sgs/rtld/common/rtld.msg12
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c22
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c280
-rw-r--r--usr/src/cmd/sgs/rtld/i386/i386_elf.c13
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c7
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_elf.c7
-rw-r--r--usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c7
33 files changed, 915 insertions, 451 deletions
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h
index 1b733bbf6f..0a42f8dd9e 100644
--- a/usr/src/cmd/sgs/include/debug.h
+++ b/usr/src/cmd/sgs/include/debug.h
@@ -405,6 +405,7 @@ extern uintptr_t Dbg_setup(const char *, Dbg_desc *);
#define Dbg_unused_file Dbg64_unused_file
#define Dbg_unused_lcinterface Dbg64_unused_lcinterface
+#define Dbg_unused_path Dbg64_unused_path
#define Dbg_unused_sec Dbg64_unused_sec
#define Dbg_unused_unref Dbg64_unused_unref
@@ -607,6 +608,7 @@ extern uintptr_t Dbg_setup(const char *, Dbg_desc *);
#define Dbg_unused_file Dbg32_unused_file
#define Dbg_unused_lcinterface Dbg32_unused_lcinterface
+#define Dbg_unused_path Dbg32_unused_path
#define Dbg_unused_sec Dbg32_unused_sec
#define Dbg_unused_unref Dbg32_unused_unref
@@ -676,7 +678,7 @@ extern void Dbg_file_del_rescan(Lm_list *);
extern void Dbg_file_delete(Rt_map *);
extern void Dbg_file_dlclose(Lm_list *, const char *, int);
extern void Dbg_file_dldump(Rt_map *, const char *, int);
-extern void Dbg_file_dlopen(Rt_map *, const char *, int);
+extern void Dbg_file_dlopen(Rt_map *, const char *, int *, int);
extern void Dbg_file_elf(Lm_list *, const char *, ulong_t, ulong_t,
ulong_t, ulong_t, const char *, Aliste);
extern void Dbg_file_filtee(Lm_list *, const char *, const char *, int);
@@ -708,7 +710,7 @@ extern void Dbg_libs_found(Lm_list *, const char *, int);
extern void Dbg_libs_ignore(Lm_list *, const char *);
extern void Dbg_libs_init(Lm_list *, List *, List *);
extern void Dbg_libs_l(Lm_list *, const char *, const char *);
-extern void Dbg_libs_path(Lm_list *, const char *, Half, const char *);
+extern void Dbg_libs_path(Lm_list *, const char *, uint_t, const char *);
extern void Dbg_libs_req(Lm_list *, const char *, const char *,
const char *);
extern void Dbg_libs_update(Lm_list *, List *, List *);
@@ -805,7 +807,8 @@ extern void Dbg_syms_ar_resolve(Lm_list *, Xword, Elf_Arsym *,
extern void Dbg_syms_ar_title(Lm_list *, const char *, int);
extern void Dbg_syms_created(Lm_list *, const char *);
extern void Dbg_syms_discarded(Lm_list *, Sym_desc *);
-extern void Dbg_syms_dlsym(Rt_map *, const char *, const char *, int);
+extern void Dbg_syms_dlsym(Rt_map *, const char *, int *, const char *,
+ int);
extern void Dbg_syms_dup_sort_addr(Lm_list *, const char *, const char *,
const char *, Addr);
extern void Dbg_syms_entered(Ofl_desc *, Sym *, Sym_desc *);
@@ -858,6 +861,8 @@ extern void Dbg_util_wait(Rt_map *, Rt_map *, int);
extern void Dbg_unused_file(Lm_list *, const char *, int, uint_t);
extern void Dbg_unused_lcinterface(Rt_map *, Rt_map *, int);
+extern void Dbg_unused_path(Lm_list *, const char *, uint_t, uint_t,
+ const char *);
extern void Dbg_unused_sec(Lm_list *, Is_desc *);
extern void Dbg_unused_unref(Rt_map *, const char *);
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index edcfd7a185..a7a65ee49c 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -514,15 +514,25 @@ typedef struct {
#define FLG_DI_LAZYFAIL 0x02000 /* the lazy loading of this entry */
/* failed */
/*
- * Data Structure to track AVL tree for pathnames of objects
- * loaded into memory
+ * Data structure to track AVL tree of pathnames. This structure provides the
+ * basis of both the "not-found" node tree, and the "full-path" node tree. Both
+ * of these trees persist for the life of a process, although the "not-found"
+ * tree may be moved aside during a dlopen() or dlsym() fall back operation.
*/
typedef struct {
- const char *fpn_name; /* object name */
+ const char *pn_name; /* path name */
+ avl_node_t pn_avl; /* avl book-keeping (see SGSOFFSETOF) */
+ uint_t pn_hash; /* path name hash value */
+} PathNode;
+
+/*
+ * Data structure to track AVL tree for full path names of objects that are
+ * loaded into memory.
+ */
+typedef struct {
+ PathNode fpn_node; /* path node */
Rt_map *fpn_lmp; /* object link-map */
- avl_node_t fpn_avl; /* avl book-keeping (see SGSOFFSETOF) */
- uint_t fpn_hash; /* object name hash value */
-} FullpathNode;
+} FullPathNode;
/*
* Define a mapping structure, which is maintained to describe each mapping
@@ -968,8 +978,8 @@ extern Lm_list *lml_list[];
extern Pltbindtype elf_plt_write(uintptr_t, uintptr_t, void *, uintptr_t,
Xword);
-extern Rt_map *is_so_loaded(Lm_list *, const char *);
-extern Sym *lookup_sym(Slookup *, Rt_map **, uint_t *);
+extern Rt_map *is_so_loaded(Lm_list *, const char *, int *);
+extern Sym *lookup_sym(Slookup *, Rt_map **, uint_t *, int *);
extern int rt_dldump(Rt_map *, const char *, int, Addr);
#ifdef __cplusplus
diff --git a/usr/src/cmd/sgs/liblddbg/common/files.c b/usr/src/cmd/sgs/liblddbg/common/files.c
index f91dbef0ee..22e5314830 100644
--- a/usr/src/cmd/sgs/liblddbg/common/files.c
+++ b/usr/src/cmd/sgs/liblddbg/common/files.c
@@ -347,16 +347,29 @@ Dbg_file_bindings(Rt_map *lmp, int flag)
}
void
-Dbg_file_dlopen(Rt_map *clmp, const char *name, int mode)
+Dbg_file_dlopen(Rt_map *clmp, const char *name, int *in_nfavl, int mode)
{
Conv_dl_mode_buf_t dl_mode_buf;
Lm_list *lml = LIST(clmp);
+ const char *retry;
if (DBG_NOTCLASS(DBG_C_FILES))
return;
+ /*
+ * The core functionality of dlopen() can be called twice. The first
+ * attempt can be affected by path names that exist in the "not-found"
+ * AVL tree. Should a "not-found" path name be found, a second attempt
+ * is made to locate the required file (in_nfavl is NULL). This fall-
+ * back provides for file system changes while a process executes.
+ */
+ if (in_nfavl)
+ retry = MSG_ORIG(MSG_STR_EMPTY);
+ else
+ retry = MSG_INTL(MSG_STR_RETRY);
+
Dbg_util_nl(lml, DBG_NL_STD);
- dbg_print(lml, MSG_INTL(MSG_FIL_DLOPEN), name, NAME(clmp),
+ dbg_print(lml, MSG_INTL(MSG_FIL_DLOPEN), name, NAME(clmp), retry,
conv_dl_mode(mode, 1, &dl_mode_buf));
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
index 67f7932a1d..420a00bc01 100644
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
@@ -178,7 +178,7 @@
# detail shows layout of string tables
# tls display TLS processing
# unused display unused/unreferenced files; detail flag shows unused
-# sections (ld only)
+# sections (ld only), and unused search paths (ld.so.1 only)
# versions display version processing
#
#
@@ -379,7 +379,7 @@
@ MSG_FIL_REUSE "file=%s; reusing: originally processed as %s"
@ MSG_FIL_PROT "file=%s; modifying memory protections (%c PROT_WRITE)"
@ MSG_FIL_DELETE "file=%s; deleting"
-@ MSG_FIL_DLOPEN "file=%s; dlopen() called from file=%s %s"
+@ MSG_FIL_DLOPEN "file=%s; dlopen() called from file=%s %s %s"
@ MSG_FIL_DLCLOSE "file=%s; dlclose() %s"
@ MSG_FIL_CLEANUP "file=%s; loading failed: cleaning up lmco 0x%llx"
@ MSG_FIL_DLDUMP "file=%s; dldump() to file=%s %s"
@@ -593,6 +593,15 @@
@ MSG_USD_LCINTERFACE "file=%s unused interface [%s]: using interface \
from previously loaded object: file=%s"
+@ MSG_USD_LDLIBPATH " search path=%s unused: LD_LIBRARY_PATH entry"
+@ MSG_DUP_LDLIBPATH " search path=%s unused: (duplicate) LD_LIBRARY_PATH \
+ entry"
+@ MSG_USD_LDLIBPATHC " search path=%s unused: configuration \
+ LD_LIBRARY_PATH entry - %s"
+@ MSG_DUP_LDLIBPATHC " search path=%s unused: (duplicate) configuration \
+ LD_LIBRARY_PATH entry - %s"
+@ MSG_USD_RUNPATH " search path=%s unused: RUNPATH/RPATH from file %s"
+
# Segment messages
@ MSG_SEG_DESC_INUSE "Segment Descriptor List (in use)"
@@ -652,9 +661,9 @@
@ MSG_SYM_AOUT "symbol=%s; (original AOUT name)"
@ MSG_SYM_LOOKUP "symbol=%s; lookup in file=%s [ %s ]"
-@ MSG_SYM_DLSYM_1 "symbol=%s; dlsym() called from file=%s %s"
-@ MSG_SYM_DLSYM_2 "symbol=%s; dlsym() called from file=%s; starting at \
- file=%s %s"
+@ MSG_SYM_DLSYM_1 "symbol=%s; dlsym() called from file=%s %s %s"
+@ MSG_SYM_DLSYM_2 "symbol=%s; dlsym() called from file=%s; starting \
+ at file=%s %s %s"
@ MSG_SYM_LAZY_RESCAN "rescanning for lazy dependencies for symbol: %s"
@@ -776,6 +785,7 @@
@ MSG_STR_ALTER " (alternate)"
@ MSG_STR_COPYZERO " (copy zero's unnecessary)"
@ MSG_STR_TEMPORARY " (temporary)"
+@ MSG_STR_RETRY " (retry) "
# TLS related messages
diff --git a/usr/src/cmd/sgs/liblddbg/common/libs.c b/usr/src/cmd/sgs/liblddbg/common/libs.c
index 75330c4a2f..227a0cce0c 100644
--- a/usr/src/cmd/sgs/liblddbg/common/libs.c
+++ b/usr/src/cmd/sgs/liblddbg/common/libs.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -105,7 +105,7 @@ Dbg_libs_l(Lm_list *lml, const char *name, const char *path)
}
void
-Dbg_libs_path(Lm_list *lml, const char *path, Half orig, const char *obj)
+Dbg_libs_path(Lm_list *lml, const char *path, uint_t orig, const char *obj)
{
const char *fmt;
diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
index 8489c34c97..cd83abd77d 100644
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
@@ -112,8 +112,8 @@ void Dbg32_file_dlclose(Lm_list *, const char *, int);
void Dbg64_file_dlclose(Lm_list *, const char *, int);
void Dbg32_file_dldump(Rt_map *, const char *, int);
void Dbg64_file_dldump(Rt_map *, const char *, int);
-void Dbg32_file_dlopen(Rt_map *, const char *, int);
-void Dbg64_file_dlopen(Rt_map *, const char *, int);
+void Dbg32_file_dlopen(Rt_map *, const char *, int *, int);
+void Dbg64_file_dlopen(Rt_map *, const char *, int *, int);
void Dbg32_file_elf(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
ulong_t, const char *, Aliste);
void Dbg64_file_elf(Lm_list *, const char *, ulong_t, ulong_t, ulong_t,
@@ -172,8 +172,8 @@ void Dbg32_libs_init(Lm_list *, List *, List *);
void Dbg64_libs_init(Lm_list *, List *, List *);
void Dbg32_libs_l(Lm_list *, const char *, const char *);
void Dbg64_libs_l(Lm_list *, const char *, const char *);
-void Dbg32_libs_path(Lm_list *, const char *, Half, const char *);
-void Dbg64_libs_path(Lm_list *, const char *, Half, const char *);
+void Dbg32_libs_path(Lm_list *, const char *, uint_t, const char *);
+void Dbg64_libs_path(Lm_list *, const char *, uint_t, const char *);
void Dbg32_libs_req(Lm_list *, const char *, const char *, const char *);
void Dbg64_libs_req(Lm_list *, const char *, const char *, const char *);
void Dbg32_libs_update(Lm_list *, List *, List *);
@@ -346,8 +346,8 @@ void Dbg32_syms_created(Lm_list *, const char *);
void Dbg64_syms_created(Lm_list *, const char *);
void Dbg32_syms_discarded(Lm_list *, Sym_desc *);
void Dbg64_syms_discarded(Lm_list *, Sym_desc *);
-void Dbg32_syms_dlsym(Rt_map *, const char *, const char *, int);
-void Dbg64_syms_dlsym(Rt_map *, const char *, const char *, int);
+void Dbg32_syms_dlsym(Rt_map *, const char *, int *, const char *, int);
+void Dbg64_syms_dlsym(Rt_map *, const char *, int *, const char *, int);
void Dbg32_syms_entered(Ofl_desc *, Sym *, Sym_desc *);
void Dbg64_syms_entered(Ofl_desc *, Sym *, Sym_desc *);
void Dbg32_syms_entry(Lm_list *, Elf32_Word, Sym_desc *);
@@ -427,6 +427,10 @@ void Dbg32_unused_file(Lm_list *, const char *, int, uint_t);
void Dbg64_unused_file(Lm_list *, const char *, int, uint_t);
void Dbg32_unused_lcinterface(Rt_map *, Rt_map *, int);
void Dbg64_unused_lcinterface(Rt_map *, Rt_map *, int);
+void Dbg32_unused_path(Lm_list *, const char *, uint_t, uint_t,
+ const char *);
+void Dbg64_unused_path(Lm_list *, const char *, uint_t, uint_t,
+ const char *);
void Dbg32_unused_sec(Lm_list *, Is_desc *);
void Dbg64_unused_sec(Lm_list *, Is_desc *);
void Dbg32_unused_unref(Rt_map *, const char *);
diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
index 0de413a7ef..573761a5f1 100644
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
@@ -38,7 +38,7 @@
# Policy for Shared Library Version Names and Interface Definitions
-SUNWprivate_4.61 {
+SUNWprivate_4.62 {
global:
dbg_desc = NODIRECT; # interposed - ld.so.1(1)
dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1)
@@ -415,6 +415,8 @@ SUNWprivate_4.61 {
Dbg64_unused_file;
Dbg32_unused_lcinterface;
Dbg64_unused_lcinterface;
+ Dbg32_unused_path;
+ Dbg64_unused_path;
Dbg32_unused_sec;
Dbg64_unused_sec;
Dbg32_unused_unref;
diff --git a/usr/src/cmd/sgs/liblddbg/common/syms.c b/usr/src/cmd/sgs/liblddbg/common/syms.c
index 03f302040a..c3b8d7c27d 100644
--- a/usr/src/cmd/sgs/liblddbg/common/syms.c
+++ b/usr/src/cmd/sgs/liblddbg/common/syms.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -70,14 +70,27 @@ Dbg_syms_ignore_gnuver(Rt_map *lmp, const char *name, Word symndx,
}
void
-Dbg_syms_dlsym(Rt_map *clmp, const char *sym, const char *next, int flag)
+Dbg_syms_dlsym(Rt_map *clmp, const char *sym, int *in_nfavl, const char *next,
+ int flag)
{
- const char *str, *from = NAME(clmp);
+ const char *str, *retry, *from = NAME(clmp);
Lm_list *lml = LIST(clmp);
if (DBG_NOTCLASS(DBG_C_SYMBOLS))
return;
+ /*
+ * The core functionality of dlsym() can be called twice. The first
+ * attempt can be affected by path names that exist in the "not-found"
+ * AVL tree. Should a "not-found" path name be found, a second attempt
+ * is made to locate the required file (in_nfavl is NULL). This fall-
+ * back provides for file system changes while a process executes.
+ */
+ if (in_nfavl)
+ retry = MSG_ORIG(MSG_STR_EMPTY);
+ else
+ retry = MSG_INTL(MSG_STR_RETRY);
+
switch (flag) {
case DBG_DLSYM_NEXT:
str = MSG_ORIG(MSG_SYM_NEXT);
@@ -101,10 +114,10 @@ Dbg_syms_dlsym(Rt_map *clmp, const char *sym, const char *next, int flag)
Dbg_util_nl(lml, DBG_NL_STD);
if (next == 0)
dbg_print(lml, MSG_INTL(MSG_SYM_DLSYM_1),
- Dbg_demangle_name(sym), from, str);
+ Dbg_demangle_name(sym), from, retry, str);
else
dbg_print(lml, MSG_INTL(MSG_SYM_DLSYM_2),
- Dbg_demangle_name(sym), from, next, str);
+ Dbg_demangle_name(sym), from, next, retry, str);
}
void
diff --git a/usr/src/cmd/sgs/liblddbg/common/unused.c b/usr/src/cmd/sgs/liblddbg/common/unused.c
index f096d40d24..c0bcdf9e41 100644
--- a/usr/src/cmd/sgs/liblddbg/common/unused.c
+++ b/usr/src/cmd/sgs/liblddbg/common/unused.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -81,3 +81,34 @@ Dbg_unused_file(Lm_list *lml, const char *name, int needstr, uint_t cycle)
else
dbg_print(lml, MSG_INTL(MSG_USD_FILE), name);
}
+
+void
+Dbg_unused_path(Lm_list *lml, const char *path, uint_t orig, uint_t dup,
+ const char *obj)
+{
+ const char *fmt;
+
+ if (DBG_NOTCLASS(DBG_C_UNUSED))
+ return;
+ if (DBG_NOTDETAIL())
+ return;
+
+ if (orig & LA_SER_LIBPATH) {
+ if (orig & LA_SER_CONFIG) {
+ if (dup)
+ fmt = MSG_INTL(MSG_DUP_LDLIBPATHC);
+ else
+ fmt = MSG_INTL(MSG_USD_LDLIBPATHC);
+ } else {
+ if (dup)
+ fmt = MSG_INTL(MSG_DUP_LDLIBPATH);
+ else
+ fmt = MSG_INTL(MSG_USD_LDLIBPATH);
+ }
+ } else if (orig & LA_SER_RUNPATH) {
+ fmt = MSG_INTL(MSG_USD_RUNPATH);
+ } else
+ return;
+
+ dbg_print(lml, fmt, path, obj);
+}
diff --git a/usr/src/cmd/sgs/librtld/common/dynamic.c b/usr/src/cmd/sgs/librtld/common/dynamic.c
index f11ff24da2..1167d9c228 100644
--- a/usr/src/cmd/sgs/librtld/common/dynamic.c
+++ b/usr/src/cmd/sgs/librtld/common/dynamic.c
@@ -71,7 +71,7 @@ update_dynamic(Cache *cache, Cache *_cache, Rt_map *lmp, int flags,
* to, undo any lazy-loading position flag.
*/
if (dlmp = is_so_loaded(LIST(lmp),
- (strs + dyn->d_un.d_val))) {
+ (strs + dyn->d_un.d_val), NULL)) {
Bnd_desc *bdp;
Aliste idx;
diff --git a/usr/src/cmd/sgs/librtld/common/relocate.c b/usr/src/cmd/sgs/librtld/common/relocate.c
index 2fa32d44aa..afba8b400b 100644
--- a/usr/src/cmd/sgs/librtld/common/relocate.c
+++ b/usr/src/cmd/sgs/librtld/common/relocate.c
@@ -282,7 +282,7 @@ count_reloc(Cache *cache, Cache *_cache, Rt_map *lmp, int flags, Addr addr,
_bound = _weak = 0;
_sym = sym;
- if ((sym = lookup_sym(&sl, &_lmp, &binfo)) != 0) {
+ if ((sym = lookup_sym(&sl, &_lmp, &binfo, NULL)) != 0) {
/*
* Determine from the various relocation requirements
* whether this binding is appropriate. If we're called
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 51ec4906c3..243c7583dd 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1333,3 +1333,5 @@ Bugid Risk Synopsis
6678244 elfdump dynamic section sanity checking needs refinement
6679212 sgs use of SCCS id for versioning is obstacle to mercurial migration
6681761 lies, darn lies, and linker README files
+6509323 Need to disable the Multiple Files loading - same name, different
+ directories (or its stat() use)
diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
index b2e9584c4e..3f760ab02e 100644
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
@@ -276,7 +276,7 @@ elf_bndr(Rt_map *lmp, ulong_t pltndx, caddr_t from)
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0,
rsymndx, rsym, 0, LKUP_DEFT);
- if ((nsym = lookup_sym(&sl, &nlmp, &binfo)) == 0) {
+ if ((nsym = lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
rtldexit(lml, 1);
@@ -450,7 +450,7 @@ elf_reloc_relacount(ulong_t relbgn, ulong_t relacount, ulong_t relsiz,
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
{
ulong_t relbgn, relend, relsiz, basebgn;
ulong_t pltbgn, pltend, _pltbgn, _pltend;
@@ -516,7 +516,8 @@ elf_reloc(Rt_map *lmp, uint_t plt)
SLOOKUP_INIT(sl, MSG_ORIG(MSG_SYM_PLT), lmp, lmp, ld_entry_cnt,
elf_hash(MSG_ORIG(MSG_SYM_PLT)), 0, 0, 0, LKUP_DEFT);
- if ((symdef = elf_find_sym(&sl, &_lmp, &binfo)) == 0)
+ if ((symdef = elf_find_sym(&sl, &_lmp,
+ &binfo, in_nfavl)) == 0)
return (1);
_pltbgn = symdef->st_value;
@@ -791,7 +792,8 @@ elf_reloc(Rt_map *lmp, uint_t plt)
ld_entry_cnt, 0, rsymndx, symref,
rtype, LKUP_STDRELOC);
- symdef = lookup_sym(&sl, &_lmp, &binfo);
+ symdef = lookup_sym(&sl, &_lmp,
+ &binfo, in_nfavl);
/*
* If the symbol is not found and the
diff --git a/usr/src/cmd/sgs/rtld/common/_a.out.h b/usr/src/cmd/sgs/rtld/common/_a.out.h
index 5d7e6e7e25..8f105058de 100644
--- a/usr/src/cmd/sgs/rtld/common/_a.out.h
+++ b/usr/src/cmd/sgs/rtld/common/_a.out.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,11 +44,11 @@ typedef struct link_dynamic Link_dynamic;
* Extern functions for a.out format file class.
*/
extern ulong_t aout_bndr(caddr_t);
-extern Sym *aout_lookup_sym(Slookup *, Rt_map **, uint_t *);
+extern Sym *aout_lookup_sym(Slookup *, Rt_map **, uint_t *, int *);
extern Rt_map *aout_new_lm(Lm_list *, const char *, const char *,
Link_dynamic *, caddr_t, size_t, Aliste);
extern void aout_plt_write(caddr_t, ulong_t);
-extern int aout_reloc(Rt_map *, uint_t);
+extern int aout_reloc(Rt_map *, uint_t, int *);
extern void aout_rtbndr(caddr_t);
extern int aout_set_prot(Rt_map *, int);
diff --git a/usr/src/cmd/sgs/rtld/common/_audit.h b/usr/src/cmd/sgs/rtld/common/_audit.h
index 8f13add42f..6386bb03d2 100644
--- a/usr/src/cmd/sgs/rtld/common/_audit.h
+++ b/usr/src/cmd/sgs/rtld/common/_audit.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -113,7 +113,7 @@ struct audit_list {
/*
* Link-Edit audit functions
*/
-extern int audit_setup(Rt_map *, Audit_desc *, uint_t);
+extern int audit_setup(Rt_map *, Audit_desc *, uint_t, int *);
extern void audit_desc_cleanup(Rt_map *);
extern void audit_info_cleanup(Rt_map *);
diff --git a/usr/src/cmd/sgs/rtld/common/_elf.h b/usr/src/cmd/sgs/rtld/common/_elf.h
index c2b524cf89..7d52eeab1f 100644
--- a/usr/src/cmd/sgs/rtld/common/_elf.h
+++ b/usr/src/cmd/sgs/rtld/common/_elf.h
@@ -43,21 +43,23 @@ extern "C" {
/*
* Common extern functions for ELF file class.
*/
-extern int elf_reloc(Rt_map *, uint_t);
+extern int elf_reloc(Rt_map *, uint_t, int *);
extern int elf_reloc_error(Rt_map *, const char *, void *, uint_t);
extern void elf_plt_init(void *, caddr_t);
extern int elf_set_prot(Rt_map *, int);
extern Rt_map *elf_obj_file(Lm_list *, Aliste, const char *, int);
-extern Rt_map *elf_obj_fini(Lm_list *, Rt_map *);
+extern Rt_map *elf_obj_fini(Lm_list *, Rt_map *, int *);
extern int elf_copy_reloc(char *, Sym *, Rt_map *, void *, Sym *,
Rt_map *, const void *);
-extern Sym *elf_find_sym(Slookup *, Rt_map **, uint_t *);
-extern Sym *elf_lazy_find_sym(Slookup *, Rt_map **, uint_t *);
-extern Rt_map *elf_lazy_load(Rt_map *, Slookup *, uint_t, const char *);
-extern Sym *elf_lookup_filtee(Slookup *, Rt_map **, uint_t *, uint_t);
+extern Sym *elf_find_sym(Slookup *, Rt_map **, uint_t *, int *);
+extern Sym *elf_lazy_find_sym(Slookup *, Rt_map **, uint_t *, int *);
+extern Rt_map *elf_lazy_load(Rt_map *, Slookup *, uint_t, const char *,
+ int *);
+extern Sym *elf_lookup_filtee(Slookup *, Rt_map **, uint_t *, uint_t,
+ int *);
extern Rt_map *elf_new_lm(Lm_list *, const char *, const char *, Dyn *,
ulong_t, ulong_t, Aliste, ulong_t, ulong_t, ulong_t,
- ulong_t, Mmap *, uint_t);
+ ulong_t, Mmap *, uint_t, int *);
extern int elf_rtld_load();
#if defined(__sparcv9)
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index 46f0223f95..375e04215b 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -72,13 +72,14 @@ typedef struct fct {
int (*fct_are_u_this)(Rej_desc *); /* determine type of object */
ulong_t (*fct_entry_pt)(void); /* get entry point */
Rt_map *(*fct_map_so)(Lm_list *, Aliste, const char *, const char *,
- int); /* map in a shared object */
+ int, int *); /* map in a shared object */
void (*fct_unmap_so)(Rt_map *); /* unmap a shared object */
- int (*fct_needed)(Lm_list *, Aliste, Rt_map *);
+ int (*fct_needed)(Lm_list *, Aliste, Rt_map *, int *);
/* determine needed objects */
- Sym *(*fct_lookup_sym)(Slookup *, Rt_map **, uint_t *);
+ Sym *(*fct_lookup_sym)(Slookup *, Rt_map **, uint_t *, int *);
/* initialize symbol lookup */
- int (*fct_reloc)(Rt_map *, uint_t); /* relocate shared object */
+ int (*fct_reloc)(Rt_map *, uint_t, int *);
+ /* relocate shared object */
Pnode *fct_dflt_dirs; /* list of default dirs to */
/* search */
Pnode *fct_secure_dirs; /* list of secure dirs to */
@@ -89,8 +90,8 @@ typedef struct fct {
/* get shared object */
void (*fct_dladdr)(ulong_t, Rt_map *, Dl_info *, void **, int);
/* get symbolic address */
- Sym *(*fct_dlsym)(Grp_hdl *, Slookup *, Rt_map **, uint_t *);
- /* process dlsym request */
+ Sym *(*fct_dlsym)(Grp_hdl *, Slookup *, Rt_map **, uint_t *,
+ int *); /* process dlsym request */
int (*fct_verify_vers)(const char *, Rt_map *, Rt_map *);
/* verify versioning (ELF) */
int (*fct_set_prot)(Rt_map *, int);
@@ -279,7 +280,7 @@ typedef struct {
#define RT_FL_CONFAPP 0x00000400 /* application specific configuration */
/* cache required */
#define RT_FL_DEBUGGER 0x00000800 /* a debugger is monitoring us */
-
+#define RT_FL_OPERATION 0x00001000 /* start recording operations */
#define RT_FL_NEWLOCALE 0x00002000 /* message locale has changed */
#define RT_FL_NOBAPLT 0x00004000 /* sparc: don't use ba plt's */
#define RT_FL_NOAUXFLTR 0x00008000 /* disable auxiliary filters */
@@ -314,8 +315,8 @@ typedef struct {
#define RT_FL2_BINDNOW 0x00000100 /* LD_BIND_NOW in effect */
#define RT_FL2_BINDLAZY 0x00000200 /* disable RTLD_NOW (and LD_BIND_NOW) */
#define RT_FL2_PLMSETUP 0x00000400 /* primary link-map set up complete */
-#define RT_FL2_BRANDED 0x00000800 /* Process is branded */
-#define RT_FL2_NOPLM 0x00001000 /* Process has no primary link map */
+#define RT_FL2_BRANDED 0x00000800 /* process is branded */
+#define RT_FL2_NOPLM 0x00001000 /* process has no primary link map */
/*
* Information flags for env_info.
@@ -340,8 +341,7 @@ typedef struct {
#define THR_FLG_RTLD 0x00000001 /* rtldlock bind_guard() flag */
#define THR_FLG_MASK THR_FLG_RTLD /* mask for all THR_FLG flags */
-#define ROUND(x, a) (((int)(x) + ((int)(a) - 1)) & \
- ~((int)(a) - 1))
+#define ROUND(x, a) (((int)(x) + ((int)(a) - 1)) & ~((int)(a) - 1))
/*
* Print buffer.
@@ -365,19 +365,19 @@ typedef struct {
* in link.h). Definitions here extend the path information to other uses of
* pathname expansion, and are or'd together with any LA_SER_* flags.
*/
-#define PN_SER_NEEDED 0x00001000 /* paths define DT_NEEDED entry */
-#define PN_SER_FILTEE 0x00002000 /* paths define filtees */
-#define PN_SER_EXTLOAD 0x00004000 /* paths define extra loaded objects */
+#define PN_FLG_EXTLOAD 0x00001000 /* path defines extra loaded objects */
/* (preload, audit etc.) */
-#define PN_SER_DLOPEN 0x00008000 /* paths define dlopen() request */
+#define PN_FLG_UNIQUE 0x00002000 /* ensure path is unique */
+#define PN_FLG_USED 0x00004000 /* indicate that path is used */
+#define PN_FLG_DUPLICAT 0x00008000 /* path is a duplicate */
-#define PN_SER_MASK 0x000ff000 /* mask for p_orig incorporation */
+#define PN_FLG_MASK 0x000ff000 /* mask for p_orig incorporation */
/*
* Define reserved path tokens. These are used to prevent various expansions
* from occurring, and record those expansions that do. Note that any expansion
* information is also recorded in the p_orig field of a Pnode, and thus is
- * or'd together with any LA_SER_* flags.
+ * or'd together with any LA_SER, and PN_FLG flags.
*/
#define PN_TKN_ORIGIN 0x00100000 /* $ORIGIN expansion has occurred */
#define PN_TKN_PLATFORM 0x00200000 /* $PLATFORM expansion has occurred */
@@ -388,6 +388,11 @@ typedef struct {
#define PN_TKN_MASK 0xfff00000 /* mask for p_orig incorporation */
+/*
+ * Additional token expansion information. Although these flags may be set
+ * within a token data item they are masked off with PN_TKN_MASK prior to any
+ * expansion information being recorded in a Pnode for later diagnostics.
+ */
#define TKN_NONE 0x00000001 /* no token expansion has occurred */
#define TKN_DOTSLASH 0x00000002 /* path contains a "./" */
@@ -495,12 +500,14 @@ extern const char *nosym_str; /* MSG_GEN_NOSYM message cache */
extern ulong_t hwcap; /* hardware capabilities */
extern ulong_t sfcap; /* software capabilities */
+extern avl_tree_t *nfavl; /* not-found AVL path name tree */
+
/*
* Function declarations.
*/
extern void addfree(void *, size_t);
extern int append_alias(Rt_map *, const char *, int *);
-extern int analyze_lmc(Lm_list *, Aliste, Rt_map *);
+extern int analyze_lmc(Lm_list *, Aliste, Rt_map *, int *);
extern Am_ret anon_map(Lm_list *, caddr_t *, size_t, int, int);
extern Fct *are_u_this(Rej_desc *, int, struct stat *,
const char *);
@@ -521,10 +528,10 @@ extern const char *demangle(const char *);
extern int dlclose_intn(Grp_hdl *, Rt_map *);
extern int dlclose_core(Grp_hdl *, Rt_map *, Lm_list *);
extern Sym *dlsym_handle(Grp_hdl *, Slookup *, Rt_map **,
- uint_t *);
+ uint_t *, int *);
extern void *dlsym_intn(void *, const char *, Rt_map *, Rt_map **);
extern Grp_hdl *dlmopen_intn(Lm_list *, const char *, int, Rt_map *,
- uint_t, uint_t, int *);
+ uint_t, uint_t);
extern size_t doprf(const char *, va_list, Prfbuf *);
extern int dowrite(Prfbuf *);
extern void dz_init(int);
@@ -550,10 +557,10 @@ extern void free_hdl(Grp_hdl *, Rt_map *, uint_t);
extern void file_notfound(Lm_list *, const char *, Rt_map *,
uint_t, Rej_desc *);
extern int find_path(Lm_list *, const char *, Rt_map *, uint_t,
- Fdesc *, Rej_desc *);
+ Fdesc *, Rej_desc *, int *);
extern int fpavl_insert(Lm_list *, Rt_map *, const char *,
avl_index_t);
-extern Rt_map *fpavl_loaded(Lm_list *, const char *, avl_index_t *);
+extern Rt_map *fpavl_recorded(Lm_list *, const char *, avl_index_t *);
extern void fpavl_remove(Rt_map *);
extern size_t fullpath(Rt_map *, const char *);
extern void fmap_setup();
@@ -566,7 +573,7 @@ extern Grp_hdl *hdl_create(Lm_list *, Rt_map *, Rt_map *, uint_t,
extern int hdl_initialize(Grp_hdl *, Rt_map *, int, int);
extern int hwcap_check(Rej_desc *, Ehdr *);
extern Pnode *hwcap_filtees(Pnode **, Aliste, Lm_cntl *, Dyninfo *,
- Rt_map *, const char *, int, uint_t);
+ Rt_map *, const char *, int, uint_t, int *);
extern void is_dep_ready(Rt_map *, Rt_map *, int);
extern void is_dep_init(Rt_map *, Rt_map *);
extern int is_sym_interposer(Rt_map *, Sym *);
@@ -582,12 +589,15 @@ extern void lm_move(Lm_list *, Aliste, Aliste, Lm_cntl *,
Lm_cntl *);
extern void load_completion(Rt_map *);
extern Rt_map *load_hwcap(Lm_list *, Aliste, const char *, Rt_map *,
- uint_t, uint_t, Grp_hdl **, Rej_desc *);
+ uint_t, uint_t, Grp_hdl **, Rej_desc *, int *);
extern Rt_map *load_path(Lm_list *, Aliste, const char **, Rt_map *,
- int, uint_t, Grp_hdl **, Fdesc *, Rej_desc *);
+ int, uint_t, Grp_hdl **, Fdesc *, Rej_desc *,
+ int *);
extern Rt_map *load_one(Lm_list *, Aliste, Pnode *, Rt_map *, int,
- uint_t, Grp_hdl **);
+ uint_t, Grp_hdl **, int *);
extern int load_trace(Lm_list *, const char **, Rt_map *);
+extern void nfavl_insert(const char *, avl_index_t);
+extern int nfavl_recorded(const char *, avl_index_t *);
extern caddr_t nu_map(Lm_list *, caddr_t, size_t, int, int);
extern void *malloc(size_t);
extern void move_data(Rt_map *);
@@ -596,7 +606,8 @@ extern void rd_event(Lm_list *, rd_event_e, r_state_e);
extern int readenv_user(const char **, Word *, Word *, int);
extern int readenv_config(Rtc_env *, Addr, int);
extern void rejection_inherit(Rej_desc *, Rej_desc *);
-extern int relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *);
+extern int relocate_lmc(Lm_list *, Aliste, Rt_map *, Rt_map *,
+ int *);
extern int relocate_finish(Rt_map *, APlist *, int, int);
extern void remove_cntl(Lm_list *, Aliste);
extern int remove_hdl(Grp_hdl *, Rt_map *, int *);
diff --git a/usr/src/cmd/sgs/rtld/common/a.out.c b/usr/src/cmd/sgs/rtld/common/a.out.c
index b871cda747..e91c0bdf3b 100644
--- a/usr/src/cmd/sgs/rtld/common/a.out.c
+++ b/usr/src/cmd/sgs/rtld/common/a.out.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -139,7 +139,6 @@ aout_fix_name(const char *name, Rt_map *clmp)
if (pnp->p_name) {
pnp->p_len = len;
- pnp->p_orig = PN_SER_NEEDED;
DBG_CALL(Dbg_file_fixname(LIST(clmp), pnp->p_name, name));
return (pnp);
}
@@ -200,7 +199,7 @@ aout_verify_vers()
* defined link map the the dlopen list.
*/
static int
-aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
+aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
{
void *need;
@@ -268,8 +267,7 @@ aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
}
name = path;
}
- if ((pnp = expand_paths(clmp, name,
- PN_SER_NEEDED, 0)) == 0)
+ if ((pnp = expand_paths(clmp, name, 0, 0)) == 0)
return (0);
} else {
/*
@@ -283,7 +281,8 @@ aout_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
DBG_CALL(Dbg_file_needed(clmp, name));
- nlmp = load_one(lml, lmco, pnp, clmp, MODE(clmp), 0, 0);
+ nlmp = load_one(lml, lmco, pnp, clmp, MODE(clmp), 0, 0,
+ in_nfavl);
remove_pnode(pnp);
if (((nlmp == 0) || (bind_one(clmp, nlmp, BND_NEEDED) == 0)) &&
((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
@@ -403,7 +402,7 @@ aout_findsb(const char *aname, Rt_map *lmp, int flag)
hval = hval & HASHMASK;
i = hval % (AOUTDYN(lmp)->v2->ld_buckets == 0 ? RTHS :
- AOUTDYN(lmp)->v2->ld_buckets);
+ AOUTDYN(lmp)->v2->ld_buckets);
p = LM2LP(lmp)->lp_hash + i;
if (p->fssymbno != -1)
@@ -441,7 +440,7 @@ aout_findsb(const char *aname, Rt_map *lmp, int flag)
* iii. nuts -> .nuts
*/
Sym *
-aout_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+aout_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
char name[PATH_MAX];
Slookup sl = *slp;
@@ -462,14 +461,15 @@ aout_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* Call the generic lookup routine to cycle through the specified
* link maps.
*/
- return (lookup_sym(&sl, dlmp, binfo));
+ return (lookup_sym(&sl, dlmp, binfo, in_nfavl));
}
/*
* Symbol lookup for an a.out format module.
*/
+/* ARGSUSED3 */
static Sym *
-aout_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+aout_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
const char *name = slp->sl_name;
Rt_map *ilmp = slp->sl_imap;
@@ -754,7 +754,7 @@ aout_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info,
struct nlist *sym, *_sym;
cnt = ((int)LM2LP(lmp)->lp_symstr - (int)LM2LP(lmp)->lp_symtab) /
- sizeof (struct nlist);
+ sizeof (struct nlist);
sym = LM2LP(lmp)->lp_symtab;
if (FLAGS(lmp) & FLG_RT_FIXED)
@@ -809,7 +809,8 @@ aout_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info,
* lookup routine (see lookup_sym():analyze.c).
*/
Sym *
-aout_dlsym_handle(Grp_hdl * ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
+aout_dlsym_handle(Grp_hdl * ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
+ int *in_nfavl)
{
Sym *sym;
char buffer[PATH_MAX];
@@ -818,7 +819,7 @@ aout_dlsym_handle(Grp_hdl * ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
buffer[0] = '_';
(void) strcpy(&buffer[1], slp->sl_name);
- if ((sym = dlsym_handle(ghp, slp, _lmp, binfo)) != 0)
+ if ((sym = dlsym_handle(ghp, slp, _lmp, binfo, in_nfavl)) != 0)
return (sym);
/*
@@ -830,5 +831,5 @@ aout_dlsym_handle(Grp_hdl * ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
sl = *slp;
sl.sl_name = (const char *)buffer;
- return (dlsym_handle(ghp, &sl, _lmp, binfo));
+ return (dlsym_handle(ghp, &sl, _lmp, binfo, in_nfavl));
}
diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c
index 6ed3b0473c..8e9d115f68 100644
--- a/usr/src/cmd/sgs/rtld/common/analyze.c
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c
@@ -63,7 +63,7 @@ static Fct *vector[] = {
* flag. Otherwise, filtee loading is deferred until triggered by a relocation.
*/
static void
-load_filtees(Rt_map *lmp)
+load_filtees(Rt_map *lmp, int *in_nfavl)
{
if ((FLAGS1(lmp) & MSK_RT_FILTER) &&
((FLAGS(lmp) & FLG_RT_LOADFLTR) ||
@@ -82,7 +82,7 @@ load_filtees(Rt_map *lmp)
((dip->di_flags & FLG_DI_AUXFLTR) &&
(rtld_flags & RT_FL_NOAUXFLTR)))
continue;
- (void) elf_lookup_filtee(&sl, 0, 0, cnt);
+ (void) elf_lookup_filtee(&sl, 0, 0, cnt, in_nfavl);
}
}
}
@@ -99,7 +99,7 @@ load_filtees(Rt_map *lmp)
* breadth first ordering of all needed objects.
*/
int
-analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
+analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl)
{
Rt_map *lmp = nlmp;
Lm_cntl *nlmc;
@@ -144,7 +144,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
* need to finish the link-editing of the object at this point.
*/
if (FLAGS(lmp) & FLG_RT_OBJECT) {
- if (elf_obj_fini(lml, lmp) == 0) {
+ if (elf_obj_fini(lml, lmp, in_nfavl) == 0) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
continue;
ret = 0;
@@ -157,7 +157,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
/*
* Establish any dependencies this object requires.
*/
- if (LM_NEEDED(lmp)(lml, nlmco, lmp) == 0) {
+ if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
continue;
ret = 0;
@@ -174,7 +174,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp)
* an object will load filters as part of relocation processing.
*/
if (MODE(nlmp) & RTLD_CONFGEN)
- load_filtees(lmp);
+ load_filtees(lmp, in_nfavl);
/*
* If an interposer has been added, it will have been inserted
@@ -229,7 +229,7 @@ copy_zerobits(Rt_map *dlmp, Sym *dsym)
* Relocate an individual object.
*/
static int
-relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now)
+relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl)
{
/*
* If we're running under ldd(1), and haven't been asked to trace any
@@ -241,7 +241,7 @@ relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now)
if (relocated)
(*relocated)++;
- if ((LM_RELOC(lmp)(lmp, now) == 0) &&
+ if ((LM_RELOC(lmp)(lmp, now, in_nfavl) == 0) &&
((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
return (0);
}
@@ -252,7 +252,7 @@ relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now)
* Relocate the objects on a link-map control list.
*/
static int
-_relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)
+_relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl)
{
Rt_map *lmp;
@@ -274,7 +274,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)
/*
* Relocate the object.
*/
- if (relocate_so(lml, lmp, relocated, 0) == 0)
+ if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0)
return (0);
/*
@@ -301,7 +301,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)
* Determine if this object is a filter, and if a load filter
* flag is in effect, trigger the loading of all its filtees.
*/
- load_filtees(lmp);
+ load_filtees(lmp, in_nfavl);
}
/*
@@ -374,7 +374,8 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated)
}
int
-relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)
+relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp,
+ int *in_nfavl)
{
int lret = 1, pret = 1;
APlist *alp;
@@ -440,7 +441,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)
* to the present link-map control list, try and clean up any
* failed objects now.
*/
- lret = _relocate_lmc(lml, nlmp, &relocated);
+ lret = _relocate_lmc(lml, nlmp, &relocated, in_nfavl);
if ((lret == 0) && (nlmco != ALIST_OFF_DATA))
remove_lmc(lml, clmp, nlmc, nlmco, NAME(nlmp));
}
@@ -516,7 +517,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp)
* then the process will receive a fatal error at that
* time. But, the .plt may never be called.
*/
- if (relocate_so(lml, lmp, 0, 1) == 0)
+ if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0)
pret = 0;
}
@@ -796,20 +797,27 @@ is_so_matched(Rt_map *lmp, const char *name, int path)
/*
* Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen()
* requests. Each request investigates the file based upon the callers
- * environment, and once a full path name has been established a check is made
- * against the FullpathNode AVL tree and a device/inode check, to ensure the
- * same file isn't mapped multiple times. See file_open().
+ * environment. Once a full path name has been established, the following
+ * checks are made:
*
- * However, there are one of two cases where a test for an existing file name
- * needs to be carried out, such as dlopen(NOLOAD) requests, dldump() requests,
- * and as a final fallback to dependency loading. These requests are handled
- * by is_so_loaded().
+ * . does the path exist in the link-map lists FullPathNode AVL tree? if
+ * so, the file is already loaded, and its associated link-map pointer
+ * is returned.
+ * . does the path exist in the not-found AVL tree? if so, this path has
+ * already been determined to not exist, and a failure is returned.
+ * . a device/inode check, to ensure the same file isn't mapped multiple
+ * times through different paths. See file_open().
+ *
+ * However, there are cases where a test for an existing file name needs to be
+ * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a
+ * final fallback to dependency loading. These requests are handled by
+ * is_so_loaded().
*
* A traversal through the callers link-map list is carried out, and from each
* link-map, a comparison is made against all of the various names by which the
- * object has been referenced. The subroutine, is_so_matched() compares the
- * link-map names against the name being searched for. Whether the search name
- * is a full path name or a simple file name, governs what comparisons are made.
+ * object has been referenced. is_so_matched() is used to compares the link-map
+ * names against the name being searched for. Whether the search name is a full
+ * path name or a simple file name, governs what comparisons are made.
*
* A full path name, which is a fully resolved path name that starts with a "/"
* character, or a relative path name that includes a "/" character, must match
@@ -818,7 +826,7 @@ is_so_matched(Rt_map *lmp, const char *name, int path)
* any link-map names.
*/
Rt_map *
-is_so_loaded(Lm_list *lml, const char *name)
+is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl)
{
Rt_map *lmp;
avl_index_t where;
@@ -828,12 +836,23 @@ is_so_loaded(Lm_list *lml, const char *name)
/*
* If the name is a full path name, first determine if the path name is
- * registered in the FullpathNode AVL tree.
+ * registered on the FullPathNode AVL, or not-found AVL trees.
*/
- if ((name[0] == '/') &&
- ((lmp = fpavl_loaded(lml, name, &where)) != NULL) &&
- ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
- return (lmp);
+ if (name[0] == '/') {
+ if (((lmp = fpavl_recorded(lml, name, &where)) != NULL) &&
+ ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
+ return (lmp);
+ if (nfavl_recorded(name, 0)) {
+ /*
+ * For dlopen() and dlsym() fall backs, indicate that
+ * a registered not-found path has indicated that this
+ * object does not exist.
+ */
+ if (in_nfavl)
+ (*in_nfavl)++;
+ return (0);
+ }
+ }
/*
* Determine whether the name is a simple file name, or a path name.
@@ -1175,11 +1194,13 @@ file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags,
static int
file_open(int err, Lm_list *lml, const char *oname, const char *nname,
- Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej)
+ Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej, int *in_nfavl)
{
struct stat status;
Rt_map *nlmp;
int resolved = 0;
+ char *name;
+ avl_index_t nfavlwhere = 0;
fdesc->fd_oname = oname;
@@ -1193,12 +1214,28 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname,
* one previously used, the process may have changed directory.
*/
if ((err == 0) && (nname[0] == '/')) {
- if ((nlmp = fpavl_loaded(lml, nname,
+ if ((nlmp = fpavl_recorded(lml, nname,
&(fdesc->fd_avlwhere))) != NULL) {
fdesc->fd_nname = nname;
fdesc->fd_lmp = nlmp;
return (1);
}
+ if (nfavl_recorded(nname, &nfavlwhere)) {
+ /*
+ * For dlopen() and dlsym() fall backs, indicate that
+ * a registered not-found path has indicated that this
+ * object does not exist. If this path has been
+ * constructed as part of expanding a HWCAP directory,
+ * and as this is a silent failure, where no rejection
+ * message is created, free the original name to
+ * simplify the life of the caller.
+ */
+ if (in_nfavl)
+ (*in_nfavl)++;
+ if (flags & FLG_RT_HWCAP)
+ free((void *)nname);
+ return (0);
+ }
}
if ((err == 0) && ((stat(nname, &status)) != -1)) {
@@ -1236,7 +1273,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname,
if (strcmp(nname, path)) {
if ((nlmp =
- fpavl_loaded(lml, path, 0)) != NULL) {
+ fpavl_recorded(lml, path, 0)) != NULL) {
added = 0;
if (append_alias(nlmp, nname,
@@ -1351,6 +1388,13 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname,
}
/*
+ * Regardless of error, duplicate and record any full path names that
+ * can't be used on the "not-found" AVL tree.
+ */
+ if ((nname[0] == '/') && ((name = strdup(nname)) != NULL))
+ nfavl_insert(name, nfavlwhere);
+
+ /*
* Indicate any rejection.
*/
if (rej->rej_type) {
@@ -1374,7 +1418,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname,
*/
int
find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
- Fdesc *fdesc, Rej_desc *rej)
+ Fdesc *fdesc, Rej_desc *rej, int *in_nfavl)
{
int err = 0;
@@ -1413,7 +1457,7 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
DBG_CALL(Dbg_libs_found(lml, aname,
FLG_FD_ALTER));
if (((ret = file_open(0, lml, oname, aname,
- clmp, flags, fdesc, rej)) != 0) ||
+ clmp, flags, fdesc, rej, in_nfavl)) != 0) ||
((obj->co_flags & RTC_OBJ_OPTINAL) == 0))
return (ret);
@@ -1422,7 +1466,8 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
}
}
DBG_CALL(Dbg_libs_found(lml, oname, 0));
- return (file_open(err, lml, oname, oname, clmp, flags, fdesc, rej));
+ return (file_open(err, lml, oname, oname, clmp, flags, fdesc,
+ rej, in_nfavl));
}
/*
@@ -1430,7 +1475,8 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
*/
static int
_find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp,
- uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag)
+ uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag,
+ int *in_nfavl)
{
DBG_CALL(Dbg_libs_found(lml, nname, aflag));
if ((lml->lm_flags & LML_FLG_TRC_SEARCH) &&
@@ -1445,9 +1491,10 @@ _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp,
* dependency, or indicate that this dependency should be ignored.
*/
if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
- char *aname = audit_objsearch(clmp, nname, dir->p_orig);
+ char *aname;
- if (aname == 0) {
+ if ((aname = audit_objsearch(clmp, nname,
+ (dir->p_orig & LA_SER_MASK))) == 0) {
DBG_CALL(Dbg_audit_terminate(lml, nname));
return (0);
}
@@ -1460,12 +1507,14 @@ _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp,
if (nname != aname)
(void) strncpy((char *)nname, aname, PATH_MAX);
}
- return (file_open(0, lml, oname, nname, clmp, flags, fdesc, rej));
+ return (file_open(0, lml, oname, nname, clmp, flags, fdesc,
+ rej, in_nfavl));
}
static int
find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
- Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen)
+ Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen,
+ int *in_nfavl)
{
static Rtc_obj Obj = { 0 };
Rtc_obj *dobj;
@@ -1542,7 +1591,8 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
* open the original path.
*/
ret = _find_file(lml, oname, alt, clmp,
- flags, fdesc, rej, dir, 1);
+ flags, fdesc, rej, dir, 1,
+ in_nfavl);
if (ret || ((fobj->co_flags &
RTC_OBJ_OPTINAL) == 0))
return (ret);
@@ -1564,7 +1614,8 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
if ((nname = (LM_GET_SO(clmp)(dir->p_name, nname))) == 0)
return (0);
- return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej, dir, 0));
+ return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej,
+ dir, 0, in_nfavl));
}
/*
@@ -1572,7 +1623,7 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags,
* process the various names by which it can be referenced.
*/
static Rt_map *
-load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc)
+load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc, int *in_nfavl)
{
const char *oname = fdesc->fd_oname;
const char *nname = fdesc->fd_nname;
@@ -1595,7 +1646,7 @@ load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc)
* original file so as not to accumulate file descriptors.
*/
nlmp = ((fdesc->fd_ftp)->fct_map_so)(lml, lmco, nname, oname,
- fdesc->fd_fd);
+ fdesc->fd_fd, in_nfavl);
(void) close(fdesc->fd_fd);
fdesc->fd_fd = 0;
@@ -1701,7 +1752,7 @@ load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc)
*/
static Rt_map *
load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
- uint_t flags, Fdesc *nfdp, Rej_desc *rej)
+ uint_t flags, Fdesc *nfdp, Rej_desc *rej, int *in_nfavl)
{
char *name;
uint_t slash = 0;
@@ -1765,7 +1816,8 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
/*
* Obtain the avl index for this object.
*/
- (void) fpavl_loaded(lml, nfdp->fd_nname, &(nfdp->fd_avlwhere));
+ (void) fpavl_recorded(lml, nfdp->fd_nname,
+ &(nfdp->fd_avlwhere));
/*
* If the name and resolved pathname differ, duplicate the path
@@ -1784,7 +1836,8 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
*nfdp = fdesc;
nfdp->fd_flags = FLG_FD_SLASH;
- if (find_path(lml, oname, clmp, flags, nfdp, &_rej) == 0) {
+ if (find_path(lml, oname, clmp, flags, nfdp,
+ &_rej, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
return (0);
}
@@ -1808,7 +1861,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
DBG_CALL(Dbg_libs_find(lml, oname));
#if !defined(ISSOLOAD_BASENAME_DISABLED)
- if ((nlmp = is_so_loaded(lml, oname)))
+ if ((nlmp = is_so_loaded(lml, oname, in_nfavl)))
return (nlmp);
#endif
/*
@@ -1824,17 +1877,36 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
*nfdp = fdesc;
/*
+ * Under debugging, duplicate path name entries are
+ * tagged but remain part of the search path list so
+ * that they can be diagnosed under "unused" processing.
+ * Skip these entries, as this path would have already
+ * been attempted.
+ */
+ if (dir->p_orig & PN_FLG_DUPLICAT)
+ continue;
+
+ /*
* Try and locate this file. Make sure to clean up
* any rejection information should the file have
* been found, but not appropriate.
*/
if (find_file(lml, oname, clmp, flags, nfdp, &_rej,
- dir, &strhash, olen) == 0) {
+ dir, &strhash, olen, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
continue;
}
/*
+ * Indicate that this search path has been used. If
+ * this is an LD_LIBRARY_PATH setting, ignore any use
+ * by ld.so.1 itself.
+ */
+ if (((dir->p_orig & LA_SER_LIBPATH) == 0) ||
+ ((lml->lm_flags & LML_FLG_RTLDLM) == 0))
+ dir->p_orig |= PN_FLG_USED;
+
+ /*
* If this object is already loaded, we're done.
*/
if (nfdp->fd_lmp)
@@ -1853,7 +1925,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
* already been opened using its full pathname).
*/
if (nfdp->fd_nname == NULL)
- return (is_so_loaded(lml, oname));
+ return (is_so_loaded(lml, oname, in_nfavl));
}
/*
@@ -1878,7 +1950,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp,
* this mapping needs to be reset to insure it doesn't mistakenly get
* unmapped as part of HWCAP cleanup.
*/
- return (load_file(lml, lmco, nfdp));
+ return (load_file(lml, lmco, nfdp, in_nfavl));
}
/*
@@ -2199,7 +2271,8 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,
*/
static Rt_map *
_load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp,
- int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej)
+ int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej,
+ int *in_nfavl)
{
Rt_map *nlmp;
const char *name = *oname;
@@ -2215,7 +2288,7 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp,
name = *oname;
if ((nlmp = load_so(lml, lmco, name, clmp, flags,
- nfdp, rej)) == 0)
+ nfdp, rej, in_nfavl)) == 0)
return (0);
/*
@@ -2243,7 +2316,7 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp,
* has already been loaded.
*/
/* LINTED */
- if (nlmp = is_so_loaded(lml, name)) {
+ if (nlmp = is_so_loaded(lml, name, in_nfavl)) {
if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) &&
((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
(void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name,
@@ -2310,8 +2383,8 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp,
}
Rt_map *
-load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp,
- int nmode, uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej)
+load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, int nmode,
+ uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej, int *in_nfavl)
{
Rt_map *lmp;
Fdesc nfdp = { 0 };
@@ -2343,7 +2416,8 @@ load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp,
nfdp = *cfdp;
}
- lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp, rej);
+ lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp,
+ rej, in_nfavl);
/*
* If this path originated from a $HWCAP specification, re-establish the
@@ -2369,7 +2443,7 @@ load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp,
*/
Rt_map *
load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode,
- uint_t flags, Grp_hdl ** hdl)
+ uint_t flags, Grp_hdl **hdl, int *in_nfavl)
{
Rej_desc rej = { 0 };
Pnode *tpnp;
@@ -2384,13 +2458,14 @@ load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode,
*/
if (tpnp->p_orig & PN_TKN_HWCAP) {
if ((tlmp = load_hwcap(lml, lmco, tpnp->p_name, clmp,
- mode, (flags | FLG_RT_HWCAP), hdl, &rej)) != 0) {
+ mode, (flags | FLG_RT_HWCAP), hdl, &rej,
+ in_nfavl)) != 0) {
remove_rej(&rej);
return (tlmp);
}
} else {
if ((tlmp = load_path(lml, lmco, &tpnp->p_name, clmp,
- mode, flags, hdl, 0, &rej)) != 0) {
+ mode, flags, hdl, 0, &rej, in_nfavl)) != 0) {
remove_rej(&rej);
return (tlmp);
}
@@ -2436,7 +2511,7 @@ is_sym_interposer(Rt_map *lmp, Sym *sym)
*/
static Sym *
lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,
- Sym *osym)
+ Sym *osym, int *in_nfavl)
{
Rt_map *lmp;
Slookup sl;
@@ -2494,8 +2569,8 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,
* executable, that the size and type of symbol are the same,
* and that the symbol is also associated with .bss.
*/
- if (((isym = SYMINTP(lmp)(&sl, &ilmp, binfo)) != NULL) &&
- (isym->st_size == osym->st_size) &&
+ if (((isym = SYMINTP(lmp)(&sl, &ilmp, binfo,
+ in_nfavl)) != NULL) && (isym->st_size == osym->st_size) &&
(isym->st_info == osym->st_info) &&
copy_zerobits(lmp, isym)) {
*dlmp = lmp;
@@ -2530,7 +2605,7 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,
Sym *isym;
sl.sl_imap = lmp;
- if (isym = SYMINTP(lmp)(&sl, &ilmp, binfo)) {
+ if (isym = SYMINTP(lmp)(&sl, &ilmp, binfo, in_nfavl)) {
/*
* If this object provides individual symbol
* interposers, make sure that the symbol we
@@ -2560,7 +2635,7 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,
*/
static Sym *
lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
- Rt_map *lmp)
+ Rt_map *lmp, int *in_nfavl)
{
Rt_map *clmp = slp->sl_cmap;
Sym *sym;
@@ -2585,7 +2660,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
(sip->si_flags & SYMINFO_FLG_COPY)) {
slp->sl_imap = LIST(clmp)->lm_head;
- if (sym = SYMINTP(clmp)(slp, dlmp, binfo))
+ if (sym = SYMINTP(clmp)(slp, dlmp, binfo, in_nfavl))
*binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF);
return (sym);
}
@@ -2609,7 +2684,8 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
*/
for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) {
sl.sl_imap = lmp = bdp->b_caller;
- if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo)) != NULL)
+ if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo,
+ in_nfavl)) != NULL)
goto found;
}
@@ -2629,7 +2705,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
continue;
sl.sl_imap = lmp = gdp->gd_depend;
if ((sym = SYMINTP(lmp)(&sl, dlmp,
- binfo)) != NULL)
+ binfo, in_nfavl)) != NULL)
goto found;
}
}
@@ -2644,7 +2720,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip,
sl.sl_imap = lmp;
if (lmp)
- sym = SYMINTP(lmp)(&sl, dlmp, binfo);
+ sym = SYMINTP(lmp)(&sl, dlmp, binfo, in_nfavl);
}
found:
if (sym)
@@ -2659,7 +2735,7 @@ found:
Sym *isym;
if ((isym = lookup_sym_interpose(slp, dlmp, binfo,
- LIST(*dlmp), sym)) != 0)
+ LIST(*dlmp), sym, in_nfavl)) != 0)
return (isym);
}
@@ -2668,7 +2744,7 @@ found:
static Sym *
core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
- Aliste off)
+ Aliste off, int *in_nfavl)
{
Rt_map *lmp;
@@ -2686,8 +2762,8 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
Sym *sym;
slp->sl_imap = lmp;
- if (((sym = SYMINTP(lmp)(slp, dlmp, binfo)) != NULL) ||
- (*binfo & BINFO_REJSINGLE))
+ if (((sym = SYMINTP(lmp)(slp, dlmp, binfo,
+ in_nfavl)) != NULL) || (*binfo & BINFO_REJSINGLE))
return (sym);
}
}
@@ -2695,7 +2771,8 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
}
static Sym *
-_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo,
+ int *in_nfavl)
{
Rt_map *lmp;
@@ -2706,7 +2783,8 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo)
Sym *sym;
slp->sl_imap = lmp;
- if ((sym = elf_lazy_find_sym(slp, dlmp, binfo)) != 0)
+ if ((sym = elf_lazy_find_sym(slp, dlmp, binfo,
+ in_nfavl)) != 0)
return (sym);
}
}
@@ -2714,7 +2792,7 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo)
}
static Sym *
-_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
const char *name = slp->sl_name;
Rt_map *clmp = slp->sl_cmap;
@@ -2732,7 +2810,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* the link map).
*/
if (slp->sl_flags & LKUP_FIRST)
- return (SYMINTP(ilmp)(slp, dlmp, binfo));
+ return (SYMINTP(ilmp)(slp, dlmp, binfo, in_nfavl));
/*
* Determine whether this lookup can be satisfied by an objects direct,
@@ -2773,7 +2851,8 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
lmp = 0;
if (bound < SYMINFO_BT_LOWRESERVE)
- lmp = elf_lazy_load(clmp, slp, bound, name);
+ lmp = elf_lazy_load(clmp, slp, bound,
+ name, in_nfavl);
/*
* If direct bindings have been disabled, and this isn't
@@ -2792,7 +2871,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
((FLAGS1(clmp) & FL1_RT_DIRECT) ||
(sip->si_flags & SYMINFO_FLG_DIRECTBIND))) {
sym = lookup_sym_direct(slp, dlmp, binfo,
- sip, lmp);
+ sip, lmp, in_nfavl);
/*
* Determine whether this direct binding has
@@ -2831,7 +2910,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) &&
((sl.sl_flags & LKUP_SINGLETON) == 0)) {
sl.sl_imap = clmp;
- if (sym = SYMINTP(clmp)(&sl, dlmp, binfo)) {
+ if (sym = SYMINTP(clmp)(&sl, dlmp, binfo, in_nfavl)) {
ulong_t dsymndx = (((ulong_t)sym -
(ulong_t)SYMTAB(*dlmp)) / SYMENT(*dlmp));
@@ -2864,12 +2943,13 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {
if (((sym = core_lookup_sym(lmc->lc_head, &sl, dlmp,
- binfo, off)) != NULL) ||
+ binfo, off, in_nfavl)) != NULL) ||
(*binfo & BINFO_REJSINGLE))
break;
}
} else
- sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA);
+ sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA,
+ in_nfavl);
/*
* If a symbol binding was rejected, because a binding occurred to a
@@ -2903,7 +2983,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* initial link-map.
*/
if (sl.sl_flags & LKUP_NEXT)
- sym = _lazy_find_sym(clmp, &sl, dlmp, binfo);
+ sym = _lazy_find_sym(clmp, &sl, dlmp, binfo, in_nfavl);
else {
Aliste idx;
Lm_cntl *lmc;
@@ -2911,7 +2991,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
sl.sl_flags |= LKUP_NOFALLBACK;
if ((sym = _lazy_find_sym(lmc->lc_head, &sl,
- dlmp, binfo)) != 0)
+ dlmp, binfo, in_nfavl)) != 0)
break;
}
}
@@ -2930,7 +3010,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* locate the symbol, the a.out function will simply ignore it.
*/
Sym *
-lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
Rt_map *clmp = slp->sl_cmap;
Sym *rsym = slp->sl_rsym, *sym = 0;
@@ -2980,7 +3060,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* Carry out an initial symbol search. This search takes into account
* all the modes of the requested search.
*/
- if (((sym = _lookup_sym(slp, dlmp, binfo)) == NULL) &&
+ if (((sym = _lookup_sym(slp, dlmp, binfo, in_nfavl)) == NULL) &&
(*binfo & BINFO_REJSINGLE)) {
Slookup sl = *slp;
@@ -2994,7 +3074,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
sl.sl_flags |= LKUP_SINGLETON;
sl.sl_rsymndx = 0;
*binfo &= ~BINFO_REJECTED;
- sym = _lookup_sym(&sl, dlmp, binfo);
+ sym = _lookup_sym(&sl, dlmp, binfo, in_nfavl);
}
/*
@@ -3006,7 +3086,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
Sym *isym;
if ((isym = lookup_sym_interpose(slp, dlmp, binfo, LIST(*dlmp),
- sym)) != 0)
+ sym, in_nfavl)) != 0)
return (isym);
}
return (sym);
diff --git a/usr/src/cmd/sgs/rtld/common/audit.c b/usr/src/cmd/sgs/rtld/common/audit.c
index 11c0f93e7c..c863943be1 100644
--- a/usr/src/cmd/sgs/rtld/common/audit.c
+++ b/usr/src/cmd/sgs/rtld/common/audit.c
@@ -862,7 +862,7 @@ static const Aud_info aud_info[] = {
#define AI_LAPLTEXIT 9
static Addr
-audit_symget(Audit_list *alp, int info)
+audit_symget(Audit_list *alp, int info, int *in_nfavl)
{
Rt_map *_lmp, *lmp = alp->al_lmp;
const char *sname = MSG_ORIG(aud_info[info].sname);
@@ -878,7 +878,7 @@ audit_symget(Audit_list *alp, int info)
SLOOKUP_INIT(sl, sname, lml_rtld.lm_head, lmp, ld_entry_cnt,
0, 0, 0, 0, LKUP_FIRST);
- if (sym = LM_LOOKUP_SYM(lmp)(&sl, &_lmp, &binfo)) {
+ if (sym = LM_LOOKUP_SYM(lmp)(&sl, &_lmp, &binfo, in_nfavl)) {
Addr addr = sym->st_value;
if (!(FLAGS(lmp) & FLG_RT_FIXED))
@@ -916,7 +916,7 @@ audit_disable(char *name, Rt_map *clmp, Grp_hdl *ghp, Audit_list *alp)
* a descriptor representing the entry points it provides.
*/
int
-audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig)
+audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig, int *in_nfavl)
{
char *ptr, *next;
Lm_list *clml = LIST(clmp);
@@ -945,7 +945,7 @@ audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig)
*/
if ((ghp = dlmopen_intn((Lm_list *)LM_ID_NEWLM, ptr,
(RTLD_FIRST | RTLD_GLOBAL | RTLD_WORLD), clmp,
- FLG_RT_AUDIT, orig, 0)) == 0) {
+ FLG_RT_AUDIT, orig)) == 0) {
error = audit_disable(ptr, clmp, 0, 0);
continue;
}
@@ -994,8 +994,8 @@ audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig)
* Determine that the symbol exists, finish initializing the
* object, and then call the function.
*/
- if ((alp->al_version =
- (uint_t(*)())audit_symget(alp, AI_LAVERSION)) == 0) {
+ if ((alp->al_version = (uint_t(*)())audit_symget(alp,
+ AI_LAVERSION, in_nfavl)) == 0) {
eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_GEN_NOSYM),
MSG_ORIG(MSG_SYM_LAVERSION));
error = audit_disable(ptr, clmp, ghp, alp);
@@ -1031,24 +1031,24 @@ audit_setup(Rt_map *clmp, Audit_desc *adp, uint_t orig)
/*
* Collect any remaining entry points.
*/
- alp->al_preinit =
- (void(*)())audit_symget(alp, AI_LAPREINIT);
- alp->al_objsearch =
- (char *(*)())audit_symget(alp, AI_LAOBJSEARCH);
- alp->al_objopen =
- (uint_t(*)())audit_symget(alp, AI_LAOBJOPEN);
- alp->al_objfilter =
- (int(*)())audit_symget(alp, AI_LAOBJFILTER);
- alp->al_objclose =
- (uint_t(*)())audit_symget(alp, AI_LAOBJCLOSE);
- alp->al_activity =
- (void (*)())audit_symget(alp, AI_LAACTIVITY);
- alp->al_symbind =
- (uintptr_t(*)())audit_symget(alp, AI_LASYMBIND);
- alp->al_pltenter =
- (uintptr_t(*)())audit_symget(alp, AI_LAPLTENTER);
- alp->al_pltexit =
- (uintptr_t(*)())audit_symget(alp, AI_LAPLTEXIT);
+ alp->al_preinit = (void(*)())audit_symget(alp,
+ AI_LAPREINIT, in_nfavl);
+ alp->al_objsearch = (char *(*)())audit_symget(alp,
+ AI_LAOBJSEARCH, in_nfavl);
+ alp->al_objopen = (uint_t(*)())audit_symget(alp,
+ AI_LAOBJOPEN, in_nfavl);
+ alp->al_objfilter = (int(*)())audit_symget(alp,
+ AI_LAOBJFILTER, in_nfavl);
+ alp->al_objclose = (uint_t(*)())audit_symget(alp,
+ AI_LAOBJCLOSE, in_nfavl);
+ alp->al_activity = (void (*)())audit_symget(alp,
+ AI_LAACTIVITY, in_nfavl);
+ alp->al_symbind = (uintptr_t(*)())audit_symget(alp,
+ AI_LASYMBIND, in_nfavl);
+ alp->al_pltenter = (uintptr_t(*)())audit_symget(alp,
+ AI_LAPLTENTER, in_nfavl);
+ alp->al_pltexit = (uintptr_t(*)())audit_symget(alp,
+ AI_LAPLTEXIT, in_nfavl);
/*
* Collect the individual object flags, and assign this audit
diff --git a/usr/src/cmd/sgs/rtld/common/cap.c b/usr/src/cmd/sgs/rtld/common/cap.c
index be646b40f3..7c69c7d4fb 100644
--- a/usr/src/cmd/sgs/rtld/common/cap.c
+++ b/usr/src/cmd/sgs/rtld/common/cap.c
@@ -145,7 +145,7 @@ remove_fdesc(Fdesc *fdp)
*/
static int
hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,
- uint_t flags, Rej_desc *rej)
+ uint_t flags, Rej_desc *rej, int *in_nfavl)
{
char path[PATH_MAX], *dst;
const char *src;
@@ -217,7 +217,8 @@ hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,
* point for control keeps the number of stat()'s down, and
* provides a single point for error diagnostics.
*/
- if (find_path(lml, name, clmp, flags, &fdesc, &_rej) == 0) {
+ if (find_path(lml, name, clmp, flags, &fdesc,
+ &_rej, in_nfavl) == 0) {
rejection_inherit(rej, &_rej);
if ((rej->rej_name != _rej.rej_name) &&
(_rej.rej_name == name))
@@ -280,7 +281,7 @@ hwcap_dir(Alist **fdalpp, Lm_list *lml, const char *name, Rt_map *clmp,
static Pnode *
_hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
- const char *ref, const char *dir, int mode, uint_t flags)
+ const char *ref, const char *dir, int mode, uint_t flags, int *in_nfavl)
{
Alist *fdalp = NULL;
Aliste idx;
@@ -290,7 +291,7 @@ _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
int unused = 0;
Rej_desc rej = { 0 };
- if (hwcap_dir(&fdalp, lml, dir, flmp, flags, &rej) == 0) {
+ if (hwcap_dir(&fdalp, lml, dir, flmp, flags, &rej, in_nfavl) == 0) {
remove_rej(&rej);
return (0);
}
@@ -322,7 +323,7 @@ _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
DBG_CALL(Dbg_file_filtee(lml, NAME(flmp), fdp->fd_nname, 0));
nlmp = load_path(lml, nlmco, &fdp->fd_nname, flmp, mode,
- (flags | FLG_RT_HANDLE), &ghp, fdp, &rej);
+ (flags | FLG_RT_HANDLE), &ghp, fdp, &rej, in_nfavl);
remove_fdesc(fdp);
if (nlmp == 0)
continue;
@@ -393,8 +394,9 @@ _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
/*
* Finish processing the objects associated with this request.
*/
- if (nlmp && ghp && ((analyze_lmc(lml, nlmco, nlmp) == 0) ||
- (relocate_lmc(lml, nlmco, flmp, nlmp) == 0)))
+ if (nlmp && ghp &&
+ ((analyze_lmc(lml, nlmco, nlmp, in_nfavl) == 0) ||
+ (relocate_lmc(lml, nlmco, flmp, nlmp, in_nfavl) == 0)))
nlmp = 0;
/*
@@ -440,7 +442,7 @@ _hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Rt_map *flmp,
Pnode *
hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Dyninfo *dip,
- Rt_map *flmp, const char *ref, int mode, uint_t flags)
+ Rt_map *flmp, const char *ref, int mode, uint_t flags, int *in_nfavl)
{
Pnode *pnp = *pnpp;
const char *dir = pnp->p_name;
@@ -449,7 +451,7 @@ hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Dyninfo *dip,
DBG_CALL(Dbg_cap_hw_filter(flml, dir, flmp));
if ((pnp = _hwcap_filtees(pnpp, nlmco, nlmc, flmp, ref, dir, mode,
- flags)) != 0)
+ flags, in_nfavl)) != 0)
return (pnp);
/*
@@ -472,7 +474,7 @@ hwcap_filtees(Pnode **pnpp, Aliste nlmco, Lm_cntl *nlmc, Dyninfo *dip,
*/
Rt_map *
load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,
- uint_t mode, uint_t flags, Grp_hdl **hdl, Rej_desc *rej)
+ uint_t mode, uint_t flags, Grp_hdl **hdl, Rej_desc *rej, int *in_nfavl)
{
Alist *fdalp = NULL;
Aliste idx;
@@ -483,7 +485,7 @@ load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,
/*
* Obtain the sorted list of hardware capabilites objects available.
*/
- if (hwcap_dir(&fdalp, lml, dir, clmp, flags, rej) == 0)
+ if (hwcap_dir(&fdalp, lml, dir, clmp, flags, rej, in_nfavl) == 0)
return (0);
/*
@@ -492,7 +494,7 @@ load_hwcap(Lm_list *lml, Aliste lmco, const char *dir, Rt_map *clmp,
*/
for (ALIST_TRAVERSE(fdalp, idx, fdp)) {
if ((found == 0) && ((lmp = load_path(lml, lmco, &fdp->fd_nname,
- clmp, mode, flags, hdl, fdp, rej)) != 0))
+ clmp, mode, flags, hdl, fdp, rej, in_nfavl)) != 0))
found++;
/*
diff --git a/usr/src/cmd/sgs/rtld/common/dlfcns.c b/usr/src/cmd/sgs/rtld/common/dlfcns.c
index 2a71f96bf2..05a707232c 100644
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c
+++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c
@@ -258,17 +258,6 @@ hdl_create(Lm_list *lml, Rt_map *nlmp, Rt_map *clmp, uint_t hflags,
if (aplist_append(alpp, ghp, AL_CNT_GROUPS) == 0)
return (0);
- /*
- * Indicate that this object has been referenced. In truth a
- * reference hasn't yet occurred, it's a dlsym() that makes the
- * reference. However, we assume that anyone performing a
- * dlopen() will eventually call dlsym(), plus this makes for a
- * better diagnostic location rather than having to call
- * unused() after every dlsym() operation.
- */
- if (nlmp)
- FLAGS1(nlmp) |= FL1_RT_USED;
-
ghp->gh_refcnt = 1;
ghp->gh_flags = hflags;
@@ -588,7 +577,7 @@ newlmid(Lm_list *lml)
*/
static Grp_hdl *
dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
- uint_t flags, uint_t orig)
+ uint_t flags, uint_t orig, int *in_nfavl)
{
Rt_map *nlmp;
Grp_hdl *ghp;
@@ -597,7 +586,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
Lm_cntl *lmc;
DBG_CALL(Dbg_file_dlopen(clmp,
- (path ? path : MSG_ORIG(MSG_STR_ZERO)), mode));
+ (path ? path : MSG_ORIG(MSG_STR_ZERO)), in_nfavl, mode));
/*
* If the path specified is null then we're operating on global
@@ -660,7 +649,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
}
if (promote)
(void) relocate_lmc(lml, ALIST_OFF_DATA, clmp,
- lml->lm_head);
+ lml->lm_head, in_nfavl);
return (ghp);
}
@@ -695,7 +684,7 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
olmco = nlmco = (Aliste)((char *)lmc - (char *)lml->lm_lists);
nlmp = load_one(lml, nlmco, pnp, clmp, mode,
- (flags | FLG_RT_HANDLE), &ghp);
+ (flags | FLG_RT_HANDLE), &ghp, in_nfavl);
/*
* Remove any expanded pathname infrastructure, and if the dependency
@@ -725,8 +714,8 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
/*
* Finish processing the objects associated with this request.
*/
- if ((analyze_lmc(lml, nlmco, nlmp) == 0) ||
- (relocate_lmc(lml, nlmco, clmp, nlmp) == 0)) {
+ if ((analyze_lmc(lml, nlmco, nlmp, in_nfavl) == 0) ||
+ (relocate_lmc(lml, nlmco, clmp, nlmp, in_nfavl) == 0)) {
ghp = 0;
nlmp = 0;
}
@@ -749,16 +738,46 @@ dlmopen_core(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
}
/*
+ * dlopen() and dlsym() operations are the means by which a process can
+ * test for the existence of required dependencies. If the necessary
+ * dependencies don't exist, then associated functionality can't be used.
+ * However, the lack of dependencies can be fixed, and the dlopen() and
+ * dlsym() requests can be repeated. As we use a "not-found" AVL tree to
+ * cache any failed full path loads, secondary dlopen() and dlsym() requests
+ * will fail, even if the dependencies have been installed.
+ *
+ * dlopen() and dlsym() retry any failures by removing the "not-found" AVL
+ * tree. Should any dependencies be found, their names are added to the
+ * FullPath AVL tree. This routine removes any new "not-found" AVL tree,
+ * so that the dlopen() or dlsym() can replace the original "not-found" tree.
+ */
+inline static void
+nfavl_remove(avl_tree_t *avlt)
+{
+ PathNode *pnp;
+ void *cookie = NULL;
+
+ if (avlt) {
+ while ((pnp = avl_destroy_nodes(avlt, &cookie)) != NULL) {
+ free((void *)pnp->pn_name);
+ free(pnp);
+ }
+ avl_destroy(avlt);
+ free(avlt);
+ }
+}
+
+/*
* Internal dlopen() activity. Called from user level or directly for internal
* opens that require a handle.
*/
Grp_hdl *
dlmopen_intn(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
- uint_t flags, uint_t orig, int *loaded)
+ uint_t flags, uint_t orig)
{
Rt_map *dlmp = 0;
Grp_hdl *ghp;
- int objcnt;
+ int in_nfavl = 0;
/*
* Check for magic link-map list values:
@@ -803,23 +822,40 @@ dlmopen_intn(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
lml = &lml_rtld;
}
- objcnt = lml->lm_obj;
-
/*
* Open the required object on the associated link-map list.
*/
- if ((ghp = dlmopen_core(lml, path, mode, clmp, flags,
- (orig | PN_SER_DLOPEN))) != 0) {
+ ghp = dlmopen_core(lml, path, mode, clmp, flags, orig, &in_nfavl);
+
+ /*
+ * If the object could not be found it is possible that the "not-found"
+ * AVL tree had indicated that the file does not exist. In case the
+ * file system has changes since this "not-found" recording was made,
+ * retry the dlopen() with a clean "not-found" AVL tree.
+ */
+ if ((ghp == 0) && in_nfavl) {
+ avl_tree_t *oavlt = nfavl;
+
+ nfavl = NULL;
+ ghp = dlmopen_core(lml, path, mode, clmp, flags, orig, NULL);
+
/*
- * Establish the new link-map from which .init processing will
- * begin. Ignore .init firing when constructing a configuration
- * file (crle(1)).
+ * If the file is found, then its full path name will have been
+ * registered in the FullPath AVL tree. Remove any new
+ * "not-found" AVL information, and restore the former AVL tree.
*/
- if ((mode & RTLD_CONFGEN) == 0)
- dlmp = ghp->gh_ownlmp;
+ nfavl_remove(nfavl);
+ nfavl = oavlt;
}
/*
+ * Establish the new link-map from which .init processing will begin.
+ * Ignore .init firing when constructing a configuration file (crle(1)).
+ */
+ if (ghp && ((mode & RTLD_CONFGEN) == 0))
+ dlmp = ghp->gh_ownlmp;
+
+ /*
* If loading an auditor was requested, and the auditor already existed,
* then the link-map returned will be to the original auditor. Remove
* the link-map control list that was created for this request.
@@ -830,13 +866,6 @@ dlmopen_intn(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
}
/*
- * Return the number of objects loaded if required. This is used to
- * trigger used() processing on return from a dlopen().
- */
- if (loaded)
- *loaded = lml->lm_obj - objcnt;
-
- /*
* If this load failed, remove any alternative link-map list.
*/
if ((ghp == 0) &&
@@ -859,8 +888,7 @@ dlmopen_intn(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
* Argument checking for dlopen. Only called via external entry.
*/
static Grp_hdl *
-dlmopen_check(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
- int *loaded)
+dlmopen_check(Lm_list *lml, const char *path, int mode, Rt_map *clmp)
{
/*
* Verify that a valid pathname has been supplied.
@@ -899,7 +927,7 @@ dlmopen_check(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
mode |= RTLD_LAZY;
}
- return (dlmopen_intn(lml, path, mode, clmp, 0, 0, loaded));
+ return (dlmopen_intn(lml, path, mode, clmp, 0, 0));
}
#pragma weak dlopen = _dlopen
@@ -912,7 +940,7 @@ dlmopen_check(Lm_list *lml, const char *path, int mode, Rt_map *clmp,
void *
_dlopen(const char *path, int mode)
{
- int entry, loaded = 0;
+ int entry;
Rt_map *clmp;
Grp_hdl *ghp;
Lm_list *lml;
@@ -922,10 +950,7 @@ _dlopen(const char *path, int mode)
clmp = _caller(caller(), CL_EXECDEF);
lml = LIST(clmp);
- ghp = dlmopen_check(lml, path, mode, clmp, &loaded);
-
- if (entry && ghp && loaded)
- unused(lml);
+ ghp = dlmopen_check(lml, path, mode, clmp);
if (entry)
leave(lml);
@@ -940,7 +965,7 @@ _dlopen(const char *path, int mode)
void *
_dlmopen(Lmid_t lmid, const char *path, int mode)
{
- int entry, loaded = 0;
+ int entry;
Rt_map *clmp;
Grp_hdl *ghp;
@@ -948,10 +973,7 @@ _dlmopen(Lmid_t lmid, const char *path, int mode)
clmp = _caller(caller(), CL_EXECDEF);
- ghp = dlmopen_check((Lm_list *)lmid, path, mode, clmp, &loaded);
-
- if (entry && ghp && ghp->gh_ownlmp && loaded)
- unused(LIST(ghp->gh_ownlmp));
+ ghp = dlmopen_check((Lm_list *)lmid, path, mode, clmp);
if (entry)
leave(LIST(clmp));
@@ -962,7 +984,8 @@ _dlmopen(Lmid_t lmid, const char *path, int mode)
* Handle processing for dlsym.
*/
Sym *
-dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
+dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo,
+ int *in_nfavl)
{
Rt_map *nlmp, * lmp = ghp->gh_ownlmp;
Rt_map *clmp = slp->sl_cmap;
@@ -1011,7 +1034,8 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
continue;
sl.sl_imap = nlmp;
- if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo))
+ if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo,
+ in_nfavl))
return (sym);
}
@@ -1041,7 +1065,8 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
lazy = 1;
sl.sl_imap = nlmp;
- if (sym = elf_lazy_find_sym(&sl, _lmp, binfo))
+ if (sym = elf_lazy_find_sym(&sl, _lmp, binfo,
+ in_nfavl))
return (sym);
}
@@ -1070,7 +1095,8 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
continue;
sl.sl_imap = gdp->gd_depend;
- if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo))
+ if (sym = LM_LOOKUP_SYM(clmp)(&sl, _lmp, binfo,
+ in_nfavl))
return (sym);
if (ghp->gh_flags & GPH_FIRST)
@@ -1097,7 +1123,8 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
lazy = 1;
sl.sl_imap = nlmp;
- if (sym = elf_lazy_find_sym(&sl, _lmp, binfo))
+ if (sym = elf_lazy_find_sym(&sl, _lmp,
+ binfo, in_nfavl))
return (sym);
}
@@ -1120,7 +1147,8 @@ dlsym_handle(Grp_hdl *ghp, Slookup *slp, Rt_map **_lmp, uint_t *binfo)
* Core dlsym activity. Selects symbol lookup method from handle.
*/
void *
-dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
+dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp,
+ int *in_nfavl)
{
Sym *sym = NULL;
Syminfo *sip;
@@ -1146,7 +1174,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
0, 0, 0, LKUP_SYMNDX);
if ((FCT(clmp) == &elf_fct) &&
- ((sym = SYMINTP(clmp)(&sl, 0, 0)) != NULL)) {
+ ((sym = SYMINTP(clmp)(&sl, 0, 0, NULL)) != NULL)) {
sl.sl_rsymndx = (((ulong_t)sym -
(ulong_t)SYMTAB(clmp)) / SYMENT(clmp));
sl.sl_rsym = sym;
@@ -1160,13 +1188,14 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
* that the symbol is a singleton, then the search for the
* symbol must follow the default search path.
*/
- DBG_CALL(Dbg_syms_dlsym(clmp, name, 0, DBG_DLSYM_SINGLETON));
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl, 0,
+ DBG_DLSYM_SINGLETON));
sl.sl_imap = hlmp;
sl.sl_flags = LKUP_SPEC;
if (handle == RTLD_PROBE)
sl.sl_flags |= LKUP_NOFALLBACK;
- sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
+ sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo, in_nfavl);
} else if (handle == RTLD_NEXT) {
Rt_map *nlmp;
@@ -1186,7 +1215,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
if ((sip->si_flags & SYMINFO_FLG_DIRECT) &&
(sip->si_boundto < SYMINFO_BT_LOWRESERVE))
(void) elf_lazy_load(clmp, &sl,
- sip->si_boundto, name);
+ sip->si_boundto, name, in_nfavl);
/*
* Clear the symbol index, so as not to confuse
@@ -1205,25 +1234,26 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
*/
sl.sl_imap = nlmp = (Rt_map *)NEXT(clmp);
- DBG_CALL(Dbg_syms_dlsym(clmp, name, (nlmp ? NAME(nlmp) :
- MSG_INTL(MSG_STR_NULL)), DBG_DLSYM_NEXT));
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl,
+ (nlmp ? NAME(nlmp) : MSG_INTL(MSG_STR_NULL)),
+ DBG_DLSYM_NEXT));
if (nlmp == 0)
return (0);
sl.sl_flags = LKUP_NEXT;
- sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
+ sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo, in_nfavl);
} else if (handle == RTLD_SELF) {
/*
* If the handle is RTLD_SELF start searching from the caller.
*/
- DBG_CALL(Dbg_syms_dlsym(clmp, name, NAME(clmp),
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl, NAME(clmp),
DBG_DLSYM_SELF));
sl.sl_imap = clmp;
sl.sl_flags = (LKUP_SPEC | LKUP_SELF);
- sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
+ sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo, in_nfavl);
} else if (handle == RTLD_DEFAULT) {
Rt_map *hlmp = LIST(clmp)->lm_head;
@@ -1232,11 +1262,12 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
* If the handle is RTLD_DEFAULT mimic the standard symbol
* lookup as would be triggered by a relocation.
*/
- DBG_CALL(Dbg_syms_dlsym(clmp, name, 0, DBG_DLSYM_DEFAULT));
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl, 0,
+ DBG_DLSYM_DEFAULT));
sl.sl_imap = hlmp;
sl.sl_flags = LKUP_SPEC;
- sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
+ sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo, in_nfavl);
} else if (handle == RTLD_PROBE) {
Rt_map *hlmp = LIST(clmp)->lm_head;
@@ -1250,11 +1281,12 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
* loaded to satisfy this request, but no exhaustive lazy load
* rescan is carried out.
*/
- DBG_CALL(Dbg_syms_dlsym(clmp, name, 0, DBG_DLSYM_PROBE));
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl, 0,
+ DBG_DLSYM_PROBE));
sl.sl_imap = hlmp;
sl.sl_flags = (LKUP_SPEC | LKUP_NOFALLBACK);
- sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
+ sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo, in_nfavl);
} else {
Grp_hdl *ghp = (Grp_hdl *)handle;
@@ -1263,10 +1295,10 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
* Look in the shared object specified by the handle and in all
* of its dependencies.
*/
- DBG_CALL(Dbg_syms_dlsym(clmp, name, NAME(ghp->gh_ownlmp),
- DBG_DLSYM_DEF));
+ DBG_CALL(Dbg_syms_dlsym(clmp, name, in_nfavl,
+ NAME(ghp->gh_ownlmp), DBG_DLSYM_DEF));
- sym = LM_DLSYM(clmp)(ghp, &sl, dlmp, &binfo);
+ sym = LM_DLSYM(clmp)(ghp, &sl, dlmp, &binfo, in_nfavl);
}
if (sym) {
@@ -1276,6 +1308,12 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
if (!(FLAGS(*dlmp) & FLG_RT_FIXED))
addr += ADDR(*dlmp);
+ /*
+ * Indicate that the defining object is now used.
+ */
+ if (*dlmp != clmp)
+ FLAGS1(*dlmp) |= FL1_RT_USED;
+
DBG_CALL(Dbg_bind_global(clmp, 0, 0, (Xword)-1, PLT_T_NONE,
*dlmp, addr, sym->st_value, name, binfo));
@@ -1303,6 +1341,7 @@ dlsym_intn(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
void *error;
Aliste idx;
Grp_desc *gdp;
+ int in_nfavl = 0;
/*
* While looking for symbols it's quite possible that additional objects
@@ -1326,7 +1365,31 @@ dlsym_intn(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
}
}
- if ((error = dlsym_core(handle, name, clmp, dlmp)) == 0) {
+ error = dlsym_core(handle, name, clmp, dlmp, &in_nfavl);
+
+ /*
+ * If the symbol could not be found it is possible that the "not-found"
+ * AVL tree had indicated that a required file does not exist. In case
+ * the file system has changed since this "not-found" recording was
+ * made, retry the dlsym() with a clean "not-found" AVL tree.
+ */
+ if ((error == 0) && in_nfavl) {
+ avl_tree_t *oavlt = nfavl;
+
+ nfavl = NULL;
+ error = dlsym_core(handle, name, clmp, dlmp, NULL);
+
+ /*
+ * If the symbol is found, then any file that was loaded will
+ * have had its full path name registered in the FullPath AVL
+ * tree. Remove any new "not-found" AVL information, and
+ * restore the former AVL tree.
+ */
+ nfavl_remove(nfavl);
+ nfavl = oavlt;
+ }
+
+ if (error == 0) {
/*
* Cache the error message, as Java tends to fall through this
* code many times.
@@ -1520,7 +1583,7 @@ dldump_core(Lm_list *lml, const char *ipath, const char *opath, int flags)
* have to be revisited.
*/
if (ipath) {
- if ((lmp = is_so_loaded(&lml_main, ipath)) == 0) {
+ if ((lmp = is_so_loaded(&lml_main, ipath, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_GEN_NOFILE),
ipath);
return (1);
diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c
index d3ead6b3aa..cf19a36c34 100644
--- a/usr/src/cmd/sgs/rtld/common/elf.c
+++ b/usr/src/cmd/sgs/rtld/common/elf.c
@@ -95,8 +95,9 @@ static int elf_are_u(Rej_desc *);
static void elf_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int);
static ulong_t elf_entry_pt(void);
static char *elf_get_so(const char *, const char *);
-static Rt_map *elf_map_so(Lm_list *, Aliste, const char *, const char *, int);
-static int elf_needed(Lm_list *, Aliste, Rt_map *);
+static Rt_map *elf_map_so(Lm_list *, Aliste, const char *, const char *,
+ int, int *);
+static int elf_needed(Lm_list *, Aliste, Rt_map *, int *);
static void elf_unmap_so(Rt_map *);
static int elf_verify_vers(const char *, Rt_map *, Rt_map *);
@@ -152,7 +153,6 @@ elf_fix_name(const char *name, Rt_map *clmp, uint_t orig)
return (0);
}
pnp->p_len = MSG_PTH_LIBSYS_SIZE;
- pnp->p_orig = (orig & PN_SER_MASK);
return (pnp);
}
@@ -250,7 +250,7 @@ elf_rtld_load()
* As we need to refer to the DYNINFO() information, insure that it has
* been initialized.
*/
- if (elf_needed(lml, ALIST_OFF_DATA, lmp) == 0)
+ if (elf_needed(lml, ALIST_OFF_DATA, lmp, NULL) == 0)
return (0);
#if defined(__i386)
@@ -278,7 +278,8 @@ elf_rtld_load()
* Lazy load an object.
*/
Rt_map *
-elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym)
+elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym,
+ int *in_nfavl)
{
Rt_map *nlmp, *hlmp;
Dyninfo *dip = &DYNINFO(clmp)[ndx], *pdip;
@@ -336,7 +337,7 @@ elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym)
/*
* Expand the requested name if necessary.
*/
- if ((pnp = elf_fix_name(name, clmp, PN_SER_NEEDED)) == 0)
+ if ((pnp = elf_fix_name(name, clmp, 0)) == 0)
return (0);
/*
@@ -360,7 +361,7 @@ elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym)
* Load the associated object.
*/
dip->di_info = nlmp =
- load_one(lml, lmco, pnp, clmp, MODE(clmp), flags, 0);
+ load_one(lml, lmco, pnp, clmp, MODE(clmp), flags, 0, in_nfavl);
/*
* Remove any expanded pathname infrastructure. Reduce the pending lazy
@@ -376,8 +377,8 @@ elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym)
* create an association between the caller and this dependency.
*/
if (nlmp && ((bind_one(clmp, nlmp, BND_NEEDED) == 0) ||
- (analyze_lmc(lml, lmco, nlmp) == 0) ||
- (relocate_lmc(lml, lmco, clmp, nlmp) == 0)))
+ (analyze_lmc(lml, lmco, nlmp, in_nfavl) == 0) ||
+ (relocate_lmc(lml, lmco, clmp, nlmp, in_nfavl) == 0)))
dip->di_info = nlmp = 0;
/*
@@ -589,7 +590,7 @@ elf_verify_vers(const char *name, Rt_map *clmp, Rt_map *nlmp)
* link map the the dlopen list.
*/
static int
-elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
+elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
{
Dyn *dyn, *pdyn;
ulong_t ndx = 0;
@@ -709,9 +710,9 @@ elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
* Establish the objects name, load it and establish a binding
* with the caller.
*/
- if (((pnp = elf_fix_name(name, clmp, PN_SER_NEEDED)) == 0) ||
- ((nlmp = load_one(lml, lmco, pnp, clmp, MODE(clmp),
- flags, 0)) == 0) || (bind_one(clmp, nlmp, BND_NEEDED) == 0))
+ if (((pnp = elf_fix_name(name, clmp, 0)) == 0) || ((nlmp =
+ load_one(lml, lmco, pnp, clmp, MODE(clmp), flags, 0,
+ in_nfavl)) == 0) || (bind_one(clmp, nlmp, BND_NEEDED) == 0))
nlmp = 0;
/*
@@ -1323,7 +1324,7 @@ elf_map_it(
*/
/* ARGSUSED0 */
static Sym *
-elf_null_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+elf_null_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
return ((Sym *)0);
}
@@ -1376,7 +1377,8 @@ elf_disable_filtee(Rt_map *lmp, Dyninfo *dip)
* A symbol name of 0 is used to trigger filtee loading.
*/
static Sym *
-_elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
+_elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx,
+ int *in_nfavl)
{
const char *name = slp->sl_name, *filtees;
Rt_map *clmp = slp->sl_cmap;
@@ -1436,7 +1438,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
NAME(ilmp), filtees);
if ((dip->di_info = (void *)expand_paths(ilmp,
- filtees, PN_SER_FILTEE, 0)) == 0) {
+ filtees, 0, 0)) == 0) {
elf_disable_filtee(ilmp, dip);
return ((Sym *)0);
}
@@ -1494,7 +1496,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
}
pnp = hwcap_filtees(pnpp, lmco, lmc, dip, ilmp, filtees,
- mode, (FLG_RT_HANDLE | FLG_RT_HWCAP));
+ mode, (FLG_RT_HANDLE | FLG_RT_HWCAP), in_nfavl);
/*
* Now that any hardware capability objects have been
@@ -1590,7 +1592,7 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
*/
if ((nlmp = load_path(lml, lmco, &(pnp->p_name),
ilmp, mode, FLG_RT_HANDLE, &ghp, 0,
- &rej)) == 0) {
+ &rej, in_nfavl)) == 0) {
file_notfound(LIST(ilmp), filtee, ilmp,
FLG_RT_HANDLE, &rej);
remove_rej(&rej);
@@ -1604,6 +1606,8 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
if (nlmp && ghp) {
ghp->gh_flags |= GPH_FILTEE;
pnp->p_info = (void *)ghp;
+
+ FLAGS1(nlmp) |= FL1_RT_USED;
}
/*
@@ -1627,9 +1631,9 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
* provide sufficient information to tear down
* this filtee if necessary.
*/
- if (nlmp && ghp &&
- ((analyze_lmc(lml, lmco, nlmp) == 0) ||
- (relocate_lmc(lml, lmco, ilmp, nlmp) == 0)))
+ if (nlmp && ghp && ((analyze_lmc(lml, lmco,
+ nlmp, in_nfavl) == 0) || (relocate_lmc(lml,
+ lmco, ilmp, nlmp, in_nfavl) == 0)))
nlmp = 0;
/*
@@ -1783,7 +1787,8 @@ _elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
* be suppressed. All detailed ldd messages should still be produced.
*/
Sym *
-elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
+elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx,
+ int *in_nfavl)
{
Sym *sym;
Dyninfo *dip = &DYNINFO(slp->sl_imap)[ndx];
@@ -1808,7 +1813,7 @@ elf_lookup_filtee(Slookup *slp, Rt_map **dlmp, uint_t *binfo, uint_t ndx)
silent = 1;
}
- sym = _elf_lookup_filtee(slp, dlmp, binfo, ndx);
+ sym = _elf_lookup_filtee(slp, dlmp, binfo, ndx, in_nfavl);
if (silent)
rtld_flags &= ~RT_FL_SILENCERR;
@@ -1854,7 +1859,7 @@ elf_hash(const char *name)
* routines do NOT set LKUP_SPEC in the flag.
*/
Sym *
-elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
+elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl)
{
const char *name = slp->sl_name;
Rt_map *ilmp = slp->sl_imap;
@@ -2047,7 +2052,7 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* catch any object filtering that may be available.
*/
if ((fsym = elf_lookup_filtee(slp, dlmp, binfo,
- sip->si_boundto)) != 0)
+ sip->si_boundto, in_nfavl)) != 0)
return (fsym);
if (sip->si_flags & SYMINFO_FLG_FILTER)
return ((Sym *)0);
@@ -2069,7 +2074,7 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* within the filter itself.
*/
if ((fsym = elf_lookup_filtee(slp, dlmp, binfo,
- OBJFLTRNDX(ilmp))) != 0)
+ OBJFLTRNDX(ilmp), in_nfavl)) != 0)
return (fsym);
}
@@ -2086,7 +2091,8 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
Rt_map *
elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
ulong_t addr, ulong_t etext, Aliste lmco, ulong_t msize, ulong_t entry,
- ulong_t paddr, ulong_t padimsize, Mmap *mmaps, uint_t mmapcnt)
+ ulong_t paddr, ulong_t padimsize, Mmap *mmaps, uint_t mmapcnt,
+ int *in_nfavl)
{
Rt_map *lmp;
ulong_t base, fltr = 0, audit = 0, cfile = 0, crle = 0;
@@ -2599,7 +2605,8 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
return (0);
}
if (lml_main.lm_head) {
- if (audit_setup(lmp, AUDITORS(lmp), 0) == 0) {
+ if (audit_setup(lmp, AUDITORS(lmp), 0,
+ in_nfavl) == 0) {
remove_so(0, lmp);
return (0);
}
@@ -2650,7 +2657,7 @@ cap_assign(Cap *cap, Rt_map *lmp)
*/
static Rt_map *
elf_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
- int fd)
+ int fd, int *in_nfavl)
{
int i; /* general temporary */
Off memsize = 0; /* total memory size of pathname */
@@ -2918,7 +2925,7 @@ elf_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
*/
if (!(lmp = elf_new_lm(lml, pname, oname, mld, (ulong_t)faddr,
fmap->fm_etext, lmco, memsize, mentry, (ulong_t)paddr, plen, mmaps,
- mmapcnt))) {
+ mmapcnt, in_nfavl))) {
(void) munmap((caddr_t)faddr, memsize);
return (0);
}
@@ -3312,7 +3319,7 @@ elf_lazy_cleanup(APlist *alp)
* search duplication.
*/
Sym *
-elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
+elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo, int *in_nfavl)
{
Sym *sym = 0;
APlist *alist = NULL;
@@ -3388,7 +3395,8 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
* search, whereas before the object might have been
* skipped.
*/
- if ((nlmp = elf_lazy_load(lmp, &sl, cnt, name)) == 0)
+ if ((nlmp = elf_lazy_load(lmp, &sl, cnt,
+ name, in_nfavl)) == 0)
continue;
/*
@@ -3401,7 +3409,8 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
continue;
sl.sl_imap = nlmp;
- if (sym = LM_LOOKUP_SYM(sl.sl_cmap)(&sl, _lmp, binfo))
+ if (sym = LM_LOOKUP_SYM(sl.sl_cmap)(&sl, _lmp,
+ binfo, in_nfavl))
break;
/*
diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c
index a77df480ea..2b220be94e 100644
--- a/usr/src/cmd/sgs/rtld/common/globals.c
+++ b/usr/src/cmd/sgs/rtld/common/globals.c
@@ -48,15 +48,17 @@ Lm_list lml_main = { 0 }; /* the `main's link map list */
Lm_list lml_rtld = { 0 }; /* rtld's link map list */
/*
- * Entrance count. Each time ld.so.1 is entered this count is bumped. This
- * value serves to identify the present ld.so.1 operation. Any ld.so.1
- * operation can result in many symbol lookup requests (ie. loading objects and
- * relocating all symbolic bindings). This count is used to protect against
- * attempting to re-load a failed lazy load within a single call to ld.so.1,
- * while allowing such attempts across calls. Should a lazy load fail, the
- * present operation identifier is saved in the current symbol lookup data
+ * Entrance count. Each time ld.so.1 is entered following initial process
+ * setup, this count is bumped. This value serves to identify the present
+ * ld.so.1 operation.
+ *
+ * An ld.so.1 operation can result in many symbol lookup requests (i.e., loading
+ * objects and relocating all symbolic bindings). This count is used to protect
+ * against attempting to re-load a failed lazy load within a single call to
+ * ld.so.1, while allowing such attempts across calls. Should a lazy load fail,
+ * the present operation identifier is saved in the current symbol lookup data
* block (Slookup). Should a lazy load fall back operation be triggered, the
- * identifier in the symbol lookup block is compared to the current ld.so.1
+ * identifier in the symbol lookup block is compared to the current ld.so.1
* entry count, and if the two are equal the fall back is skipped.
*
* With this count, there is a danger of wrap-around, although as an unsigned
@@ -64,9 +66,9 @@ Lm_list lml_rtld = { 0 }; /* rtld's link map list */
* 4.3 giga-calls into ld.so.1. The worst that can occur is that a fall back
* lazy load isn't triggered. However, most lazy loads that fail typically
* continue to fail unless the user takes corrective action (adds the necessary
- * (fixed) dependencies to the system.
+ * (fixed) dependencies to the system).
*/
-ulong_t ld_entry_cnt = 0;
+ulong_t ld_entry_cnt = 1;
/*
* BEGIN: Exposed to rtld_db, don't change without a coordinated handshake with
@@ -90,9 +92,8 @@ static Fmap _fmap = { 0, 0, 0, 0, 0 };
Fmap * fmap = &_fmap; /* initial file mapping info */
/*
- * Set of integers to track how many of what type of
- * PLT's have been bound. This is only really interesting
- * for SPARC since ia32 basically just has the one PLT.
+ * Set of integers to track how many of what type of PLT's have been bound.
+ * This is only really interesting for SPARC since ia32 has only one PLT.
*/
uint32_t pltcnt21d = 0;
uint32_t pltcnt24d = 0;
@@ -102,6 +103,11 @@ uint32_t pltcntfull = 0;
uint32_t pltcntfar = 0;
/*
+ * Provide for recording not-found path names.
+ */
+avl_tree_t *nfavl = NULL;
+
+/*
* Enable technology (via status flags for RTLD) dependent upon whether we're
* in a patch or major release build environment.
*/
diff --git a/usr/src/cmd/sgs/rtld/common/object.c b/usr/src/cmd/sgs/rtld/common/object.c
index a654b632f2..89217f52ba 100644
--- a/usr/src/cmd/sgs/rtld/common/object.c
+++ b/usr/src/cmd/sgs/rtld/common/object.c
@@ -163,7 +163,7 @@ elf_obj_file(Lm_list *lml, Aliste lmco, const char *name, int fd)
* the appropriate link-edit functionality (refer to sgs/ld/common/main.c).
*/
Rt_map *
-elf_obj_fini(Lm_list *lml, Rt_map *lmp)
+elf_obj_fini(Lm_list *lml, Rt_map *lmp, int *in_nfavl)
{
Ofl_desc *ofl = (Ofl_desc *)lmp->rt_priv;
Rt_map *nlmp;
@@ -221,7 +221,7 @@ elf_obj_fini(Lm_list *lml, Rt_map *lmp)
if ((nlmp = elf_new_lm(lml, ofl->ofl_name, ofl->ofl_name,
ofl->ofl_osdynamic->os_outdata->d_buf, (ulong_t)ehdr,
(ulong_t)ehdr + etext, CNTL(olmp), (ulong_t)ofl->ofl_size,
- 0, 0, 0, mmaps, mmapcnt)) == 0)
+ 0, 0, 0, mmaps, mmapcnt, in_nfavl)) == 0)
return (0);
/*
diff --git a/usr/src/cmd/sgs/rtld/common/paths.c b/usr/src/cmd/sgs/rtld/common/paths.c
index dd1569b00e..91a3a6e6dd 100644
--- a/usr/src/cmd/sgs/rtld/common/paths.c
+++ b/usr/src/cmd/sgs/rtld/common/paths.c
@@ -48,7 +48,7 @@
* to the specified rule.
*/
static Pnode *
-get_dir_list(unsigned char rules, Rt_map * lmp, uint_t flags)
+get_dir_list(uchar_t rules, Rt_map *lmp, uint_t flags)
{
Pnode * dirlist = (Pnode *)0;
Lm_list * lml = LIST(lmp);
@@ -74,7 +74,7 @@ get_dir_list(unsigned char rules, Rt_map * lmp, uint_t flags)
* be preceded with the appropriate search path information.
*/
if (rpl_libpath) {
- Half mode = LA_SER_LIBPATH;
+ uint_t mode = (LA_SER_LIBPATH | PN_FLG_UNIQUE);
/*
* Note, this path may have originated from the users
@@ -128,8 +128,11 @@ get_dir_list(unsigned char rules, Rt_map * lmp, uint_t flags)
* always call Dbg_libs_path().
*/
if (prm_libpath) {
- DBG_CALL(Dbg_libs_path(lml, prm_libpath,
- (LA_SER_LIBPATH | LA_SER_CONFIG), config->c_name));
+ uint_t mode =
+ (LA_SER_LIBPATH | LA_SER_CONFIG | PN_FLG_UNIQUE);
+
+ DBG_CALL(Dbg_libs_path(lml, prm_libpath, mode,
+ config->c_name));
/*
* For ldd(1) -s, indicate the search paths that'll
@@ -153,8 +156,7 @@ get_dir_list(unsigned char rules, Rt_map * lmp, uint_t flags)
* be selective over what directories we use.
*/
prm_libdirs = expand_paths(lmp, prm_libpath,
- (LA_SER_LIBPATH | LA_SER_CONFIG),
- PN_TKN_HWCAP);
+ mode, PN_TKN_HWCAP);
}
dirlist = prm_libdirs;
}
@@ -281,7 +283,6 @@ get_next_dir(Pnode ** dirlist, Rt_map * lmp, uint_t flags)
return (NULL);
}
-
/*
* Process a directory (runpath) or filename (needed or filter) string looking
* for tokens to expand. Allocate a new buffer for the string.
@@ -667,7 +668,7 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit,
* A path that has been expanded, is typically used to create full
* pathnames for objects that will be opened. The final pathname is
* resolved to simplify it, and set the stage for possible $ORIGIN
- * processing. Therefore, it's usually unncessary to resolve the path
+ * processing. Therefore, it's usually unnecessary to resolve the path
* at this point. However, if a configuration file, containing
* directory information is in use, then we might need to lookup this
* path in the configuration file. To keep the number of pathname
@@ -706,7 +707,7 @@ expand(char **name, size_t *len, char **list, uint_t orig, uint_t omit,
* Determine whether a pathname is secure.
*/
static int
-is_path_secure(const char *opath, Rt_map * clmp, uint_t info, uint_t flags)
+is_path_secure(char *opath, Rt_map *clmp, uint_t info, uint_t flags)
{
Pnode *sdir = LM_SECURE_DIRS(LIST(clmp)->lm_head);
char buffer[PATH_MAX], *npath;
@@ -741,7 +742,7 @@ is_path_secure(const char *opath, Rt_map * clmp, uint_t info, uint_t flags)
* . any relative path
*/
if (((str == 0) || ((*opath == '/') && (str != opath) &&
- ((info & PN_SER_EXTLOAD) == 0))) &&
+ ((info & PN_FLG_EXTLOAD) == 0))) &&
((flags & PN_TKN_ORIGIN) == 0))
return (1);
@@ -786,7 +787,7 @@ is_path_secure(const char *opath, Rt_map * clmp, uint_t info, uint_t flags)
* diagnostic. Preloaded, or audit libraries generate a warning, as
* the process will run without them.
*/
- if (info & PN_SER_EXTLOAD) {
+ if (info & PN_FLG_EXTLOAD) {
if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
if ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)
(void) printf(MSG_INTL(MSG_LDD_FIL_ILLEGAL),
@@ -832,6 +833,19 @@ is_path_secure(const char *opath, Rt_map * clmp, uint_t info, uint_t flags)
}
/*
+ * Determine whether a path already exists within the callers Pnode list.
+ */
+inline static uint_t
+is_path_unique(Pnode *pnp, const char *path)
+{
+ for (; pnp; pnp = pnp->p_next) {
+ if (pnp->p_len && (strcmp(pnp->p_name, path) == 0))
+ return (PN_FLG_DUPLICAT);
+ }
+ return (0);
+}
+
+/*
* Expand one or more pathnames. This routine is called for all path strings,
* i.e., NEEDED, rpaths, default search paths, configuration file search paths,
* filtees, etc. The path may be a single pathname, or a colon separated list
@@ -851,6 +865,7 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit)
char *str, *olist = 0, *nlist = (char *)list;
Pnode *pnp, *npnp, *opnp;
int fnull = FALSE; /* TRUE if empty final path segment seen */
+ uint_t unique = 0;
for (pnp = opnp = 0, str = nlist; *nlist || fnull; str = nlist) {
char *ostr;
@@ -919,8 +934,36 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit)
* pathname may be necessary.
*/
if (rtld_flags & RT_FL_SECURE) {
- if (is_path_secure((const char *)str, clmp, orig,
- tkns) == 0) {
+ if (is_path_secure(str, clmp, orig, tkns) == 0) {
+ free(str);
+ continue;
+ }
+ }
+
+ /*
+ * If required, ensure that the string is unique. For search
+ * paths such as LD_LIBRARY_PATH, users often inherit multiple
+ * paths which result in unnecessary duplication. Note, if
+ * we're debugging, any duplicate entry is retained and flagged
+ * so that the entry can be diagnosed later as part of unused
+ * processing.
+ */
+ if (orig & PN_FLG_UNIQUE) {
+ Word tracing;
+
+ tracing = LIST(clmp)->lm_flags &
+ (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
+ unique = is_path_unique(pnp, str);
+
+ /*
+ * Note, use the debug strings rpl_debug and prm_debug
+ * as an indicator that debugging has been requested,
+ * rather than DBG_ENABLE(), as the initial use of
+ * LD_LIBRARY_PATH occurs in preparation for loading
+ * our debugging library.
+ */
+ if ((unique == PN_FLG_DUPLICAT) && (tracing == 0) &&
+ (rpl_debug == 0) && (prm_debug == 0)) {
free(str);
continue;
}
@@ -938,7 +981,7 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit)
else
opnp->p_next = npnp;
- if ((orig & PN_SER_MASK) && (tkns & PN_TKN_MASK)) {
+ if (tkns & PN_TKN_MASK) {
char *oname;
/*
@@ -956,7 +999,7 @@ expand_paths(Rt_map *clmp, const char *list, uint_t orig, uint_t omit)
}
npnp->p_name = str;
npnp->p_len = len;
- npnp->p_orig = (orig & (LA_SER_MASK | PN_SER_MASK)) |
+ npnp->p_orig = (orig & LA_SER_MASK) | unique |
(tkns & PN_TKN_MASK);
opnp = npnp;
diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg
index 1087a58647..60a1dd765e 100644
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg
@@ -243,6 +243,18 @@
@ MSG_STR_UNKNOWN "(unknown)"
@ MSG_STR_NULL "(null)"
+# Unused errors - used by ldd.
+
+@ MSG_USD_LDLIBPATH " unused search path=%s (LD_LIBRARY_PATH)\n"
+@ MSG_DUP_LDLIBPATH " unused (duplicate) search path=%s \
+ (LD_LIBRARY_PATH)\n"
+@ MSG_USD_LDLIBPATHC " unused search path=%s (configuration \
+ LD_LIBRARY_PATH - %s)\n"
+@ MSG_DUP_LDLIBPATHC " unused (duplicate) search path=%s (configuration \
+ LD_LIBRARY_PATH - %s)\n"
+@ MSG_USD_RUNPATH " unused search path=%s (RUNPATH/RPATH from \
+ file %s)\n"
+
@ _END_
@ MSG_LDD_FIL_PATH "\t%s%s%s\n"
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 43f5de56e8..e064a6925e 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -112,9 +112,9 @@ preload(const char *str, Rt_map *lmp)
*/
if (rtld_flags & RT_FL_SECURE)
rtld_flags2 |= RT_FL2_FTL2WARN;
- if ((pnp = expand_paths(clmp, ptr, PN_SER_EXTLOAD, 0)) != 0)
+ if ((pnp = expand_paths(clmp, ptr, PN_FLG_EXTLOAD, 0)) != 0)
nlmp = load_one(&lml_main, ALIST_OFF_DATA, pnp, clmp,
- MODE(lmp), flags, 0);
+ MODE(lmp), flags, 0, NULL);
if (pnp)
remove_pnode(pnp);
if (rtld_flags & RT_FL_SECURE)
@@ -355,7 +355,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
*/
if ((rlmp = elf_new_lm(&lml_rtld, _rtldname, rtldname, dyn_ptr, ld_base,
(ulong_t)&_etext, ALIST_OFF_DATA, (ulong_t)(eaddr - ld_base), 0,
- ld_base, (ulong_t)(eaddr - ld_base), mmaps, 2)) == 0) {
+ ld_base, (ulong_t)(eaddr - ld_base), mmaps, 2, NULL)) == 0) {
return (0);
}
@@ -426,7 +426,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
* Map in object.
*/
if ((mlmp = (ftp->fct_map_so)(&lml_main, ALIST_OFF_DATA,
- execname, argvname, fd)) == 0)
+ execname, argvname, fd, NULL)) == 0)
return (0);
/*
@@ -639,7 +639,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
if ((mlmp = elf_new_lm(&lml_main, execname, argvname,
dyn, (Addr)ehdr, etext, ALIST_OFF_DATA, memsize,
entry, (ulong_t)ehdr, memsize, mmaps,
- mmapcnt)) == 0) {
+ mmapcnt, NULL)) == 0) {
return (0);
}
if (tlsphdr &&
@@ -911,7 +911,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
return (0);
rtld_flags2 |= RT_FL2_FTL2WARN;
(void) audit_setup(mlmp, auditors,
- PN_SER_EXTLOAD);
+ PN_FLG_EXTLOAD, NULL);
rtld_flags2 &= ~RT_FL2_FTL2WARN;
}
}
@@ -934,7 +934,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
return (0);
auditors->ad_name = AUDITORS(mlmp)->ad_name;
- if (audit_setup(mlmp, auditors, 0) == 0)
+ if (audit_setup(mlmp, auditors, 0, NULL) == 0)
return (0);
lml_main.lm_tflags |= auditors->ad_flags;
@@ -948,7 +948,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
/*
* Establish any local auditing.
*/
- if (audit_setup(mlmp, AUDITORS(mlmp), 0) == 0)
+ if (audit_setup(mlmp, AUDITORS(mlmp), 0, NULL) == 0)
return (0);
FLAGS1(mlmp) |= AUDITORS(mlmp)->ad_flags;
@@ -982,7 +982,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
/*
* Load all dependent (needed) objects.
*/
- if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp) == 0)
+ if (analyze_lmc(&lml_main, ALIST_OFF_DATA, mlmp, NULL) == 0)
return (0);
/*
@@ -1003,7 +1003,8 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
DBG_CALL(Dbg_util_nl(&lml_main, DBG_NL_STD));
- if (relocate_lmc(&lml_main, ALIST_OFF_DATA, mlmp, mlmp) == 0)
+ if (relocate_lmc(&lml_main, ALIST_OFF_DATA, mlmp,
+ mlmp, NULL) == 0)
return (0);
/*
@@ -1149,6 +1150,7 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
DBG_CALL(Dbg_util_call_main(mlmp));
+ rtld_flags |= RT_FL_OPERATION;
leave(LIST(mlmp));
return (mlmp);
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 5c81ae6222..e67071632b 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -349,25 +349,25 @@ rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags,
}
/*
- * Compare function for FullpathNode AVL tree.
+ * Compare function for PathNode AVL tree.
*/
static int
-fpavl_compare(const void * n1, const void * n2)
+pnavl_compare(const void *n1, const void *n2)
{
uint_t hash1, hash2;
const char *st1, *st2;
int rc;
- hash1 = ((FullpathNode *)n1)->fpn_hash;
- hash2 = ((FullpathNode *)n2)->fpn_hash;
+ hash1 = ((PathNode *)n1)->pn_hash;
+ hash2 = ((PathNode *)n2)->pn_hash;
if (hash1 > hash2)
return (1);
if (hash1 < hash2)
return (-1);
- st1 = ((FullpathNode *)n1)->fpn_name;
- st2 = ((FullpathNode *)n2)->fpn_name;
+ st1 = ((PathNode *)n1)->pn_name;
+ st2 = ((PathNode *)n2)->pn_name;
rc = strcmp(st1, st2);
if (rc > 0)
@@ -377,17 +377,17 @@ fpavl_compare(const void * n1, const void * n2)
return (0);
}
-
/*
- * Determine if a given pathname has already been loaded in the AVL tree.
- * If the pathname does not exist in the AVL tree, the next insertion point
- * is deposited in "where". This value can be used by fpavl_insert() to
- * expedite the insertion.
+ * Determine if a pathname has already been recorded on the full path name
+ * AVL tree. This tree maintains a node for each path name that ld.so.1 has
+ * successfully loaded. If the path name does not exist in this AVL tree, then
+ * the next insertion point is deposited in "where". This value can be used by
+ * fpavl_insert() to expedite the insertion.
*/
Rt_map *
-fpavl_loaded(Lm_list *lml, const char *name, avl_index_t *where)
+fpavl_recorded(Lm_list *lml, const char *name, avl_index_t *where)
{
- FullpathNode fpn, *fpnp;
+ FullPathNode fpn, *fpnp;
avl_tree_t *avlt;
/*
@@ -396,13 +396,13 @@ fpavl_loaded(Lm_list *lml, const char *name, avl_index_t *where)
if ((avlt = lml->lm_fpavl) == NULL) {
if ((avlt = calloc(sizeof (avl_tree_t), 1)) == 0)
return (0);
- avl_create(avlt, fpavl_compare, sizeof (FullpathNode),
- SGSOFFSETOF(FullpathNode, fpn_avl));
+ avl_create(avlt, pnavl_compare, sizeof (FullPathNode),
+ SGSOFFSETOF(FullPathNode, fpn_node.pn_avl));
lml->lm_fpavl = avlt;
}
- fpn.fpn_name = name;
- fpn.fpn_hash = sgs_str_hash(name);
+ fpn.fpn_node.pn_name = name;
+ fpn.fpn_node.pn_hash = sgs_str_hash(name);
if ((fpnp = avl_find(lml->lm_fpavl, &fpn, where)) == NULL)
return (NULL);
@@ -410,22 +410,22 @@ fpavl_loaded(Lm_list *lml, const char *name, avl_index_t *where)
return (fpnp->fpn_lmp);
}
-
/*
- * Insert a name into the FullpathNode AVL tree for the link-map list. The
+ * Insert a name into the FullPathNode AVL tree for the link-map list. The
* objects NAME() is the path that would have originally been searched for, and
* is therefore the name to associate with any "where" value. If the object has
* a different PATHNAME(), perhaps because it has resolved to a different file
- * (see fullpath), then this name is recorded also. See load_file().
+ * (see fullpath()), then this name will be recorded as a separate FullPathNode
+ * (see load_file()).
*/
int
fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
{
- FullpathNode *fpnp;
+ FullPathNode *fpnp;
if (where == 0) {
/* LINTED */
- Rt_map *_lmp = fpavl_loaded(lml, name, &where);
+ Rt_map *_lmp = fpavl_recorded(lml, name, &where);
/*
* We better not get a hit now, we do not want duplicates in
@@ -435,13 +435,13 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
}
/*
- * Insert new node in tree
+ * Insert new node in tree.
*/
- if ((fpnp = calloc(sizeof (FullpathNode), 1)) == 0)
+ if ((fpnp = calloc(sizeof (FullPathNode), 1)) == 0)
return (0);
- fpnp->fpn_name = name;
- fpnp->fpn_hash = sgs_str_hash(name);
+ fpnp->fpn_node.pn_name = name;
+ fpnp->fpn_node.pn_hash = sgs_str_hash(name);
fpnp->fpn_lmp = lmp;
if (aplist_append(&FPNODE(lmp), fpnp, AL_CNT_FPNODE) == NULL) {
@@ -455,14 +455,14 @@ fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
}
/*
- * Remove an object from the Fullpath AVL tree. Note, this is called *before*
+ * Remove an object from the FullPath AVL tree. Note, this is called *before*
* the objects link-map is torn down (remove_so), which is where any NAME() and
* PATHNAME() strings will be deallocated.
*/
void
fpavl_remove(Rt_map *lmp)
{
- FullpathNode *fpnp;
+ FullPathNode *fpnp;
Aliste idx;
for (APLIST_TRAVERSE(FPNODE(lmp), idx, fpnp)) {
@@ -473,6 +473,68 @@ fpavl_remove(Rt_map *lmp)
FPNODE(lmp) = NULL;
}
+/*
+ * Determine if a pathname has already been recorded on the not-found AVL tree.
+ * This tree maintains a node for each path name that ld.so.1 has explicitly
+ * inspected, but has failed to load during a single ld.so.1 operation. If the
+ * path name does not exist in this AVL tree, then the next insertion point is
+ * deposited in "where". This value can be used by nfavl_insert() to expedite
+ * the insertion.
+ */
+int
+nfavl_recorded(const char *name, avl_index_t *where)
+{
+ PathNode pn;
+ avl_tree_t *avlt;
+
+ /*
+ * Create the avl tree if required.
+ */
+ if ((avlt = nfavl) == NULL) {
+ if ((avlt = calloc(sizeof (avl_tree_t), 1)) == 0)
+ return (0);
+ avl_create(avlt, pnavl_compare, sizeof (PathNode),
+ SGSOFFSETOF(PathNode, pn_avl));
+ nfavl = avlt;
+ }
+
+ pn.pn_name = name;
+ pn.pn_hash = sgs_str_hash(name);
+
+ if (avl_find(avlt, &pn, where) == NULL)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Insert a name into the not-found AVL tree.
+ */
+void
+nfavl_insert(const char *name, avl_index_t where)
+{
+ PathNode *pnp;
+
+ if (where == 0) {
+ /* LINTED */
+ int in_nfavl = nfavl_recorded(name, &where);
+
+ /*
+ * We better not get a hit now, we do not want duplicates in
+ * the tree.
+ */
+ ASSERT(in_nfavl == 0);
+ }
+
+ /*
+ * Insert new node in tree.
+ */
+ if ((pnp = calloc(sizeof (PathNode), 1)) != 0) {
+ pnp->pn_name = name;
+ pnp->pn_hash = sgs_str_hash(name);
+ avl_insert(nfavl, pnp, where);
+ }
+}
/*
* Prior to calling an object, either via a .plt or through dlsym(), make sure
@@ -484,9 +546,9 @@ fpavl_remove(Rt_map *lmp)
* provides for dynamic .init firing.
*/
void
-is_dep_init(Rt_map * dlmp, Rt_map * clmp)
+is_dep_init(Rt_map *dlmp, Rt_map *clmp)
{
- Rt_map ** tobj;
+ Rt_map **tobj;
/*
* If the caller is an auditor, and the destination isn't, then don't
@@ -541,7 +603,7 @@ is_dep_init(Rt_map * dlmp, Rt_map * clmp)
* block (see comments in load_completion()).
*/
void
-is_dep_ready(Rt_map * dlmp, Rt_map * clmp, int what)
+is_dep_ready(Rt_map *dlmp, Rt_map *clmp, int what)
{
thread_t tid;
@@ -606,9 +668,9 @@ call_array(Addr *array, uint_t arraysz, Rt_map *lmp, Word shtype)
* (by default) will have been sorted.
*/
void
-call_init(Rt_map ** tobj, int flag)
+call_init(Rt_map **tobj, int flag)
{
- Rt_map ** _tobj, ** _nobj;
+ Rt_map **_tobj, **_nobj;
static List pending = { NULL, NULL };
/*
@@ -626,8 +688,8 @@ call_init(Rt_map ** tobj, int flag)
* Traverse the tobj array firing each objects init.
*/
for (_tobj = _nobj = tobj, _nobj++; *_tobj != NULL; _tobj++, _nobj++) {
- Rt_map * lmp = *_tobj;
- void (* iptr)() = INIT(lmp);
+ Rt_map *lmp = *_tobj;
+ void (*iptr)() = INIT(lmp);
if (FLAGS(lmp) & FLG_RT_INITCALL)
continue;
@@ -700,8 +762,8 @@ call_init(Rt_map ** tobj, int flag)
*/
if ((rtld_flags & RT_FL_INITFIRST) &&
((*_nobj == NULL) || !(FLAGS(*_nobj) & FLG_RT_INITFRST))) {
- Listnode * lnp;
- Rt_map ** pobj;
+ Listnode *lnp;
+ Rt_map **pobj;
rtld_flags &= ~RT_FL_INITFIRST;
@@ -809,9 +871,9 @@ call_fini(Lm_list * lml, Rt_map ** tobj)
void
atexit_fini()
{
- Rt_map ** tobj, * lmp;
- Lm_list * lml;
- Listnode * lnp;
+ Rt_map **tobj, *lmp;
+ Lm_list *lml;
+ Listnode *lnp;
(void) enter();
@@ -823,11 +885,6 @@ atexit_fini()
lmp = (Rt_map *)lml->lm_head;
/*
- * Display any objects that haven't been referenced so far.
- */
- unused(lml);
-
- /*
* Reverse topologically sort the main link-map for .fini execution.
*/
if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) &&
@@ -848,10 +905,7 @@ atexit_fini()
/*
* Now that all .fini code has been run, see what unreferenced objects
- * remain. Any difference between this and the above unused() would
- * indicate an object is only being used for .fini processing, which
- * might be fine, but might also indicate an overhead whose removal
- * would be worth considering.
+ * remain.
*/
unused(lml);
@@ -979,7 +1033,7 @@ load_completion(Rt_map *nlmp)
Listnode *
list_append(List *lst, const void *item)
{
- Listnode * _lnp;
+ Listnode *_lnp;
if ((_lnp = malloc(sizeof (Listnode))) == 0)
return (0);
@@ -1004,7 +1058,7 @@ list_append(List *lst, const void *item)
Listnode *
list_insert(List *lst, const void *item, Listnode *lnp)
{
- Listnode * _lnp;
+ Listnode *_lnp;
if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0)
return (0);
@@ -1024,7 +1078,7 @@ list_insert(List *lst, const void *item, Listnode *lnp)
Listnode *
list_prepend(List * lst, const void * item)
{
- Listnode * _lnp;
+ Listnode *_lnp;
if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0)
return (0);
@@ -2329,8 +2383,8 @@ readenv_user(const char ** envp, Word *lmflags, Word *lmtflags, int aout)
int
readenv_config(Rtc_env * envtbl, Addr addr, int aout)
{
- Word * lmflags = &(lml_main.lm_flags);
- Word * lmtflags = &(lml_main.lm_tflags);
+ Word *lmflags = &(lml_main.lm_flags);
+ Word *lmtflags = &(lml_main.lm_tflags);
if (envtbl == (Rtc_env *)0)
return (0);
@@ -3102,56 +3156,140 @@ enter(void)
{
if (rt_bind_guard(THR_FLG_RTLD)) {
(void) rt_mutex_lock(&rtldlock);
- ld_entry_cnt++;
+ if (rtld_flags & RT_FL_OPERATION)
+ ld_entry_cnt++;
return (1);
}
return (0);
}
/*
+ * Determine whether a search path has been used.
+ */
+static void
+is_path_used(Lm_list *lml, Word unref, int *nl, Pnode *pnp, const char *obj)
+{
+ for (; pnp; pnp = pnp->p_next) {
+ const char *fmt, *name;
+
+ if ((pnp->p_len == 0) || (pnp->p_orig & PN_FLG_USED))
+ continue;
+
+ /*
+ * If this pathname originated from an expanded token, use the
+ * original for any diagnostic output.
+ */
+ if ((name = pnp->p_oname) == 0)
+ name = pnp->p_name;
+
+ if (unref == 0) {
+ if ((*nl)++ == 0)
+ DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
+ DBG_CALL(Dbg_unused_path(lml, name, pnp->p_orig,
+ (pnp->p_orig & PN_FLG_DUPLICAT), obj));
+ continue;
+ }
+
+ /*
+ * For now, disable any unused search path processing that has
+ * been triggered for ldd(1).
+ */
+ if (unref)
+ continue;
+
+ if (pnp->p_orig & LA_SER_LIBPATH) {
+ if (pnp->p_orig & LA_SER_CONFIG) {
+ if (pnp->p_orig & PN_FLG_DUPLICAT)
+ fmt = MSG_INTL(MSG_DUP_LDLIBPATHC);
+ else
+ fmt = MSG_INTL(MSG_USD_LDLIBPATHC);
+ } else {
+ if (pnp->p_orig & PN_FLG_DUPLICAT)
+ fmt = MSG_INTL(MSG_DUP_LDLIBPATH);
+ else
+ fmt = MSG_INTL(MSG_USD_LDLIBPATH);
+ }
+ } else if (pnp->p_orig & LA_SER_RUNPATH) {
+ fmt = MSG_INTL(MSG_USD_RUNPATH);
+ } else
+ continue;
+
+ if ((*nl)++ == 0)
+ (void) printf(MSG_ORIG(MSG_STR_NL));
+ (void) printf(fmt, name, obj);
+ }
+}
+
+/*
* Generate diagnostics as to whether an object has been used. A symbolic
* reference that gets bound to an object marks it as used. Dependencies that
* are unused when RTLD_NOW is in effect should be removed from future builds
* of an object. Dependencies that are unused without RTLD_NOW in effect are
* candidates for lazy-loading.
+ *
* Unreferenced objects identify objects that are defined as dependencies but
- * are unreferenced by the caller (they may however be referenced by other
- * objects within the process, and therefore don't qualify as completely unused.
+ * are unreferenced by the caller. These unreferenced objects may however be
+ * referenced by other objects within the process, and therefore don't qualify
+ * as completely unused. They are still an unnecessary overhead.
+ *
+ * Unreferenced runpaths are also captured under ldd -U, or "unused,detail"
+ * debugging.
*/
void
unused(Lm_list *lml)
{
Rt_map *lmp;
int nl = 0;
- Word tracing;
+ Word unref, unuse;
/*
* If we're not tracing unused references or dependencies, or debugging
* there's nothing to do.
*/
- tracing = lml->lm_flags & (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
+ unref = lml->lm_flags & LML_FLG_TRC_UNREF;
+ unuse = lml->lm_flags & LML_FLG_TRC_UNUSED;
- if ((tracing == 0) && (DBG_ENABLED == 0))
+ if ((unref == 0) && (unuse == 0) && (DBG_ENABLED == 0))
return;
/*
+ * Detect unused global search paths.
+ */
+ if (rpl_libdirs)
+ is_path_used(lml, unref, &nl, rpl_libdirs, config->c_name);
+ if (prm_libdirs)
+ is_path_used(lml, unref, &nl, prm_libdirs, config->c_name);
+
+ nl = 0;
+ lmp = lml->lm_head;
+ if (RLIST(lmp))
+ is_path_used(lml, unref, &nl, RLIST(lmp), NAME(lmp));
+
+ /*
* Traverse the link-maps looking for unreferenced or unused
* dependencies. Ignore the first object on a link-map list, as this
- * is effectively always used.
+ * is always used.
*/
- for (lmp = (Rt_map *)NEXT(lml->lm_head); lmp;
- lmp = (Rt_map *)NEXT(lmp)) {
+ nl = 0;
+ for (lmp = (Rt_map *)NEXT(lmp); lmp; lmp = (Rt_map *)NEXT(lmp)) {
+ /*
+ * Determine if this object contains any runpaths that have
+ * not been used.
+ */
+ if (RLIST(lmp))
+ is_path_used(lml, unref, &nl, RLIST(lmp), NAME(lmp));
+
/*
* If tracing unreferenced objects, or under debugging,
* determine whether any of this objects callers haven't
* referenced it.
*/
- if ((tracing & LML_FLG_TRC_UNREF) || DBG_ENABLED) {
+ if (unref || DBG_ENABLED) {
Bnd_desc *bdp;
Aliste idx;
for (APLIST_TRAVERSE(CALLERS(lmp), idx, bdp)) {
- Rt_map * clmp;
+ Rt_map *clmp;
if (bdp->b_flags & BND_REFER)
continue;
@@ -3162,14 +3300,14 @@ unused(Lm_list *lml)
/* BEGIN CSTYLED */
if (nl++ == 0) {
- if (tracing & LML_FLG_TRC_UNREF)
+ if (unref)
(void) printf(MSG_ORIG(MSG_STR_NL));
else
DBG_CALL(Dbg_util_nl(lml,
DBG_NL_STD));
}
- if (tracing & LML_FLG_TRC_UNREF)
+ if (unref)
(void) printf(MSG_INTL(MSG_LDD_UNREF_FMT),
NAME(lmp), NAME(clmp));
else
@@ -3186,20 +3324,20 @@ unused(Lm_list *lml)
continue;
if (nl++ == 0) {
- if (tracing)
+ if (unref || unuse)
(void) printf(MSG_ORIG(MSG_STR_NL));
else
DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
}
if (CYCGROUP(lmp)) {
- if (tracing)
+ if (unref || unuse)
(void) printf(MSG_INTL(MSG_LDD_UNCYC_FMT),
NAME(lmp), CYCGROUP(lmp));
else
DBG_CALL(Dbg_unused_file(lml, NAME(lmp), 0,
CYCGROUP(lmp)));
} else {
- if (tracing)
+ if (unref || unuse)
(void) printf(MSG_INTL(MSG_LDD_UNUSED_FMT),
NAME(lmp));
else
@@ -3445,7 +3583,7 @@ set_environ(Lm_list *lml)
SLOOKUP_INIT(sl, MSG_ORIG(MSG_SYM_ENVIRON), lml->lm_head, lml->lm_head,
ld_entry_cnt, 0, 0, 0, 0, LKUP_WEAK);
- if (sym = LM_LOOKUP_SYM(lml->lm_head)(&sl, &dlmp, &binfo)) {
+ if (sym = LM_LOOKUP_SYM(lml->lm_head)(&sl, &dlmp, &binfo, 0)) {
lml->lm_environ = (char ***)sym->st_value;
if (!(FLAGS(dlmp) & FLG_RT_FIXED))
diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
index 7335714a6a..7c9da3f9ae 100644
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
@@ -254,7 +254,7 @@ elf_bndr(Rt_map *lmp, ulong_t reloff, caddr_t from)
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0,
rsymndx, rsym, 0, LKUP_DEFT);
- if ((nsym = lookup_sym(&sl, &nlmp, &binfo)) == 0) {
+ if ((nsym = lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
rtldexit(lml, 1);
@@ -426,7 +426,7 @@ elf_reloc_relacount(ulong_t relbgn, ulong_t relacount, ulong_t relsiz,
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
{
ulong_t relbgn, relend, relsiz, basebgn;
ulong_t pltbgn, pltend, _pltbgn, _pltend;
@@ -492,7 +492,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)
SLOOKUP_INIT(sl, MSG_ORIG(MSG_SYM_PLT), lmp, lmp, ld_entry_cnt,
elf_hash(MSG_ORIG(MSG_SYM_PLT)), 0, 0, 0, LKUP_DEFT);
- if ((symdef = elf_find_sym(&sl, &_lmp, &binfo)) == 0)
+ if ((symdef = elf_find_sym(&sl, &_lmp, &binfo, NULL)) == 0)
return (1);
_pltbgn = symdef->st_value;
@@ -747,7 +747,8 @@ elf_reloc(Rt_map *lmp, uint_t plt)
ld_entry_cnt, 0, rsymndx, symref,
rtype, LKUP_STDRELOC);
- symdef = lookup_sym(&sl, &_lmp, &binfo);
+ symdef = lookup_sym(&sl, &_lmp,
+ &binfo, in_nfavl);
/*
* If the symbol is not found and the
@@ -996,13 +997,13 @@ _elf_copy_reloc(const char *name, Rt_map *rlmp, Rt_map *dlmp)
SLOOKUP_INIT(sl, name, rlmp, rlmp, ld_entry_cnt, 0, 0, 0, 0,
LKUP_FIRST);
- if ((symref = lookup_sym(&sl, &_lmp, &binfo)) == 0)
+ if ((symref = lookup_sym(&sl, &_lmp, &binfo, NULL)) == 0)
return (1);
sl.sl_imap = dlmp;
sl.sl_flags = LKUP_DEFT;
- if ((symdef = lookup_sym(&sl, &_lmp, &binfo)) == 0)
+ if ((symdef = lookup_sym(&sl, &_lmp, &binfo, NULL)) == 0)
return (1);
if (strcmp(NAME(_lmp), MSG_ORIG(MSG_PTH_LIBC)))
return (1);
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
index 5163fc324d..a1d6e811bd 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
@@ -117,7 +117,7 @@ aout_bndr(caddr_t pc)
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0, 0, 0, 0,
LKUP_DEFT);
- if ((sym = aout_lookup_sym(&sl, &nlmp, &binfo)) == 0) {
+ if ((sym = aout_lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
rtldexit(lml, 1);
@@ -204,7 +204,7 @@ static const uchar_t pc_rel_type[] = {
};
int
-aout_reloc(Rt_map * lmp, uint_t plt)
+aout_reloc(Rt_map * lmp, uint_t plt, int *in_nfavl)
{
int k; /* loop temporary */
int nr; /* number of relocations */
@@ -282,7 +282,8 @@ aout_reloc(Rt_map * lmp, uint_t plt)
SLOOKUP_INIT(sl, name, lmp, 0, ld_entry_cnt, 0, 0, 0, 0,
LKUP_STDRELOC);
- if ((sym = aout_lookup_sym(&sl, &_lmp, &binfo)) == 0) {
+ if ((sym = aout_lookup_sym(&sl, &_lmp,
+ &binfo, in_nfavl)) == 0) {
if (lml->lm_flags & LML_FLG_TRC_WARN) {
(void)
printf(MSG_INTL(MSG_LDD_SYM_NFOUND),
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
index 635e508fdd..e2fde63c4e 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
@@ -426,7 +426,7 @@ elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0,
rsymndx, rsym, 0, LKUP_DEFT);
- if ((nsym = lookup_sym(&sl, &nlmp, &binfo)) == 0) {
+ if ((nsym = lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
rtldexit(lml, 1);
@@ -533,7 +533,7 @@ elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
{
ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
@@ -832,7 +832,8 @@ elf_reloc(Rt_map *lmp, uint_t plt)
ld_entry_cnt, 0, rsymndx, symref,
rtype, LKUP_STDRELOC);
- symdef = lookup_sym(&sl, &_lmp, &binfo);
+ symdef = lookup_sym(&sl, &_lmp,
+ &binfo, in_nfavl);
/*
* If the symbol is not found and the
diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
index 0f56741c08..c64c42eb00 100644
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
@@ -570,7 +570,7 @@ elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0,
rsymndx, rsym, 0, LKUP_DEFT);
- if ((nsym = lookup_sym(&sl, &nlmp, &binfo)) == 0) {
+ if ((nsym = lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
rtldexit(lml, 1);
@@ -752,7 +752,7 @@ bindpltpad(Rt_map *lmp, List *padlist, Addr value, void **pltaddr,
* the file.
*/
int
-elf_reloc(Rt_map *lmp, uint_t plt)
+elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl)
{
ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp);
@@ -1076,7 +1076,8 @@ elf_reloc(Rt_map *lmp, uint_t plt)
ld_entry_cnt, 0, rsymndx, symref,
rtype, LKUP_STDRELOC);
- symdef = lookup_sym(&sl, &_lmp, &binfo);
+ symdef = lookup_sym(&sl, &_lmp,
+ &binfo, in_nfavl);
/*
* If the symbol is not found and the