summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-03-12 12:16:08 +0000
committerkib <kib@FreeBSD.org>2012-03-12 12:16:08 +0000
commit4861f7911395459349e837d48f6d239d6c1e80d7 (patch)
tree1a7dded64140f715315e91afedeffdfea48ee09b /libexec
parent4f080c8f731c78d2241481894214dbdcced51b11 (diff)
downloadFreeBSD-src-4861f7911395459349e837d48f6d239d6c1e80d7.zip
FreeBSD-src-4861f7911395459349e837d48f6d239d6c1e80d7.tar.gz
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
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/libmap.c148
1 files changed, 76 insertions, 72 deletions
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c
index 7f55c9d..92a0469 100644
--- a/libexec/rtld-elf/libmap.c
+++ b/libexec/rtld-elf/libmap.c
@@ -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;
-}
OpenPOWER on IntegriCloud