#include #include #include #include #include #include struct global_type { varint7 value_type; varuint1 mutability; }; static int check_global_type(FILE *const f, struct global_type *const g) { if (varint7_read(f, &g->value_type)) { fprintf(stderr, "%s: varint7_read failed\n", __func__); return -1; } else if (varuint1_read(f, &g->mutability)) { fprintf(stderr, "%s: varuint1_read failed\n", __func__); return -1; } return 0; } static int check(FILE *const f, const unsigned long len) { int ret = -1; struct global_type g; struct interp *i = NULL; const long start = ftell(f); const struct interp_cfg cfg = { .f = f }; if (start < 0) { fprintf(stderr, "%s: ftell(3): %s\n", __func__, strerror(errno)); return -1; } else if (check_global_type(f, &g)) { fprintf(stderr, "%s: check_global_type\n", __func__); goto end; } else if (!(i = interp_alloc(&cfg))) { fprintf(stderr, "%s: interp_alloc failed\n", __func__); goto end; } else if (interp_run_limited(i, &interp_initexpr_set)) { fprintf(stderr, "%s: interp_run failed\n", __func__); goto end; } const long end = ftell(f); if (end < 0) { fprintf(stderr, "%s: ftell(3): %s\n", __func__, strerror(errno)); return -1; } const unsigned long size = end - start; if (size != len) { fprintf(stderr, "%s: size exceeded (%lu expected, got %lu)\n", __func__, len, size); return -1; } ret = 0; end: interp_free(i); return ret; } int section_global(struct wasmfs *const w, FILE *const f, const unsigned long len) { if (w->sections.global) { fprintf(stderr, "%s: ignoring duplicate section\n", __func__); return 0; } const long offset = ftell(f); if (offset < 0) { fprintf(stderr, "%s: ftell(3): %s\n", __func__, strerror(errno)); return -1; } else if (check(f, len)) { fprintf(stderr, "%s: check failed\n", __func__); return -1; } w->sections.global = offset; return 0; }