[master] d032e522e Make VCC produce a "proper" symbol table for the compiled VCL.
Poul-Henning Kamp
phk at FreeBSD.org
Wed May 22 08:50:15 UTC 2019
commit d032e522e9e9d294569b3aa15ab6fc2e657fe7af
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed May 22 08:48:00 2019 +0000
Make VCC produce a "proper" symbol table for the compiled VCL.
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 88844c295..c50e44dd3 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -422,7 +422,7 @@ VCL_Close(struct vcl **vclp)
}
/*--------------------------------------------------------------------
- * NB: This function is called from the test-load subprocess.
+ * NB: This function is called in/from the test-load subprocess.
*/
int
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 7575de2d8..78f79ce4d 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -48,6 +48,7 @@
#include "common/common_param.h"
+struct vjsn;
struct vsc_seg;
struct vsmw_cluster;
#include "VSC_mgt.h"
@@ -216,8 +217,7 @@ void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin,
int mgt_push_vcls(struct cli *, unsigned *status, char **p);
void mgt_vcl_export_labels(struct vcc *);
int mgt_has_vcl(void);
-void mgt_vcl_depends(struct vclprog *vp1, const char *name);
-void mgt_vcl_vmod(struct vclprog *, const char *src, const char *dst);
+void mgt_vcl_symtab(struct vclprog *, struct vjsn *);
extern char *mgt_cc_cmd;
extern const char *mgt_vcl_path;
extern const char *mgt_vmod_path;
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 8a4074efa..6187c8d97 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -45,8 +45,8 @@
#include "libvcc.h"
#include "vcli_serve.h"
#include "vfil.h"
+#include "vjsn.h"
#include "vsub.h"
-#include "vav.h"
#include "vtim.h"
struct vcc_priv {
@@ -57,6 +57,7 @@ struct vcc_priv {
const char *vclsrcfile;
char *csrcfile;
char *libfile;
+ char *symfile;
};
char *mgt_cc_cmd;
@@ -69,6 +70,7 @@ unsigned mgt_vcc_unsafe_path;
#define VGC_SRC "vgc.c"
#define VGC_LIB "vgc.so"
+#define VGC_SYM "vgc.sym"
/*--------------------------------------------------------------------*/
@@ -107,7 +109,8 @@ run_vcc(void *priv)
STV_Foreach(stv)
VCC_Predef(vcc, "VCL_STEVEDORE", stv->ident);
mgt_vcl_export_labels(vcc);
- i = VCC_Compile(vcc, &sb, vp->vclsrc, vp->vclsrcfile, VGC_SRC);
+ i = VCC_Compile(vcc, &sb, vp->vclsrc, vp->vclsrcfile,
+ VGC_SRC, VGC_SYM);
if (VSB_len(sb))
printf("%s", VSB_data(sb));
VSB_destroy(&sb);
@@ -212,7 +215,9 @@ static unsigned
mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
{
char *csrc;
+ const char *err;
unsigned subs;
+ struct vjsn *vj;
if (mgt_vcc_touchfile(vp->csrcfile, sb))
return (2);
@@ -228,6 +233,18 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
AN(csrc);
VSB_cat(sb, csrc);
free(csrc);
+
+ VSB_printf(sb, "/* EXTERNAL SYMBOL TABLE\n");
+ csrc = VFIL_readfile(NULL, vp->symfile, NULL);
+ AN(csrc);
+ VSB_cat(sb, csrc);
+ vj = vjsn_parse(csrc, &err);
+ if (err != NULL)
+ VSB_printf(sb, "# Parse error: %s\n", err);
+ if (vj != NULL)
+ vjsn_delete(&vj);
+ VSB_printf(sb, "*/\n");
+ free(csrc);
}
subs = VSUB_run(sb, run_cc, vp, "C-compiler", 10);
@@ -246,11 +263,10 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
{
struct vcc_priv vp;
struct vsb *sb;
+ struct vjsn *vj;
unsigned status;
- char buf[1024];
- FILE *fcs;
- char **av;
- int ac;
+ const char *err;
+ char *p;
AN(cli);
@@ -319,6 +335,12 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
AN(vp.csrcfile);
VSB_clear(sb);
+ VSB_printf(sb, "%s/%s", vp.dir, VGC_SYM);
+ AZ(VSB_finish(sb));
+ vp.symfile = strdup(VSB_data(sb));
+ AN(vp.symfile);
+ VSB_clear(sb);
+
status = mgt_vcc_compile(&vp, sb, C_flag);
AZ(VSB_finish(sb));
@@ -330,6 +352,7 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
if (!MGT_DO_DEBUG(DBG_VCL_KEEP)) {
(void)unlink(vp.csrcfile);
(void)unlink(vp.libfile);
+ (void)unlink(vp.symfile);
(void)rmdir(vp.dir);
}
free(vp.csrcfile);
@@ -342,26 +365,17 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
return (NULL);
}
- fcs = fopen(vp.csrcfile, "r");
- AN(fcs);
- while (1) {
- AN(fgets(buf, sizeof buf, fcs));
- if (memcmp(buf, VCC_INFO_PREFIX, strlen(VCC_INFO_PREFIX)))
- break;
- av = VAV_Parse(buf, &ac, 0);
- AN(av);
- AZ(av[0]);
- AZ(strcmp(av[1], "/*"));
- AZ(strcmp(av[ac-1], "*/"));
- if (!strcmp(av[3], "VCL"))
- mgt_vcl_depends(vcl, av[4]);
- else if (!strcmp(av[3], "VMOD"))
- mgt_vcl_vmod(vcl, av[4], av[5]);
- else
- WRONG("Wrong VCCINFO");
- VAV_Free(av);
- }
- AZ(fclose(fcs));
+ p = VFIL_readfile(NULL, vp.symfile, NULL);
+ AN(p);
+ vj = vjsn_parse(p, &err);
+ if (err != NULL)
+ fprintf(stderr, "FATAL: Symtab parse error: %s\n%s\n",
+ err, p);
+ AZ(err);
+ AN(vj);
+ free(p);
+ mgt_vcl_symtab(vcl, vj);
+ (void)unlink(vp.symfile);
if (!MGT_DO_DEBUG(DBG_VCL_KEEP))
(void)unlink(vp.csrcfile);
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 2710e82fd..1a388248c 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -45,6 +45,7 @@
#include "vcli_serve.h"
#include "vct.h"
#include "vev.h"
+#include "vjsn.h"
#include "vtim.h"
#define VCL_STATE(sym, str) \
@@ -84,6 +85,7 @@ struct vclprog {
unsigned warm;
const char * state;
double go_cold;
+ struct vjsn *symtab;
VTAILQ_HEAD(, vcldep) dfrom;
VTAILQ_HEAD(, vcldep) dto;
int nto;
@@ -309,17 +311,32 @@ mgt_vcl_del(struct vclprog *vp)
}
}
free(vp->name);
+ if (vp->symtab)
+ vjsn_delete(&vp->symtab);
FREE_OBJ(vp);
}
-void
-mgt_vcl_depends(struct vclprog *vp1, const char *name)
+static const char *
+mgt_vcl_symtab_val(const struct vjsn_val *vv, const char *val)
+{
+ const struct vjsn_val *jv;
+
+ jv = vjsn_child(vv, val);
+ AN(jv);
+ assert(jv->type == VJSN_STRING);
+ AN(jv->value);
+ return (jv->value);
+}
+
+static void
+mgt_vcl_import_vcl(struct vclprog *vp1, const struct vjsn_val *vv)
{
struct vclprog *vp2;
CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
+ AN(vv);
- vp2 = mcf_vcl_byname(name);
+ vp2 = mcf_vcl_byname(mgt_vcl_symtab_val(vv, "name"));
CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
mgt_vcl_dep_add(vp1, vp2);
}
@@ -336,8 +353,8 @@ mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
if (fo < 0 && errno == EEXIST)
return (0);
if (fo < 0) {
- fprintf(stderr, "Creating copy of vmod %s: %s\n",
- nm, vstrerror(errno));
+ fprintf(stderr, "While creating copy of vmod %s:\n\t%s: %s\n",
+ nm, to, vstrerror(errno));
return (1);
}
fi = open(fm, O_RDONLY);
@@ -366,27 +383,32 @@ mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
return (ret);
}
-void
-mgt_vcl_vmod(struct vclprog *vp, const char *src, const char *dst)
+static void
+mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
{
struct vmodfile *vf;
struct vmoddep *vd;
+ const char *v_name;
+ const char *v_file;
+ const char *v_dst;
CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
- AN(src);
- AN(dst);
- assert(!strncmp(dst, "./vmod_cache/", 13));
+ AN(vv);
+
+ v_name = mgt_vcl_symtab_val(vv, "name");
+ v_file = mgt_vcl_symtab_val(vv, "file");
+ v_dst = mgt_vcl_symtab_val(vv, "dst");
VTAILQ_FOREACH(vf, &vmodhead, list)
- if (!strcmp(vf->fname, dst))
+ if (!strcmp(vf->fname, v_dst))
break;
if (vf == NULL) {
ALLOC_OBJ(vf, VMODFILE_MAGIC);
AN(vf);
- REPLACE(vf->fname, dst);
+ REPLACE(vf->fname, v_dst);
AN(vf->fname);
VTAILQ_INIT(&vf->vcls);
- AZ(mgt_vcl_cache_vmod(vp->name, src, dst));
+ AZ(mgt_vcl_cache_vmod(v_name, v_file, v_dst));
VTAILQ_INSERT_TAIL(&vmodhead, vf, list);
}
ALLOC_OBJ(vd, VMODDEP_MAGIC);
@@ -396,6 +418,33 @@ mgt_vcl_vmod(struct vclprog *vp, const char *src, const char *dst)
VTAILQ_INSERT_TAIL(&vf->vcls, vd, lto);
}
+void
+mgt_vcl_symtab(struct vclprog *vp, struct vjsn *vj)
+{
+ struct vjsn_val *v1, *v2;
+ const char *typ;
+
+ CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+ vp->symtab = vj;
+ assert(vj->value->type == VJSN_ARRAY);
+ VTAILQ_FOREACH(v1, &vj->value->children, list) {
+ assert(v1->type == VJSN_OBJECT);
+ v2 = vjsn_child(v1, "dir");
+ if (v2 == NULL)
+ continue;
+ assert(v2->type == VJSN_STRING);
+ if (strcmp(v2->value, "import"))
+ continue;
+ typ = mgt_vcl_symtab_val(v1, "type");
+ if (!strcmp(typ, "$VMOD"))
+ mgt_vcl_import_vmod(vp, v1);
+ else if (!strcmp(typ, "$VCL"))
+ mgt_vcl_import_vcl(vp, v1);
+ else
+ WRONG("Bad symtab import entry");
+ }
+}
+
int
mgt_has_vcl(void)
{
diff --git a/include/libvcc.h b/include/libvcc.h
index 45f012a1a..10ed6f04d 100644
--- a/include/libvcc.h
+++ b/include/libvcc.h
@@ -30,8 +30,6 @@
struct vcc;
-#define VCC_INFO_PREFIX "/* VCC_INFO"
-
struct vcc *VCC_New(void);
void VCC_Allow_InlineC(struct vcc *, unsigned);
void VCC_Builtin_VCL(struct vcc *, const char *);
@@ -43,4 +41,4 @@ void VCC_Predef(struct vcc *, const char *type, const char *name);
void VCC_VCL_Range(unsigned *, unsigned *);
int VCC_Compile(struct vcc *, struct vsb **,
- const char *, const char *, const char *);
+ const char *, const char *, const char *, const char *);
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 8126f9924..4e547a2ab 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -273,8 +273,11 @@ vcc_act_return_vcl(struct vcc *tl)
ERRCHK(tl);
AN(sym);
if (sym->eval_priv == NULL) {
- VSB_printf(tl->fi, "%s VCL %s */\n", VCC_INFO_PREFIX,
- sym->name);
+ VSB_printf(tl->symtab, ",\n {\n");
+ VSB_printf(tl->symtab, "\t\"dir\": \"import\",\n");
+ VSB_printf(tl->symtab, "\t\"type\": \"$VCL\",\n");
+ VSB_printf(tl->symtab, "\t\"name\": \"%s\"\n", sym->name);
+ VSB_printf(tl->symtab, " }");
bprintf(buf, "vgc_vcl_%u", tl->unique++);
sym->eval_priv = strdup(buf);
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index 8b8c2e9d3..cfbc62c2e 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -94,6 +94,30 @@ TlDup(struct vcc *tl, const char *s)
return (p);
}
+static int
+TLWriteVSB(struct vcc *tl, const char *fn, const struct vsb *vsb,
+ const char *what)
+{
+ int fo;
+ int i;
+
+ fo = open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0600);
+ if (fo < 0) {
+ VSB_printf(tl->sb,
+ "Could not open %s file %s: %s\n",
+ what, fn, strerror(errno));
+ return (-1);
+ }
+ i = VSB_tofile(fo, vsb);
+ if (i) {
+ VSB_printf(tl->sb,
+ "Could not write %s to %s: %s\n",
+ what, fn, strerror(errno));
+ }
+ closefd(&fo);
+ return (i);
+}
+
/*--------------------------------------------------------------------*/
struct proc *
@@ -590,7 +614,7 @@ vcc_resolve_includes(struct vcc *tl)
*/
static struct vsb *
-vcc_CompileSource(struct vcc *tl, struct source *sp)
+vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
{
struct proc *p;
struct vsb *vsb;
@@ -691,14 +715,16 @@ vcc_CompileSource(struct vcc *tl, struct source *sp)
VCC_XrefTable(tl);
+ VSB_printf(tl->symtab, "\n]\n");
+ AZ(VSB_finish(tl->symtab));
+ if (TLWriteVSB(tl, jfile, tl->symtab, "Symbol table"))
+ return (NULL);
+
/* Combine it all */
vsb = VSB_new_auto();
AN(vsb);
- AZ(VSB_finish(tl->fi));
- VSB_cat(vsb, VSB_data(tl->fi));
-
vcl_output_lang_h(vsb);
EmitCoordinates(tl, vsb);
@@ -734,38 +760,27 @@ VCC_VCL_Range(unsigned *lo, unsigned *hi)
int
VCC_Compile(struct vcc *tl, struct vsb **sb,
const char *vclsrc, const char *vclsrcfile,
- const char *ofile)
+ const char *ofile, const char *jfile)
{
struct source *sp;
struct vsb *r = NULL;
- int fo, retval = 0;
+ int retval = 0;
CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
AN(sb);
AN(vclsrcfile);
AN(ofile);
+ AN(jfile);
if (vclsrc != NULL)
sp = vcc_new_source(vclsrc, NULL, vclsrcfile);
else
sp = vcc_file_source(tl, vclsrcfile);
if (sp != NULL)
- r = vcc_CompileSource(tl, sp);
+ r = vcc_CompileSource(tl, sp, jfile);
if (r != NULL) {
- fo = open(ofile, O_WRONLY|O_TRUNC|O_CREAT, 0600);
- if (fo < 0) {
- VSB_printf(tl->sb,
- "Could not open C-source file %s: %s\n",
- ofile, strerror(errno));
- } else {
- if (VSB_tofile(fo, r)) {
- VSB_printf(tl->sb,
- "Could not write C-source to %s: %s\n",
- ofile, strerror(errno));
- }
- closefd(&fo);
- }
+ retval = TLWriteVSB(tl, ofile, r, "C-source");
VSB_destroy(&r);
} else {
retval = -1;
@@ -798,8 +813,9 @@ VCC_New(void)
tl->nsources = 0;
- tl->fi = VSB_new_auto();
- assert(tl->fi != NULL);
+ tl->symtab = VSB_new_auto();
+ assert(tl->symtab != NULL);
+ VSB_printf(tl->symtab, "[\n {\"version\": 0}");
tl->fc = VSB_new_auto();
assert(tl->fc != NULL);
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 20213c0b9..aa4496316 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -237,7 +237,7 @@ struct vcc {
int hindent;
unsigned cnt;
- struct vsb *fi; /* VCC info to MGT */
+ struct vsb *symtab; /* VCC info to MGT */
struct vsb *fc; /* C-code */
struct vsb *fh; /* H-code (before C-code) */
struct vsb *fb; /* Body of current sub
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 38863ceb5..a9c2ffe33 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -357,8 +357,15 @@ vcc_ParseImport(struct vcc *tl)
VSB_printf(ifp->ini, "\t ))\n");
VSB_printf(ifp->ini, "\t\treturn(1);");
- VSB_printf(tl->fi, "%s VMOD %s ./vmod_cache/_vmod_%.*s.%s */\n",
- VCC_INFO_PREFIX, fnpx, PF(mod), vmd->file_id);
+ VSB_printf(tl->symtab, ",\n {\n");
+ VSB_printf(tl->symtab, "\t\"dir\": \"import\",\n");
+ VSB_printf(tl->symtab, "\t\"type\": \"$VMOD\",\n");
+ VSB_printf(tl->symtab, "\t\"name\": \"%.*s\",\n", PF(mod));
+ VSB_printf(tl->symtab, "\t\"file\": \"%s\",\n", fnpx);
+ VSB_printf(tl->symtab,
+ "\t\"dst\": \"./vmod_cache/_vmod_%.*s.%s\"\n",
+ PF(mod), vmd->file_id);
+ VSB_printf(tl->symtab, " }");
/* XXX: zero the function pointer structure ?*/
VSB_printf(ifp->fin, "\t\tVRT_priv_fini(&vmod_priv_%.*s);", PF(mod));
More information about the varnish-commit
mailing list