diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Wasm.zig | 33 | ||||
| -rw-r--r-- | src/main.zig | 57 |
2 files changed, 66 insertions, 24 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index fdac89f837..baa10be603 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2817,15 +2817,11 @@ fn setupExports(wasm: *Wasm) !void { } fn setupStart(wasm: *Wasm) !void { - const entry_name = wasm.base.options.entry orelse "_start"; + // do not export entry point if user set none or no default was set. + const entry_name = wasm.base.options.entry orelse return; const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { - if (wasm.base.options.output_mode == .Exe) { - if (wasm.base.options.wasi_exec_model == .reactor) return; // Not required for reactors - } else { - return; // No entry point needed for non-executable wasm files - } - log.err("Entry symbol '{s}' missing", .{entry_name}); + log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); return error.MissingSymbol; }; @@ -4535,6 +4531,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! if (wasm.base.options.entry) |entry| { try argv.append("--entry"); try argv.append(entry); + } else { + try argv.append("--no-entry"); } // Increase the default stack size to a more reasonable value of 1MB instead of @@ -4544,24 +4542,17 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}); try argv.append(arg); - if (wasm.base.options.output_mode == .Exe) { - if (wasm.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 (!wasm.base.options.rdynamic) { - try argv.append("--export-dynamic"); - } - } - } else if (wasm.base.options.entry == null) { - try argv.append("--no-entry"); // So lld doesn't look for _start. - } if (wasm.base.options.import_symbols) { try argv.append("--allow-undefined"); } + if (wasm.base.options.output_mode == .Lib and wasm.base.options.link_mode == .Dynamic) { + try argv.append("--shared"); + } + if (wasm.base.options.pie) { + try argv.append("--pie"); + } + // XXX - TODO: add when wasm-ld supports --build-id. // if (wasm.base.options.build_id) { // try argv.append("--build-id=tree"); diff --git a/src/main.zig b/src/main.zig index 385067f703..eb613a65f2 100644 --- a/src/main.zig +++ b/src/main.zig @@ -519,7 +519,9 @@ const usage_build_generic = \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) \\ --sysroot [path] Set the system root directory (usually /) \\ --version [ver] Dynamic library semver - \\ --entry [name] Set the entrypoint symbol name + \\ -fentry Enable entry point with default symbol name + \\ -fentry=[name] Override the entry point symbol name + \\ -fno-entry Do not output any entry point \\ --force_undefined [name] Specify the symbol must be defined for the link to succeed \\ -fsoname[=name] Override the default SONAME value \\ -fno-soname Disable emitting a SONAME @@ -845,6 +847,7 @@ fn buildOutputType( var linker_import_symbols: bool = false; var linker_import_table: bool = false; var linker_export_table: bool = false; + var linker_force_entry: ?bool = null; var linker_initial_memory: ?u64 = null; var linker_max_memory: ?u64 = null; var linker_shared_memory: bool = false; @@ -1081,8 +1084,8 @@ fn buildOutputType( subsystem = try parseSubSystem(args_iter.nextOrFatal()); } else if (mem.eql(u8, arg, "-O")) { optimize_mode_string = args_iter.nextOrFatal(); - } else if (mem.eql(u8, arg, "--entry")) { - entry = args_iter.nextOrFatal(); + } else if (mem.startsWith(u8, arg, "-fentry=")) { + entry = arg["-fentry=".len..]; } else if (mem.eql(u8, arg, "--force_undefined")) { try force_undefined_symbols.put(gpa, args_iter.nextOrFatal(), {}); } else if (mem.eql(u8, arg, "--stack")) { @@ -1513,6 +1516,10 @@ fn buildOutputType( } } else if (mem.eql(u8, arg, "--import-memory")) { linker_import_memory = true; + } else if (mem.eql(u8, arg, "-fentry")) { + linker_force_entry = true; + } else if (mem.eql(u8, arg, "-fno-entry")) { + linker_force_entry = false; } else if (mem.eql(u8, arg, "--export-memory")) { linker_export_memory = true; } else if (mem.eql(u8, arg, "--import-symbols")) { @@ -2144,6 +2151,8 @@ fn buildOutputType( linker_import_table = true; } else if (mem.eql(u8, arg, "--export-table")) { linker_export_table = true; + } else if (mem.eql(u8, arg, "--no-entry")) { + linker_force_entry = false; } else if (mem.eql(u8, arg, "--initial-memory")) { const next_arg = linker_args_it.nextOrFatal(); linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { @@ -2606,6 +2615,23 @@ fn buildOutputType( link_libcpp = true; } + if (linker_force_entry) |force| { + if (!force) { + entry = null; + } else if (entry == null and output_mode == .Exe) { + entry = switch (target_info.target.ofmt) { + .coff => "wWinMainCRTStartup", + .macho => "_main", + .elf, .plan9 => "_start", + .wasm => defaultWasmEntryName(wasi_exec_model), + else => |tag| fatal("No default entry point available for output format {s}", .{@tagName(tag)}), + }; + } + } else if (entry == null and target_info.target.isWasm() and output_mode == .Exe) { + // For WebAssembly the compiler defaults to setting the entry name when no flags are set. + entry = defaultWasmEntryName(wasi_exec_model); + } + if (target_info.target.ofmt == .coff) { // Now that we know the target supports resources, // we can add the res files as link objects. @@ -2628,6 +2654,23 @@ fn buildOutputType( if (single_threaded == null) { single_threaded = true; } + if (link_mode) |mode| { + if (mode == .Dynamic) { + if (linker_export_memory != null and linker_export_memory.?) { + fatal("flags '-dynamic' and '--export-memory' are incompatible", .{}); + } + // User did not supply `--export-memory` which is incompatible with -dynamic, therefore + // set the flag to false to ensure it does not get enabled by default. + linker_export_memory = false; + } + } + if (wasi_exec_model != null and wasi_exec_model.? == .reactor) { + if (entry) |entry_name| { + if (!mem.eql(u8, "_initialize", entry_name)) { + fatal("the entry symbol of the reactor model must be '_initialize', but found '{s}'", .{entry_name}); + } + } + } if (linker_shared_memory) { if (output_mode == .Obj) { fatal("shared memory is not allowed in object files", .{}); @@ -7225,3 +7268,11 @@ fn createDependenciesModule( try main_mod.deps.put(arena, "@dependencies", deps_mod); return deps_mod; } + +fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 { + const model = exec_model orelse .command; + if (model == .reactor) { + return "_initialize"; + } + return "_start"; +} |
