diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-11-26 22:43:30 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2024-04-21 01:51:24 +0200 |
| commit | f25b015e5b668028c34974bbb22faa4105c26690 (patch) | |
| tree | 28f2b08c17b3585d06694ad74004d0617eadb785 /src/search.c | |
| download | nanowasm-sync-f25b015e5b668028c34974bbb22faa4105c26690.tar.gz | |
First commit
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/search.c b/src/search.c new file mode 100644 index 0000000..622b74c --- /dev/null +++ b/src/search.c @@ -0,0 +1,181 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2024 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include <nw/search.h> +#include <nw/log.h> +#include <nw/fstring.h> +#include <nw/sections.h> +#include <nanowasm/nw.h> +#include <nw/types.h> +#include <errno.h> +#include <stdint.h> +#include <string.h> + +static int ensure_export(const char *const fn, + const struct nw_mod *const m, FILE *const f, varuint32 *const out) +{ + if (!m->sections.export) + { + LOG("%s: export section not found", __func__); + return -1; + } + else if (fseek(f, m->sections.export, SEEK_SET)) + { + LOG("%s: fseek(3): %s\n", __func__, strerror(errno)); + return -1; + } + + varuint32 count; + + if (varuint32_read(f, &count)) + { + LOG("%s: varuint32_read failed\n", __func__); + return -1; + } + + for (varuint32 i = 0; i < count; i++) + { + varuint32 len; + bool found = false; + + if (varuint32_read(f, &len)) + { + LOG("%s: varuint32_read failed\n", __func__); + return -1; + } + else if (len != strlen(fn)) + { + if (fseek(f, len, SEEK_CUR)) + { + LOG("%s: fseek(3): %s\n", __func__, strerror(errno)); + return -1; + } + } + else if (!fstrcmp(fn, f, false)) + found = true; + + uint8_t kind; + + if (!fread(&kind, sizeof kind, 1, f)) + { + LOG("%s: fread(3) failed: feof=%d, ferror=%d\n", __func__, + feof(f), ferror(f)); + return -1; + } + + varuint32 index; + + if (varuint32_read(f, &index)) + { + LOG("%s: varuint32_read failed\n", __func__); + return -1; + } + else if (found) + { + if (kind != NW_KIND_FUNCTION) + { + LOG("%s: expected kind %d, got %d\n", __func__, + NW_KIND_FUNCTION, kind); + return -1; + } + + *out = index; + return 0; + } + } + + return -1; +} + +static int get_function_index(const struct nw_mod *const m, + const varuint32 index, varuint32 *const findex) +{ + const size_t n = m->cfg.n_imports; + + if (index < n) + { + LOG("%s: index (%lu) must be greater than number of imports (%zu)\n", + __func__, (unsigned long)index, n); + return -1; + } + + *findex = index - n; + return 0; +} + +static int get_fn_start(const struct nw_mod *const m, FILE *const f, + const varuint32 index, struct search_fn *const out) +{ + const struct section s = + { + .cfg = &m->cfg, + .f = f + }; + + struct section_function sf; + struct section_code c; + + if (section_function(&s, m, index, &sf)) + { + LOG("%s: section_function failed\n", __func__); + return -1; + } + else if (section_code(&s, m, index, &c)) + { + LOG("%s: section_code failed\n", __func__); + return -1; + } + + out->start = c.start; + out->index = index; + return 0; +} + +int search_exported_fn(const char *const fn, const struct nw_mod *const m, + FILE *const f, struct search_fn *const out) +{ + varuint32 index, findex; + + if (ensure_export(fn, m, f, &index)) + { + LOG("%s: %s not an exported function\n", __func__, fn); + return -1; + } + else if (get_function_index(m, index, &findex)) + { + LOG("%s: get_function_index failed\n", __func__); + return -1; + } + else if (get_fn_start(m, f, findex, out)) + { + LOG("%s: get_fn_start %s failed\n", __func__, fn); + return -1; + } + + return 0; +} + +int search_fn(const varuint32 index, const struct nw_mod *const m, + FILE *const f, struct search_fn *const out) +{ + varuint32 findex; + + if (get_function_index(m, index, &findex)) + { + LOG("%s: get_function_index failed\n", __func__); + return -1; + } + else if (get_fn_start(m, f, findex, out)) + { + LOG("%s: get_fn_start failed\n", __func__); + return -1; + } + + return 0; +} |
