authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-12-31 15:27:24+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-01-02 18:36:14+01:00
log9932372fae88a6dabdb3945d55556e373bd4bb45
treedcce097733520419f04610b6fce1868f7fa5d488
parent4172c2916684655a9742de99384be8110922ed07
signaturelock-open Commit is signed but in an unrecognized format.

wasm-linker: support export flags

Adds support for both the `-rdynamic` and the `--export=<value>` flags. Support is added to both the incremental linker as well as the traditional linker (zld).

2 files changed, 31 insertions(+), 6 deletions(-)

src/link/Wasm.zig+28-1
...@@ -1800,9 +1800,36 @@ fn setupExports(wasm: *Wasm) !void {...@@ -1800,9 +1800,36 @@ fn setupExports(wasm: *Wasm) !void {
1800 if (wasm.base.options.output_mode == .Obj) return;1800 if (wasm.base.options.output_mode == .Obj) return;
1801 log.debug("Building exports from symbols", .{});1801 log.debug("Building exports from symbols", .{});
18021802
1803 const force_exp_names = wasm.base.options.export_symbol_names;
1804 if (force_exp_names.len > 0) {
1805 var failed_exports = try std.ArrayList([]const u8).initCapacity(wasm.base.allocator, force_exp_names.len);
1806 defer failed_exports.deinit();
1807
1808 for (force_exp_names) |exp_name| {
1809 const name_index = wasm.string_table.getOffset(exp_name) orelse {
1810 failed_exports.appendAssumeCapacity(exp_name);
1811 continue;
1812 };
1813 const loc = wasm.globals.get(name_index) orelse {
1814 failed_exports.appendAssumeCapacity(exp_name);
1815 continue;
1816 };
1817
1818 const symbol = loc.getSymbol(wasm);
1819 symbol.setFlag(.WASM_SYM_EXPORTED);
1820 }
1821
1822 if (failed_exports.items.len > 0) {
1823 for (failed_exports.items) |exp_name| {
1824 log.err("could not export '{s}', symbol not found", .{exp_name});
1825 }
1826 return error.MissingSymbol;
1827 }
1828 }
1829
1803 for (wasm.resolved_symbols.keys()) |sym_loc| {1830 for (wasm.resolved_symbols.keys()) |sym_loc| {
1804 const symbol = sym_loc.getSymbol(wasm);1831 const symbol = sym_loc.getSymbol(wasm);
1805 if (!symbol.isExported()) continue;1832 if (!symbol.isExported(wasm.base.options.rdynamic)) continue;
18061833
1807 const sym_name = sym_loc.getName(wasm);1834 const sym_name = sym_loc.getName(wasm);
1808 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {1835 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {
src/link/Wasm/Symbol.zig+3-5
...@@ -139,12 +139,10 @@ pub fn isNoStrip(symbol: Symbol) bool {...@@ -139,12 +139,10 @@ pub fn isNoStrip(symbol: Symbol) bool {
139 return symbol.flags & @enumToInt(Flag.WASM_SYM_NO_STRIP) != 0;139 return symbol.flags & @enumToInt(Flag.WASM_SYM_NO_STRIP) != 0;
140}140}
141141
142pub fn isExported(symbol: Symbol) bool {142pub fn isExported(symbol: Symbol, is_dynamic: bool) bool {
143 if (symbol.isUndefined() or symbol.isLocal()) return false;143 if (symbol.isUndefined() or symbol.isLocal()) return false;
144 if (symbol.isHidden()) return false;144 if (is_dynamic and symbol.isVisible()) return true;
145 if (symbol.hasFlag(.WASM_SYM_EXPORTED)) return true;145 return symbol.hasFlag(.WASM_SYM_EXPORTED);
146 if (symbol.hasFlag(.WASM_SYM_BINDING_WEAK)) return false;
147 return true;
148}146}
149147
150pub fn isWeak(symbol: Symbol) bool {148pub fn isWeak(symbol: Symbol) bool {