Well, here's a short patch to add the necessarily functionality to
/var/run/ld-elf.so.hints and /usr/libexec/ld-elf.so.1.  If this is
acceptable, /sbin/ldconfig would need to be patched.

Looks like the major bug is that if you preload libraries globally you
break linux binary compatibility.

On Tue, 30 Oct 2001, Lamont Granquist wrote:
> Is there anything in FreeBSD that gives this functionality?  My reading of
> src/libexec/rtld-elf/rtld.c in both -stable and -current seems to indicate
> that there isn't any such functionality (i need the global functionality
> that LD_PRELOAD doesn't give me).  I'd be willing to write a patch for it,
> but I'd need some guidance on what would be a proper way to fix it.
>
> I'm thinking of a patch to ldconfig to get /etc/ld.so.preload into the
> hints file and then to hack gethints() in rtld.c to take an argument
> indicating which path you want to return.
>
>
>
> To Unsubscribe: send mail to [EMAIL PROTECTED]
> with "unsubscribe freebsd-hackers" in the body of the message
>
>
--- include/elf-hints.h~        Tue Oct 30 18:29:57 2001
+++ include/elf-hints.h Tue Oct 30 18:31:47 2001
@@ -40,7 +40,10 @@
        u_int32_t       dirlist;        /* Offset of directory list in
                                           string table */
        u_int32_t       dirlistlen;     /* strlen(dirlist) */
-       u_int32_t       spare[26];      /* Room for expansion */
+       u_int32_t       preloadlist;    /* Offset of preload list in 
+                                          string table */
+       u_int32_t       preloadlistlen; /* strlen(preloadlist) */
+       u_int32_t       spare[24];      /* Room for expansion */
 };
 
 #define ELFHINTS_MAGIC 0x746e6845
--- libexec/rtld-elf/rtld.c~    Tue Oct 30 18:28:00 2001
+++ libexec/rtld-elf/rtld.c     Tue Oct 30 21:06:39 2001
@@ -52,8 +52,10 @@
 #include "debug.h"
 #include "rtld.h"
 
-#define END_SYM                "_end"
-#define PATH_RTLD      "/usr/libexec/ld-elf.so.1"
+#define END_SYM                        "_end"
+#define PATH_RTLD              "/usr/libexec/ld-elf.so.1"
+#define HINT_LIBRARY_PATH      0x01
+#define HINT_PRELOAD           0x02
 
 /* Types. */
 typedef void (*func_ptr_type)();
@@ -80,7 +82,7 @@
 static void errmsg_restore(char *);
 static char *errmsg_save(void);
 static char *find_library(const char *, const Obj_Entry *);
-static const char *gethints(void);
+static char *gethints(int);
 static void init_dag(Obj_Entry *);
 static void init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *);
 static void init_rtld(caddr_t);
@@ -91,7 +93,7 @@
 static void linkmap_add(Obj_Entry *);
 static void linkmap_delete(Obj_Entry *);
 static int load_needed_objects(Obj_Entry *);
-static int load_preload_objects(void);
+static int load_preload_objects(char *);
 static Obj_Entry *load_object(char *);
 static void lock_check(void);
 static Obj_Entry *obj_from_addr(const void *);
@@ -359,7 +361,9 @@
     sym_zero.st_shndx = SHN_ABS;
 
     dbg("loading LD_PRELOAD libraries");
-    if (load_preload_objects() == -1)
+    if (load_preload_objects(ld_preload) == -1)
+       die();
+    if (load_preload_objects(gethints(HINT_PRELOAD)) == -1)
        die();
     preload_tail = obj_tail;
 
@@ -805,7 +809,7 @@
     if ((refobj != NULL &&
       (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
       (pathname = search_library_path(name, ld_library_path)) != NULL ||
-      (pathname = search_library_path(name, gethints())) != NULL ||
+      (pathname = search_library_path(name, gethints(HINT_LIBRARY_PATH))) != NULL ||
       (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
        return pathname;
 
@@ -873,18 +877,20 @@
  * necessary.  Returns NULL if there are problems with the hints file,
  * or if the search path there is empty.
  */
-static const char *
-gethints(void)
+static char *
+gethints(int hintflag)
 {
-    static char *hints;
+    static char *preload;
+    static char *library_path;
 
-    if (hints == NULL) {
+    if ((library_path == NULL) || (preload == NULL)) {
        int fd;
        struct elfhints_hdr hdr;
        char *p;
 
        /* Keep from trying again in case the hints file is bad. */
-       hints = "";
+       library_path = "";
+       preload = "";
 
        if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
            return NULL;
@@ -901,10 +907,25 @@
            close(fd);
            return NULL;
        }
-       hints = p;
+       library_path = p;
+       p = xmalloc(hdr.preloadlistlen + 1);
+       if (lseek(fd, hdr.strtab + hdr.preloadlist, SEEK_SET) == -1 ||
+         read(fd, p, hdr.preloadlistlen + 1) != hdr.preloadlistlen + 1) {
+           free(p);
+           close(fd);
+           return NULL;
+       }
+       preload = p;
        close(fd);
     }
-    return hints[0] != '\0' ? hints : NULL;
+    switch (hintflag) {
+       case HINT_LIBRARY_PATH:
+          return library_path[0] != '\0' ? library_path : NULL;
+       case HINT_PRELOAD:
+          return preload[0] != '\0' ? preload : NULL;
+       default:
+         return NULL;
+    }
 }
 
 static void
@@ -1077,9 +1098,8 @@
 }
 
 static int
-load_preload_objects(void)
+load_preload_objects(char *p)
 {
-    char *p = ld_preload;
     static const char delim[] = " \t:;";
 
     if (p == NULL)

Reply via email to