1 /*-
2  * Copyright (c) 2010 Varnish Software AS
3  * All rights reserved.
4  *
5  * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 /*lint -save -esym(759, SYMTAB_NOERR) -esym(765, SYMTAB_NOERR)*/
31 
32 #include "config.h"
33 
34 #include <ctype.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #include "vcc_compile.h"
40 
41 #include "vct.h"
42 
43 /*--------------------------------------------------------------------*/
44 
45 #define VCC_KIND(U,l) const struct kind SYM_##U[1] = {{ KIND_MAGIC, #l}};
46 #include "tbl/symbol_kind.h"
47 
48 /*--------------------------------------------------------------------*/
49 
50 struct vcc_namespace {
51 	unsigned		magic;
52 #define VCC_NAMESPACE_MAGIC	0x27b842f4
53 	const char		*name;
54 	enum vcc_namespace_e	id;
55 };
56 
57 #define VCC_NAMESPACE(U, l)				\
58 	static const struct vcc_namespace sym_##l = {	\
59 		VCC_NAMESPACE_MAGIC,			\
60 		#l,					\
61 		VCC_NAMESPACE_##U			\
62 	};						\
63 	vcc_ns_t SYM_##U = &sym_##l;
64 #include "vcc_namespace.h"
65 
66 /*--------------------------------------------------------------------*/
67 
68 struct symtab {
69 	unsigned			magic;
70 #define SYMTAB_MAGIC			0x084d9c8a
71 	unsigned			nlen;
72 	const char			*name;
73 	const struct symtab		*parent;
74 	VTAILQ_ENTRY(symtab)		list;
75 	VTAILQ_HEAD(,symtab)		children;
76 	VTAILQ_HEAD(,symbol)		symbols;
77 };
78 
79 static vcc_kind_t
VCC_HandleKind(vcc_type_t fmt)80 VCC_HandleKind(vcc_type_t fmt)
81 {
82 	if (fmt == ACL)		return (SYM_ACL);
83 	if (fmt == BACKEND)	return (SYM_BACKEND);
84 	if (fmt == PROBE)	return (SYM_PROBE);
85 	if (fmt == STEVEDORE)	return (SYM_STEVEDORE);
86 	if (fmt == SUB)		return (SYM_SUB);
87 	if (fmt == INSTANCE)	return (SYM_INSTANCE);
88 	return (SYM_NONE);
89 }
90 
91 void
VCC_PrintCName(struct vsb * vsb,const char * b,const char * e)92 VCC_PrintCName(struct vsb *vsb, const char *b, const char *e)
93 {
94 
95 	AN(vsb);
96 	AN(b);
97 
98 	if (e == NULL)
99 		e = strchr(b, '\0');
100 	assert(b < e);
101 
102 	for (; b < e; b++)
103 		if (vct_isalnum(*b))
104 			VSB_putc(vsb, *b);
105 		else
106 			VSB_printf(vsb, "_%02x_", *b);
107 }
108 
109 static void
vcc_symtabname(struct vsb * vsb,const struct symtab * st)110 vcc_symtabname(struct vsb *vsb, const struct symtab *st)
111 {
112 	if (st->parent != NULL && st->parent->parent != NULL) {
113 		vcc_symtabname(vsb, st->parent);
114 		VSB_putc(vsb, '.');
115 	}
116 	VSB_cat(vsb, st->name);
117 }
118 
119 void
VCC_SymName(struct vsb * vsb,const struct symbol * sym)120 VCC_SymName(struct vsb *vsb, const struct symbol *sym)
121 {
122 	AN(vsb);
123 	CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
124 	CHECK_OBJ_NOTNULL(sym->symtab, SYMTAB_MAGIC);
125 	vcc_symtabname(vsb, sym->symtab);
126 }
127 
128 static char *
vcc_dup_be(const char * b,const char * e)129 vcc_dup_be(const char *b, const char *e)
130 {
131 	char *p;
132 
133 	AN(b);
134 	if (e == NULL)
135 		e = strchr(b, '\0');
136 	AN(e);
137 	assert(e >= b);
138 
139 	p = strndup(b, e - b);
140 	AN(p);
141 	return (p);
142 }
143 
144 static struct symtab *
vcc_symtab_new(const char * name)145 vcc_symtab_new(const char *name)
146 {
147 	struct symtab *st;
148 
149 	ALLOC_OBJ(st, SYMTAB_MAGIC);
150 	AN(st);
151 	st->name = name;
152 	st->nlen = strlen(st->name);
153 	VTAILQ_INIT(&st->children);
154 	VTAILQ_INIT(&st->symbols);
155 	return (st);
156 }
157 
158 static struct symtab *
vcc_symtab_str(struct symtab * st,const char * b,const char * e)159 vcc_symtab_str(struct symtab *st, const char *b, const char *e)
160 {
161 	struct symtab *st2, *st3;
162 	size_t l;
163 	int i;
164 	const char *q;
165 
166 	if (e == NULL)
167 		e = strchr(b, '\0');
168 
169 	while (b < e) {
170 		for (q = b; q < e && *q != '.'; q++)
171 			continue;
172 		AN(q);
173 		l = q - b;
174 		VTAILQ_FOREACH(st2, &st->children, list) {
175 			i = strncasecmp(st2->name, b, l);
176 			if (i < 0)
177 				continue;
178 			if (i == 0 && l == st2->nlen)
179 				break;
180 			st3 = vcc_symtab_new(vcc_dup_be(b, q));
181 			st3->parent = st;
182 			VTAILQ_INSERT_BEFORE(st2, st3, list);
183 			st2 = st3;
184 			break;
185 		}
186 		if (st2 == NULL) {
187 			st2 = vcc_symtab_new(vcc_dup_be(b, q));
188 			st2->parent = st;
189 			VTAILQ_INSERT_TAIL(&st->children, st2, list);
190 		}
191 		st = st2;
192 		b = q + 1;
193 	}
194 	return (st);
195 }
196 
197 static struct symbol *
vcc_new_symbol(struct vcc * tl,struct symtab * st,vcc_kind_t kind,int vlo,int vhi)198 vcc_new_symbol(struct vcc *tl, struct symtab *st,
199     vcc_kind_t kind, int vlo, int vhi)
200 {
201 	struct symbol *sym;
202 
203 	sym = TlAlloc(tl, sizeof *sym);
204 	INIT_OBJ(sym, SYMBOL_MAGIC);
205 	AN(sym);
206 	sym->name = st->name;
207 	sym->symtab = st;
208 	sym->kind = kind;
209 	sym->type = VOID;
210 	sym->lorev = vlo;
211 	sym->hirev = vhi;
212 	VTAILQ_INSERT_TAIL(&st->symbols, sym, list);
213 	return (sym);
214 }
215 
216 static struct symbol *
vcc_sym_in_tab(struct vcc * tl,struct symtab * st,vcc_kind_t kind,int vlo,int vhi)217 vcc_sym_in_tab(struct vcc *tl, struct symtab *st,
218     vcc_kind_t kind, int vlo, int vhi)
219 {
220 	const struct symtab *pst;
221 	struct symbol *sym, *psym;
222 
223 	VTAILQ_FOREACH(sym, &st->symbols, list) {
224 		if (sym->lorev > vhi || sym->hirev < vlo)
225 			continue;
226 		if ((kind == SYM_NONE && kind == sym->kind))
227 			continue;
228 		if (tl->syntax < VCL_41 && strcmp(sym->name, "default") &&
229 		     (kind != SYM_NONE && kind != sym->kind))
230 			continue;
231 		return (sym);
232 	}
233 	pst = st->parent;
234 	if (pst == NULL)
235 		return (sym);
236 	psym = VTAILQ_FIRST(&pst->symbols);
237 	if (psym == NULL)
238 		return (sym);
239 	if (psym->wildcard == NULL)
240 		return (sym);
241 
242 	sym = vcc_new_symbol(tl, st, kind, vlo, vhi);
243 	psym->wildcard(tl, psym, sym);
244 	if (tl->err)
245 		return (NULL);
246 	return (sym);
247 }
248 
249 
250 const struct symxref XREF_NONE[1] = {{"xref_none"}};
251 const struct symxref XREF_DEF[1] = {{"xref_def"}};
252 const struct symxref XREF_REF[1] = {{"xref_ref"}};
253 
254 const struct symmode SYMTAB_NOERR[1] = {{
255 		.name = "sym_noerror",
256 		.noerr = 1
257 	}};
258 const struct symmode SYMTAB_CREATE[1] = {{
259 		.name = "sym_create"
260 	}};
261 const struct symmode SYMTAB_EXISTING[1] = {{
262 		.name = "Symbol not found"
263 	}};
264 const struct symmode SYMTAB_PARTIAL[1] = {{
265 		.name = "Symbol not found",
266 		.partial = 1
267 	}};
268 const struct symmode SYMTAB_PARTIAL_NOERR[1] = {{
269 		.name = "Symbol not found",
270 		.partial = 1,
271 		.noerr = 1
272 	}};
273 
274 struct symbol *
VCC_SymbolGet(struct vcc * tl,vcc_ns_t ns,vcc_kind_t kind,const struct symmode * e,const struct symxref * x)275 VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
276     const struct symmode *e, const struct symxref *x)
277 {
278 	struct symtab *st, *st2 = NULL;
279 	struct symbol *sym = NULL, *sym2 = NULL;
280 	struct token *t0, *tn, *tn1, *tn2 = NULL;
281 
282 	AN(tl);
283 	CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
284 	AN(ns->name);
285 	CHECK_OBJ_NOTNULL(kind, KIND_MAGIC);
286 	AN(e);
287 	AN(x);
288 	AN(x->name);
289 	if (tl->syntax >= VCL_41 && e == SYMTAB_CREATE && kind != SYM_SUB &&
290 	    (tl->t->b[0] == 'v'|| tl->t->b[0] == 'V') &&
291 	    (tl->t->b[1] == 'c'|| tl->t->b[1] == 'C') &&
292 	    (tl->t->b[2] == 'l'|| tl->t->b[2] == 'L') &&
293 	    (tl->t->b[3] == '_')) {
294 		VSB_cat(tl->sb, "Symbols named 'vcl_*' are reserved.\nAt:");
295 		vcc_ErrWhere(tl, tl->t);
296 		return (NULL);
297 	}
298 
299 	st = tl->syms[ns->id];
300 	t0 = tl->t;
301 	tn = tl->t;
302 	while (1) {
303 		st = vcc_symtab_str(st, tn->b, tn->e);
304 		sym2 = vcc_sym_in_tab(tl, st, kind, tl->syntax, tl->syntax);
305 		if (sym2 != NULL) {
306 			sym = sym2;
307 			st2 = st;
308 			tn2 = tn;
309 		}
310 		tn1 = VTAILQ_NEXT(tn, list);
311 		if (tn1->tok != '.')
312 			break;
313 		tn1 = VTAILQ_NEXT(tn1, list);
314 		if (tn1->tok != ID)
315 			break;
316 		tn = tn1;
317 	}
318 	if (sym != NULL && sym->kind == SYM_VMOD && e->partial)
319 		e = SYMTAB_EXISTING;
320 	if (sym != NULL && e->partial) {
321 		st = st2;
322 		tn = tn2;
323 	} else if (st != st2) {
324 		sym = NULL;
325 	}
326 	if (sym == NULL && e->noerr)
327 		return (sym);
328 	AN(st);
329 	AN(tn);
330 	if (sym == NULL && e == SYMTAB_CREATE)
331 		sym = vcc_new_symbol(tl, st, kind, tl->syntax, tl->syntax);
332 	tl->t = VTAILQ_NEXT(tn, list);
333 	if (sym == NULL) {
334 		VSB_printf(tl->sb, "%s: '", e->name);
335 		for (tn1 = t0; tn1 != tl->t; tn1 = VTAILQ_NEXT(tn1, list))
336 			VSB_printf(tl->sb, "%.*s", PF(tn1));
337 		VSB_cat(tl->sb, "'");
338 		sym = vcc_sym_in_tab(tl, st, kind, VCL_LOW, VCL_HIGH);
339 		if (sym != NULL && sym->kind != SYM_OBJECT &&
340 		    sym->kind != SYM_INSTANCE) { /* XXX: too specific */
341 			VSB_cat(tl->sb, " (Only available when");
342 			if (sym->lorev >= VCL_LOW)
343 				VSB_printf(tl->sb, " %.1f <=", .1 * sym->lorev);
344 			VSB_cat(tl->sb, " VCL syntax");
345 			if (sym->hirev <= VCL_HIGH)
346 				VSB_printf(tl->sb, " <= %.1f", .1 * sym->hirev);
347 			VSB_cat(tl->sb, ")");
348 		}
349 		VSB_cat(tl->sb, "\nAt: ");
350 		vcc_ErrWhere2(tl, t0, tl->t);
351 		return (NULL);
352 	}
353 	if (kind != SYM_NONE && kind != sym->kind) {
354 		VSB_cat(tl->sb, "Symbol '");
355 		for (tn1 = t0; tn1 != tl->t; tn1 = VTAILQ_NEXT(tn1, list))
356 			VSB_printf(tl->sb, "%.*s", PF(tn1));
357 		VSB_printf(tl->sb, "' has wrong type (%s), expected %s:",
358 		    sym->kind->name, kind->name);
359 		VSB_cat(tl->sb, "\nAt: ");
360 		vcc_ErrWhere2(tl, t0, tl->t);
361 		if (sym->def_b != NULL) {
362 			VSB_cat(tl->sb, "Symbol was defined here: ");
363 			vcc_ErrWhere(tl, sym->def_b);
364 		} else if (sym->ref_b != NULL) {
365 			VSB_cat(tl->sb, "Symbol was declared here: ");
366 			vcc_ErrWhere(tl, sym->ref_b);
367 		} else {
368 			VSB_cat(tl->sb, "Symbol was builtin\n");
369 		}
370 		return (NULL);
371 	}
372 	if (x == XREF_DEF) {
373 		if (sym->def_b == NULL)
374 			sym->def_b = t0;
375 		sym->ndef++;
376 	} else if (x == XREF_REF) {
377 		if (sym->ref_b == NULL)
378 			sym->ref_b = t0;
379 		sym->nref++;
380 	} else {
381 		assert (x == XREF_NONE);
382 	}
383 	return (sym);
384 }
385 
386 static struct symbol *
vcc_TypeSymbol(struct vcc * tl,vcc_ns_t ns,vcc_kind_t kind,vcc_type_t type)387 vcc_TypeSymbol(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind, vcc_type_t type)
388 {
389 	struct token t[1], *t0;
390 	struct symbol *sym;
391 	struct vsb *buf;
392 
393 	buf = VSB_new_auto();
394 	AN(buf);
395 	VSB_printf(buf, "%s.%.*s", type->name, PF(tl->t));
396 	AZ(VSB_finish(buf));
397 
398 	/* NB: we create a fake token but errors are handled by the caller. */
399 	memcpy(t, tl->t, sizeof *t);
400 	t->b = VSB_data(buf);
401 	t->e = t->b + VSB_len(buf);
402 
403 	t0 = tl->t;
404 	tl->t = t;
405 	sym = VCC_SymbolGet(tl, ns, kind, SYMTAB_NOERR, XREF_NONE);
406 	tl->t = t0;
407 	VSB_destroy(&buf);
408 
409 	return (sym);
410 }
411 
412 struct symbol *
VCC_TypeSymbol(struct vcc * tl,vcc_kind_t kind,vcc_type_t type)413 VCC_TypeSymbol(struct vcc *tl, vcc_kind_t kind, vcc_type_t type)
414 {
415 
416 	if (strchr(type->name, '.') == NULL)
417 		return (vcc_TypeSymbol(tl, SYM_TYPE, kind, type));
418 
419 	/* NB: type imported from a VMOD */
420 	return (vcc_TypeSymbol(tl, SYM_MAIN, kind, type));
421 }
422 
423 struct symbol *
VCC_MkSym(struct vcc * tl,const char * b,vcc_ns_t ns,vcc_kind_t kind,int vlo,int vhi)424 VCC_MkSym(struct vcc *tl, const char *b, vcc_ns_t ns, vcc_kind_t kind,
425     int vlo, int vhi)
426 {
427 	struct symtab *st;
428 	struct symbol *sym;
429 
430 	AN(tl);
431 	AN(b);
432 	CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
433 	CHECK_OBJ_NOTNULL(kind, KIND_MAGIC);
434 	assert(vlo <= vhi);
435 
436 	if (tl->syms[ns->id] == NULL)
437 		tl->syms[ns->id] = vcc_symtab_new("");
438 	st = vcc_symtab_str(tl->syms[ns->id], b, NULL);
439 	AN(st);
440 	sym = vcc_sym_in_tab(tl, st, kind, vlo, vhi);
441 	AZ(sym);
442 	sym = vcc_new_symbol(tl, st, kind, vlo, vhi);
443 	AN(sym);
444 	sym->noref = 1;
445 	return (sym);
446 }
447 
448 static void
vcc_walksymbols(struct vcc * tl,const struct symtab * root,symwalk_f * func,vcc_kind_t kind)449 vcc_walksymbols(struct vcc *tl, const struct symtab *root,
450     symwalk_f *func, vcc_kind_t kind)
451 {
452 	struct symbol *sym;
453 	struct symtab *st1, *st2 = NULL;
454 
455 	VTAILQ_FOREACH(sym, &root->symbols, list) {
456 		if (kind == SYM_NONE || kind == sym->kind)
457 			func(tl, sym);
458 		ERRCHK(tl);
459 	}
460 	VTAILQ_FOREACH(st1, &root->children, list) {
461 		if (st2 != NULL)
462 			assert(strcasecmp(st1->name, st2->name) >= 0);
463 		st2 = st1;
464 		vcc_walksymbols(tl, st1, func, kind);
465 		ERRCHK(tl);
466 	}
467 }
468 
469 void
VCC_WalkSymbols(struct vcc * tl,symwalk_f * func,vcc_ns_t ns,vcc_kind_t kind)470 VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, vcc_ns_t ns, vcc_kind_t kind)
471 {
472 
473 	CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
474 	vcc_walksymbols(tl, tl->syms[ns->id], func, kind);
475 }
476 
477 void
VCC_GlobalSymbol(struct symbol * sym,vcc_type_t type,const char * pfx)478 VCC_GlobalSymbol(struct symbol *sym, vcc_type_t type, const char *pfx)
479 {
480 	struct vsb *vsb;
481 
482 	CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
483 	AN(pfx);
484 
485 	vsb = VSB_new_auto();
486 	AN(vsb);
487 	VSB_printf(vsb, "%s_", pfx);
488 	VCC_PrintCName(vsb, sym->name, NULL);
489 	AZ(VSB_finish(vsb));
490 	sym->lname = strdup(VSB_data(vsb));
491 	AN(sym->lname);
492 	if (type == SUB) {
493 		VSB_destroy(&vsb);
494 		vsb = VSB_new_auto();
495 		AN(vsb);
496 		VSB_printf(vsb, "sub_%s", sym->lname);
497 		AZ(VSB_finish(vsb));
498 	}
499 	sym->rname = strdup(VSB_data(vsb));
500 	AN(sym->rname);
501 	VSB_destroy(&vsb);
502 
503 	sym->type = type;
504 	sym->kind = VCC_HandleKind(sym->type);
505 	if (sym->kind != SYM_NONE) {
506 		AZ(VCT_invalid_name(sym->rname, NULL));
507 		sym->eval = vcc_Eval_Handle;
508 	} else {
509 		WRONG("Wrong kind of global symbol");
510 	}
511 
512 #define VCL_MET_MAC(l,u,t,b)   sym->r_methods |= VCL_MET_##u;
513 #include "tbl/vcl_returns.h"
514 }
515 
516 struct symbol *
VCC_HandleSymbol(struct vcc * tl,vcc_type_t fmt,const char * pfx)517 VCC_HandleSymbol(struct vcc *tl, vcc_type_t fmt, const char *pfx)
518 {
519 	struct symbol *sym;
520 	vcc_kind_t kind;
521 	struct token *t;
522 	const char *p;
523 
524 	kind = VCC_HandleKind(fmt);
525 	assert(kind != SYM_NONE);
526 
527 	t = tl->t;
528 	sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_NONE);
529 	if (sym != NULL && sym->def_b != NULL && kind == sym->kind) {
530 		p = sym->kind->name;
531 		VSB_printf(tl->sb, "%c%s '%.*s' redefined.\n",
532 		    toupper(*p), p + 1, PF(t));
533 		vcc_ErrWhere(tl, t);
534 		VSB_cat(tl->sb, "First definition:\n");
535 		AN(sym->def_b);
536 		vcc_ErrWhere(tl, sym->def_b);
537 		return (sym);
538 	} else if (sym != NULL && sym->def_b != NULL) {
539 		VSB_printf(tl->sb, "Name '%.*s' already defined.\n", PF(t));
540 		vcc_ErrWhere(tl, t);
541 		VSB_cat(tl->sb, "First definition:\n");
542 		AN(sym->def_b);
543 		vcc_ErrWhere(tl, sym->def_b);
544 		return (sym);
545 	} else if (sym != NULL && sym->kind != kind) {
546 		VSB_printf(tl->sb,
547 		    "Name %.*s must have type '%s'.\n",
548 		    PF(t), sym->kind->name);
549 		vcc_ErrWhere(tl, t);
550 		return (sym);
551 	}
552 	if (sym == NULL)
553 		sym = VCC_SymbolGet(tl, SYM_MAIN, kind, SYMTAB_CREATE,
554 		    XREF_NONE);
555 	if (sym == NULL)
556 		return (NULL);
557 	AN(sym);
558 	AZ(sym->ndef);
559 	VCC_GlobalSymbol(sym, fmt, pfx);
560 	sym->ndef = 1;
561 	if (sym->def_b == NULL)
562 		sym->def_b = t;
563 	return (sym);
564 }
565 /*lint -restore */
566