Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Feb 2010 15:45:25 GMT
From:      Jonathan Anderson <jona@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 174095 for review
Message-ID:  <201002011545.o11FjPiR075012@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=174095

Change 174095 by jona@jona-belle-freebsd8 on 2010/02/01 15:45:08

	Implementation of ld_libdirs()

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/Symbol.map#4 edit
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#32 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/Symbol.map#4 (text+ko) ====

@@ -18,6 +18,10 @@
     __tls_get_addr;
 };
 
+FBSD_1.2 {
+    ld_libdirs;
+};
+
 FBSDprivate_1.0 {
     _rtld_thread_init;
     _rtld_allocate_tls;

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#32 (text+ko) ====

@@ -78,6 +78,8 @@
 #endif
 #endif
 
+#define INITIAL_FDLEN	16
+
 /* Types. */
 typedef void (*func_ptr_type)();
 typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
@@ -167,6 +169,8 @@
 static int  object_match_name(const Obj_Entry *, const char *);
 static void ld_utrace_log(int, void *, void *, size_t, int, const char *);
 
+int ld_libdirs(int *, int *);
+
 void r_debug_state(struct r_debug *, struct link_map *);
 
 /*
@@ -183,6 +187,8 @@
 				   used to affect the libraries loaded */
 static char *ld_bind_now;	/* Environment variable for immediate binding */
 static char *ld_debug;		/* Environment variable for debugging */
+static int *ld_library_dirs = NULL; /* File descriptors of lib path (end: -1) */
+static int ld_library_dirlen;	/* Capacity of ld_library_dirs */
 #ifndef IN_RTLD_CAP
 static char *ld_library_path;	/* Environment variable for search path */
 static char *ld_preload;	/* Environment variable for libraries to
@@ -249,6 +255,8 @@
     (func_ptr_type) &ld_libcache_lookup,
     (func_ptr_type) &ld_insandbox,
 #endif
+    (func_ptr_type) &ld_libdirs,
+ 
     NULL
 };
 
@@ -2020,6 +2028,7 @@
 
     return (NULL);
 }
+#endif
 
 struct try_library_args {
     const char	*name;
@@ -2055,6 +2064,7 @@
     return (NULL);
 }
 
+#ifndef IN_RTLD_CAP
 static char *
 search_library_path(const char *name, const char *path)
 {
@@ -2077,6 +2087,124 @@
 }
 #endif
 
+/*
+ * Add a file descriptor to ld_library_dirs.
+ */
+static void
+add_libdir_fd(int fd) {
+
+	if (ld_library_dirs == NULL) {
+	    /* Initialize the FD list. */
+
+	    ld_library_dirlen = INITIAL_FDLEN;
+	    ld_library_dirs = xmalloc(ld_library_dirlen * sizeof(int));
+	    memset(ld_library_dirs, 0xff, ld_library_dirlen * sizeof(int));
+	}
+
+	/* Find the next available FD slot. */
+	int i;
+	for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) ;
+
+	if (i == ld_library_dirlen) {
+	    /* We need more space. */
+	    int old_size = ld_library_dirlen + sizeof(int);
+
+	    ld_library_dirlen *= 2;
+	    ld_library_dirs = realloc(ld_library_dirs, 2 * old_size);
+	    memset(ld_library_dirs + old_size, 0xff, old_size);
+
+	    if (ld_library_dirs == NULL)
+		err(-1, "realloc() failed");
+	}
+
+	ld_library_dirs[i] = fd;
+}
+
+/*
+ * Add file descriptors for a path list (e.g. '/lib:/usr/lib') to ld_library_dirs.
+ */
+static void
+add_libdir_paths(const char *path) {
+
+    char *pathcopy, *dirname, *tokcontext;
+    int pathlen = strnlen(path, PATH_MAX);
+
+    pathcopy = malloc(pathlen + 1);
+    strncpy(pathcopy, path, pathlen + 1);
+
+    for (dirname = strtok_r(pathcopy, ":", &tokcontext); dirname;
+         dirname = strtok_r(NULL, ":", &tokcontext)) {
+
+	int fd;
+
+	struct try_library_args arg;
+	arg.name = "";
+	arg.namelen = 0;
+	arg.buffer = xmalloc(PATH_MAX);
+	arg.buflen = PATH_MAX;
+
+	if (try_library_path(dirname, strnlen(dirname, PATH_MAX), &arg))
+	    fd = open(dirname, O_RDONLY);
+
+	else {
+	    /* 'dirname' is not a directory path; perhaps it's a descriptor? */
+	    fd = (int) strtol(dirname, NULL, 0);
+	    if ((fd == 0) && (errno == 0))
+		    continue;
+	}
+
+	if (fd >= 0)
+	    add_libdir_fd(fd);
+    }
+
+    free(pathcopy);
+}
+
+/*
+ * Return an array of file descriptors for the library search paths.
+ */
+int
+ld_libdirs(int *fds, int *fdcount) {
+
+	if (fdcount == NULL)
+	    return (-1);
+
+	else if (fds == NULL) {
+	    *fdcount = -1;
+	    return (-1);
+	}
+
+	if (ld_library_dirs == NULL) {
+#ifdef IN_RTLD_CAP
+
+	    char *envvar = getenv(LD_ "LIBRARY_DIRS");
+	    if (envvar == NULL)
+		err(-1, "No %s set in capability mode", LD_ "LIBRARY_DIRS");
+
+	    add_libdir_paths(envvar);
+
+#else /* !IN_RTLD_CAP */
+
+	    /* Look for directories a la find_library (TODO: refactor!). */
+	    add_libdir_paths(ld_library_path);
+	    add_libdir_paths(gethints());
+	    add_libdir_paths(STANDARD_LIBRARY_PATH);
+#endif
+	}
+
+	int i = 0;
+	for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) ;
+
+	if (*fdcount < i) {
+		*fdcount = i;
+		return (-1);
+	}
+
+	*fdcount = i;
+	memcpy(fds, ld_library_dirs, i * sizeof(int));
+	return 0;
+}
+
 int
 dlclose(void *handle)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002011545.o11FjPiR075012>