Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Mar 2012 12:16:08 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232862 - head/libexec/rtld-elf
Message-ID:  <201203121216.q2CCG8gG061304@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Mar 12 12:16:08 2012
New Revision: 232862
URL: http://svn.freebsd.org/changeset/base/232862

Log:
  Rtld on diet part 2:
  
  Do not use stdio for libmap.conf read.  Directly map the file and
  parse lines from the mappings.
  
  Reviewed by:	kan
  MFC after:	3 weeks

Modified:
  head/libexec/rtld-elf/libmap.c

Modified: head/libexec/rtld-elf/libmap.c
==============================================================================
--- head/libexec/rtld-elf/libmap.c	Mon Mar 12 12:15:47 2012	(r232861)
+++ head/libexec/rtld-elf/libmap.c	Mon Mar 12 12:16:08 2012	(r232862)
@@ -2,11 +2,14 @@
  * $FreeBSD$
  */
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/queue.h>
 #include <sys/param.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "debug.h"
 #include "rtld.h"
@@ -25,7 +28,6 @@ TAILQ_HEAD(lm_list, lm);
 struct lm {
 	char *f;
 	char *t;
-
 	TAILQ_ENTRY(lm)	lm_link;
 };
 
@@ -37,17 +39,15 @@ struct lmp {
 	TAILQ_ENTRY(lmp) lmp_link;
 };
 
-static int	lm_count;
+static int lm_count;
 
-static void		lmc_parse	(FILE *);
-static void		lm_add		(const char *, const char *, const char *);
-static void		lm_free		(struct lm_list *);
-static char *		lml_find	(struct lm_list *, const char *);
-static struct lm_list *	lmp_find	(const char *);
-static struct lm_list *	lmp_init	(char *);
-static const char * quickbasename	(const char *);
-static int	readstrfn	(void * cookie, char *buf, int len);
-static int	closestrfn	(void * cookie);
+static void lmc_parse(char *, size_t);
+static void lm_add(const char *, const char *, const char *);
+static void lm_free(struct lm_list *);
+static char *lml_find(struct lm_list *, const char *);
+static struct lm_list *lmp_find(const char *);
+static struct lm_list *lmp_init(char *);
+static const char *quickbasename(const char *);
 
 #define	iseol(c)	(((c) == '#') || ((c) == '\0') || \
 			 ((c) == '\n') || ((c) == '\r'))
@@ -59,56 +59,88 @@ static int	closestrfn	(void * cookie);
 #define	rtld_isspace(c)	((c) == ' ' || (c) == '\t')
 
 int
-lm_init (char *libmap_override)
+lm_init(char *libmap_override)
 {
-	FILE	*fp;
-
-	dbg("%s(\"%s\")", __func__, libmap_override);
+	struct stat st;
+	char *lm_map, *p;
+	int fd;
 
+	dbg("lm_init(\"%s\")", libmap_override);
 	TAILQ_INIT(&lmp_head);
 
-	fp = fopen(_PATH_LIBMAP_CONF, "r");
-	if (fp) {
-		lmc_parse(fp);
-		fclose(fp);
+	fd = open(_PATH_LIBMAP_CONF, O_RDONLY);
+	if (fd == -1) {
+		dbg("lm_init: open(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+		    strerror(errno));
+		goto override;
+	}
+	if (fstat(fd, &st) == -1) {
+		close(fd);
+		dbg("lm_init: fstat(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+		    strerror(errno));
+		goto override;
 	}
+	lm_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (lm_map == (const char *)MAP_FAILED) {
+		close(fd);
+		dbg("lm_init: mmap(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
+		    strerror(errno));
+		goto override;
+	}
+	close(fd);
+	lmc_parse(lm_map, st.st_size);
+	munmap(lm_map, st.st_size);
 
+override:
 	if (libmap_override) {
-		char	*p;
-		/* do some character replacement to make $LIBMAP look like a
-		   text file, then "open" it with funopen */
+		/*
+		 * Do some character replacement to make $LIBMAP look
+		 * like a text file, then parse it.
+		 */
 		libmap_override = xstrdup(libmap_override);
-
 		for (p = libmap_override; *p; p++) {
 			switch (*p) {
-				case '=':
-					*p = ' '; break;
-				case ',':
-					*p = '\n'; break;
+			case '=':
+				*p = ' ';
+				break;
+			case ',':
+				*p = '\n';
+				break;
 			}
 		}
-		fp = funopen(libmap_override, readstrfn, NULL, NULL, closestrfn);
-		if (fp) {
-			lmc_parse(fp);
-			fclose(fp);
-		}
+		lmc_parse(p, strlen(p));
+		free(p);
 	}
 
 	return (lm_count == 0);
 }
 
 static void
-lmc_parse (FILE *fp)
+lmc_parse(char *lm_p, size_t lm_len)
 {
-	char	*cp;
-	char	*f, *t, *c, *p;
-	char	prog[MAXPATHLEN];
-	char	line[MAXPATHLEN + 2];
-
-	dbg("%s(%p)", __func__, fp);
+	char *cp, *f, *t, *c, *p;
+	char prog[MAXPATHLEN];
+	char line[MAXPATHLEN + 2];
+	size_t cnt;
+	int i;
 	
+	cnt = 0;
 	p = NULL;
-	while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
+	while (cnt < lm_len) {
+		i = 0;
+		while (lm_p[cnt] != '\n' && cnt < lm_len &&
+		    i < sizeof(line) - 1) {
+			line[i] = lm_p[cnt];
+			cnt++;
+			i++;
+		}
+		line[i] = '\0';
+		while (lm_p[cnt] != '\n' && cnt < lm_len)
+			cnt++;
+		/* skip over nl */
+		cnt++;
+
+		cp = &line[0];
 		t = f = c = NULL;
 
 		/* Skip over leading space */
@@ -344,31 +376,3 @@ quickbasename (const char *path)
 	}
 	return (p);
 }
-
-static int
-readstrfn(void * cookie, char *buf, int len)
-{
-	static char	*current;
-	static int	left;
-	int 	copied;
-	
-	copied = 0;
-	if (!current) {
-		current = cookie;
-		left = strlen(cookie);
-	}
-	while (*current && left && len) {
-		*buf++ = *current++;
-		left--;
-		len--;
-		copied++;
-	}
-	return copied;
-}
-
-static int
-closestrfn(void * cookie)
-{
-	free(cookie);
-	return 0;
-}



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