From 3f47c82a7f19d659d0b8e24ac47653f25005ed25 Mon Sep 17 00:00:00 2001 From: John Polstra Date: Sat, 7 Nov 1998 01:59:39 +0000 Subject: [PATCH] Fix a bug in the handling of minor version numbers. Formerly, the rtld would accept the first shared library it found with the right major version number, even if the minor version number was too low. If a different version of the shared library with an adequate minor version number appeared later in the search path, it would not be found. Now the rtld searches all locations first looking for a library with a minor version that is high enough. Only if such a library is not found will it fall back to accepting a minor version number that is too low. As before, a warning comes out in that case. This solves some problems encountered when building an older world on a -current system. --- libexec/rtld-aout/rtld.c | 47 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c index 5e7843ef3868..eff59b6a2a20 100644 --- a/libexec/rtld-aout/rtld.c +++ b/libexec/rtld-aout/rtld.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.55 1998/06/21 14:22:29 mckay Exp $ + * $Id: rtld.c,v 1.56 1998/08/22 15:51:41 mckay Exp $ */ #include @@ -241,7 +241,7 @@ static void init_internal_malloc __P((void)); static void init_external_malloc __P((void)); static int call_map __P((struct so_map *, char *)); static char *findhint __P((char *, int, int *)); -static char *rtfindlib __P((char *, int, int)); +static char *rtfindlib __P((char *, int, int, int)); static char *rtfindfile __P((const char *)); void binder_entry __P((void)); long binder __P((jmpslot_t *)); @@ -890,8 +890,21 @@ map_sods(parent) struct so_map *smp = NULL; if(sodp->sod_library) { + /* + * First try for a match with an adequate minor + * number. + */ path = rtfindlib(name, sodp->sod_major, - sodp->sod_minor); + sodp->sod_minor, 1); + /* + * If none was found, try for just a major version + * match. A warning is issued by rtfindlib in + * this case, since the minor version number isn't + * really high enough. + */ + if (path == NULL) + path = rtfindlib(name, sodp->sod_major, + sodp->sod_minor, 0); if(path == NULL && !ld_tracing) { generror ("Can't find shared library" " \"lib%s.so.%d.%d\"", name, @@ -1827,8 +1840,11 @@ hinthash(cp, vmajor) * returns the full pathname of the matching library. This string is * always dynamically allocated on the heap. * - * Returns the minor number of the matching library via the pointer - * argument MINORP. + * MINORP is an in/out parameter. If the incoming value of *MINORP is + * >= 0, then no library will be considered a match unless its minor + * version number is at least that large. Otherwise, only the major + * version number is checked. In any case, the minor number of the + * matching library is stored into *MINORP. * * Returns NULL if the library cannot be found. */ @@ -1851,20 +1867,23 @@ findhint(name, major, minorp) warnx("Bad path index: %#x\n", bp->hi_pathx); break; } - /* - * We accept the current hints entry if its name matches - * and its major number matches. We don't have to search - * for the best minor number, because that was already - * done by "ldconfig" when it built the hints file. + * For a given major number, the hints file has only one + * entry -- namely, the one with the highest minor number. + * If we find an entry with a matching major number, we + * know it is the best one. */ if (strcmp(name, hstrtab + bp->hi_namex) == 0 && bp->hi_major == major) { struct stat s; + int realminor; + realminor = bp->hi_ndewey >= 2 ? bp->hi_minor : 0; + if (realminor < *minorp) /* Not good enough */ + return NULL; if (stat(hstrtab + bp->hi_pathx, &s) == -1) return NULL; /* Doesn't actually exist */ - *minorp = bp->hi_ndewey >= 2 ? bp->hi_minor : -1; + *minorp = realminor; return strdup(hstrtab + bp->hi_pathx); } @@ -1887,14 +1906,16 @@ findhint(name, major, minorp) * Returns NULL if the library cannot be found. */ static char * -rtfindlib(name, major, minor) +rtfindlib(name, major, minor, strictminor) char *name; int major, minor; + int strictminor; { char *ld_path = ld_library_path; char *path = NULL; - int realminor = -1; + int realminor; + realminor = strictminor ? minor : -1; if (ld_path != NULL) { /* First, search the directories in ld_path */ /* * There is no point in trying to use the hints file for this.