summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpipcet <pipcet@users.noreply.github.com>2017-04-03 19:30:36 +0000
committerSam Clegg <sbc@chromium.org>2017-04-03 12:30:36 -0700
commitad0d589c6bf89afaac6ab24fb0c20c9b1a6f0297 (patch)
treef93dd864bcb5ae71d5d3d73c4d2c2b2b584dce66
parentf57ff31c1425e5f066dd0959992fb2aabc39b510 (diff)
downloadwabt-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.cc30
-rw-r--r--src/wasm-link.h1
-rw-r--r--test/link/names.txt85
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 ;;)