aboutsummaryrefslogtreecommitdiff
path: root/src/section/type.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-11-26 22:43:30 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-12-29 23:36:21 +0100
commit52c18e60929b64285d4bb333f87482d954c9b2e0 (patch)
tree836ab3a01d160f45cda4f5a28522fc0bf471011c /src/section/type.c
downloadnanowasm-52c18e60929b64285d4bb333f87482d954c9b2e0.tar.gz
First commitfirst-step
Diffstat (limited to 'src/section/type.c')
-rw-r--r--src/section/type.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/section/type.c b/src/section/type.c
new file mode 100644
index 0000000..fad2208
--- /dev/null
+++ b/src/section/type.c
@@ -0,0 +1,126 @@
+#include <sections.h>
+#include <wasm_types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+static int check_value_type(FILE *const f)
+{
+ varint7 value_type;
+
+ if (varint7_read(f, &value_type))
+ {
+ fprintf(stderr, "%s: varint7_read failed\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int check_func_type(FILE *const f)
+{
+ varint7 form;
+ varuint32 param_count;
+
+ if (varint7_read(f, &form))
+ {
+ fprintf(stderr, "%s: varint7_read failed\n", __func__);
+ return -1;
+ }
+ else if (varuint32_read(f, &param_count))
+ {
+ fprintf(stderr, "%s: varuint32_read failed\n", __func__);
+ return -1;
+ }
+
+ for (varuint32 i = 0; i < param_count; i++)
+ if (check_value_type(f))
+ {
+ fprintf(stderr, "%s: check_value_type failed\n", __func__);
+ return -1;
+ }
+
+ varuint1 return_count;
+
+ if (varuint1_read(f, &return_count))
+ {
+ fprintf(stderr, "%s: varuint1_read failed\n", __func__);
+ return -1;
+ }
+ else if (return_count && check_value_type(f))
+ {
+ fprintf(stderr, "%s: check_value_type 2 failed\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int check(FILE *const f, const unsigned long len)
+{
+ const long start = ftell(f);
+ varuint32 count;
+
+ if (start < 0)
+ {
+ fprintf(stderr, "%s: ftell(3): %s\n", __func__, strerror(errno));
+ return -1;
+ }
+ else if (varuint32_read(f, &count))
+ {
+ fprintf(stderr, "%s: varuint32_read failed\n", __func__);
+ return -1;
+ }
+
+ for (varuint32 i = 0; i < count; i++)
+ if (check_func_type(f))
+ {
+ fprintf(stderr, "%s: check_func_type failed\n", __func__);
+ return -1;
+ }
+
+ 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;
+ }
+
+ return 0;
+}
+
+int section_type(struct wasmfs *const w, FILE *const f,
+ const unsigned long len)
+{
+ if (w->sections.type)
+ {
+ 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.type = offset;
+ return 0;
+}