From b4302557b93f97e9c5fb77ca6321b13f2606cdd8 Mon Sep 17 00:00:00 2001 From: tyfkda <tyfkda@gmail.com> Date: Tue, 15 Oct 2024 19:55:05 +0900 Subject: [PATCH] Generate function in linker only if needed `__wasm_call_ctors`: Function which calls constructors --- src/wcc/wasm_linker.c | 107 ++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/src/wcc/wasm_linker.c b/src/wcc/wasm_linker.c index 11239406f..7525c58d3 100644 --- a/src/wcc/wasm_linker.c +++ b/src/wcc/wasm_linker.c @@ -23,6 +23,8 @@ #define ADD_ULEB128(x) data_uleb128(CODE, -1, x) #define ADD_VARUINT32(x) data_varuint32(CODE, -1, x) +static const char LINKER_GENERATED_FILENAME[] = "*linker-generated*"; + static int64_t read_leb128(unsigned char *p, unsigned char **next) { int64_t result = 0; int shift = 0; @@ -642,6 +644,58 @@ static int resolve_symbols_archive(WasmLinker *linker, Archive *ar) { return 0; } +static void resolve_symbols_auto_fill(WasmLinker *linker) { + const Name *call_ctors_name = alloc_name("__wasm_call_ctors", NULL, false); + WasmObj *obj = NULL; + if (table_get(&linker->unresolved, call_ctors_name) != NULL) { + // Prepare linker generated wasmobj. + obj = calloc_or_die(sizeof(*obj)); + obj->linking.symtab = new_vector(); + + // Funcion type. + obj->types = new_vector(); + { + static const unsigned char functype[] = {0x00, 0x00}; + unsigned char *dup = malloc_or_die(sizeof(functype)); + memcpy(dup, functype, sizeof(functype)); + int index = getsert_func_type(dup, sizeof(functype), true); + vec_push(obj->types, INT2VOIDP(index)); + } + + File *file = calloc_or_die(sizeof(*file)); + file->filename = LINKER_GENERATED_FILENAME; + file->kind = FK_WASMOBJ; + file->wasmobj = obj; + vec_push(linker->files, file); + + // Register symbol `__wasm_call_ctors`. + SymbolInfo *sym = calloc_or_die(sizeof(*sym)); + sym->kind = SIK_SYMTAB_FUNCTION; + sym->module_name = NULL; + sym->name = call_ctors_name; + vec_push(obj->linking.symtab, sym); + + // Function + int section_count = 1; + WasmSection *sections = calloc_or_die(sizeof(*sections) * section_count); + obj->section_count = section_count; + obj->sections = sections; + { + WasmSection *p = §ions[0]; + p->id = SEC_CODE; + p->start = NULL; + p->size = 0; + } + obj->func.count = 1; + } + + if (obj != NULL) { + int err_count = resolve_symbols_wasmobj(linker, obj); + UNUSED(err_count); + assert(err_count == 0); + } +} + static bool resolve_symbols(WasmLinker *linker) { int err_count = 0; @@ -658,6 +712,8 @@ static bool resolve_symbols(WasmLinker *linker) { } } + resolve_symbols_auto_fill(linker); + // Enumerate unresolved: import const Name *wasi_module_name = alloc_name(WASI_MODULE_NAME, NULL, false); uint32_t unresolved_func_count = 0; @@ -705,6 +761,14 @@ static bool resolve_symbols(WasmLinker *linker) { } static void generate_init_funcs(WasmLinker *linker) { + if (linker->files->len <= 0) + return; + + // Assume the linker generated wasmobj is the last one. + File *generated = linker->files->data[linker->files->len - 1]; + if (strcmp(generated->filename, LINKER_GENERATED_FILENAME) != 0) + return; + Vector *init_funcs = new_vector(); for (int i = 0; i < linker->files->len; ++i) { File *file = linker->files->data[i]; @@ -729,7 +793,8 @@ static void generate_init_funcs(WasmLinker *linker) { } // Generate - WasmObj *wasmobj = ((File*)linker->files->data[0])->wasmobj; + assert(generated->kind == FK_WASMOBJ); + WasmObj *wasmobj = generated->wasmobj; WasmSection *codesec = &wasmobj->sections[0]; assert(codesec->id == SEC_CODE); DataStorage ds; @@ -1412,46 +1477,6 @@ void linker_init(WasmLinker *linker) { linker->sp_name = alloc_name(SP_NAME, NULL, false); linker->curbrk_name = alloc_name(BREAK_ADDRESS_NAME, NULL, false); - - // Prepare linker generated wasmobj. - WasmObj *obj = calloc_or_die(sizeof(*obj)); - obj->linking.symtab = new_vector(); - - // Funcion type. - obj->types = new_vector(); - { - static const unsigned char functype[] = {0x00, 0x00}; - unsigned char *dup = malloc_or_die(sizeof(functype)); - memcpy(dup, functype, sizeof(functype)); - int index = getsert_func_type(dup, sizeof(functype), true); - vec_push(obj->types, INT2VOIDP(index)); - } - - File *file = calloc_or_die(sizeof(*file)); - file->filename = "*linker-generated*"; - file->kind = FK_WASMOBJ; - file->wasmobj = obj; - vec_push(linker->files, file); - - // Register symbol `__wasm_call_ctors`. - SymbolInfo *sym = calloc_or_die(sizeof(*sym)); - sym->kind = SIK_SYMTAB_FUNCTION; - sym->module_name = NULL; - sym->name = alloc_name("__wasm_call_ctors", NULL, false); - vec_push(obj->linking.symtab, sym); - - // Function - int section_count = 1; - WasmSection *sections = calloc_or_die(sizeof(*sections) * section_count); - obj->section_count = section_count; - obj->sections = sections; - { - WasmSection *p = §ions[0]; - p->id = SEC_CODE; - p->start = NULL; - p->size = 0; - } - obj->func.count = 1; } bool read_wasm_obj(WasmLinker *linker, const char *filename) {