aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/link/Wasm.zig33
-rw-r--r--src/main.zig57
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";
+}