Skip to content

Commit 02d291a

Browse files
wit-component: Allow cabi_realloc to be weakly defined (#1625)
If a weak "default" visibility symbol is defined in a shared library, wasm-ld emits an import for the symbol for the "env" module for the case where the symbol is overridden by other modules. `cabi_realloc` is usually defined weakly by wit-bindgen'ed code, and if the code is compiled with `-fvisibility=default`, it emits an import for "env.cabi_realloc". The import leads re-exporting the symbol to the "env" module, and it conflicts with the special re-exporting logic for `cabi_realloc`. This commit fixes the duplicate re-exporting issue.
1 parent 85270ca commit 02d291a

5 files changed

Lines changed: 167 additions & 4 deletions

File tree

crates/wit-component/src/linking.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,14 +1046,19 @@ fn find_dependencies(
10461046
}
10471047
}
10481048

1049+
struct EnvFunctionExports<'a> {
1050+
exports: Vec<(&'a str, &'a FunctionType, usize)>,
1051+
reexport_cabi_realloc: bool,
1052+
}
1053+
10491054
/// Analyze the specified metadata and generate a list of functions which should be re-exported as a
10501055
/// `call.indirect`-based function by the main (AKA "env") module, including the offset of the library containing
10511056
/// the original export.
10521057
fn env_function_exports<'a>(
10531058
metadata: &'a [Metadata<'a>],
10541059
exporters: &'a IndexMap<&'a ExportKey, (&'a str, &Export)>,
10551060
topo_sorted: &[usize],
1056-
) -> Result<Vec<(&'a str, &'a FunctionType, usize)>> {
1061+
) -> Result<EnvFunctionExports<'a>> {
10571062
let function_exporters = exporters
10581063
.iter()
10591064
.filter_map(|(export, exporter)| {
@@ -1103,7 +1108,12 @@ fn env_function_exports<'a>(
11031108
seen.insert(index);
11041109
}
11051110

1106-
Ok(result)
1111+
let reexport_cabi_realloc = exported.contains("cabi_realloc");
1112+
1113+
Ok(EnvFunctionExports {
1114+
exports: result,
1115+
reexport_cabi_realloc,
1116+
})
11071117
}
11081118

