diff options
-rw-r--r-- | src/binary-reader-linker.cc | 80 | ||||
-rw-r--r-- | src/binary-reader.cc | 2 | ||||
-rw-r--r-- | src/binary-writer.cc | 34 | ||||
-rw-r--r-- | test/binary/bad-duplicate-subsection.txt | 1 | ||||
-rw-r--r-- | test/binary/bad-name-section-invalid-index.txt | 25 | ||||
-rw-r--r-- | test/binary/bad-subsection-out-of-order.txt | 1 | ||||
-rw-r--r-- | test/binary/bad-subsection-size.txt | 1 | ||||
-rw-r--r-- | test/binary/bad-subsection-unfinished.txt | 1 | ||||
-rw-r--r-- | test/dump/debug-names.txt | 172 | ||||
-rw-r--r-- | test/link/names_import_only.txt | 27 |
10 files changed, 191 insertions, 153 deletions
diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc index 40d3c420..0da7b9c2 100644 --- a/src/binary-reader-linker.cc +++ b/src/binary-reader-linker.cc @@ -34,8 +34,6 @@ class BinaryReaderLinker : public BinaryReaderNop { virtual Result BeginSection(BinarySection section_type, uint32_t size); - virtual Result BeginCustomSection(uint32_t size, StringSlice section_name); - virtual Result OnImport(uint32_t index, StringSlice module_name, StringSlice field_name); @@ -51,6 +49,8 @@ class BinaryReaderLinker : public BinaryReaderNop { Type type, bool mutable_); + virtual Result OnFunctionCount(uint32_t count); + virtual Result OnTable(uint32_t index, Type elem_type, const Limits* elem_limits); @@ -70,6 +70,8 @@ class BinaryReaderLinker : public BinaryReaderNop { const void* data, uint32_t size); + virtual Result BeginNamesSection(uint32_t size); + virtual Result OnFunctionName(uint32_t function_index, StringSlice function_name); @@ -88,6 +90,7 @@ class BinaryReaderLinker : public BinaryReaderNop { Section* reloc_section = nullptr; Section* current_section = nullptr; + uint32_t function_count = 0; }; BinaryReaderLinker::BinaryReaderLinker(LinkerInputBinary* binary) @@ -163,6 +166,11 @@ Result BinaryReaderLinker::OnImportGlobal(uint32_t import_index, return Result::Ok; } +Result BinaryReaderLinker::OnFunctionCount(uint32_t count) { + function_count = count; + return Result::Ok; +} + Result BinaryReaderLinker::BeginSection(BinarySection section_code, uint32_t size) { Section* sec = new Section(); @@ -185,62 +193,6 @@ Result BinaryReaderLinker::BeginSection(BinarySection section_code, return Result::Ok; } -Result BinaryReaderLinker::BeginCustomSection(uint32_t size, - StringSlice section_name) { - Section* sec = current_section; - sec->data.custom.name = section_name; - - /* Modify section size and offset to not include the name itself. */ - size_t delta = state->offset - sec->offset; - sec->offset = sec->offset + delta; - sec->size = sec->size - delta; - sec->payload_offset = sec->offset; - sec->payload_size = sec->size; - - /* Special handling for certain CUSTOM sections */ - if (string_slice_eq_cstr(§ion_name, "name")) { - uint32_t name_type; - size_t bytes_read = read_u32_leb128( - &binary->data[sec->offset], &binary->data[binary->size], &name_type); - - if (static_cast<NameSectionSubsection>(name_type) != - NameSectionSubsection::Function) { - WABT_FATAL("no function name section"); - } - - sec->payload_offset += bytes_read; - sec->payload_size -= bytes_read; - - uint32_t subsection_size; - bytes_read = read_u32_leb128(&binary->data[sec->offset], - &binary->data[binary->size], &subsection_size); - - sec->payload_offset += bytes_read; - sec->payload_size -= bytes_read; - - bytes_read = read_u32_leb128(&binary->data[sec->payload_offset], - &binary->data[binary->size], &sec->count); - sec->payload_offset += bytes_read; - sec->payload_size -= bytes_read; - - /* We don't currently support merging name sections unless they contain - * a name for every function. */ - uint32_t total_funcs = binary->function_imports.size(); - for (const std::unique_ptr<Section>& section : binary->sections) { - if (section->section_code == BinarySection::Function) { - total_funcs += section->count; - break; - } - } - if (total_funcs != sec->count) { - WABT_FATAL("name section count (%d) does not match function count (%d)\n", - sec->count, total_funcs); - } - } - - return Result::Ok; -} - Result BinaryReaderLinker::OnTable(uint32_t index, Type elem_type, const Limits* elem_limits) { @@ -313,13 +265,13 @@ Result BinaryReaderLinker::OnExport(uint32_t index, return Result::Ok; } +Result BinaryReaderLinker::BeginNamesSection(uint32_t size) { + binary->debug_names.resize(function_count + binary->function_imports.size()); + return Result::Ok; +} + Result BinaryReaderLinker::OnFunctionName(uint32_t index, StringSlice name) { - while (binary->debug_names.size() < index) { - binary->debug_names.emplace_back(); - } - if (binary->debug_names.size() == index) { - binary->debug_names.push_back(string_slice_to_string(name)); - } + binary->debug_names[index] = string_slice_to_string(name); return Result::Ok; } diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 4ac9c746..136b4c4a 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -943,6 +943,8 @@ static void read_custom_section(Context* ctx, uint32_t section_size) { StringSlice function_name; in_u32_leb128(ctx, &function_index, "function index"); + RAISE_ERROR_UNLESS(function_index < num_total_funcs(ctx), + "invalid function index: %u", function_index); in_str(ctx, &function_name, "function name"); CALLBACK(OnFunctionName, function_index, function_name); } diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 839752d7..8c7d9be4 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -315,8 +315,6 @@ static void begin_subsection(Context* ctx, const char* name, size_t leb_size_guess) { assert(ctx->last_subsection_leb_size_guess == 0); - char desc[100]; - wabt_snprintf(desc, sizeof(desc), "subsection \"%s\"", name); ctx->last_subsection_leb_size_guess = leb_size_guess; ctx->last_subsection_offset = write_u32_leb128_space(ctx, leb_size_guess, "subsection size (guess)"); @@ -880,17 +878,29 @@ static Result write_module(Context* ctx, const Module* module) { char desc[100]; begin_custom_section(ctx, WABT_BINARY_SECTION_NAME, LEB_SECTION_SIZE_GUESS); - write_u32_leb128(&ctx->stream, 1, "function name type"); - begin_subsection(ctx, "function name subsection", LEB_SECTION_SIZE_GUESS); - write_u32_leb128(&ctx->stream, module->funcs.size(), "num functions"); - for (size_t i = 0; i < module->funcs.size(); ++i) { - const Func* func = module->funcs[i]; - write_u32_leb128(&ctx->stream, i, "function index"); - wabt_snprintf(desc, sizeof(desc), "func name %" PRIzd, i); - write_str(&ctx->stream, func->name.start, func->name.length, - PrintChars::Yes, desc); + + size_t named_functions = 0; + for (const Func* func: module->funcs) { + if (func->name.length > 0) + named_functions++; + } + + if (named_functions > 0) { + write_u32_leb128(&ctx->stream, 1, "function name type"); + begin_subsection(ctx, "function name subsection", LEB_SECTION_SIZE_GUESS); + + write_u32_leb128(&ctx->stream, named_functions, "num functions"); + for (size_t i = 0; i < module->funcs.size(); ++i) { + const Func* func = module->funcs[i]; + if (func->name.length == 0) + continue; + write_u32_leb128(&ctx->stream, i, "function index"); + wabt_snprintf(desc, sizeof(desc), "func name %" PRIzd, i); + write_str(&ctx->stream, func->name.start, func->name.length, + PrintChars::Yes, desc); + } + end_subsection(ctx); } - end_subsection(ctx); write_u32_leb128(&ctx->stream, 2, "local name type"); diff --git a/test/binary/bad-duplicate-subsection.txt b/test/binary/bad-duplicate-subsection.txt index 5e95c163..9444caf6 100644 --- a/test/binary/bad-duplicate-subsection.txt +++ b/test/binary/bad-duplicate-subsection.txt @@ -22,4 +22,5 @@ section("name") { (;; STDERR ;;; Error running "wasm2wast": error: @0x00000028: duplicate sub-section + ;;; STDERR ;;) diff --git a/test/binary/bad-name-section-invalid-index.txt b/test/binary/bad-name-section-invalid-index.txt new file mode 100644 index 00000000..d69f9a69 --- /dev/null +++ b/test/binary/bad-name-section-invalid-index.txt @@ -0,0 +1,25 @@ +;;; ERROR: 1 +;;; TOOL: run-gen-wasm +magic +version +section(TYPE) { count[1] function params[0] results[1] i32 } +section(FUNCTION) { count[1] type[0] } +section(CODE) { + count[1] + func { + locals[decl_count[1] i32_count[1] i32] + get_local 0 + } +} +section("name") { + subsection[1] + length[6] + func_count[1] + index[8] + str("$F0") +} +(;; STDERR ;;; +Error running "wasm2wast": +error: @0x00000028: invalid function index: 8 + +;;; STDERR ;;) diff --git a/test/binary/bad-subsection-out-of-order.txt b/test/binary/bad-subsection-out-of-order.txt index 96d2063d..49fa5e4f 100644 --- a/test/binary/bad-subsection-out-of-order.txt +++ b/test/binary/bad-subsection-out-of-order.txt @@ -22,4 +22,5 @@ section("name") { (;; STDERR ;;; Error running "wasm2wast": error: @0x00000028: out-of-order sub-section + ;;; STDERR ;;) diff --git a/test/binary/bad-subsection-size.txt b/test/binary/bad-subsection-size.txt index 3ff90af7..8b9e9f60 100644 --- a/test/binary/bad-subsection-size.txt +++ b/test/binary/bad-subsection-size.txt @@ -21,4 +21,5 @@ section("name") { (;; STDERR ;;; Error running "wasm2wast": error: @0x00000027: unable to read u32 leb128: function index + ;;; STDERR ;;) diff --git a/test/binary/bad-subsection-unfinished.txt b/test/binary/bad-subsection-unfinished.txt index ff9703a0..c3716841 100644 --- a/test/binary/bad-subsection-unfinished.txt +++ b/test/binary/bad-subsection-unfinished.txt @@ -25,4 +25,5 @@ section("name") { (;; STDERR ;;; Error running "wasm2wast": error: @0x0000002c: unfinished sub-section (expected end: 0x30) + ;;; STDERR ;;) diff --git a/test/dump/debug-names.txt b/test/dump/debug-names.txt index d71e719c..247f1531 100644 --- a/test/dump/debug-names.txt +++ b/test/dump/debug-names.txt @@ -6,10 +6,13 @@ (local $F1L2 i32) (local i32)) - (func $F2 (param $F2P0 f32) - (local $F2L1 f64) + ;; An unnamed function with a named param + (func (param $F2P0 f32)) + + (func $F2 (param $F3P0 f32) + (local $F3L1 f64) (local i64) - (local $F2L3 i64))) + (local $F3L3 i64))) (;; STDOUT ;;; 0000000: 0061 736d ; WASM_BINARY_MAGIC 0000004: 0100 0000 ; WASM_BINARY_VERSION @@ -31,79 +34,90 @@ ; section "Function" (3) 0000013: 03 ; section code 0000014: 00 ; section size (guess) -0000015: 02 ; num functions +0000015: 03 ; num functions 0000016: 00 ; function 0 signature index 0000017: 01 ; function 1 signature index -0000014: 03 ; FIXUP section size +0000018: 01 ; function 2 signature index +0000014: 04 ; FIXUP section size ; section "Code" (10) -0000018: 0a ; section code -0000019: 00 ; section size (guess) -000001a: 02 ; num functions +0000019: 0a ; section code +000001a: 00 ; section size (guess) +000001b: 03 ; num functions ; function body 0 -000001b: 00 ; func body size (guess) -000001c: 02 ; local decl count -000001d: 01 ; local type count -000001e: 7d ; f32 -000001f: 02 ; local type count -0000020: 7f ; i32 -0000021: 0b ; end -000001b: 06 ; FIXUP func body size +000001c: 00 ; func body size (guess) +000001d: 02 ; local decl count +000001e: 01 ; local type count +000001f: 7d ; f32 +0000020: 02 ; local type count +0000021: 7f ; i32 +0000022: 0b ; end +000001c: 06 ; FIXUP func body size ; function body 1 -0000022: 00 ; func body size (guess) -0000023: 02 ; local decl count -0000024: 01 ; local type count -0000025: 7c ; f64 -0000026: 02 ; local type count -0000027: 7e ; i64 -0000028: 0b ; end -0000022: 06 ; FIXUP func body size -0000019: 0f ; FIXUP section size +0000023: 00 ; func body size (guess) +0000024: 00 ; local decl count +0000025: 0b ; end +0000023: 02 ; FIXUP func body size +; function body 2 +0000026: 00 ; func body size (guess) +0000027: 02 ; local decl count +0000028: 01 ; local type count +0000029: 7c ; f64 +000002a: 02 ; local type count +000002b: 7e ; i64 +000002c: 0b ; end +0000026: 06 ; FIXUP func body size +000001a: 12 ; FIXUP section size ; section "name" -0000029: 00 ; custom section code -000002a: 00 ; section size (guess) -000002b: 04 ; string length -000002c: 6e61 6d65 name ; custom section name -0000030: 01 ; function name type -0000031: 00 ; subsection size (guess) -0000032: 02 ; num functions -0000033: 00 ; function index -0000034: 03 ; string length -0000035: 2446 31 $F1 ; func name 0 -0000038: 01 ; function index -0000039: 03 ; string length -000003a: 2446 32 $F2 ; func name 1 -0000031: 0b ; FIXUP subsection size -000003d: 02 ; local name type -000003e: 00 ; subsection size (guess) -000003f: 02 ; num functions -0000040: 00 ; function index -0000041: 04 ; num locals -0000042: 00 ; local index -0000043: 05 ; string length -0000044: 2446 3150 30 $F1P0 ; local name 0 -0000049: 01 ; local index -000004a: 05 ; string length -000004b: 2446 314c 31 $F1L1 ; local name 1 -0000050: 02 ; local index -0000051: 05 ; string length -0000052: 2446 314c 32 $F1L2 ; local name 2 -0000057: 03 ; local index -0000058: 00 ; string length -0000059: 01 ; function index -000005a: 04 ; num locals -000005b: 00 ; local index -000005c: 05 ; string length -000005d: 2446 3250 30 $F2P0 ; local name 0 -0000062: 01 ; local index -0000063: 05 ; string length -0000064: 2446 324c 31 $F2L1 ; local name 1 -0000069: 02 ; local index -000006a: 00 ; string length -000006b: 03 ; local index -000006c: 05 ; string length -000006d: 2446 324c 33 $F2L3 ; local name 3 -000003e: 33 ; FIXUP subsection size -000002a: 47 ; FIXUP section size +000002d: 00 ; custom section code +000002e: 00 ; section size (guess) +000002f: 04 ; string length +0000030: 6e61 6d65 name ; custom section name +0000034: 01 ; function name type +0000035: 00 ; subsection size (guess) +0000036: 02 ; num functions +0000037: 00 ; function index +0000038: 03 ; string length +0000039: 2446 31 $F1 ; func name 0 +000003c: 02 ; function index +000003d: 03 ; string length +000003e: 2446 32 $F2 ; func name 2 +0000035: 0b ; FIXUP subsection size +0000041: 02 ; local name type +0000042: 00 ; subsection size (guess) +0000043: 03 ; num functions +0000044: 00 ; function index +0000045: 04 ; num locals +0000046: 00 ; local index +0000047: 05 ; string length +0000048: 2446 3150 30 $F1P0 ; local name 0 +000004d: 01 ; local index +000004e: 05 ; string length +000004f: 2446 314c 31 $F1L1 ; local name 1 +0000054: 02 ; local index +0000055: 05 ; string length +0000056: 2446 314c 32 $F1L2 ; local name 2 +000005b: 03 ; local index +000005c: 00 ; string length +000005d: 01 ; function index +000005e: 01 ; num locals +000005f: 00 ; local index +0000060: 05 ; string length +0000061: 2446 3250 30 $F2P0 ; local name 0 +0000066: 02 ; function index +0000067: 04 ; num locals +0000068: 00 ; local index +0000069: 05 ; string length +000006a: 2446 3350 30 $F3P0 ; local name 0 +000006f: 01 ; local index +0000070: 05 ; string length +0000071: 2446 334c 31 $F3L1 ; local name 1 +0000076: 02 ; local index +0000077: 00 ; string length +0000078: 03 ; local index +0000079: 05 ; string length +000007a: 2446 334c 33 $F3L3 ; local name 3 +0000042: 3c ; FIXUP subsection size +000002e: 50 ; FIXUP section size debug-names.wasm: file format wasm 0x000001 Section Details: @@ -114,21 +128,25 @@ Type: Function: - func[0] sig=0 - func[1] sig=1 + - func[2] sig=1 Custom: - name: "name" - func[0] $F1 - - func[1] $F2 + - func[2] $F2 - func[0] local[0] $F1P0 - func[0] local[1] $F1L1 - func[0] local[2] $F1L2 - func[1] local[0] $F2P0 - - func[1] local[1] $F2L1 - - func[1] local[3] $F2L3 + - func[2] local[0] $F3P0 + - func[2] local[1] $F3L1 + - func[2] local[3] $F3L3 Code Disassembly: -00001b <$F1>: - 000021: 0b | end -000022 <$F2>: - 000028: 0b | end +00001c <$F1>: + 000022: 0b | end +000023 func[1]: + 000025: 0b | end +000026 <$F2>: + 00002c: 0b | end ;;; STDOUT ;;) diff --git a/test/link/names_import_only.txt b/test/link/names_import_only.txt new file mode 100644 index 00000000..b3d05ac3 --- /dev/null +++ b/test/link/names_import_only.txt @@ -0,0 +1,27 @@ +;;; TOOL: run-wasm-link +;;; FLAGS: --debug-names -r +(module + (import "__extern" "baz" (func $import_func1)) +) +(;; STDOUT ;;; +linked.wasm: file format wasm 0x000001 + +Sections: + + Type start=0x0000000a end=0x0000000e (size=0x00000004) count: 1 + Import start=0x00000014 end=0x00000024 (size=0x00000010) count: 1 + Custom start=0x0000002a end=0x00000045 (size=0x0000001b) "name" + +Section Details: + +Type: + - [0] () -> nil +Import: + - func[0] sig=0 <- __extern.baz +Custom: + - name: "name" + - func[0] $import_func1 + +Code Disassembly: + +;;; STDOUT ;;) |