svn commit: r324856 - head/libexec/rtld-elf

Edward Tomasz Napierala trasz at FreeBSD.org
Sun Oct 22 10:32:41 UTC 2017


Author: trasz
Date: Sun Oct 22 10:32:40 2017
New Revision: 324856
URL: https://svnweb.freebsd.org/changeset/base/324856

Log:
  Don't call realpath(3) from libmap rtld code. This gets rid of a few calls
  to fstatat(2) at binary startup; the difference looks like this:
  
  --- przed       2017-10-14 13:55:49.983528000 +0100
  +++ po  2017-10-14 14:10:39.134343000 +0100
  @@ -1,15 +1,10 @@
   mmap(0x0,32768,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34366173184 (0x800623000)
   issetugid()                                     = 0 (0x0)
  -fstatat(AT_FDCWD,"/etc",{ mode=drwxr-xr-x ,inode=1364352,size=2560,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0)
  -fstatat(AT_FDCWD,"/etc/libmap.conf",{ mode=-rw-r--r-- ,inode=1373288,size=102,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0)
   openat(AT_FDCWD,"/etc/libmap.conf",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
   fstat(3,{ mode=-rw-r--r-- ,inode=1373288,size=102,blksize=32768 }) = 0 (0x0)
   mmap(0x0,102,PROT_READ,MAP_PRIVATE,3,0x0)       = 34366205952 (0x80062b000)
   close(3)                                        = 0 (0x0)
  -fstatat(AT_FDCWD,"/usr",{ mode=drwxr-xr-x ,inode=561792,size=512,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0)
  -fstatat(AT_FDCWD,"/usr/local",{ mode=drwxr-xr-x ,inode=561800,size=512,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0)
  -fstatat(AT_FDCWD,"/usr/local/etc",{ mode=drwxr-xr-x ,inode=653279,size=1536,blksize=32768 },AT_SYMLINK_NOFOLLOW) = 0 (0x0)
  -fstatat(AT_FDCWD,"/usr/local/etc/libmap.d",0x7fffffffcf50,AT_SYMLINK_NOFOLLOW) ERR#2 'No such file or directory'
  +open("/usr/local/etc/libmap.d",O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC,0165) ERR#2 'No such file or directory'
   munmap(0x80062b000,102)                                 = 0 (0x0)
   openat(AT_FDCWD,"/var/run/ld-elf.so.hints",O_RDONLY|O_CLOEXEC,00) = 3 (0x3)
   read(3,"Ehnt\^A\0\0\0\M^@\0\0\0\M-2\0\0"...,128) = 128 (0x80)
  
  Reviewed by:	kib
  MFC after:	2 weeks
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D12741

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

Modified: head/libexec/rtld-elf/libmap.c
==============================================================================
--- head/libexec/rtld-elf/libmap.c	Sun Oct 22 08:47:13 2017	(r324855)
+++ head/libexec/rtld-elf/libmap.c	Sun Oct 22 10:32:40 2017	(r324856)
@@ -36,6 +36,8 @@ struct lmp {
 static TAILQ_HEAD(lmc_list, lmc) lmc_head = TAILQ_HEAD_INITIALIZER(lmc_head);
 struct lmc {
 	char *path;
+	dev_t dev;
+	ino_t ino;
 	TAILQ_ENTRY(lmc) next;
 };
 
@@ -99,45 +101,45 @@ lmc_parse_file(char *path)
 	struct lmc *p;
 	struct stat st;
 	int fd;
-	char *rpath;
 	char *lm_map;
 
-	rpath = realpath(path, NULL);
-	if (rpath == NULL)
-		return;
-
 	TAILQ_FOREACH(p, &lmc_head, next) {
-		if (strcmp(p->path, rpath) == 0) {
-			free(rpath);
+		if (strcmp(p->path, path) == 0)
 			return;
-		}
 	}
 
-	fd = open(rpath, O_RDONLY | O_CLOEXEC);
+	fd = open(path, O_RDONLY | O_CLOEXEC);
 	if (fd == -1) {
-		dbg("lm_parse_file: open(\"%s\") failed, %s", rpath,
+		dbg("lm_parse_file: open(\"%s\") failed, %s", path,
 		    rtld_strerror(errno));
-		free(rpath);
 		return;
 	}
 	if (fstat(fd, &st) == -1) {
 		close(fd);
-		dbg("lm_parse_file: fstat(\"%s\") failed, %s", rpath,
+		dbg("lm_parse_file: fstat(\"%s\") failed, %s", path,
 		    rtld_strerror(errno));
-		free(rpath);
 		return;
 	}
+
+	TAILQ_FOREACH(p, &lmc_head, next) {
+		if (p->dev == st.st_dev && p->ino == st.st_ino) {
+			close(fd);
+			return;
+		}
+	}
+
 	lm_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
 	if (lm_map == (const char *)MAP_FAILED) {
 		close(fd);
-		dbg("lm_parse_file: mmap(\"%s\") failed, %s", rpath,
+		dbg("lm_parse_file: mmap(\"%s\") failed, %s", path,
 		    rtld_strerror(errno));
-		free(rpath);
 		return;
 	}
 	close(fd);
 	p = xmalloc(sizeof(struct lmc));
-	p->path = rpath;
+	p->path = xstrdup(path);
+	p->dev = st.st_dev;
+	p->ino = st.st_ino;
 	TAILQ_INSERT_HEAD(&lmc_head, p, next);
 	lmc_parse(lm_map, st.st_size);
 	munmap(lm_map, st.st_size);
@@ -151,26 +153,19 @@ lmc_parse_dir(char *idir)
 	struct lmc *p;
 	char conffile[MAXPATHLEN];
 	char *ext;
-	char *rpath;
 
-	rpath = realpath(idir, NULL);
-	if (rpath == NULL)
-		return;
-
 	TAILQ_FOREACH(p, &lmc_head, next) {
-		if (strcmp(p->path, rpath) == 0) {
-			free(rpath);
+		if (strcmp(p->path, idir) == 0)
 			return;
-		}
 	}
 	d = opendir(idir);
-	if (d == NULL) {
-		free(rpath);
+	if (d == NULL)
 		return;
-	}
 
 	p = xmalloc(sizeof(struct lmc));
-	p->path = rpath;
+	p->path = xstrdup(idir);
+	p->dev = NODEV;
+	p->ino = 0;
 	TAILQ_INSERT_HEAD(&lmc_head, p, next);
 
 	while ((dp = readdir(d)) != NULL) {


More information about the svn-src-all mailing list