rtld: Add directory mapping functionality
authorJohn Marino <draco@marino.st>
Sat, 30 Nov 2013 10:23:00 +0000 (11:23 +0100)
committerJohn Marino <draco@marino.st>
Sat, 30 Nov 2013 11:55:32 +0000 (12:55 +0100)
Partially taken from:
FreeBSD SVN 255765 (21 SEP 2013)

libexec/rtld-elf/libmap.c
libexec/rtld-elf/libmap.h
libexec/rtld-elf/rtld.c

index 96d305a..dcc896e 100644 (file)
@@ -296,7 +296,7 @@ lmc_parse(char *lm_p, size_t lm_len)
                else if (strcmp(f, "include") == 0)
                        lmc_parse_file(t);
                else
-               lm_add(p, f, t);
+                       lm_add(p, f, t);
        }
 }
 
@@ -389,6 +389,25 @@ lm_find (const char *p, const char *f)
                return (NULL);
 }
 
+/* Given a libmap translation list and a library name, return the
+   replacement library, or NULL */
+char *
+lm_findn (const char *p, const char *f, const int n)
+{
+       char pathbuf[64], *s, *t;
+
+       if (n < sizeof(pathbuf) - 1)
+               s = pathbuf;
+       else
+               s = xmalloc(n + 1);
+       memcpy(s, f, n);
+       s[n] = '\0';
+       t = lm_find(p, s);
+       if (s != pathbuf)
+               free(s);
+       return (t);
+}
+
 static char *
 lml_find (struct lm_list *lmh, const char *f)
 {
index 4e5f0f4..54b4a2f 100644 (file)
@@ -5,3 +5,4 @@
 int    lm_init (char *);
 void   lm_fini (void);
 char * lm_find (const char *, const char *);
+char * lm_findn (const char *, const char *, const int);
index 581aaff..1e0a6d4 100644 (file)
@@ -2707,9 +2707,14 @@ rtld_exit(void)
     lock_release(rtld_bind_lock, &lockstate);
 }
 
+/*
+ * Iterate over a search path, translate each element, and invoke the
+ * callback on the result.
+ */
 static void *
 path_enumerate(const char *path, path_enum_proc callback, void *arg)
 {
+    const char *trans;
     if (path == NULL)
        return (NULL);
 
@@ -2719,7 +2724,11 @@ path_enumerate(const char *path, path_enum_proc callback, void *arg)
        char  *res;
 
        len = strcspn(path, ":;");
-       res = callback(path, len, arg);
+       trans = lm_findn(NULL, path, len);
+       if (trans)
+           res = callback(trans, strlen(trans), arg);
+       else
+           res = callback(path, len, arg);
 
        if (res != NULL)
            return (res);