xref: /freebsd-14.2/libexec/rtld-elf/libmap.c (revision 29ade362)
1*29ade362SMatthew N. Dodd /*
2*29ade362SMatthew N. Dodd  * $FreeBSD$
3*29ade362SMatthew N. Dodd  */
4*29ade362SMatthew N. Dodd 
5*29ade362SMatthew N. Dodd #include <stdio.h>
6*29ade362SMatthew N. Dodd #include <ctype.h>
7*29ade362SMatthew N. Dodd #include <string.h>
8*29ade362SMatthew N. Dodd #include <stdlib.h>
9*29ade362SMatthew N. Dodd #include <sys/queue.h>
10*29ade362SMatthew N. Dodd #include <sys/param.h>
11*29ade362SMatthew N. Dodd 
12*29ade362SMatthew N. Dodd #ifndef _PATH_LIBMAP_CONF
13*29ade362SMatthew N. Dodd #define	_PATH_LIBMAP_CONF	"/etc/libmap.conf"
14*29ade362SMatthew N. Dodd #endif
15*29ade362SMatthew N. Dodd 
16*29ade362SMatthew N. Dodd TAILQ_HEAD(lm_list, lm);
17*29ade362SMatthew N. Dodd struct lm {
18*29ade362SMatthew N. Dodd 	char *f;
19*29ade362SMatthew N. Dodd 	char *t;
20*29ade362SMatthew N. Dodd 
21*29ade362SMatthew N. Dodd 	TAILQ_ENTRY(lm)	lm_link;
22*29ade362SMatthew N. Dodd };
23*29ade362SMatthew N. Dodd 
24*29ade362SMatthew N. Dodd TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head);
25*29ade362SMatthew N. Dodd struct lmp {
26*29ade362SMatthew N. Dodd 	char *p;
27*29ade362SMatthew N. Dodd 	struct lm_list lml;
28*29ade362SMatthew N. Dodd 	TAILQ_ENTRY(lmp) lmp_link;
29*29ade362SMatthew N. Dodd };
30*29ade362SMatthew N. Dodd 
31*29ade362SMatthew N. Dodd static void		lm_add		(char *, char *, char *);
32*29ade362SMatthew N. Dodd static void		lm_free		(struct lm_list *);
33*29ade362SMatthew N. Dodd static char *		lml_find	(struct lm_list *, const char *);
34*29ade362SMatthew N. Dodd static struct lm_list *	lmp_find	(const char *);
35*29ade362SMatthew N. Dodd static struct lm_list *	lmp_init	(char *);
36*29ade362SMatthew N. Dodd 
37*29ade362SMatthew N. Dodd void
38*29ade362SMatthew N. Dodd lm_init (void)
39*29ade362SMatthew N. Dodd {
40*29ade362SMatthew N. Dodd 	FILE	*fp;
41*29ade362SMatthew N. Dodd 	char	*cp;
42*29ade362SMatthew N. Dodd 	char	*f, *t, *p;
43*29ade362SMatthew N. Dodd 	char	prog[MAXPATHLEN];
44*29ade362SMatthew N. Dodd 	char	line[MAXPATHLEN + 2];
45*29ade362SMatthew N. Dodd 
46*29ade362SMatthew N. Dodd 	TAILQ_INIT(&lmp_head);
47*29ade362SMatthew N. Dodd 
48*29ade362SMatthew N. Dodd 	if ((fp = fopen(_PATH_LIBMAP_CONF, "r")) == NULL)
49*29ade362SMatthew N. Dodd 		return;
50*29ade362SMatthew N. Dodd 
51*29ade362SMatthew N. Dodd 	p = NULL;
52*29ade362SMatthew N. Dodd 	while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
53*29ade362SMatthew N. Dodd 		t = f = NULL;
54*29ade362SMatthew N. Dodd 		/* Skip over leading space */
55*29ade362SMatthew N. Dodd 		while (!isalpha(*cp) &&
56*29ade362SMatthew N. Dodd 		       *cp != '#' && *cp != '\0' && *cp != '[') cp++;
57*29ade362SMatthew N. Dodd 		/* Found a comment or EOL */
58*29ade362SMatthew N. Dodd 		if (*cp == '#' || *cp == '\0')
59*29ade362SMatthew N. Dodd 			continue;
60*29ade362SMatthew N. Dodd 		/* Found a costraint selector */
61*29ade362SMatthew N. Dodd 		if (*cp == '[') {
62*29ade362SMatthew N. Dodd 			cp++;
63*29ade362SMatthew N. Dodd 			/* Skip leading space */
64*29ade362SMatthew N. Dodd 			while (isspace(*cp) &&
65*29ade362SMatthew N. Dodd 			       *cp != '#' && *cp != '\0' && *cp != ']') cp++;
66*29ade362SMatthew N. Dodd 			/* Found comment, EOL or end of selector */
67*29ade362SMatthew N. Dodd 			if  (*cp == '#' || *cp == '\0' || *cp == ']')
68*29ade362SMatthew N. Dodd 				continue;
69*29ade362SMatthew N. Dodd 			p = cp;
70*29ade362SMatthew N. Dodd 			/* Skip to end of word */
71*29ade362SMatthew N. Dodd 			while (!isspace(*cp) &&
72*29ade362SMatthew N. Dodd 			       *cp != '#' && *cp != '\0' && *cp != ']') cp++;
73*29ade362SMatthew N. Dodd 			*cp++ = '\0';
74*29ade362SMatthew N. Dodd 			bzero(prog, MAXPATHLEN);
75*29ade362SMatthew N. Dodd 			strncpy(prog, p, strlen(p));
76*29ade362SMatthew N. Dodd 			p = prog;
77*29ade362SMatthew N. Dodd 			continue;
78*29ade362SMatthew N. Dodd 		}
79*29ade362SMatthew N. Dodd 		f = cp;
80*29ade362SMatthew N. Dodd 		while (!isspace(*cp) && *cp != '#' && *cp != '\0') cp++;
81*29ade362SMatthew N. Dodd 		*cp++ = '\0';
82*29ade362SMatthew N. Dodd 		while (isspace(*cp) && *cp != '#' && *cp != '\0') cp++;
83*29ade362SMatthew N. Dodd 		t = cp;
84*29ade362SMatthew N. Dodd 		while (!isspace(*cp) && *cp != '#' && *cp != '\0') cp++;
85*29ade362SMatthew N. Dodd 		*cp++ = '\0';
86*29ade362SMatthew N. Dodd 
87*29ade362SMatthew N. Dodd 		lm_add(p, strdup(f), strdup(t));
88*29ade362SMatthew N. Dodd 		bzero(line, sizeof(line));
89*29ade362SMatthew N. Dodd 	}
90*29ade362SMatthew N. Dodd 	(void)fclose(fp);
91*29ade362SMatthew N. Dodd 	return;
92*29ade362SMatthew N. Dodd }
93*29ade362SMatthew N. Dodd 
94*29ade362SMatthew N. Dodd static void
95*29ade362SMatthew N. Dodd lm_free (struct lm_list *lml)
96*29ade362SMatthew N. Dodd {
97*29ade362SMatthew N. Dodd 	struct lm *lm;
98*29ade362SMatthew N. Dodd 
99*29ade362SMatthew N. Dodd 	while (!TAILQ_EMPTY(lml)) {
100*29ade362SMatthew N. Dodd 		lm = TAILQ_FIRST(lml);
101*29ade362SMatthew N. Dodd 		TAILQ_REMOVE(lml, lm, lm_link);
102*29ade362SMatthew N. Dodd 		free(lm->f);
103*29ade362SMatthew N. Dodd 		free(lm->t);
104*29ade362SMatthew N. Dodd 		free(lm);
105*29ade362SMatthew N. Dodd 	}
106*29ade362SMatthew N. Dodd 	return;
107*29ade362SMatthew N. Dodd }
108*29ade362SMatthew N. Dodd 
109*29ade362SMatthew N. Dodd void
110*29ade362SMatthew N. Dodd lm_fini (void)
111*29ade362SMatthew N. Dodd {
112*29ade362SMatthew N. Dodd 	struct lmp *lmp;
113*29ade362SMatthew N. Dodd 
114*29ade362SMatthew N. Dodd 	while (!TAILQ_EMPTY(&lmp_head)) {
115*29ade362SMatthew N. Dodd 		lmp = TAILQ_FIRST(&lmp_head);
116*29ade362SMatthew N. Dodd 		TAILQ_REMOVE(&lmp_head, lmp, lmp_link);
117*29ade362SMatthew N. Dodd 		free(lmp->p);
118*29ade362SMatthew N. Dodd 		lm_free(&lmp->lml);
119*29ade362SMatthew N. Dodd 		free(lmp);
120*29ade362SMatthew N. Dodd 	}
121*29ade362SMatthew N. Dodd 	return;
122*29ade362SMatthew N. Dodd }
123*29ade362SMatthew N. Dodd 
124*29ade362SMatthew N. Dodd static void
125*29ade362SMatthew N. Dodd lm_add (char *p, char *f, char *t)
126*29ade362SMatthew N. Dodd {
127*29ade362SMatthew N. Dodd 	struct lm_list *lml;
128*29ade362SMatthew N. Dodd 	struct lm *lm;
129*29ade362SMatthew N. Dodd 
130*29ade362SMatthew N. Dodd 	if (p == NULL)
131*29ade362SMatthew N. Dodd 		p = "$DEFAULT$";
132*29ade362SMatthew N. Dodd 
133*29ade362SMatthew N. Dodd #if 0
134*29ade362SMatthew N. Dodd 	printf("%s(\"%s\", \"%s\", \"%s\")\n", __func__, p, f, t);
135*29ade362SMatthew N. Dodd #endif
136*29ade362SMatthew N. Dodd 
137*29ade362SMatthew N. Dodd 	if ((lml = lmp_find(p)) == NULL)
138*29ade362SMatthew N. Dodd 		lml = lmp_init(strdup(p));
139*29ade362SMatthew N. Dodd 
140*29ade362SMatthew N. Dodd 	lm = malloc(sizeof(struct lm));
141*29ade362SMatthew N. Dodd 	lm->f = f;
142*29ade362SMatthew N. Dodd 	lm->t = t;
143*29ade362SMatthew N. Dodd 	TAILQ_INSERT_HEAD(lml, lm, lm_link);
144*29ade362SMatthew N. Dodd }
145*29ade362SMatthew N. Dodd 
146*29ade362SMatthew N. Dodd char *
147*29ade362SMatthew N. Dodd lm_find (const char *p, const char *f)
148*29ade362SMatthew N. Dodd {
149*29ade362SMatthew N. Dodd 	struct lm_list *lml;
150*29ade362SMatthew N. Dodd 	char *t;
151*29ade362SMatthew N. Dodd 
152*29ade362SMatthew N. Dodd 	if (p != NULL && (lml = lmp_find(p)) != NULL) {
153*29ade362SMatthew N. Dodd 		t = lml_find(lml, f);
154*29ade362SMatthew N. Dodd 		if (t != NULL)
155*29ade362SMatthew N. Dodd 			return (t);
156*29ade362SMatthew N. Dodd 	}
157*29ade362SMatthew N. Dodd 	lml = lmp_find("$DEFAULT$");
158*29ade362SMatthew N. Dodd 	if (lml != NULL)
159*29ade362SMatthew N. Dodd 		return (lml_find(lml, f));
160*29ade362SMatthew N. Dodd 	else
161*29ade362SMatthew N. Dodd 		return (NULL);
162*29ade362SMatthew N. Dodd }
163*29ade362SMatthew N. Dodd 
164*29ade362SMatthew N. Dodd static char *
165*29ade362SMatthew N. Dodd lml_find (struct lm_list *lmh, const char *f)
166*29ade362SMatthew N. Dodd {
167*29ade362SMatthew N. Dodd 	struct lm *lm;
168*29ade362SMatthew N. Dodd 
169*29ade362SMatthew N. Dodd 	TAILQ_FOREACH(lm, lmh, lm_link)
170*29ade362SMatthew N. Dodd 		if ((strncmp(f, lm->f, strlen(lm->f)) == 0) &&
171*29ade362SMatthew N. Dodd 		    (strlen(f) == strlen(lm->f)))
172*29ade362SMatthew N. Dodd 			return (lm->t);
173*29ade362SMatthew N. Dodd 	return NULL;
174*29ade362SMatthew N. Dodd }
175*29ade362SMatthew N. Dodd 
176*29ade362SMatthew N. Dodd static struct lm_list *
177*29ade362SMatthew N. Dodd lmp_find (const char *n)
178*29ade362SMatthew N. Dodd {
179*29ade362SMatthew N. Dodd 	struct lmp *lmp;
180*29ade362SMatthew N. Dodd 
181*29ade362SMatthew N. Dodd 	TAILQ_FOREACH(lmp, &lmp_head, lmp_link)
182*29ade362SMatthew N. Dodd 		if ((strncmp(n, lmp->p, strlen(lmp->p)) == 0) &&
183*29ade362SMatthew N. Dodd 		    (strlen(n) == strlen(lmp->p)))
184*29ade362SMatthew N. Dodd 			return (&lmp->lml);
185*29ade362SMatthew N. Dodd 	return (NULL);
186*29ade362SMatthew N. Dodd }
187*29ade362SMatthew N. Dodd 
188*29ade362SMatthew N. Dodd static struct lm_list *
189*29ade362SMatthew N. Dodd lmp_init (char *n)
190*29ade362SMatthew N. Dodd {
191*29ade362SMatthew N. Dodd 	struct lmp *lmp;
192*29ade362SMatthew N. Dodd 
193*29ade362SMatthew N. Dodd 	lmp = malloc(sizeof(struct lmp));
194*29ade362SMatthew N. Dodd 	lmp->p = n;
195*29ade362SMatthew N. Dodd 	TAILQ_INIT(&lmp->lml);
196*29ade362SMatthew N. Dodd 	TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link);
197*29ade362SMatthew N. Dodd 
198*29ade362SMatthew N. Dodd 	return (&lmp->lml);
199*29ade362SMatthew N. Dodd }
200