diff options
author | pipcet <pipcet@users.noreply.github.com> | 2017-04-03 19:30:36 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2017-04-03 12:30:36 -0700 |
commit | ad0d589c6bf89afaac6ab24fb0c20c9b1a6f0297 (patch) | |
tree | f93dd864bcb5ae71d5d3d73c4d2c2b2b584dce66 | |
parent | f57ff31c1425e5f066dd0959992fb2aabc39b510 (diff) | |
download | wabt-ad0d589c6bf89afaac6ab24fb0c20c9b1a6f0297.tar.gz wabt-ad0d589c6bf89afaac6ab24fb0c20c9b1a6f0297.tar.bz2 wabt-ad0d589c6bf89afaac6ab24fb0c20c9b1a6f0297.zip |
Fix function name indices for imported functions (#384)
When linking, a source binary's imported function indices and its
implemented function indices can be non-contiguous; the previous
code didn't catch that.
Cache relocated indices in calculate_reloc_offsets to avoid O(n^2)
behavior.
-rw-r--r-- | src/tools/wasm-link.cc | 30 | ||||
-rw-r--r-- | src/wasm-link.h | 1 | ||||
-rw-r--r-- | test/link/names.txt | 85 |
3 files changed, 71 insertions, 45 deletions
diff --git a/src/tools/wasm-link.cc b/src/tools/wasm-link.cc index 602fdcec..5d6fc659 100644 --- a/src/tools/wasm-link.cc +++ b/src/tools/wasm-link.cc @@ -169,7 +169,6 @@ static uint32_t relocate_func_index(LinkerInputBinary* binary, } else { /* imported function call */ FunctionImport* import = &binary->function_imports[function_index]; - offset = binary->imported_function_index_offset; if (!import->active) { function_index = import->foreign_index; offset = import->foreign_binary->function_index_offset; @@ -177,6 +176,13 @@ static uint32_t relocate_func_index(LinkerInputBinary* binary, writef(&s_log_stream, "reloc for disabled import. new index = %d + %d\n", function_index, offset); + } else { + uint32_t new_index = import->relocated_function_index; + if (s_debug) + writef(&s_log_stream, + "reloc for active import. old index = %d, new index = %d\n", + function_index, new_index); + return new_index; } } return function_index + offset; @@ -505,13 +511,16 @@ static void write_names_section(Context* ctx) { write_u32_leb128(stream, total_count, "element count"); for (const std::unique_ptr<LinkerInputBinary>& binary: ctx->inputs) { for (size_t i = 0; i < binary->debug_names.size(); i++) { - if (binary->debug_names[i].empty()) - continue; if (i < binary->function_imports.size()) { - if (!binary->function_imports[i].active) + if (!binary->function_imports[i].active) { continue; + } } - write_u32_leb128(stream, i + binary->function_index_offset, "function index"); + + if (binary->debug_names[i].empty()) + continue; + write_u32_leb128(stream, relocate_func_index(&*binary, i), + "function index"); write_string(stream, binary->debug_names[i], "function name"); } } @@ -695,6 +704,17 @@ static void calculate_reloc_offsets(Context* ctx) { binary->imported_function_index_offset = total_function_imports; binary->imported_global_index_offset = total_global_imports; binary->memory_page_offset = memory_page_offset; + + size_t delta = 0; + for (size_t i = 0; i < binary->function_imports.size(); i++) { + if (!binary->function_imports[i].active) { + delta++; + } else { + binary->function_imports[i].relocated_function_index = + total_function_imports + i - delta; + } + } + memory_page_offset += binary->memory_page_count; total_function_imports += binary->active_function_imports; total_global_imports += binary->global_imports.size(); diff --git a/src/wasm-link.h b/src/wasm-link.h index cb978de0..89bce24e 100644 --- a/src/wasm-link.h +++ b/src/wasm-link.h @@ -34,6 +34,7 @@ struct FunctionImport { StringSlice name; uint32_t sig_index; bool active; /* Is this import present in the linked binary */ + uint32_t relocated_function_index; struct LinkerInputBinary* foreign_binary; uint32_t foreign_index; }; diff --git a/test/link/names.txt b/test/link/names.txt index 27d2b1b2..8895177f 100644 --- a/test/link/names.txt +++ b/test/link/names.txt @@ -1,15 +1,17 @@ ;;; TOOL: run-wasm-link ;;; FLAGS: --debug-names -r (module + (import "__extern" "missing0" (func $import_func0)) + (import "__extern" "missing1" (func)) (import "__extern" "baz" (func $import_func1)) - (import "__extern" "missing" (func $import_func2)) + (import "__extern" "missing2" (func $import_func2)) (export "foo" (func $name1)) (func $name1 (param $param1 i32) i32.const 1 - call 0) + call 2) (func $name2 (param $param2 i64) i64.const 1 - call 1) + call 3) (func (param $param2 i64)) ) (module @@ -24,12 +26,12 @@ linked.wasm: file format wasm 0x000001 Sections: Type start=0x0000000a end=0x0000001a (size=0x00000010) count: 4 - Import start=0x00000020 end=0x00000034 (size=0x00000014) count: 1 - Function start=0x0000003a end=0x0000003f (size=0x00000005) count: 4 - Export start=0x00000045 end=0x00000052 (size=0x0000000d) count: 2 - Code start=0x00000054 end=0x00000079 (size=0x00000025) count: 4 - Custom start=0x0000007f end=0x000000b2 (size=0x00000033) "name" - Custom start=0x000000b8 end=0x000000ce (size=0x00000016) "reloc.Code" + Import start=0x00000020 end=0x0000005d (size=0x0000003d) count: 3 + Function start=0x00000063 end=0x00000068 (size=0x00000005) count: 4 + Export start=0x0000006e end=0x0000007b (size=0x0000000d) count: 2 + Code start=0x0000007d end=0x000000a2 (size=0x00000025) count: 4 + Custom start=0x000000a8 end=0x000000ea (size=0x00000042) "name" + Custom start=0x000000f0 end=0x00000106 (size=0x00000016) "reloc.Code" Section Details: @@ -39,45 +41,48 @@ Type: - [2] (i64) -> nil - [3] (i32) -> nil Import: - - func[0] sig=0 <- __extern.missing + - func[0] sig=0 <- __extern.missing0 + - func[1] sig=0 <- __extern.missing1 + - func[2] sig=0 <- __extern.missing2 Function: - - func[1] sig=1 - - func[2] sig=2 - - func[3] sig=2 - - func[4] sig=3 + - func[3] sig=1 + - func[4] sig=2 + - func[5] sig=2 + - func[6] sig=3 Export: - - func[1] foo - - func[4] baz + - func[3] foo + - func[6] baz Custom: - name: "name" - - func[0] $import_func2 - - func[1] $name1 - - func[2] $name2 - - func[4] $name3 + - func[0] $import_func0 + - func[2] $import_func2 + - func[3] $name1 + - func[4] $name2 + - func[6] $name3 Custom: - name: "reloc.Code" - section: Code - - R_FUNC_INDEX_LEB idx=0 addend=0 offset=0x6(file=0x5a) - - R_FUNC_INDEX_LEB idx=0x1 addend=0 offset=0x11(file=0x65) - - R_FUNC_INDEX_LEB idx=0 addend=0 offset=0x1f(file=0x73) + - R_FUNC_INDEX_LEB idx=0x2 addend=0 offset=0x6(file=0x83) + - R_FUNC_INDEX_LEB idx=0x3 addend=0 offset=0x11(file=0x8e) + - R_FUNC_INDEX_LEB idx=0 addend=0 offset=0x1f(file=0x9c) Code Disassembly: -000055 <$name1>: - 000057: 41 01 | i32.const 0x1 - 000059: 10 84 80 80 80 00 | call 0x4 - 00005a: R_FUNC_INDEX_LEB 0 - 00005f: 0b | end -000060 <$name2>: - 000062: 42 01 | i64.const 1 - 000064: 10 81 80 80 80 00 | call 0x1 - 000065: R_FUNC_INDEX_LEB 1 - 00006a: 0b | end -00006b func[3]: - 00006d: 0b | end -00006e <$name3>: - 000070: 41 02 | i32.const 0x2 - 000072: 10 84 80 80 80 00 | call 0x4 - 000073: R_FUNC_INDEX_LEB 0 - 000078: 0b | end +00007e <$name1>: + 000080: 41 01 | i32.const 0x1 + 000082: 10 86 80 80 80 00 | call 0x6 + 000083: R_FUNC_INDEX_LEB 2 + 000088: 0b | end +000089 <$name2>: + 00008b: 42 01 | i64.const 1 + 00008d: 10 82 80 80 80 00 | call 0x2 + 00008e: R_FUNC_INDEX_LEB 3 + 000093: 0b | end +000094 func[5]: + 000096: 0b | end +000097 <$name3>: + 000099: 41 02 | i32.const 0x2 + 00009b: 10 86 80 80 80 00 | call 0x6 + 00009c: R_FUNC_INDEX_LEB 0 + 0000a1: 0b | end ;;; STDOUT ;;) |