diff options
Diffstat (limited to 'usr/src/cmd/sgs/rtld/common/analyze.c')
-rw-r--r-- | usr/src/cmd/sgs/rtld/common/analyze.c | 258 |
1 files changed, 169 insertions, 89 deletions
diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index 6ed3b0473c..8e9d115f68 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -63,7 +63,7 @@ static Fct *vector[] = { * flag. Otherwise, filtee loading is deferred until triggered by a relocation. */ static void -load_filtees(Rt_map *lmp) +load_filtees(Rt_map *lmp, int *in_nfavl) { if ((FLAGS1(lmp) & MSK_RT_FILTER) && ((FLAGS(lmp) & FLG_RT_LOADFLTR) || @@ -82,7 +82,7 @@ load_filtees(Rt_map *lmp) ((dip->di_flags & FLG_DI_AUXFLTR) && (rtld_flags & RT_FL_NOAUXFLTR))) continue; - (void) elf_lookup_filtee(&sl, 0, 0, cnt); + (void) elf_lookup_filtee(&sl, 0, 0, cnt, in_nfavl); } } } @@ -99,7 +99,7 @@ load_filtees(Rt_map *lmp) * breadth first ordering of all needed objects. */ int -analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp) +analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl) { Rt_map *lmp = nlmp; Lm_cntl *nlmc; @@ -144,7 +144,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp) * need to finish the link-editing of the object at this point. */ if (FLAGS(lmp) & FLG_RT_OBJECT) { - if (elf_obj_fini(lml, lmp) == 0) { + if (elf_obj_fini(lml, lmp, in_nfavl) == 0) { if (lml->lm_flags & LML_FLG_TRC_ENABLE) continue; ret = 0; @@ -157,7 +157,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp) /* * Establish any dependencies this object requires. */ - if (LM_NEEDED(lmp)(lml, nlmco, lmp) == 0) { + if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) { if (lml->lm_flags & LML_FLG_TRC_ENABLE) continue; ret = 0; @@ -174,7 +174,7 @@ analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp) * an object will load filters as part of relocation processing. */ if (MODE(nlmp) & RTLD_CONFGEN) - load_filtees(lmp); + load_filtees(lmp, in_nfavl); /* * If an interposer has been added, it will have been inserted @@ -229,7 +229,7 @@ copy_zerobits(Rt_map *dlmp, Sym *dsym) * Relocate an individual object. */ static int -relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now) +relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl) { /* * If we're running under ldd(1), and haven't been asked to trace any @@ -241,7 +241,7 @@ relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now) if (relocated) (*relocated)++; - if ((LM_RELOC(lmp)(lmp, now) == 0) && + if ((LM_RELOC(lmp)(lmp, now, in_nfavl) == 0) && ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0)) return (0); } @@ -252,7 +252,7 @@ relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now) * Relocate the objects on a link-map control list. */ static int -_relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated) +_relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl) { Rt_map *lmp; @@ -274,7 +274,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated) /* * Relocate the object. */ - if (relocate_so(lml, lmp, relocated, 0) == 0) + if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0) return (0); /* @@ -301,7 +301,7 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated) * Determine if this object is a filter, and if a load filter * flag is in effect, trigger the loading of all its filtees. */ - load_filtees(lmp); + load_filtees(lmp, in_nfavl); } /* @@ -374,7 +374,8 @@ _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated) } int -relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp) +relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp, + int *in_nfavl) { int lret = 1, pret = 1; APlist *alp; @@ -440,7 +441,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp) * to the present link-map control list, try and clean up any * failed objects now. */ - lret = _relocate_lmc(lml, nlmp, &relocated); + lret = _relocate_lmc(lml, nlmp, &relocated, in_nfavl); if ((lret == 0) && (nlmco != ALIST_OFF_DATA)) remove_lmc(lml, clmp, nlmc, nlmco, NAME(nlmp)); } @@ -516,7 +517,7 @@ relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp) * then the process will receive a fatal error at that * time. But, the .plt may never be called. */ - if (relocate_so(lml, lmp, 0, 1) == 0) + if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0) pret = 0; } @@ -796,20 +797,27 @@ is_so_matched(Rt_map *lmp, const char *name, int path) /* * Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen() * requests. Each request investigates the file based upon the callers - * environment, and once a full path name has been established a check is made - * against the FullpathNode AVL tree and a device/inode check, to ensure the - * same file isn't mapped multiple times. See file_open(). + * environment. Once a full path name has been established, the following + * checks are made: * - * However, there are one of two cases where a test for an existing file name - * needs to be carried out, such as dlopen(NOLOAD) requests, dldump() requests, - * and as a final fallback to dependency loading. These requests are handled - * by is_so_loaded(). + * . does the path exist in the link-map lists FullPathNode AVL tree? if + * so, the file is already loaded, and its associated link-map pointer + * is returned. + * . does the path exist in the not-found AVL tree? if so, this path has + * already been determined to not exist, and a failure is returned. + * . a device/inode check, to ensure the same file isn't mapped multiple + * times through different paths. See file_open(). + * + * However, there are cases where a test for an existing file name needs to be + * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a + * final fallback to dependency loading. These requests are handled by + * is_so_loaded(). * * A traversal through the callers link-map list is carried out, and from each * link-map, a comparison is made against all of the various names by which the - * object has been referenced. The subroutine, is_so_matched() compares the - * link-map names against the name being searched for. Whether the search name - * is a full path name or a simple file name, governs what comparisons are made. + * object has been referenced. is_so_matched() is used to compares the link-map + * names against the name being searched for. Whether the search name is a full + * path name or a simple file name, governs what comparisons are made. * * A full path name, which is a fully resolved path name that starts with a "/" * character, or a relative path name that includes a "/" character, must match @@ -818,7 +826,7 @@ is_so_matched(Rt_map *lmp, const char *name, int path) * any link-map names. */ Rt_map * -is_so_loaded(Lm_list *lml, const char *name) +is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl) { Rt_map *lmp; avl_index_t where; @@ -828,12 +836,23 @@ is_so_loaded(Lm_list *lml, const char *name) /* * If the name is a full path name, first determine if the path name is - * registered in the FullpathNode AVL tree. + * registered on the FullPathNode AVL, or not-found AVL trees. */ - if ((name[0] == '/') && - ((lmp = fpavl_loaded(lml, name, &where)) != NULL) && - ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0)) - return (lmp); + if (name[0] == '/') { + if (((lmp = fpavl_recorded(lml, name, &where)) != NULL) && + ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0)) + return (lmp); + if (nfavl_recorded(name, 0)) { + /* + * For dlopen() and dlsym() fall backs, indicate that + * a registered not-found path has indicated that this + * object does not exist. + */ + if (in_nfavl) + (*in_nfavl)++; + return (0); + } + } /* * Determine whether the name is a simple file name, or a path name. @@ -1175,11 +1194,13 @@ file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags, static int file_open(int err, Lm_list *lml, const char *oname, const char *nname, - Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej) + Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej, int *in_nfavl) { struct stat status; Rt_map *nlmp; int resolved = 0; + char *name; + avl_index_t nfavlwhere = 0; fdesc->fd_oname = oname; @@ -1193,12 +1214,28 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname, * one previously used, the process may have changed directory. */ if ((err == 0) && (nname[0] == '/')) { - if ((nlmp = fpavl_loaded(lml, nname, + if ((nlmp = fpavl_recorded(lml, nname, &(fdesc->fd_avlwhere))) != NULL) { fdesc->fd_nname = nname; fdesc->fd_lmp = nlmp; return (1); } + if (nfavl_recorded(nname, &nfavlwhere)) { + /* + * For dlopen() and dlsym() fall backs, indicate that + * a registered not-found path has indicated that this + * object does not exist. If this path has been + * constructed as part of expanding a HWCAP directory, + * and as this is a silent failure, where no rejection + * message is created, free the original name to + * simplify the life of the caller. + */ + if (in_nfavl) + (*in_nfavl)++; + if (flags & FLG_RT_HWCAP) + free((void *)nname); + return (0); + } } if ((err == 0) && ((stat(nname, &status)) != -1)) { @@ -1236,7 +1273,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname, if (strcmp(nname, path)) { if ((nlmp = - fpavl_loaded(lml, path, 0)) != NULL) { + fpavl_recorded(lml, path, 0)) != NULL) { added = 0; if (append_alias(nlmp, nname, @@ -1351,6 +1388,13 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname, } /* + * Regardless of error, duplicate and record any full path names that + * can't be used on the "not-found" AVL tree. + */ + if ((nname[0] == '/') && ((name = strdup(nname)) != NULL)) + nfavl_insert(name, nfavlwhere); + + /* * Indicate any rejection. */ if (rej->rej_type) { @@ -1374,7 +1418,7 @@ file_open(int err, Lm_list *lml, const char *oname, const char *nname, */ int find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, - Fdesc *fdesc, Rej_desc *rej) + Fdesc *fdesc, Rej_desc *rej, int *in_nfavl) { int err = 0; @@ -1413,7 +1457,7 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, DBG_CALL(Dbg_libs_found(lml, aname, FLG_FD_ALTER)); if (((ret = file_open(0, lml, oname, aname, - clmp, flags, fdesc, rej)) != 0) || + clmp, flags, fdesc, rej, in_nfavl)) != 0) || ((obj->co_flags & RTC_OBJ_OPTINAL) == 0)) return (ret); @@ -1422,7 +1466,8 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, } } DBG_CALL(Dbg_libs_found(lml, oname, 0)); - return (file_open(err, lml, oname, oname, clmp, flags, fdesc, rej)); + return (file_open(err, lml, oname, oname, clmp, flags, fdesc, + rej, in_nfavl)); } /* @@ -1430,7 +1475,8 @@ find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, */ static int _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp, - uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag) + uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag, + int *in_nfavl) { DBG_CALL(Dbg_libs_found(lml, nname, aflag)); if ((lml->lm_flags & LML_FLG_TRC_SEARCH) && @@ -1445,9 +1491,10 @@ _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp, * dependency, or indicate that this dependency should be ignored. */ if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) { - char *aname = audit_objsearch(clmp, nname, dir->p_orig); + char *aname; - if (aname == 0) { + if ((aname = audit_objsearch(clmp, nname, + (dir->p_orig & LA_SER_MASK))) == 0) { DBG_CALL(Dbg_audit_terminate(lml, nname)); return (0); } @@ -1460,12 +1507,14 @@ _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp, if (nname != aname) (void) strncpy((char *)nname, aname, PATH_MAX); } - return (file_open(0, lml, oname, nname, clmp, flags, fdesc, rej)); + return (file_open(0, lml, oname, nname, clmp, flags, fdesc, + rej, in_nfavl)); } static int find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, - Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen) + Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen, + int *in_nfavl) { static Rtc_obj Obj = { 0 }; Rtc_obj *dobj; @@ -1542,7 +1591,8 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, * open the original path. */ ret = _find_file(lml, oname, alt, clmp, - flags, fdesc, rej, dir, 1); + flags, fdesc, rej, dir, 1, + in_nfavl); if (ret || ((fobj->co_flags & RTC_OBJ_OPTINAL) == 0)) return (ret); @@ -1564,7 +1614,8 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, if ((nname = (LM_GET_SO(clmp)(dir->p_name, nname))) == 0) return (0); - return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej, dir, 0)); + return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej, + dir, 0, in_nfavl)); } /* @@ -1572,7 +1623,7 @@ find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, * process the various names by which it can be referenced. */ static Rt_map * -load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc) +load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc, int *in_nfavl) { const char *oname = fdesc->fd_oname; const char *nname = fdesc->fd_nname; @@ -1595,7 +1646,7 @@ load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc) * original file so as not to accumulate file descriptors. */ nlmp = ((fdesc->fd_ftp)->fct_map_so)(lml, lmco, nname, oname, - fdesc->fd_fd); + fdesc->fd_fd, in_nfavl); (void) close(fdesc->fd_fd); fdesc->fd_fd = 0; @@ -1701,7 +1752,7 @@ load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc) */ static Rt_map * load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, - uint_t flags, Fdesc *nfdp, Rej_desc *rej) + uint_t flags, Fdesc *nfdp, Rej_desc *rej, int *in_nfavl) { char *name; uint_t slash = 0; @@ -1765,7 +1816,8 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, /* * Obtain the avl index for this object. */ - (void) fpavl_loaded(lml, nfdp->fd_nname, &(nfdp->fd_avlwhere)); + (void) fpavl_recorded(lml, nfdp->fd_nname, + &(nfdp->fd_avlwhere)); /* * If the name and resolved pathname differ, duplicate the path @@ -1784,7 +1836,8 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, *nfdp = fdesc; nfdp->fd_flags = FLG_FD_SLASH; - if (find_path(lml, oname, clmp, flags, nfdp, &_rej) == 0) { + if (find_path(lml, oname, clmp, flags, nfdp, + &_rej, in_nfavl) == 0) { rejection_inherit(rej, &_rej); return (0); } @@ -1808,7 +1861,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, DBG_CALL(Dbg_libs_find(lml, oname)); #if !defined(ISSOLOAD_BASENAME_DISABLED) - if ((nlmp = is_so_loaded(lml, oname))) + if ((nlmp = is_so_loaded(lml, oname, in_nfavl))) return (nlmp); #endif /* @@ -1824,17 +1877,36 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, *nfdp = fdesc; /* + * Under debugging, duplicate path name entries are + * tagged but remain part of the search path list so + * that they can be diagnosed under "unused" processing. + * Skip these entries, as this path would have already + * been attempted. + */ + if (dir->p_orig & PN_FLG_DUPLICAT) + continue; + + /* * Try and locate this file. Make sure to clean up * any rejection information should the file have * been found, but not appropriate. */ if (find_file(lml, oname, clmp, flags, nfdp, &_rej, - dir, &strhash, olen) == 0) { + dir, &strhash, olen, in_nfavl) == 0) { rejection_inherit(rej, &_rej); continue; } /* + * Indicate that this search path has been used. If + * this is an LD_LIBRARY_PATH setting, ignore any use + * by ld.so.1 itself. + */ + if (((dir->p_orig & LA_SER_LIBPATH) == 0) || + ((lml->lm_flags & LML_FLG_RTLDLM) == 0)) + dir->p_orig |= PN_FLG_USED; + + /* * If this object is already loaded, we're done. */ if (nfdp->fd_lmp) @@ -1853,7 +1925,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, * already been opened using its full pathname). */ if (nfdp->fd_nname == NULL) - return (is_so_loaded(lml, oname)); + return (is_so_loaded(lml, oname, in_nfavl)); } /* @@ -1878,7 +1950,7 @@ load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, * this mapping needs to be reset to insure it doesn't mistakenly get * unmapped as part of HWCAP cleanup. */ - return (load_file(lml, lmco, nfdp)); + return (load_file(lml, lmco, nfdp, in_nfavl)); } /* @@ -2199,7 +2271,8 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode, */ static Rt_map * _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp, - int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej) + int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej, + int *in_nfavl) { Rt_map *nlmp; const char *name = *oname; @@ -2215,7 +2288,7 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp, name = *oname; if ((nlmp = load_so(lml, lmco, name, clmp, flags, - nfdp, rej)) == 0) + nfdp, rej, in_nfavl)) == 0) return (0); /* @@ -2243,7 +2316,7 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp, * has already been loaded. */ /* LINTED */ - if (nlmp = is_so_loaded(lml, name)) { + if (nlmp = is_so_loaded(lml, name, in_nfavl)) { if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) && ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) { (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, @@ -2310,8 +2383,8 @@ _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp, } Rt_map * -load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, - int nmode, uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej) +load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, int nmode, + uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej, int *in_nfavl) { Rt_map *lmp; Fdesc nfdp = { 0 }; @@ -2343,7 +2416,8 @@ load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, nfdp = *cfdp; } - lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp, rej); + lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp, + rej, in_nfavl); /* * If this path originated from a $HWCAP specification, re-establish the @@ -2369,7 +2443,7 @@ load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, */ Rt_map * load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode, - uint_t flags, Grp_hdl ** hdl) + uint_t flags, Grp_hdl **hdl, int *in_nfavl) { Rej_desc rej = { 0 }; Pnode *tpnp; @@ -2384,13 +2458,14 @@ load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode, */ if (tpnp->p_orig & PN_TKN_HWCAP) { if ((tlmp = load_hwcap(lml, lmco, tpnp->p_name, clmp, - mode, (flags | FLG_RT_HWCAP), hdl, &rej)) != 0) { + mode, (flags | FLG_RT_HWCAP), hdl, &rej, + in_nfavl)) != 0) { remove_rej(&rej); return (tlmp); } } else { if ((tlmp = load_path(lml, lmco, &tpnp->p_name, clmp, - mode, flags, hdl, 0, &rej)) != 0) { + mode, flags, hdl, 0, &rej, in_nfavl)) != 0) { remove_rej(&rej); return (tlmp); } @@ -2436,7 +2511,7 @@ is_sym_interposer(Rt_map *lmp, Sym *sym) */ static Sym * lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml, - Sym *osym) + Sym *osym, int *in_nfavl) { Rt_map *lmp; Slookup sl; @@ -2494,8 +2569,8 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml, * executable, that the size and type of symbol are the same, * and that the symbol is also associated with .bss. */ - if (((isym = SYMINTP(lmp)(&sl, &ilmp, binfo)) != NULL) && - (isym->st_size == osym->st_size) && + if (((isym = SYMINTP(lmp)(&sl, &ilmp, binfo, + in_nfavl)) != NULL) && (isym->st_size == osym->st_size) && (isym->st_info == osym->st_info) && copy_zerobits(lmp, isym)) { *dlmp = lmp; @@ -2530,7 +2605,7 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml, Sym *isym; sl.sl_imap = lmp; - if (isym = SYMINTP(lmp)(&sl, &ilmp, binfo)) { + if (isym = SYMINTP(lmp)(&sl, &ilmp, binfo, in_nfavl)) { /* * If this object provides individual symbol * interposers, make sure that the symbol we @@ -2560,7 +2635,7 @@ lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml, */ static Sym * lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, - Rt_map *lmp) + Rt_map *lmp, int *in_nfavl) { Rt_map *clmp = slp->sl_cmap; Sym *sym; @@ -2585,7 +2660,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, (sip->si_flags & SYMINFO_FLG_COPY)) { slp->sl_imap = LIST(clmp)->lm_head; - if (sym = SYMINTP(clmp)(slp, dlmp, binfo)) + if (sym = SYMINTP(clmp)(slp, dlmp, binfo, in_nfavl)) *binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF); return (sym); } @@ -2609,7 +2684,8 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, */ for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) { sl.sl_imap = lmp = bdp->b_caller; - if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo)) != NULL) + if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo, + in_nfavl)) != NULL) goto found; } @@ -2629,7 +2705,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, continue; sl.sl_imap = lmp = gdp->gd_depend; if ((sym = SYMINTP(lmp)(&sl, dlmp, - binfo)) != NULL) + binfo, in_nfavl)) != NULL) goto found; } } @@ -2644,7 +2720,7 @@ lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, sl.sl_imap = lmp; if (lmp) - sym = SYMINTP(lmp)(&sl, dlmp, binfo); + sym = SYMINTP(lmp)(&sl, dlmp, binfo, in_nfavl); } found: if (sym) @@ -2659,7 +2735,7 @@ found: Sym *isym; if ((isym = lookup_sym_interpose(slp, dlmp, binfo, - LIST(*dlmp), sym)) != 0) + LIST(*dlmp), sym, in_nfavl)) != 0) return (isym); } @@ -2668,7 +2744,7 @@ found: static Sym * core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, - Aliste off) + Aliste off, int *in_nfavl) { Rt_map *lmp; @@ -2686,8 +2762,8 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, Sym *sym; slp->sl_imap = lmp; - if (((sym = SYMINTP(lmp)(slp, dlmp, binfo)) != NULL) || - (*binfo & BINFO_REJSINGLE)) + if (((sym = SYMINTP(lmp)(slp, dlmp, binfo, + in_nfavl)) != NULL) || (*binfo & BINFO_REJSINGLE)) return (sym); } } @@ -2695,7 +2771,8 @@ core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, } static Sym * -_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo) +_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, + int *in_nfavl) { Rt_map *lmp; @@ -2706,7 +2783,8 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo) Sym *sym; slp->sl_imap = lmp; - if ((sym = elf_lazy_find_sym(slp, dlmp, binfo)) != 0) + if ((sym = elf_lazy_find_sym(slp, dlmp, binfo, + in_nfavl)) != 0) return (sym); } } @@ -2714,7 +2792,7 @@ _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo) } static Sym * -_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) +_lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl) { const char *name = slp->sl_name; Rt_map *clmp = slp->sl_cmap; @@ -2732,7 +2810,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) * the link map). */ if (slp->sl_flags & LKUP_FIRST) - return (SYMINTP(ilmp)(slp, dlmp, binfo)); + return (SYMINTP(ilmp)(slp, dlmp, binfo, in_nfavl)); /* * Determine whether this lookup can be satisfied by an objects direct, @@ -2773,7 +2851,8 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) lmp = 0; if (bound < SYMINFO_BT_LOWRESERVE) - lmp = elf_lazy_load(clmp, slp, bound, name); + lmp = elf_lazy_load(clmp, slp, bound, + name, in_nfavl); /* * If direct bindings have been disabled, and this isn't @@ -2792,7 +2871,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) ((FLAGS1(clmp) & FL1_RT_DIRECT) || (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) { sym = lookup_sym_direct(slp, dlmp, binfo, - sip, lmp); + sip, lmp, in_nfavl); /* * Determine whether this direct binding has @@ -2831,7 +2910,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) && ((sl.sl_flags & LKUP_SINGLETON) == 0)) { sl.sl_imap = clmp; - if (sym = SYMINTP(clmp)(&sl, dlmp, binfo)) { + if (sym = SYMINTP(clmp)(&sl, dlmp, binfo, in_nfavl)) { ulong_t dsymndx = (((ulong_t)sym - (ulong_t)SYMTAB(*dlmp)) / SYMENT(*dlmp)); @@ -2864,12 +2943,13 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) { if (((sym = core_lookup_sym(lmc->lc_head, &sl, dlmp, - binfo, off)) != NULL) || + binfo, off, in_nfavl)) != NULL) || (*binfo & BINFO_REJSINGLE)) break; } } else - sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA); + sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA, + in_nfavl); /* * If a symbol binding was rejected, because a binding occurred to a @@ -2903,7 +2983,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) * initial link-map. */ if (sl.sl_flags & LKUP_NEXT) - sym = _lazy_find_sym(clmp, &sl, dlmp, binfo); + sym = _lazy_find_sym(clmp, &sl, dlmp, binfo, in_nfavl); else { Aliste idx; Lm_cntl *lmc; @@ -2911,7 +2991,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { sl.sl_flags |= LKUP_NOFALLBACK; if ((sym = _lazy_find_sym(lmc->lc_head, &sl, - dlmp, binfo)) != 0) + dlmp, binfo, in_nfavl)) != 0) break; } } @@ -2930,7 +3010,7 @@ _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) * locate the symbol, the a.out function will simply ignore it. */ Sym * -lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) +lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl) { Rt_map *clmp = slp->sl_cmap; Sym *rsym = slp->sl_rsym, *sym = 0; @@ -2980,7 +3060,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) * Carry out an initial symbol search. This search takes into account * all the modes of the requested search. */ - if (((sym = _lookup_sym(slp, dlmp, binfo)) == NULL) && + if (((sym = _lookup_sym(slp, dlmp, binfo, in_nfavl)) == NULL) && (*binfo & BINFO_REJSINGLE)) { Slookup sl = *slp; @@ -2994,7 +3074,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) sl.sl_flags |= LKUP_SINGLETON; sl.sl_rsymndx = 0; *binfo &= ~BINFO_REJECTED; - sym = _lookup_sym(&sl, dlmp, binfo); + sym = _lookup_sym(&sl, dlmp, binfo, in_nfavl); } /* @@ -3006,7 +3086,7 @@ lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo) Sym *isym; if ((isym = lookup_sym_interpose(slp, dlmp, binfo, LIST(*dlmp), - sym)) != 0) + sym, in_nfavl)) != 0) return (isym); } return (sym); |