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).
This commit is contained in:
Luuk de Gram 2022-12-31 15:27:24 +01:00
parent 4172c29166
commit 9932372fae
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
2 changed files with 31 additions and 6 deletions

View File

@ -1800,9 +1800,36 @@ fn setupExports(wasm: *Wasm) !void {
if (wasm.base.options.output_mode == .Obj) return;
log.debug("Building exports from symbols", .{});
const force_exp_names = wasm.base.options.export_symbol_names;
if (force_exp_names.len > 0) {
var failed_exports = try std.ArrayList([]const u8).initCapacity(wasm.base.allocator, force_exp_names.len);
defer failed_exports.deinit();
for (force_exp_names) |exp_name| {
const name_index = wasm.string_table.getOffset(exp_name) orelse {
failed_exports.appendAssumeCapacity(exp_name);
continue;
};
const loc = wasm.globals.get(name_index) orelse {
failed_exports.appendAssumeCapacity(exp_name);
continue;
};
const symbol = loc.getSymbol(wasm);
symbol.setFlag(.WASM_SYM_EXPORTED);
}
if (failed_exports.items.len > 0) {
for (failed_exports.items) |exp_name| {
log.err("could not export '{s}', symbol not found", .{exp_name});
}
return error.MissingSymbol;
}
}
for (wasm.resolved_symbols.keys()) |sym_loc| {
const symbol = sym_loc.getSymbol(wasm);
if (!symbol.isExported()) continue;
if (!symbol.isExported(wasm.base.options.rdynamic)) continue;
const sym_name = sym_loc.getName(wasm);
const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {

View File

@ -139,12 +139,10 @@ pub fn isNoStrip(symbol: Symbol) bool {
return symbol.flags & @enumToInt(Flag.WASM_SYM_NO_STRIP) != 0;
}
pub fn isExported(symbol: Symbol) bool {
pub fn isExported(symbol: Symbol, is_dynamic: bool) bool {
if (symbol.isUndefined() or symbol.isLocal()) return false;
if (symbol.isHidden()) return false;
if (symbol.hasFlag(.WASM_SYM_EXPORTED)) return true;
if (symbol.hasFlag(.WASM_SYM_BINDING_WEAK)) return false;
return true;
if (is_dynamic and symbol.isVisible()) return true;
return symbol.hasFlag(.WASM_SYM_EXPORTED);
}
pub fn isWeak(symbol: Symbol) bool {