Author: kib
Date: Mon Sep 10 11:50:42 2012
New Revision: 240308
URL: http://svn.freebsd.org/changeset/base/240308

Log:
  MFC r238471:
  Implement DT_RUNPATH and -z nodefaultlib.
  
  MFC note: The ld_library_path_rpath default value was flipped to true,
  effectively reverting rtld back to the pre-patch behaviour, unless
  LD_LIBRARY_PATH_RPATH environment variable is set and its value is 0/N/n.

Modified:
  stable/9/libexec/rtld-elf/rtld.1
  stable/9/libexec/rtld-elf/rtld.c
  stable/9/libexec/rtld-elf/rtld.h
Directory Properties:
  stable/9/libexec/rtld-elf/   (props changed)

Modified: stable/9/libexec/rtld-elf/rtld.1
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.1    Mon Sep 10 11:43:28 2012        
(r240307)
+++ stable/9/libexec/rtld-elf/rtld.1    Mon Sep 10 11:50:42 2012        
(r240308)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 1, 2009
+.Dd June 28, 2012
 .Dt RTLD 1
 .Os
 .Sh NAME
@@ -86,14 +86,39 @@ dynamic linker.
 After the dynamic linker has finished loading,
 relocating, and initializing the program and its required shared
 objects, it transfers control to the entry point of the program.
+The following search order is used to locate required shared objects:
 .Pp
-To locate the required shared objects in the file system,
-.Nm
-may use a
-.Dq hints
-file prepared by the
+.Bl -enum -offset indent -compact
+.It
+.Dv DT_RPATH
+of the referencing object unless that object also contains a
+.Dv DT_RUNPATH
+tag
+.It
+.Dv DT_RPATH
+of the program unless the referencing object contains a
+.Dv DT_RUNPATH
+tag
+.It
+Path indicated by
+.Ev LD_LIBRARY_PATH
+environment variable
+.It
+.Dv DT_RUNPATH
+of the referencing object
+.It
+Hints file produced by the
 .Xr ldconfig 8
-utility.
+utility
+.It
+The
+.Pa /lib
+and
+.Pa /usr/lib
+directories, unless the referencing object was linked using the
+.Dq Fl z Ar nodefaultlib
+option
+.El
 .Pp
 The
 .Nm
@@ -143,6 +168,20 @@ This variable is unset for set-user-ID a
 A colon separated list of directories, overriding the default search path
 for shared libraries.
 This variable is unset for set-user-ID and set-group-ID programs.
+.It Ev LD_LIBRARY_PATH_RPATH
+If the variable is specified and has a value starting with
+any of \'y\', \'Y\' or \'1\' symbols, the path specified by
+.Ev LD_LIBRARY_PATH
+variable is allowed to override the path from
+.Dv DT_RPATH
+for binaries which does not contain
+.Dv DT_RUNPATH
+tag.
+For such binaries, when the variable
+.Ev LD_LIBRARY_PATH_RPATH
+is set,
+.Dq Fl z Ar nodefaultlib
+link-time option is ignored as well.
 .It Ev LD_PRELOAD
 A list of shared libraries, separated by colons and/or white space,
 to be linked in before any

Modified: stable/9/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.c    Mon Sep 10 11:43:28 2012        
(r240307)
+++ stable/9/libexec/rtld-elf/rtld.c    Mon Sep 10 11:50:42 2012        
(r240308)
@@ -80,8 +80,9 @@ typedef void * (*path_enum_proc) (const 
 static const char *basename(const char *);
 static void die(void) __dead2;
 static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
-    const Elf_Dyn **);
-static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *);
+    const Elf_Dyn **, const Elf_Dyn **);
+static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
+    const Elf_Dyn *);
 static void digest_dynamic(Obj_Entry *, int);
 static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
 static Obj_Entry *dlcheck(void *);
@@ -94,7 +95,7 @@ static void errmsg_restore(char *);
 static char *errmsg_save(void);
 static void *fill_search_info(const char *, size_t, void *);
 static char *find_library(const char *, const Obj_Entry *);
-static const char *gethints(void);
+static const char *gethints(bool);
 static void init_dag(Obj_Entry *);
 static void init_rtld(caddr_t, Elf_Auxinfo **);
 static void initlist_add_neededs(Needed_Entry *, Objlist *);
@@ -233,6 +234,8 @@ size_t tls_static_space;    /* Static TLS s
 int tls_dtv_generation = 1;    /* Used to detect when dtv size changes  */
 int tls_max_index = 1;         /* Largest module index allocated */
 
