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
This commit is contained in:
Konstantin Belousov 2012-03-12 12:16:08 +00:00
parent ef5cdcbd69
commit 68f1db20b3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=232862

View File

@ -2,11 +2,14 @@
* $FreeBSD$ * $FreeBSD$
*/ */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/queue.h>
#include <sys/param.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 "debug.h"
#include "rtld.h" #include "rtld.h"
@ -25,7 +28,6 @@ TAILQ_HEAD(lm_list, lm);
struct lm { struct lm {
char *f; char *f;
char *t; char *t;
TAILQ_ENTRY(lm) lm_link; TAILQ_ENTRY(lm) lm_link;
}; };
@ -37,17 +39,15 @@ struct lmp {
TAILQ_ENTRY(lmp) lmp_link; TAILQ_ENTRY(lmp) lmp_link;
}; };
static int lm_count; static int lm_count;
static void lmc_parse (FILE *); static void lmc_parse(char *, size_t);
static void lm_add (const char *, const char *, const char *); static void lm_add(const char *, const char *, const char *);
static void lm_free (struct lm_list *); static void lm_free(struct lm_list *);
static char * lml_find (struct lm_list *, const char *); static char *lml_find(struct lm_list *, const char *);
static struct lm_list * lmp_find (const char *); static struct lm_list *lmp_find(const char *);
static struct lm_list * lmp_init (char *); static struct lm_list *lmp_init(char *);
static const char * quickbasename (const char *); static const char *quickbasename(const char *);
static int readstrfn (void * cookie, char *buf, int len);
static int closestrfn (void * cookie);
#define iseol(c) (((c) == '#') || ((c) == '\0') || \ #define iseol(c) (((c) == '#') || ((c) == '\0') || \
((c) == '\n') || ((c) == '\r')) ((c) == '\n') || ((c) == '\r'))
@ -59,56 +59,88 @@ static int closestrfn (void * cookie);
#define rtld_isspace(c) ((c) == ' ' || (c) == '\t') #define rtld_isspace(c) ((c) == ' ' || (c) == '\t')
int int
lm_init (char *libmap_override) lm_init(char *libmap_override)
{ {
FILE *fp; struct stat st;
char *lm_map, *p;
dbg("%s(\"%s\")", __func__, libmap_override); int fd;
dbg("lm_init(\"%s\")", libmap_override);
TAILQ_INIT(&lmp_head); TAILQ_INIT(&lmp_head);
fp = fopen(_PATH_LIBMAP_CONF, "r"); fd = open(_PATH_LIBMAP_CONF, O_RDONLY);
if (fp) { if (fd == -1) {
lmc_parse(fp); dbg("lm_init: open(\"%s\") failed, %s", _PATH_LIBMAP_CONF,
fclose(fp); 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) { if (libmap_override) {
char *p; /*
/* do some character replacement to make $LIBMAP look like a * Do some character replacement to make $LIBMAP look
text file, then "open" it with funopen */ * like a text file, then parse it.
*/
libmap_override = xstrdup(libmap_override); libmap_override = xstrdup(libmap_override);
for (p = libmap_override; *p; p++) { for (p = libmap_override; *p; p++) {
switch (*p) { switch (*p) {
case '=': case '=':
*p = ' '; break; *p = ' ';
case ',': break;
*p = '\n'; break; case ',':
*p = '\n';
break;
} }
} }
fp = funopen(libmap_override, readstrfn, NULL, NULL, closestrfn); lmc_parse(p, strlen(p));
if (fp) { free(p);
lmc_parse(fp);
fclose(fp);
}
} }
return (lm_count == 0); return (lm_count == 0);
} }
static void static void
lmc_parse (FILE *fp) lmc_parse(char *lm_p, size_t lm_len)
{ {
char *cp; char *cp, *f, *t, *c, *p;
char *f, *t, *c, *p; char prog[MAXPATHLEN];
char prog[MAXPATHLEN]; char line[MAXPATHLEN + 2];
char line[MAXPATHLEN + 2]; size_t cnt;
int i;
dbg("%s(%p)", __func__, fp);
cnt = 0;
p = NULL; 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; t = f = c = NULL;
/* Skip over leading space */ /* Skip over leading space */
@ -344,31 +376,3 @@ quickbasename (const char *path)
} }
return (p); 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;
}