diff options
author | rie <none@none> | 2008-01-31 11:47:19 -0800 |
---|---|---|
committer | rie <none@none> | 2008-01-31 11:47:19 -0800 |
commit | 75e7992ad4e186443b61dab39f79c9d79802f295 (patch) | |
tree | b8e23bffeafeebc91348e1cc14b33f4126fba752 /usr/src | |
parent | 9d82f4f62620e94b1b60f7096f2ce08a64013489 (diff) | |
download | illumos-joyent-75e7992ad4e186443b61dab39f79c9d79802f295.tar.gz |
6654381 lazy loading fall-back needs optimizing
Diffstat (limited to 'usr/src')
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); |