summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorrie <none@none>2008-01-31 11:47:19 -0800
committerrie <none@none>2008-01-31 11:47:19 -0800
commit75e7992ad4e186443b61dab39f79c9d79802f295 (patch)
treeb8e23bffeafeebc91348e1cc14b33f4126fba752 /usr/src
parent9d82f4f62620e94b1b60f7096f2ce08a64013489 (diff)
downloadillumos-joyent-75e7992ad4e186443b61dab39f79c9d79802f295.tar.gz
6654381 lazy loading fall-back needs optimizing
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/include/rtld.h64
-rw-r--r--usr/src/cmd/sgs/librtld/common/mapfile-vers3
-rw-r--r--usr/src/cmd/sgs/librtld/common/relocate.c15
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/rtld/amd64/amd64_elf.c36
-rw-r--r--usr/src/cmd/sgs/rtld/common/_elf.h6
-rw-r--r--usr/src/cmd/sgs/rtld/common/analyze.c21
-rw-r--r--usr/src/cmd/sgs/rtld/common/audit.c28
-rw-r--r--usr/src/cmd/sgs/rtld/common/dlfcns.c27
-rw-r--r--usr/src/cmd/sgs/rtld/common/elf.c192
-rw-r--r--usr/src/cmd/sgs/rtld/common/globals.c23
-rw-r--r--usr/src/cmd/sgs/rtld/common/mapfile-vers1
-rw-r--r--usr/src/cmd/sgs/rtld/common/remove.c34
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c19
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c20
-rw-r--r--usr/src/cmd/sgs/rtld/i386/i386_elf.c48
-rw-r--r--usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c2
-rw-r--r--usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg2
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c25
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_elf.c25
-rw-r--r--usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c26
21 files changed, 365 insertions, 253 deletions
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index e50c3d882b..0dd2001156 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -500,10 +500,16 @@ typedef struct {
/* and DT_SYMAUXILIARY */
#define MSK_DI_FILTER 0x0000f /* mask for all filter possibilities */
-#define FLG_DI_NEEDED 0x00010 /* entry represents a dependency */
-#define FLG_DI_GROUP 0x00020 /* open dependency as a group */
-#define FLG_DI_PROCESSD 0x00040 /* entry has been processed */
+#define FLG_DI_POSFLAG1 0x00010 /* .dynamic entry for DT_POSFLAG_1 */
+#define FLG_DI_NEEDED 0x00020 /* .dynamic entry for DT_NEEDED */
+#define FLG_DI_LAZY 0x00100 /* lazy needed entry - preceded by */
+ /* DF_P1_LAZYLOAD (DT_POSFLAG_1) */
+#define FLG_DI_GROUP 0x00200 /* group needed entry - preceded by */
+ /* DF_P1_GROUPPERM (DT_POSFLAG_1) */
+#define FLG_DI_LDD_DONE 0x01000 /* entry has been processed (ldd) */
+#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
@@ -723,7 +729,7 @@ typedef struct rt_map32 {
#define MSK_RT_INTPOSE 0x03000000 /* mask for all interposer */
/* possibilities */
#define FLG_RT_MOVE 0x04000000 /* object needs move operation */
-#define FLG_RT_DLSYM 0x08000000 /* dlsym in progress on object */
+#define FLG_RT_TMPLIST 0x08000000 /* object is part of a temporary list */
#define FLG_RT_REGSYMS 0x10000000 /* object has DT_REGISTER entries */
#define FLG_RT_INITCLCT 0x20000000 /* init has been collected (tsort) */
#define FLG_RT_HANDLE 0x40000000 /* generate a handle for this object */
@@ -864,7 +870,7 @@ typedef struct rt_map32 {
#define LKUP_WEAK 0x0040 /* relocation reference is weak */
#define LKUP_NEXT 0x0080 /* request originates from RTLD_NEXT */
#define LKUP_NODESCENT 0x0100 /* don't descend through dependencies */
-#define LKUP_NOFALBACK 0x0200 /* don't fall back to loading */
+#define LKUP_NOFALLBACK 0x0200 /* don't fall back to loading */
/* pending lazy dependencies */
#define LKUP_DIRECT 0x0400 /* direct binding request */
#define LKUP_SYMNDX 0x0800 /* establish symbol index */
@@ -873,12 +879,47 @@ typedef struct rt_map32 {
/* head link-map element */
/*
- * Data structure for calling lookup_sym()
+ * For the runtime linker to perform a symbol search, a number of data items
+ * related to the search are required. An Slookup data structure is used to
+ * convey this data to lookup_sym(), and in special cases, to other core
+ * routines that provide the implementation details for lookup_sym()
+ *
+ * The symbol name (sl_name), the caller (sl_cmap), and the link-map from which
+ * to start the search (sl_imap) are fundamental to the symbol search. The
+ * initial search link-map might get modified by the core routines that provide
+ * the implementation details for lookup_sym(). This modification accommodates
+ * requirements such as processing a handle, direct binding and interposition.
+ * The association between the caller and the potential destination also
+ * determines whether the destination is a candidate to search.
+ *
+ * The lookup identifier (sl_id) is used to identify a runtime linker operation.
+ * Within this operation, any lazy loads that fail are not re-examined. This
+ * technique keeps the overhead of processing a failed lazy load to a minimum.
+ *
+ * Symbol searches that originate from a relocation record are accompanied by
+ * the relocation index (sl_rsymndx), the symbol reference (sl_rsym) and
+ * possibly the relocation type (sl_rtype). This data provides for determining
+ * lazy loading, direct binding, and special symbol processing requirements
+ * such as copy relocations and singleton lookup.
+ *
+ * The symbols hash value is computed by lookup_sym, and propagated throughout
+ * the search engine. Note, occasionally the Slookup data is passed to a core
+ * routine that provides the implementation details for lookup_sym(), ie.
+ * elf_find_sym(), in which case the caller must initialize the hash value.
+ *
+ * The symbols binding information is established by lookup_sym() when the
+ * symbols relocation type is supplied. Weak bindings allow relocations to
+ * be set to zero should a symbol lookup fail.
+ *
+ * The flags allow the caller to control aspects of the search, including the
+ * interpretation of copy relocations, etc. Note, a number of flag settings
+ * are established in lookup_sym() from attributes of the symbol reference.
*/
typedef struct {
const char *sl_name; /* symbol name */
Rt_map *sl_cmap; /* callers link-map */
Rt_map *sl_imap; /* initial link-map to search */
+ ulong_t sl_id; /* identifier for this lookup */
ulong_t sl_hash; /* symbol hash value */
ulong_t sl_rsymndx; /* referencing reloc symndx */
Sym *sl_rsym; /* referencing symbol */
@@ -888,7 +929,16 @@ typedef struct {
uint_t sl_flags; /* lookup flags */
} Slookup;
+#define SLOOKUP_INIT(sl, name, cmap, imap, id, hash, rsymndx, rsym, rtype, \
+ flags) \
+ (void) (sl.sl_name = (name), sl.sl_cmap = (cmap), sl.sl_imap = (imap), \
+ sl.sl_id = (id), sl.sl_hash = (hash), sl.sl_rsymndx = (rsymndx), \
+ sl.sl_rsym = (rsym), sl.sl_rtype = (rtype), sl.sl_bind = 0, \
+ sl.sl_flags = (flags))
+/*
+ * Define a number of .plt lookup outcomes, for use in binding diagnostics.
+ */
typedef enum {
PLT_T_NONE = 0,
PLT_T_21D,
@@ -903,6 +953,8 @@ typedef enum {
/*
* Prototypes.
*/
+extern ulong_t ld_entry_cnt; /* counter bumped on each entry to */
+ /* ld.so.1. */
extern Lm_list lml_main; /* main's link map list */
extern Lm_list lml_rtld; /* rtld's link map list */
extern Lm_list *lml_list[];
diff --git a/usr/src/cmd/sgs/librtld/common/mapfile-vers b/usr/src/cmd/sgs/librtld/common/mapfile-vers
index 60f2607a2c..7294d7fc31 100644
--- a/usr/src/cmd/sgs/librtld/common/mapfile-vers
+++ b/usr/src/cmd/sgs/librtld/common/mapfile-vers
@@ -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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -39,6 +39,7 @@ SUNWprivate_1.3 {
is_so_loaded = FUNCTION parent;
lookup_sym = FUNCTION parent;
+ ld_entry_cnt = DATA parent;
lml_main = DATA parent;
local:
*;
diff --git a/usr/src/cmd/sgs/librtld/common/relocate.c b/usr/src/cmd/sgs/librtld/common/relocate.c
index 76eaeabf6b..455f85ee88 100644
--- a/usr/src/cmd/sgs/librtld/common/relocate.c
+++ b/usr/src/cmd/sgs/librtld/common/relocate.c
@@ -274,18 +274,11 @@ count_reloc(Cache *cache, Cache *_cache, Rt_map *lmp, int flags, Addr addr,
* the possibility of a dangling .plt relocation. dldump()
* users might be encouraged to set LD_FLAGS=loadavail (crle(1)
* does this for them).
+ *
+ * Initialize the symbol lookup data structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = LIST(lmp)->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = sym;
-
- if (type == M_R_COPY)
- sl.sl_flags = LKUP_COPY;
- else
- sl.sl_flags = LKUP_DEFT;
+ SLOOKUP_INIT(sl, name, lmp, LIST(lmp)->lm_head, ld_entry_cnt,
+ 0, rsymndx, sym, type, LKUP_STDRELOC);
_bound = _weak = 0;
_sym = sym;
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 373fc7be98..8d4a07bce9 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1308,3 +1308,4 @@ Bugid Risk Synopsis
6634436 XFFLAG should be updated. (link-editor components only)
6492726 Merge SHF_MERGE|SHF_STRINGS input sections
4947191 OSNet should use direct bindings (link-editor components only)
+6654381 lazy loading fall-back needs optimizing
diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
index 74568869ab..f7152fe1c8 100644
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
@@ -270,15 +270,11 @@ elf_bndr(Rt_map *lmp, ulong_t pltndx, caddr_t from)
llmp = lml->lm_tail;
/*
- * Find definition for symbol.
+ * Find definition for symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = rsym;
- sl.sl_flags = LKUP_DEFT;
+ 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) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
@@ -514,12 +510,11 @@ elf_reloc(Rt_map *lmp, uint_t plt)
if (!relbgn || (relbgn == relend))
return (1);
- sl.sl_name = MSG_ORIG(MSG_SYM_PLT);
- sl.sl_cmap = lmp;
- sl.sl_imap = lmp;
- sl.sl_hash = elf_hash(MSG_ORIG(MSG_SYM_PLT));
- sl.sl_rsymndx = 0;
- sl.sl_flags = LKUP_DEFT;
+ /*
+ * Initialize the symbol lookup data structure.
+ */
+ 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)
return (1);
@@ -786,18 +781,15 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Lookup the symbol definition.
+ * Initialize the symbol lookup data
+ * structure.
*/
name = (char *)(STRTAB(lmp) +
symref->st_name);
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = 0;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = symref;
- sl.sl_rtype = rtype;
- sl.sl_flags = LKUP_STDRELOC;
+ SLOOKUP_INIT(sl, name, lmp, 0,
+ ld_entry_cnt, 0, rsymndx, symref,
+ rtype, LKUP_STDRELOC);
symdef = lookup_sym(&sl, &_lmp, &binfo);
diff --git a/usr/src/cmd/sgs/rtld/common/_elf.h b/usr/src/cmd/sgs/rtld/common/_elf.h
index ec4da445dd..08e5dd5b15 100644
--- a/usr/src/cmd/sgs/rtld/common/_elf.h
+++ b/usr/src/cmd/sgs/rtld/common/_elf.h
@@ -23,8 +23,8 @@
* All Rights Reserved
*
*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef __ELF_DOT_H
@@ -52,7 +52,7 @@ 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 *, uint_t, const char *);
+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 Rt_map *elf_new_lm(Lm_list *, const char *, const char *, Dyn *,
ulong_t, ulong_t, Aliste, ulong_t, ulong_t, ulong_t,
diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c
index 2e3236f3cd..0d4f91dd71 100644
--- a/usr/src/cmd/sgs/rtld/common/analyze.c
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c
@@ -68,13 +68,14 @@ load_filtees(Rt_map *lmp)
if ((FLAGS1(lmp) & MSK_RT_FILTER) &&
((FLAGS(lmp) & FLG_RT_LOADFLTR) ||
(LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) {
- Dyninfo * dip = DYNINFO(lmp);
+ Dyninfo *dip = DYNINFO(lmp);
uint_t cnt, max = DYNINFOCNT(lmp);
Slookup sl;
- sl.sl_name = 0;
- sl.sl_hash = 0;
- sl.sl_imap = sl.sl_cmap = lmp;
+ /*
+ * Initialize the symbol lookup data structure.
+ */
+ SLOOKUP_INIT(sl, 0, lmp, lmp, ld_entry_cnt, 0, 0, 0, 0, 0);
for (cnt = 0; cnt < max; cnt++, dip++) {
if (((dip->di_flags & MSK_DI_FILTER) == 0) ||
@@ -2716,7 +2717,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
lmp = 0;
if (bound < SYMINFO_BT_LOWRESERVE)
- lmp = elf_lazy_load(clmp, bound, name);
+ lmp = elf_lazy_load(clmp, slp, bound, name);
/*
* If direct bindings have been disabled, and this isn't
@@ -2828,11 +2829,12 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* outstanding. If so, and we haven't been able to locate a non-weak
* symbol reference, start bringing in any lazy dependencies to see if
* the reference can be satisfied. Use of dlsym(RTLD_PROBE) sets the
- * LKUP_NOFALBACK flag, and this flag disables this fall back.
+ * LKUP_NOFALLBACK flag, and this flag disables this fall back.
*/
- if ((sym == NULL) && ((sl.sl_flags & LKUP_NOFALBACK) == 0)) {
+ if ((sym == NULL) && ((sl.sl_flags & LKUP_NOFALLBACK) == 0)) {
if ((lmp = ilmp) == 0)
lmp = LIST(clmp)->lm_head;
+
if ((sl.sl_flags & LKUP_WEAK) || (LIST(lmp)->lm_lazy == 0))
return ((Sym *)0);
@@ -2850,7 +2852,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
Lm_cntl *lmc;
for (ALIST_TRAVERSE(LIST(clmp)->lm_lists, idx, lmc)) {
- sl.sl_flags |= LKUP_NOFALBACK;
+ sl.sl_flags |= LKUP_NOFALLBACK;
if ((sym = _lazy_find_sym(lmc->lc_head, &sl,
dlmp, binfo)) != 0)
break;
@@ -2873,13 +2875,12 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
Sym *
lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
{
- const char *name = slp->sl_name;
Rt_map *clmp = slp->sl_cmap;
Sym *rsym = slp->sl_rsym, *sym = 0;
uchar_t rtype = slp->sl_rtype;
if (slp->sl_hash == 0)
- slp->sl_hash = elf_hash(name);
+ slp->sl_hash = elf_hash(slp->sl_name);
*binfo = 0;
/*
diff --git a/usr/src/cmd/sgs/rtld/common/audit.c b/usr/src/cmd/sgs/rtld/common/audit.c
index 133ad2e0ae..11c0f93e7c 100644
--- a/usr/src/cmd/sgs/rtld/common/audit.c
+++ b/usr/src/cmd/sgs/rtld/common/audit.c
@@ -65,7 +65,7 @@ uint_t audit_flags = 0; /* Copy of specific audit flags to */
/* simplify boot_elf.s access. */
static Audit_client *
-_audit_client(Audit_info * aip, Rt_map * almp)
+_audit_client(Audit_info *aip, Rt_map *almp)
{
int ndx;
@@ -331,7 +331,7 @@ audit_objopen(Rt_map *clmp, Rt_map *nlmp)
Lmid_t lmid = get_linkmap_id(LIST(nlmp));
int appl = 0, respond = 1, ndx = 0;
uint_t clients = 0;
- Audit_info * aip;
+ Audit_info *aip;
/*
* Determine the total number of audit libraries in use. This provides
@@ -390,13 +390,13 @@ audit_objopen(Rt_map *clmp, Rt_map *nlmp)
* la_objclose() entry points found.
*/
void
-_audit_objclose(List * list, Rt_map * lmp)
+_audit_objclose(List *list, Rt_map *lmp)
{
- Audit_list * alp;
- Listnode * lnp;
+ Audit_list *alp;
+ Listnode *lnp;
for (LIST_TRAVERSE(list, lnp, alp)) {
- Audit_client * acp;
+ Audit_client *acp;
if (alp->al_objclose == 0)
continue;
@@ -410,7 +410,7 @@ _audit_objclose(List * list, Rt_map * lmp)
}
void
-audit_objclose(Rt_map * clmp, Rt_map * lmp)
+audit_objclose(Rt_map *clmp, Rt_map *lmp)
{
int appl = 0;
@@ -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)
{
Rt_map *_lmp, *lmp = alp->al_lmp;
const char *sname = MSG_ORIG(aud_info[info].sname);
@@ -872,13 +872,11 @@ audit_symget(Audit_list * alp, int info)
Sym *sym;
Slookup sl;
- sl.sl_name = sname;
- sl.sl_cmap = lml_rtld.lm_head;
- sl.sl_imap = lmp;
- sl.sl_hash = 0;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_flags = LKUP_FIRST;
+ /*
+ * Initialize the symbol lookup data structure.
+ */
+ 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)) {
Addr addr = sym->st_value;
diff --git a/usr/src/cmd/sgs/rtld/common/dlfcns.c b/usr/src/cmd/sgs/rtld/common/dlfcns.c
index 82705ffbb4..2a71f96bf2 100644
--- a/usr/src/cmd/sgs/rtld/common/dlfcns.c
+++ b/usr/src/cmd/sgs/rtld/common/dlfcns.c
@@ -1127,22 +1127,23 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
Slookup sl;
uint_t binfo;
- sl.sl_name = name;
- sl.sl_cmap = clmp;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
-
/*
+ * Initialize the symbol lookup data structure.
+ *
* Standard relocations are evaluated using the symbol index of the
* associated relocation symbol. This index provides for loading
* any lazy dependency and establishing a direct binding if necessary.
* If a dlsym() operation originates from an object that contains a
- * symbol table entry for the same name, then establish the symbol
- * index so that any dependency requirements can be triggered.
+ * symbol table entry for the same name, then we need to establish the
+ * symbol index so that any dependency requirements can be triggered.
+ *
+ * Therefore, the first symbol lookup that is carried out is for the
+ * symbol name within the calling object. If this symbol exists, the
+ * symbols index is computed, added to the Slookup data, and thus used
+ * to seed the real symbol lookup.
*/
- sl.sl_imap = clmp;
- sl.sl_flags = LKUP_SYMNDX;
- sl.sl_hash = elf_hash(name);
+ SLOOKUP_INIT(sl, name, clmp, clmp, ld_entry_cnt, elf_hash(name),
+ 0, 0, 0, LKUP_SYMNDX);
if ((FCT(clmp) == &elf_fct) &&
((sym = SYMINTP(clmp)(&sl, 0, 0)) != NULL)) {
@@ -1164,7 +1165,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
sl.sl_imap = hlmp;
sl.sl_flags = LKUP_SPEC;
if (handle == RTLD_PROBE)
- sl.sl_flags |= LKUP_NOFALBACK;
+ sl.sl_flags |= LKUP_NOFALLBACK;
sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
} else if (handle == RTLD_NEXT) {
@@ -1184,7 +1185,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,
+ (void) elf_lazy_load(clmp, &sl,
sip->si_boundto, name);
/*
@@ -1252,7 +1253,7 @@ dlsym_core(void *handle, const char *name, Rt_map *clmp, Rt_map **dlmp)
DBG_CALL(Dbg_syms_dlsym(clmp, name, 0, DBG_DLSYM_PROBE));
sl.sl_imap = hlmp;
- sl.sl_flags = (LKUP_SPEC | LKUP_NOFALBACK);
+ sl.sl_flags = (LKUP_SPEC | LKUP_NOFALLBACK);
sym = LM_LOOKUP_SYM(clmp)(&sl, dlmp, &binfo);
} else {
diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c
index 45e64a557b..a2f4661532 100644
--- a/usr/src/cmd/sgs/rtld/common/elf.c
+++ b/usr/src/cmd/sgs/rtld/common/elf.c
@@ -278,10 +278,10 @@ elf_rtld_load()
* Lazy load an object.
*/
Rt_map *
-elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)
+elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym)
{
Rt_map *nlmp, *hlmp;
- Dyninfo *dip = &DYNINFO(clmp)[ndx];
+ Dyninfo *dip = &DYNINFO(clmp)[ndx], *pdip;
uint_t flags = 0;
Pnode *pnp;
const char *name;
@@ -293,22 +293,47 @@ elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)
* If this dependency has already been processed, we're done.
*/
if (((nlmp = (Rt_map *)dip->di_info) != 0) ||
- (dip->di_flags & FLG_DI_PROCESSD))
+ (dip->di_flags & FLG_DI_LDD_DONE))
return (nlmp);
/*
- * Determine the initial dependency name, and indicate that this
- * dependencies processing has initiated.
+ * If we're running under ldd(1), indicate that this dependency has been
+ * processed (see test above). It doesn't matter whether the object is
+ * successfully loaded or not, this flag simply ensures that we don't
+ * repeatedly attempt to load an object that has already failed to load.
+ * To do so would create multiple failure diagnostics for the same
+ * object under ldd(1).
+ */
+ if (lml->lm_flags & LML_FLG_TRC_ENABLE)
+ dip->di_flags |= FLG_DI_LDD_DONE;
+
+ /*
+ * Determine the initial dependency name.
*/
name = STRTAB(clmp) + DYN(clmp)[ndx].d_un.d_val;
DBG_CALL(Dbg_file_lazyload(clmp, name, sym));
- if (lml->lm_flags & LML_FLG_TRC_ENABLE)
- dip->di_flags |= FLG_DI_PROCESSD;
+ /*
+ * If this object needs to establish its own group, make sure a handle
+ * is created.
+ */
if (dip->di_flags & FLG_DI_GROUP)
flags |= (FLG_RT_SETGROUP | FLG_RT_HANDLE);
/*
+ * Lazy dependencies are identified as DT_NEEDED entries with a
+ * DF_P1_LAZYLOAD flag in the previous DT_POSFLAG_1 element. The
+ * dynamic information element that corresponds to the DT_POSFLAG_1
+ * entry is free, and thus used to store the present entrance
+ * identifier. This identifier is used to prevent multiple attempts to
+ * load a failed lazy loadable dependency within the same runtime linker
+ * operation. However, future attempts to reload this dependency are
+ * still possible.
+ */
+ if (ndx && (pdip = dip - 1) && (pdip->di_flags & FLG_DI_POSFLAG1))
+ pdip->di_info = (void *)slp->sl_id;
+
+ /*
* Expand the requested name if necessary.
*/
if ((pnp = elf_fix_name(name, clmp, PN_SER_NEEDED)) == 0)
@@ -350,8 +375,8 @@ elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)
* Finish processing the objects associated with this request, and
* create an association between the caller and this dependency.
*/
- if (nlmp && (((analyze_lmc(lml, lmco, nlmp) == 0)) ||
- (bind_one(clmp, nlmp, BND_NEEDED) == 0) ||
+ if (nlmp && ((bind_one(clmp, nlmp, BND_NEEDED) == 0) ||
+ (analyze_lmc(lml, lmco, nlmp) == 0) ||
(relocate_lmc(lml, lmco, clmp, nlmp) == 0)))
dip->di_info = nlmp = 0;
@@ -369,6 +394,16 @@ elf_lazy_load(Rt_map *clmp, uint_t ndx, const char *sym)
if (lmc)
remove_cntl(lml, lmco);
+ /*
+ * If this lazy loading failed, record the fact, and bump the lazy
+ * counts.
+ */
+ if (nlmp == 0) {
+ dip->di_flags |= FLG_DI_LAZYFAIL;
+ if (LAZY(clmp)++ == 0)
+ LIST(clmp)->lm_lazy++;
+ }
+
return (nlmp);
}
@@ -556,9 +591,9 @@ elf_verify_vers(const char *name, Rt_map *clmp, Rt_map *nlmp)
static int
elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
{
- Dyn *dyn;
+ Dyn *dyn, *pdyn;
ulong_t ndx = 0;
- uint_t lazy = 0, flags = 0;
+ uint_t lazy, flags;
Word lmflags = lml->lm_flags;
Word lmtflags = lml->lm_tflags;
@@ -568,7 +603,8 @@ elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
if (DYN(clmp) == 0)
return (1);
- for (dyn = (Dyn *)DYN(clmp); dyn->d_tag != DT_NULL; dyn++, ndx++) {
+ for (dyn = (Dyn *)DYN(clmp), pdyn = NULL; dyn->d_tag != DT_NULL;
+ pdyn = dyn++, ndx++) {
Dyninfo *dip = &DYNINFO(clmp)[ndx];
Rt_map *nlmp = 0;
char *name;
@@ -577,17 +613,25 @@ elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
switch (dyn->d_tag) {
case DT_POSFLAG_1:
- if ((dyn->d_un.d_val & DF_P1_LAZYLOAD) &&
- !(lmtflags & LML_TFLG_NOLAZYLD))
- lazy = 1;
- if (dyn->d_un.d_val & DF_P1_GROUPPERM)
- flags = (FLG_RT_SETGROUP | FLG_RT_HANDLE);
+ dip->di_flags |= FLG_DI_POSFLAG1;
continue;
case DT_NEEDED:
case DT_USED:
+ lazy = flags = 0;
dip->di_flags |= FLG_DI_NEEDED;
- if (flags)
- dip->di_flags |= FLG_DI_GROUP;
+
+ if (pdyn && (pdyn->d_tag == DT_POSFLAG_1)) {
+ if ((pdyn->d_un.d_val & DF_P1_LAZYLOAD) &&
+ ((lmtflags & LML_TFLG_NOLAZYLD) == 0)) {
+ dip->di_flags |= FLG_DI_LAZY;
+ lazy = 1;
+ }
+ if (pdyn->d_un.d_val & DF_P1_GROUPPERM) {
+ dip->di_flags |= FLG_DI_GROUP;
+ flags =
+ (FLG_RT_SETGROUP | FLG_RT_HANDLE);
+ }
+ }
name = (char *)STRTAB(clmp) + dyn->d_un.d_val;
@@ -634,28 +678,32 @@ elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
break;
case DT_AUXILIARY:
dip->di_flags |= FLG_DI_AUXFLTR;
- lazy = flags = 0;
continue;
case DT_SUNW_AUXILIARY:
dip->di_flags |= (FLG_DI_AUXFLTR | FLG_DI_SYMFLTR);
- lazy = flags = 0;
continue;
case DT_FILTER:
dip->di_flags |= FLG_DI_STDFLTR;
- lazy = flags = 0;
continue;
case DT_SUNW_FILTER:
dip->di_flags |= (FLG_DI_STDFLTR | FLG_DI_SYMFLTR);
- lazy = flags = 0;
continue;
default:
- lazy = flags = 0;
continue;
}
DBG_CALL(Dbg_file_needed(clmp, name));
+
+ /*
+ * If we're running under ldd(1), indicate that this dependency
+ * has been processed. It doesn't matter whether the object is
+ * successfully loaded or not, this flag simply ensures that we
+ * don't repeatedly attempt to load an object that has already
+ * failed to load. To do so would create multiple failure
+ * diagnostics for the same object under ldd(1).
+ */
if (lml->lm_flags & LML_FLG_TRC_ENABLE)
- dip->di_flags |= FLG_DI_PROCESSD;
+ dip->di_flags |= FLG_DI_LDD_DONE;
/*
* Establish the objects name, load it and establish a binding
@@ -675,7 +723,7 @@ elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp)
remove_pnode(pnp);
if (silent)
rtld_flags &= ~RT_FL_SILENCERR;
- lazy = flags = 0;
+
if ((dip->di_info = (void *)nlmp) == 0) {
/*
* If the object could not be mapped, continue if error
@@ -1989,7 +2037,7 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
if ((sip->si_flags & SYMINFO_FLG_FILTER) ||
((sip->si_flags & SYMINFO_FLG_AUXILIARY) &&
SYMAFLTRCNT(ilmp))) {
- Sym * fsym;
+ Sym *fsym;
/*
* This symbol has an associated filtee. Lookup the
@@ -2010,7 +2058,7 @@ elf_find_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo)
* Determine if this object provides global filtering.
*/
if (flags1 & (FL1_RT_OBJSFLTR | FL1_RT_OBJAFLTR)) {
- Sym * fsym;
+ Sym *fsym;
if (OBJFLTRNDX(ilmp) != FLTR_DISABLED) {
/*
@@ -2097,12 +2145,12 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
* dynamic structure.
*/
if (ld) {
- uint_t dyncnt = 0;
+ uint_t dynndx = 0;
Xword pltpadsz = 0;
Rti_desc *rti;
/* CSTYLED */
- for ( ; ld->d_tag != DT_NULL; ++ld, dyncnt++) {
+ for ( ; ld->d_tag != DT_NULL; ++ld, dynndx++) {
switch ((Xword)ld->d_tag) {
case DT_SYMTAB:
SYMTAB(lmp) = (void *)(ld->d_un.d_ptr + base);
@@ -2138,8 +2186,8 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
case DT_REL:
case DT_RELA:
/*
- * At this time we can only handle 1 type of
- * relocation per object.
+ * At this time, ld.so. can only handle one
+ * type of relocation per object.
*/
REL(lmp) = (void *)(ld->d_un.d_ptr + base);
break;
@@ -2207,13 +2255,13 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
break;
case DT_FILTER:
fltr = ld->d_un.d_val;
- OBJFLTRNDX(lmp) = dyncnt;
+ OBJFLTRNDX(lmp) = dynndx;
FLAGS1(lmp) |= FL1_RT_OBJSFLTR;
break;
case DT_AUXILIARY:
if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
fltr = ld->d_un.d_val;
- OBJFLTRNDX(lmp) = dyncnt;
+ OBJFLTRNDX(lmp) = dynndx;
}
FLAGS1(lmp) |= FL1_RT_OBJAFLTR;
break;
@@ -2435,7 +2483,6 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
}
}
-
if (PLTPAD(lmp)) {
if (pltpadsz == (Xword)0)
PLTPAD(lmp) = 0;
@@ -2445,14 +2492,14 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
}
/*
- * Allocate Dynamic Info structure
+ * Allocate a Dynamic Info structure.
*/
- if ((DYNINFO(lmp) = calloc((size_t)dyncnt,
+ if ((DYNINFO(lmp) = calloc((size_t)dynndx,
sizeof (Dyninfo))) == 0) {
remove_so(0, lmp);
return (0);
}
- DYNINFOCNT(lmp) = dyncnt;
+ DYNINFOCNT(lmp) = dynndx;
}
/*
@@ -3245,13 +3292,13 @@ elf_lazy_cleanup(APlist *alp)
* Cleanup any link-maps added to this dynamic list and free it.
*/
for (APLIST_TRAVERSE(alp, idx, lmp))
- FLAGS(lmp) &= ~FLG_RT_DLSYM;
+ FLAGS(lmp) &= ~FLG_RT_TMPLIST;
free(alp);
}
/*
- * This routine is called upon to search for a symbol from the dependencies of
- * the initial link-map. To maintain lazy loadings goal of reducing the number
+ * This routine is called as a last fall-back to search for a symbol from a
+ * standard relocation. To maintain lazy loadings goal of reducing the number
* of objects mapped, any symbol search is first carried out using the objects
* that already exist in the process (either on a link-map list or handle).
* If a symbol can't be found, and lazy dependencies are still pending, this
@@ -3263,7 +3310,6 @@ elf_lazy_cleanup(APlist *alp)
* as someone elses dependency. Thus there's a possibility of some symbol
* search duplication.
*/
-
Sym *
elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
{
@@ -3273,35 +3319,65 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
Rt_map *lmp1, *lmp = slp->sl_imap;
const char *name = slp->sl_name;
+ /*
+ * Generate a local list of new objects to process. This list can grow
+ * as each object supplies its own lazy dependencies.
+ */
if (aplist_append(&alist, lmp, AL_CNT_LAZYFIND) == NULL)
return (NULL);
- FLAGS(lmp) |= FLG_RT_DLSYM;
+ FLAGS(lmp) |= FLG_RT_TMPLIST;
for (APLIST_TRAVERSE(alist, idx, lmp1)) {
uint_t cnt = 0;
Slookup sl = *slp;
- Dyninfo *dip;
+ Dyninfo *dip, *pdip;
/*
- * Loop through the DT_NEEDED entries examining each object for
- * the symbol. If the symbol is not found the object is in turn
- * added to the alist, so that its DT_NEEDED entires may be
- * examined.
+ * Discard any relocation index from further symbol searches.
+ * This index will have already been used to trigger any
+ * necessary lazy-loads, and it might be because one of these
+ * lazy loads have failed that we're here performing this
+ * fallback. By removing the relocation index we don't try
+ * and perform the same failed lazy loading activity again.
+ */
+ sl.sl_rsymndx = 0;
+
+ /*
+ * Loop through the lazy DT_NEEDED entries examining each object
+ * for the required symbol. If the symbol is not found, the
+ * object is in turn added to the local alist, so that the
+ * objects lazy DT_NEEDED entries can be examined.
*/
lmp = lmp1;
- for (dip = DYNINFO(lmp); cnt < DYNINFOCNT(lmp); cnt++, dip++) {
+ for (dip = DYNINFO(lmp), pdip = NULL; cnt < DYNINFOCNT(lmp);
+ cnt++, pdip = dip++) {
Rt_map *nlmp;
- if (((dip->di_flags & FLG_DI_NEEDED) == 0) ||
+ if (((dip->di_flags & FLG_DI_LAZY) == 0) ||
dip->di_info)
continue;
/*
- * If this entry defines a lazy dependency try loading
- * it. If the file can't be loaded, consider this
- * non-fatal and continue the search (lazy loaded
- * dependencies need not exist and their loading should
- * only be fatal if called from a relocation).
+ * If this object has already failed to lazy load, and
+ * we're still processing the same runtime linker
+ * operation that produced the failure, don't bother
+ * to try and load the object again.
+ */
+ if ((dip->di_flags & FLG_DI_LAZYFAIL) && pdip &&
+ (pdip->di_flags & FLG_DI_POSFLAG1)) {
+ if (pdip->di_info == (void *)ld_entry_cnt)
+ continue;
+
+ dip->di_flags &= ~FLG_DI_LAZYFAIL;
+ pdip->di_info = NULL;
+ }
+
+ /*
+ * Try loading this lazy dependency. If the object
+ * can't be loaded, consider this non-fatal and continue
+ * the search. Lazy loaded dependencies need not exist
+ * and their loading should only turn out to be fatal
+ * if they are required to satisfy a relocation.
*
* If the file is already loaded and relocated we must
* still inspect it for symbols, even though it might
@@ -3311,7 +3387,7 @@ 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, cnt, name)) == 0)
+ if ((nlmp = elf_lazy_load(lmp, &sl, cnt, name)) == 0)
continue;
/*
@@ -3320,7 +3396,7 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
* found add the object to the dynamic list so that we
* can inspect its dependencies.
*/
- if (FLAGS(nlmp) & FLG_RT_DLSYM)
+ if (FLAGS(nlmp) & FLG_RT_TMPLIST)
continue;
sl.sl_imap = nlmp;
@@ -3338,7 +3414,7 @@ elf_lazy_find_sym(Slookup *slp, Rt_map **_lmp, uint_t *binfo)
elf_lazy_cleanup(alist);
return (0);
}
- FLAGS(nlmp) |= FLG_RT_DLSYM;
+ FLAGS(nlmp) |= FLG_RT_TMPLIST;
}
}
if (sym)
diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c
index 11665d080e..a77df480ea 100644
--- a/usr/src/cmd/sgs/rtld/common/globals.c
+++ b/usr/src/cmd/sgs/rtld/common/globals.c
@@ -23,7 +23,7 @@
* All Rights Reserved
*
*
- * 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"
@@ -48,6 +48,27 @@ 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
+ * 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
+ * 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
+ * 32-bit value, it is highly unlikely that any application could usefully make
+ * 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.
+ */
+ulong_t ld_entry_cnt = 0;
+
+/*
* BEGIN: Exposed to rtld_db, don't change without a coordinated handshake with
* librtld_db (remembering that librtld_db must be able to read old as well as
* current core files).
diff --git a/usr/src/cmd/sgs/rtld/common/mapfile-vers b/usr/src/cmd/sgs/rtld/common/mapfile-vers
index 2915fce8ef..566b9b2a8b 100644
--- a/usr/src/cmd/sgs/rtld/common/mapfile-vers
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-vers
@@ -77,6 +77,7 @@ SUNWprivate_1.2 {
lookup_sym;
alist_append; # librtld support
+ ld_entry_cnt;
dbg_desc; # Diagnostic support
dbg_print;
eprintf; # Error message printing
diff --git a/usr/src/cmd/sgs/rtld/common/remove.c b/usr/src/cmd/sgs/rtld/common/remove.c
index efb517656a..ae8c73283c 100644
--- a/usr/src/cmd/sgs/rtld/common/remove.c
+++ b/usr/src/cmd/sgs/rtld/common/remove.c
@@ -420,11 +420,11 @@ remove_so(Lm_list *lml, Rt_map *lmp)
/*
* Traverse an objects dependency list removing callers and dependencies.
* There's a chicken and egg problem with tearing down link-maps. Any
- * relationship between link-maps is maintained on a DEPENDS, and associated
- * CALLERS list. These lists can't be broken down at the time a single link-
- * map is removed as any related link-map may have already been removed. Thus,
- * lists between link-maps must be broken down before the individual link-maps
- * themselves.
+ * relationship between link-maps is maintained on a DEPENDS list, and an
+ * associated CALLERS list. These lists can't be broken down at the time a
+ * single link-map is removed, as any related link-map may have already been
+ * removed. Thus, lists between link-maps must be broken down before the
+ * individual link-maps themselves.
*/
void
remove_lists(Rt_map *lmp, int lazy)
@@ -454,6 +454,7 @@ remove_lists(Rt_map *lmp, int lazy)
*/
for (APLIST_TRAVERSE(CALLERS(lmp), idx1, bdp)) {
Rt_map *clmp = bdp->b_caller;
+ Dyninfo *dip;
/*
* If we're removing an object that was triggered by a lazyload,
@@ -464,23 +465,18 @@ remove_lists(Rt_map *lmp, int lazy)
* failed to relocate, it's possible that one or more of the
* individual objects can be reloaded without a problem.
*/
- if (lazy) {
- Dyninfo *dip;
-
- if ((dip = DYNINFO(clmp)) != 0) {
- uint_t cnt, max = DYNINFOCNT(clmp);
+ if (lazy && ((dip = DYNINFO(clmp)) != NULL)) {
+ uint_t cnt, max = DYNINFOCNT(clmp);
- for (cnt = 0; cnt < max; cnt++, dip++) {
- if ((dip->di_flags &
- FLG_DI_NEEDED) == 0)
- continue;
+ for (cnt = 0; cnt < max; cnt++, dip++) {
+ if ((dip->di_flags & FLG_DI_LAZY) == 0)
+ continue;
- if (dip->di_info == (void *)lmp) {
- dip->di_info = 0;
+ if (dip->di_info == (void *)lmp) {
+ dip->di_info = 0;
- if (LAZY(clmp)++ == 0)
- LIST(clmp)->lm_lazy++;
- }
+ if (LAZY(clmp)++ == 0)
+ LIST(clmp)->lm_lazy++;
}
}
}
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 0ea14d3c7c..04ab939b4d 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -805,12 +805,25 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
/*
* Establish the modes of the initial object. These modes are
* propagated to any preloaded objects and explicit shared library
- * dependencies. Note, RTLD_NOW may have been established during
- * analysis of the application had it been built -z now.
+ * dependencies.
+ *
+ * If we're generating a configuration file using crle(1), remove
+ * any RTLD_NOW use, as we don't want to trigger any relocation proc-
+ * essing during crle(1)'s first past (this would just be unnecessary
+ * overhead). Any filters are explicitly loaded, and thus RTLD_NOW is
+ * not required to trigger filter loading.
+ *
+ * Note, RTLD_NOW may have been established during analysis of the
+ * application had the application been built -z now.
*/
MODE(mlmp) |= (RTLD_NODELETE | RTLD_GLOBAL | RTLD_WORLD);
- if (rtld_flags & RT_FL_CONFGEN)
+
+ if (rtld_flags & RT_FL_CONFGEN) {
MODE(mlmp) |= RTLD_CONFGEN;
+ MODE(mlmp) &= ~RTLD_NOW;
+ rtld_flags2 &= ~RT_FL2_BINDNOW;
+ }
+
if ((MODE(mlmp) & RTLD_NOW) == 0) {
if (rtld_flags2 & RT_FL2_BINDNOW)
MODE(mlmp) |= RTLD_NOW;
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 959259e8e7..1b3ea352a3 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -3081,13 +3081,15 @@ nu_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags)
}
/*
- * Generic entry point from user code - simply grabs a lock.
+ * Generic entry point from user code - simply grabs a lock, and bumps the
+ * entrance count.
*/
int
enter(void)
{
if (rt_bind_guard(THR_FLG_RTLD)) {
(void) rt_mutex_lock(&rtldlock);
+ ld_entry_cnt++;
return (1);
}
return (0);
@@ -3419,18 +3421,16 @@ callable(Rt_map *clmp, Rt_map *dlmp, Grp_hdl *ghp, uint_t slflags)
void
set_environ(Lm_list *lml)
{
- Rt_map * dlmp;
- Sym * sym;
+ Rt_map *dlmp;
+ Sym *sym;
Slookup sl;
uint_t binfo;
- sl.sl_name = MSG_ORIG(MSG_SYM_ENVIRON);
- sl.sl_cmap = lml->lm_head;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_flags = LKUP_WEAK;
+ /*
+ * Initialize the symbol lookup data structure.
+ */
+ 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)) {
lml->lm_environ = (char ***)sym->st_value;
diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
index e4216871ec..50e9c8390e 100644
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
@@ -248,15 +248,11 @@ elf_bndr(Rt_map *lmp, ulong_t reloff, caddr_t from)
llmp = lml->lm_tail;
/*
- * Find definition for symbol.
+ * Find definition for symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = rsym;
- sl.sl_flags = LKUP_DEFT;
+ 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) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
@@ -490,13 +486,11 @@ elf_reloc(Rt_map *lmp, uint_t plt)
if (!relbgn || (relbgn == relend))
return (1);
- sl.sl_name = MSG_ORIG(MSG_SYM_PLT);
- sl.sl_cmap = lmp;
- sl.sl_imap = lmp;
- sl.sl_hash = elf_hash(MSG_ORIG(MSG_SYM_PLT));
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_flags = LKUP_DEFT;
+ /*
+ * Initialize the symbol lookup data structure.
+ */
+ 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)
return (1);
@@ -743,18 +737,15 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Lookup the symbol definition.
+ * Initialize the symbol lookup data
+ * structure.
*/
name = (char *)(STRTAB(lmp) +
symref->st_name);
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = 0;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = symref;
- sl.sl_rtype = rtype;
- sl.sl_flags = LKUP_STDRELOC;
+ SLOOKUP_INIT(sl, name, lmp, 0,
+ ld_entry_cnt, 0, rsymndx, symref,
+ rtype, LKUP_STDRELOC);
symdef = lookup_sym(&sl, &_lmp, &binfo);
@@ -1017,14 +1008,11 @@ _elf_copy_reloc(const char *name, Rt_map *rlmp, Rt_map *dlmp)
/*
* Determine if the special symbol exists as a reference in the dynamic
* executable, and that an associated definition exists in libc.so.1.
+ *
+ * Initialize the symbol lookup data structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = rlmp;
- sl.sl_imap = rlmp;
- sl.sl_hash = 0;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_flags = LKUP_FIRST;
+ SLOOKUP_INIT(sl, name, rlmp, rlmp, ld_entry_cnt, 0, 0, 0, 0,
+ LKUP_FIRST);
if ((symref = lookup_sym(&sl, &_lmp, &binfo)) == 0)
return (1);
diff --git a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c
index c2dbdbda14..35091d452c 100644
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c
@@ -74,7 +74,7 @@ static const mdb_bitmask_t rtflags_bits[] = {
{ MSG_ORIG(MSG_FLG_OBJINTPO), FLG_RT_OBJINTPO, FLG_RT_OBJINTPO},
{ MSG_ORIG(MSG_FLG_SYMINTPO), FLG_RT_SYMINTPO, FLG_RT_SYMINTPO},
{ MSG_ORIG(MSG_FLG_MOVE), FLG_RT_MOVE, FLG_RT_MOVE},
- { MSG_ORIG(MSG_FLG_DLSYM), FLG_RT_DLSYM, FLG_RT_DLSYM},
+ { MSG_ORIG(MSG_FLG_TMPLIST), FLG_RT_TMPLIST, FLG_RT_TMPLIST},
{ MSG_ORIG(MSG_FLG_REGSYMS), FLG_RT_REGSYMS, FLG_RT_REGSYMS},
{ MSG_ORIG(MSG_FLG_INITCLCT), FLG_RT_INITCLCT, FLG_RT_INITCLCT},
{ MSG_ORIG(MSG_FLG_HANDLE), FLG_RT_HANDLE, FLG_RT_HANDLE},
diff --git a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg
index 5891c80cac..1fe46e0a0f 100644
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg
@@ -90,7 +90,7 @@
@ MSG_FLG_OBJINTPO "OBJECT-INTERPOSE"
@ MSG_FLG_SYMINTPO "SYMBOL-INTERPOSE"
@ MSG_FLG_MOVE "MOVE"
-@ MSG_FLG_DLSYM "DLSYM"
+@ MSG_FLG_TMPLIST "TEMPORARY-LIST"
@ MSG_FLG_REGSYMS "REGISTER-SYMS"
@ MSG_FLG_INITCLCT "INIT-COLLECTED"
@ MSG_FLG_HANDLE "HANDLE"
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 ad84bb5b24..5163fc324d 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_a.out.c
@@ -111,15 +111,11 @@ aout_bndr(caddr_t pc)
llmp = lml->lm_tail;
/*
- * Find definition for symbol.
+ * Find definition for symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_flags = LKUP_DEFT;
+ 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) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
@@ -280,16 +276,11 @@ aout_reloc(Rt_map * lmp, uint_t plt)
name = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx];
/*
- * Locate symbol.
+ * Locate symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = 0;
- sl.sl_hash = 0;
- sl.sl_rsymndx = 0;
- sl.sl_rsym = 0;
- sl.sl_rtype = 0;
- sl.sl_flags = (LKUP_DEFT | LKUP_STDRELOC);
+ 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 (lml->lm_flags & LML_FLG_TRC_WARN) {
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
index 316c7f6426..06e150b430 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
@@ -420,15 +420,11 @@ elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
llmp = lml->lm_tail;
/*
- * Find definition for symbol.
+ * Find definition for symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = rsym;
- sl.sl_flags = LKUP_DEFT;
+ 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) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
@@ -826,18 +822,15 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Lookup the symbol definition.
+ * Initialize the symbol lookup data
+ * structure.
*/
name = (char *)(STRTAB(lmp) +
symref->st_name);
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = 0;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = symref;
- sl.sl_rtype = rtype;
- sl.sl_flags = LKUP_STDRELOC;
+ SLOOKUP_INIT(sl, name, lmp, 0,
+ ld_entry_cnt, 0, rsymndx, symref,
+ rtype, LKUP_STDRELOC);
symdef = lookup_sym(&sl, &_lmp, &binfo);
diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
index 43ee59c4b9..0cd3aba752 100644
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
@@ -564,15 +564,12 @@ elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
llmp = lml->lm_tail;
/*
- * Find definition for symbol.
+ * Find definition for symbol. Initialize the symbol lookup data
+ * structure.
*/
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = lml->lm_head;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = rsym;
- sl.sl_flags = LKUP_DEFT;
+ 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) {
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
demangle(name));
@@ -1068,18 +1065,15 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Lookup the symbol definition.
+ * Initialize the symbol lookup data
+ * structure.
*/
name = (char *)(STRTAB(lmp) +
symref->st_name);
- sl.sl_name = name;
- sl.sl_cmap = lmp;
- sl.sl_imap = 0;
- sl.sl_hash = 0;
- sl.sl_rsymndx = rsymndx;
- sl.sl_rsym = symref;
- sl.sl_rtype = rtype;
- sl.sl_flags = LKUP_STDRELOC;
+ SLOOKUP_INIT(sl, name, lmp, 0,
+ ld_entry_cnt, 0, rsymndx, symref,
+ rtype, LKUP_STDRELOC);
symdef = lookup_sym(&sl, &_lmp, &binfo);