aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Wasm.zig45
1 files changed, 32 insertions, 13 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index 401bf0b410..f1dca0afe0 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -1163,7 +1163,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
};
}
- if (self.base.options.output_mode == .Obj) {
+ if (is_obj) {
// LLD's WASM driver does not support the equivalent of `-r` so we do a simple file copy
// here. TODO: think carefully about how we can avoid this redundant operation when doing
// build-obj. See also the corresponding TODO in linkAsArchive.
@@ -1233,14 +1233,45 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
try argv.append(arg);
}
+ var auto_export_symbols = true;
// Users are allowed to specify which symbols they want to export to the wasm host.
for (self.base.options.export_symbol_names) |symbol_name| {
const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
try argv.append(arg);
+ auto_export_symbols = false;
}
if (self.base.options.rdynamic) {
try argv.append("--export-dynamic");
+ auto_export_symbols = false;
+ }
+
+ if (auto_export_symbols) {
+ if (self.base.options.module) |module| {
+ // when we use stage1, we use the exports that stage1 provided us.
+ // For stage2, we can directly retrieve them from the module.
+ const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
+ if (use_stage1) {
+ for (comp.export_symbol_names.items) |symbol_name| {
+ try argv.append(try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}));
+ }
+ } else {
+ const skip_export_non_fn = target.os.tag == .wasi and
+ self.base.options.wasi_exec_model == .command;
+ for (module.decl_exports.values()) |exports| {
+ for (exports) |exprt| {
+ if (skip_export_non_fn and exprt.exported_decl.ty.zigTypeTag() != .Fn) {
+ // skip exporting symbols when we're building a WASI command
+ // and the symbol is not a function
+ continue;
+ }
+ const symbol_name = exprt.exported_decl.name;
+ const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
+ try argv.append(arg);
+ }
+ }
+ }
+ }
}
if (self.base.options.output_mode == .Exe) {
@@ -1258,12 +1289,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
if (self.base.options.wasi_exec_model == .reactor) {
// Reactor execution model does not have _start so lld doesn't look for it.
try argv.append("--no-entry");
- // Make sure "_initialize" and other used-defined functions are exported if this is WASI reactor.
- // If rdynamic is true, it will already be appended, so only verify if the user did not specify
- // the flag in which case, we ensure `--export-dynamic` is called.
- if (!self.base.options.rdynamic) {
- try argv.append("--export-dynamic");
- }
}
} else {
if (self.base.options.stack_size_override) |stack_size| {
@@ -1271,12 +1296,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size});
try argv.append(arg);
}
-
- // Only when the user has not specified how they want to export the symbols, do we want
- // to export all symbols.
- if (self.base.options.export_symbol_names.len == 0 and !self.base.options.rdynamic) {
- try argv.append("--export-all");
- }
try argv.append("--no-entry"); // So lld doesn't look for _start.
}
try argv.appendSlice(&[_][]const u8{