diff options
Diffstat (limited to 'src/section/global.c')
| -rw-r--r-- | src/section/global.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/section/global.c b/src/section/global.c new file mode 100644 index 0000000..5616e21 --- /dev/null +++ b/src/section/global.c @@ -0,0 +1,110 @@ +#include <sections.h> +#include <interp.h> +#include <wasm_types.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +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; +} |