+bool ld_library_path_rpath = true;
+
 /*
  * Fill in a DoneList with an allocation large enough to hold all of
  * the currently-loaded objects.  Keep this as a macro since it calls
@@ -323,6 +326,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     Obj_Entry **preload_tail;
     Objlist initlist;
     RtldLockState lockstate;
+    char *library_path_rpath;
     int mib[2];
     size_t len;
 
@@ -394,7 +398,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
         if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") ||
            unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") ||
            unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") ||
-           unsetenv(LD_ "LOADFLTR")) {
+           unsetenv(LD_ "LOADFLTR") || unsetenv(LD_ "LIBRARY_PATH_RPATH")) {
                _rtld_error("environment corrupt; aborting");
                die();
        }
@@ -406,6 +410,15 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     ld_preload = getenv(LD_ "PRELOAD");
     ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
     ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL;
+    library_path_rpath = getenv(LD_ "LIBRARY_PATH_RPATH");
+    if (library_path_rpath != NULL) {
+           if (library_path_rpath[0] == 'y' ||
+               library_path_rpath[0] == 'Y' ||
+               library_path_rpath[0] == '1')
+                   ld_library_path_rpath = true;
+           else
+                   ld_library_path_rpath = false;
+    }
     dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
        (ld_library_path != NULL) || (ld_preload != NULL) ||
        (ld_elf_hints_path != NULL) || ld_loadfltr;
@@ -828,7 +841,7 @@ die(void)
  */
 static void
 digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