11091119
/// Synthesize a module which contains trapping stub exports for the specified functions.
@@ -1385,12 +1395,21 @@ impl Linker {
13851395

13861396
let topo_sorted = topo_sort(metadata.len(), &dependencies)?;
13871397

1388-
let env_function_exports = env_function_exports(&metadata, &exporters, &topo_sorted)?;
1398+
let EnvFunctionExports {
1399+
exports: env_function_exports,
1400+
reexport_cabi_realloc,
1401+
} = env_function_exports(&metadata, &exporters, &topo_sorted)?;
13891402

13901403
let (env_module, dl_openables, table_base) = make_env_module(
13911404
&metadata,
13921405
&env_function_exports,
1393-
cabi_realloc_exporter,
1406+
if reexport_cabi_realloc {
1407+
// If "env" module already reexports "cabi_realloc", we don't need to
1408+
// reexport it again.
1409+
None
1410+
} else {
1411+
cabi_realloc_exporter
1412+
},
13941413
self.stack_size.unwrap_or(DEFAULT_STACK_SIZE_BYTES),
13951414
);
13961415

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
(component
2+
(core module (;0;)
3+
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
4+
(func (;0;) (type 0) (param i32 i32 i32 i32) (result i32)
5+
local.get 0
6+
local.get 1
7+
local.get 2
8+
local.get 3
9+
i32.const 1
10+
call_indirect (type 0)
11+
)
12+
(table (;0;) 2 funcref)
13+
(memory (;0;) 17)
14+
(global (;0;) (mut i32) i32.const 1048576)
15+
(global (;1;) i32 i32.const 1048592)
16+
(global (;2;) i32 i32.const 1)
17+
(global (;3;) (mut i32) i32.const 1048592)
18+
(global (;4;) (mut i32) i32.const 1114112)
19+
(export "__stack_pointer" (global 0))
20+
(export "foo:memory_base" (global 1))
21+
(export "foo:table_base" (global 2))
22+
(export "__heap_base" (global 3))
23+
(export "__heap_end" (global 4))
24+
(export "cabi_realloc" (func 0))
25+
(export "__indirect_function_table" (table 0))
26+
(export "memory" (memory 0))
27+
(@producers
28+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
29+
)
30+
)
31+
(core module (;1;)
32+
(@dylink.0
33+
(mem-info (memory 0 4))
34+
)
35+
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
36+
(type (;1;) (func (param i32)))
37+
(type (;2;) (func (param i32 i32)))
38+
(import "env" "cabi_realloc" (func $cabi_realloc.0 (;0;) (type 0)))
39+
(func $cabi_realloc.1 (;1;) (type 0) (param i32 i32 i32 i32) (result i32)
40+
i32.const -257976192
41+
)
42+
(func $foo (;2;) (type 2) (param i32 i32))
43+
(export "cabi_realloc" (func $cabi_realloc.1))
44+
(export "test:test/test#foo" (func $foo))
45+
)
46+
(core module (;2;)
47+
(type (;0;) (func))
48+
(type (;1;) (func (param i32)))
49+
(type (;2;) (func (param i32 i32 i32 i32) (result i32)))
50+
(import "env" "memory" (memory (;0;) 0))
51+
(import "env" "__indirect_function_table" (table (;0;) 0 funcref))
52+
(import "foo" "cabi_realloc" (func (;0;) (type 2)))
53+
(func (;1;) (type 0))
54+
(start 1)
55+
(elem (;0;) (i32.const 1) func)
56+
(elem (;1;) (i32.const 1) func 0)
57+
(data (;0;) (i32.const 1048576) "\00\00\00\00\00\00\10\00")
58+
(@producers
59+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
60+
)
61+
)
62+
(core instance (;0;) (instantiate 0))
63+
(alias core export 0 "memory" (core memory (;0;)))
64+
(alias core export 0 "cabi_realloc" (core func (;0;)))
65+
(alias core export 0 "__heap_base" (core global (;0;)))
66+
(alias core export 0 "__heap_end" (core global (;1;)))
67+
(core instance (;1;)
68+
(export "__heap_base" (global 0))
69+
(export "__heap_end" (global 1))
70+
)
71+
(core instance (;2;))
72+
(alias core export 0 "memory" (core memory (;1;)))
73+
(alias core export 0 "__indirect_function_table" (core table (;0;)))
74+
(alias core export 0 "__stack_pointer" (core global (;2;)))
75+
(alias core export 0 "foo:memory_base" (core global (;3;)))
76+
(alias core export 0 "foo:table_base" (core global (;4;)))
77+
(alias core export 0 "cabi_realloc" (core func (;1;)))
78+
(core instance (;3;)
79+
(export "memory" (memory 1))
80+
(export "__indirect_function_table" (table 0))
81+
(export "__stack_pointer" (global 2))
82+
(export "__memory_base" (global 3))
83+
(export "__table_base" (global 4))
84+
(export "cabi_realloc" (func 1))
85+
)
86+
(core instance (;4;) (instantiate 1
87+
(with "GOT.mem" (instance 1))
88+
(with "GOT.func" (instance 2))
89+
(with "env" (instance 3))
90+
)
91+
)
92+
(alias core export 4 "cabi_realloc" (core func (;2;)))
93+
(alias core export 4 "cabi_realloc" (core func (;3;)))
94+
(core instance (;5;) (instantiate 2
95+
(with "env" (instance 0))
96+
(with "foo" (instance 4))
97+
)
98+
)
99+
(type (;0;) (func (param "x" string)))
100+
(alias core export 4 "test:test/test#foo" (core func (;4;)))
101+
(func (;0;) (type 0) (canon lift (core func 4) (memory 0) (realloc 2) string-encoding=utf8))
102+
(component (;0;)
103+
(type (;0;) (func (param "x" string)))
104+
(import "import-func-foo" (func (;0;) (type 0)))
105+
(type (;1;) (func (param "x" string)))
106+
(export (;1;) "foo" (func 0) (func (type 1)))
107+
)
108+
(instance (;0;) (instantiate 0
109+
(with "import-func-foo" (func 0))
110+
)
111+
)
112+
(export (;1;) "test:test/test" (instance 0))
113+
(@producers
114+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
115+
)
116+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package root:component;
2+
3+
world root {
4+
export test:test/test;
5+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(module
2+
(@dylink.0
3+
(mem-info (memory 0 4))
4+
)
5+
(type (func (param i32 i32 i32 i32) (result i32)))
6+
(type (func (param i32)))
7+
(import "env" "cabi_realloc" (func $cabi_realloc.0 (type 0)))
8+
(func $cabi_realloc.1 (type 0)
9+
i32.const 0xf09f9880
10+
)
11+
(func $foo (param i32 i32))
12+
(export "cabi_realloc" (func $cabi_realloc.1))
13+
(export "test:test/test#foo" (func $foo))
14+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package test:test;
2+
3+
interface test {
4+
foo: func(x: string);
5+
}
6+
7+
world lib-foo {
8+
export test;
9+
}

0 commit comments

Comments
 (0)