-    const Elf_Dyn **dyn_soname)
+    const Elf_Dyn **dyn_soname, const Elf_Dyn **dyn_runpath)
 {
     const Elf_Dyn *dynp;
     Needed_Entry **needed_tail = &obj->needed;
@@ -843,6 +856,7 @@ digest_dynamic1(Obj_Entry *obj, int earl
 
     *dyn_rpath = NULL;
     *dyn_soname = NULL;
+    *dyn_runpath = NULL;
 
     obj->bind_now = false;
     for (dynp = obj->dynamic;  dynp->d_tag != DT_NULL;  dynp++) {
@@ -1009,7 +1023,6 @@ digest_dynamic1(Obj_Entry *obj, int earl
            break;
 
        case DT_RPATH:
-       case DT_RUNPATH:        /* XXX: process separately */
            /*
             * We have to wait until later to process this, because we
             * might not have gotten the address of the string table yet.
@@ -1021,6 +1034,10 @@ digest_dynamic1(Obj_Entry *obj, int earl
            *dyn_soname = dynp;
            break;
 
+       case DT_RUNPATH:
+           *dyn_runpath = dynp;
+           break;
+
        case DT_INIT:
            obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
            break;
@@ -1114,6 +1131,8 @@ digest_dynamic1(Obj_Entry *obj, int earl
                    obj->z_nodelete = true;
                if (dynp->d_un.d_val & DF_1_LOADFLTR)
                    obj->z_loadfltr = true;
+               if (dynp->d_un.d_val & DF_1_NODEFLIB)
+                   obj->z_nodeflib = true;
            break;
 
        default:
@@ -1153,7 +1172,7 @@ digest_dynamic1(Obj_Entry *obj, int earl
 
 static void
 digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
-    const Elf_Dyn *dyn_soname)
+    const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath)
 {
 
     if (obj->z_origin && obj->origin_path == NULL) {
@@ -1162,7 +1181,12 @@ digest_dynamic2(Obj_Entry *obj, const El
            die();
     }
 
-    if (dyn_rpath != NULL) {
+    if (dyn_runpath != NULL) {
+       obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val;
+       if (obj->z_origin)
+           obj->runpath = origin_subst(obj->runpath, obj->origin_path);
+    }
+    else if (dyn_rpath != NULL) {
        obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val;
        if (obj->z_origin)
            obj->rpath = origin_subst(obj->rpath, obj->origin_path);
@@ -1177,9 +1201,10 @@ digest_dynamic(Obj_Entry *obj, int early
 {
        const Elf_Dyn *dyn_rpath;
        const Elf_Dyn *dyn_soname;
+       const Elf_Dyn *dyn_runpath;
 
-       digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname);
-       digest_dynamic2(obj, dyn_rpath, dyn_soname);
+       digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
+       digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath);
 }
 
 /*
@@ -1389,43 +1414,71 @@ gnu_hash(const char *s)
  * loaded shared object, whose library search path will be searched.
  *
  * The search order is:
+ *   DT_RPATH in the referencing file _unless_ DT_RUNPATH is present (1)
+ *   DT_RPATH of the main object if DSO without defined DT_RUNPATH (1)
  *   LD_LIBRARY_PATH
- *   rpath in the referencing file
- *   ldconfig hints
- *   /lib:/usr/lib
+ *   DT_RUNPATH in the referencing file
+ *   ldconfig hints (if -z nodefaultlib, filter out default library directories
+ *      from list)
+ *   /lib:/usr/lib _unless_ the referencing file is linked with -z nodefaultlib
+ *
+ * (1) Handled in digest_dynamic2 - rpath left NULL if runpath defined.
  */
 static char *
 find_library(const char *xname, const Obj_Entry *refobj)
 {
     char *pathname;
     char *name;
+    bool objgiven;
 
+    objgiven = refobj != NULL;
     if (strchr(xname, '/') != NULL) {  /* Hard coded pathname */
        if (xname[0] != '/' && !trust) {
            _rtld_error("Absolute pathname required for shared object \"%s\"",
              xname);
            return NULL;
        }
-       if (refobj != NULL && refobj->z_origin)
+       if (objgiven && refobj->z_origin)
            return origin_subst(xname, refobj->origin_path);
        else
            return xstrdup(xname);
     }
 
-    if (libmap_disable || (refobj == NULL) ||
+    if (libmap_disable || !objgiven ||
        (name = lm_find(refobj->path, xname)) == NULL)
        name = (char *)xname;
 
     dbg(" Searching for \"%s\"", name);
 
-    if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
-      (refobj != NULL &&
-      (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
-      (pathname = search_library_path(name, gethints())) != NULL ||
-      (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
-       return pathname;
+    /*
+     * If refobj->rpath != NULL, then refobj->runpath is NULL.  Fall
+     * back to pre-conforming behaviour if user requested so with
+     * LD_LIBRARY_PATH_RPATH environment variable and ignore -z
+     * nodeflib.
+     */
+    if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) {
+       if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
+         (refobj != NULL &&
+         (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
+          (pathname = search_library_path(name, gethints(false))) != NULL ||
+         (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
+           return (pathname);
+    } else {
+       if ((objgiven &&
+         (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
+         (objgiven && refobj->runpath == NULL && refobj != obj_main &&
+         (pathname = search_library_path(name, obj_main->rpath)) != NULL) ||
+         (pathname = search_library_path(name, ld_library_path)) != NULL ||
+         (objgiven &&
+         (pathname = search_library_path(name, refobj->runpath)) != NULL) ||
+         (pathname = search_library_path(name, gethints(refobj->z_nodeflib)))
+         != NULL ||
+         (objgiven && !refobj->z_nodeflib &&
+         (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != 
NULL))
+           return (pathname);
+    }
 
-    if(refobj != NULL && refobj->path != NULL) {
+    if (objgiven && refobj->path != NULL) {
        _rtld_error("Shared object \"%s\" not found, required by \"%s\"",
          name, basename(refobj->path));
     } else {
@@ -1520,41 +1573,142 @@ find_symdef(unsigned long symnum, const 
 
 /*
  * Return the search path from the ldconfig hints file, reading it if
- * necessary.  Returns NULL if there are problems with the hints file,
+ * necessary.  If nostdlib is true, then the default search paths are
+ * not added to result.
+ *
+ * Returns NULL if there are problems with the hints file,
  * or if the search path there is empty.
  */
 static const char *
-gethints(void)
+gethints(bool nostdlib)
 {
-    static char *hints;
-
-    if (hints == NULL) {
-       int fd;
+       static char *hints, *filtered_path;
        struct elfhints_hdr hdr;
+       struct fill_search_info_args sargs, hargs;
+       struct dl_serinfo smeta, hmeta, *SLPinfo, *hintinfo;
+       struct dl_serpath *SLPpath, *hintpath;
        char *p;
+       unsigned int SLPndx, hintndx, fndx, fcount;
+       int fd;
+       size_t flen;
+       bool skip;
 
-       /* Keep from trying again in case the hints file is bad. */
-       hints = "";
-
-       if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1)
-           return NULL;
-       if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
-         hdr.magic != ELFHINTS_MAGIC ||
-         hdr.version != 1) {
-           close(fd);
-           return NULL;
+       /* First call, read the hints file */
+       if (hints == NULL) {
+               /* Keep from trying again in case the hints file is bad. */
+               hints = "";
+
+               if ((fd = open(ld_elf_hints_path, O_RDONLY)) == -1)
+                       return (NULL);
+               if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
+                   hdr.magic != ELFHINTS_MAGIC ||
+                   hdr.version != 1) {
+                       close(fd);
+                       return (NULL);
+               }
+               p = xmalloc(hdr.dirlistlen + 1);
+               if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
+                   read(fd, p, hdr.dirlistlen + 1) !=
+                   (ssize_t)hdr.dirlistlen + 1) {
+                       free(p);
+                       close(fd);
+                       return (NULL);
+               }
+               hints = p;
+               close(fd);
        }
-       p = xmalloc(hdr.dirlistlen + 1);
-       if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
-         read(fd, p, hdr.dirlistlen + 1) != (ssize_t)hdr.dirlistlen + 1) {
-           free(p);
-           close(fd);
-           return NULL;
+
+       /*
+        * If caller agreed to receive list which includes the default
+        * paths, we are done. Otherwise, if we still did not
+        * calculated filtered result, do it now.
+        */
+       if (!nostdlib)
+               return (hints[0] != '\0' ? hints : NULL);
+       if (filtered_path != NULL)
+               goto filt_ret;
+
+       /*
+        * Obtain the list of all configured search paths, and the
+        * list of the default paths.
+        *
+        * First estimate the size of the results.
+        */
+       smeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
+       smeta.dls_cnt = 0;
+       hmeta.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
+       hmeta.dls_cnt = 0;
+
+       sargs.request = RTLD_DI_SERINFOSIZE;
+       sargs.serinfo = &smeta;
+       hargs.request = RTLD_DI_SERINFOSIZE;
+       hargs.serinfo = &hmeta;
+
+       path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs);
+       path_enumerate(p, fill_search_info, &hargs);
+
+       SLPinfo = xmalloc(smeta.dls_size);
+       hintinfo = xmalloc(hmeta.dls_size);
+
+       /*
+        * Next fetch both sets of paths.
+        */
+       sargs.request = RTLD_DI_SERINFO;
+       sargs.serinfo = SLPinfo;
+       sargs.serpath = &SLPinfo->dls_serpath[0];
+       sargs.strspace = (char *)&SLPinfo->dls_serpath[smeta.dls_cnt];
+
+       hargs.request = RTLD_DI_SERINFO;
+       hargs.serinfo = hintinfo;
+       hargs.serpath = &hintinfo->dls_serpath[0];
+       hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt];
+
+       path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &sargs);
+       path_enumerate(p, fill_search_info, &hargs);
+
+       /*
+        * Now calculate the difference between two sets, by excluding
+        * standard paths from the full set.
+        */
+       fndx = 0;
+       fcount = 0;
+       filtered_path = xmalloc(hdr.dirlistlen + 1);
+       hintpath = &hintinfo->dls_serpath[0];
+       for (hintndx = 0; hintndx < hmeta.dls_cnt; hintndx++, hintpath++) {
+               skip = false;
+               SLPpath = &SLPinfo->dls_serpath[0];
+               /*
+                * Check each standard path against current.
+                */
+               for (SLPndx = 0; SLPndx < smeta.dls_cnt; SLPndx++, SLPpath++) {
+                       /* matched, skip the path */
+                       if (!strcmp(hintpath->dls_name, SLPpath->dls_name)) {
+                               skip = true;
+                               break;
+                       }
+               }
+               if (skip)
+                       continue;
+               /*
+                * Not matched against any standard path, add the path
+                * to result. Separate consequtive paths with ':'.
+                */
+               if (fcount > 0) {
+                       filtered_path[fndx] = ':';
+                       fndx++;
+               }
+               fcount++;
+               flen = strlen(hintpath->dls_name);
+               strncpy((filtered_path + fndx), hintpath->dls_name, flen);
+               fndx += flen;
        }
-       hints = p;
-       close(fd);
-    }
-    return hints[0] != '\0' ? hints : NULL;
+       filtered_path[fndx] = '\0';
+
+       free(SLPinfo);
+       free(hintinfo);
+
+filt_ret:
+       return (filtered_path[0] != '\0' ? filtered_path : NULL);
 }
 
 static void
@@ -1620,6 +1774,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo *
     Obj_Entry objtmp;  /* Temporary rtld object */
     const Elf_Dyn *dyn_rpath;
     const Elf_Dyn *dyn_soname;
+    const Elf_Dyn *dyn_runpath;
 
     /*
      * Conjure up an Obj_Entry structure for the dynamic linker.
@@ -1636,7 +1791,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo *
 #endif
     if (RTLD_IS_DYNAMIC()) {
        objtmp.dynamic = rtld_dynamic(&objtmp);
-       digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname);
+       digest_dynamic1(&objtmp, 1, &dyn_rpath, &dyn_soname, &dyn_runpath);
        assert(objtmp.needed == NULL);
 #if !defined(__mips__)
        /* MIPS has a bogus DT_TEXTREL. */
@@ -1662,7 +1817,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo *
     if (aux_info[AT_OSRELDATE] != NULL)
            osreldate = aux_info[AT_OSRELDATE]->a_un.a_val;
 
-    digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname);
+    digest_dynamic2(&obj_rtld, dyn_rpath, dyn_soname, dyn_runpath);
 
     /* Replace the path with a dynamically allocated copy. */
     obj_rtld.path = xstrdup(PATH_RTLD);
@@ -3091,14 +3246,6 @@ dl_iterate_phdr(__dl_iterate_hdr_callbac
     return (error);
 }
 
-struct fill_search_info_args {
-    int                 request;
-    unsigned int flags;
-    Dl_serinfo  *serinfo;
-    Dl_serpath  *serpath;
-    char       *strspace;
-};
-
 static void *
 fill_search_info(const char *dir, size_t dirlen, void *param)
 {
@@ -3108,7 +3255,7 @@ fill_search_info(const char *dir, size_t
 
     if (arg->request == RTLD_DI_SERINFOSIZE) {
        arg->serinfo->dls_cnt ++;
-       arg->serinfo->dls_size += sizeof(Dl_serpath) + dirlen + 1;
+       arg->serinfo->dls_size += sizeof(struct dl_serpath) + dirlen + 1;
     } else {
        struct dl_serpath *s_entry;
 
@@ -3138,10 +3285,12 @@ do_search_info(const Obj_Entry *obj, int
     _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
     _info.dls_cnt  = 0;
 
-    path_enumerate(ld_library_path, fill_search_info, &args);
     path_enumerate(obj->rpath, fill_search_info, &args);
-    path_enumerate(gethints(), fill_search_info, &args);
-    path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args);
+    path_enumerate(ld_library_path, fill_search_info, &args);
+    path_enumerate(obj->runpath, fill_search_info, &args);
+    path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args);
+    if (!obj->z_nodeflib)
+      path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args);
 
 
     if (request == RTLD_DI_SERINFOSIZE) {
@@ -3160,20 +3309,26 @@ do_search_info(const Obj_Entry *obj, int
     args.serpath  = &info->dls_serpath[0];
     args.strspace = (char *)&info->dls_serpath[_info.dls_cnt];
 
+    args.flags = LA_SER_RUNPATH;
+    if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL)
+       return (-1);
+
     args.flags = LA_SER_LIBPATH;
     if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL)
        return (-1);
 
     args.flags = LA_SER_RUNPATH;
-    if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL)
+    if (path_enumerate(obj->runpath, fill_search_info, &args) != NULL)
        return (-1);
 
     args.flags = LA_SER_CONFIG;
-    if (path_enumerate(gethints(), fill_search_info, &args) != NULL)
+    if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args)
+      != NULL)
        return (-1);
 
     args.flags = LA_SER_DEFAULT;
-    if (path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL)
+    if (!obj->z_nodeflib &&
+      path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL)
        return (-1);
     return (0);
 }

Modified: stable/9/libexec/rtld-elf/rtld.h
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.h    Mon Sep 10 11:43:28 2012        
(r240307)
+++ stable/9/libexec/rtld-elf/rtld.h    Mon Sep 10 11:50:42 2012        
(r240308)
@@ -222,6 +222,7 @@ typedef struct Struct_Obj_Entry {
     const Elf_Hashelt *chain_zero_gnu; /* GNU hash table value array (Zeroed) 
*/
 
     char *rpath;               /* Search path specified in object */
+    char *runpath;             /* Search path with different priority */
     Needed_Entry *needed;      /* Shared objects needed by this one (%) */
     Needed_Entry *needed_filtees;
     Needed_Entry *needed_aux_filtees;
@@ -258,6 +259,7 @@ typedef struct Struct_Obj_Entry {
     bool z_nodelete : 1;       /* Do not unload the object and dependencies */
     bool z_noopen : 1;         /* Do not load on dlopen */
     bool z_loadfltr : 1;       /* Immediately load filtees */
+    bool z_nodeflib : 1;       /* Don't search default library path */
     bool ref_nodel : 1;                /* Refcount increased to prevent 
dlclose */
     bool init_scanned: 1;      /* Object is already on init list. */
     bool on_fini_list: 1;      /* Object is already on fini list. */
@@ -321,6 +323,14 @@ struct Struct_RtldLockState {
        sigjmp_buf env;
 };
 
+struct fill_search_info_args {
+       int request;
+       unsigned int flags;
+       struct dl_serinfo *serinfo;
+       struct dl_serpath *serpath;
+       char *strspace;
+};
+
 /*
  * The pack of arguments and results for the symbol lookup functions.
  */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to