From bf568ec62a06fcea5f09c725529635425f1b8a76 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Wed, 9 Jun 2021 17:07:06 +0900 Subject: [PATCH 1/2] cc,wasi: support WASI reactors via -mexec-model flag. Signed-off-by: Takeshi Yoneda --- src/Compilation.zig | 19 ++++++++++++++++--- src/clang_options_data.zig | 9 ++++++++- src/link.zig | 3 +++ src/link/Wasm.zig | 15 +++++++++++---- src/main.zig | 10 ++++++++++ tools/update_clang_options.zig | 4 ++++ 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 371bcdaf18..e90c635808 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -603,6 +603,11 @@ pub const ClangPreprocessorMode = enum { stdout, }; +pub const WasiExecModel = enum { + command, + reactor, +}; + pub const InitOptions = struct { zig_lib_directory: Directory, local_cache_directory: Directory, @@ -725,6 +730,8 @@ pub const InitOptions = struct { test_filter: ?[]const u8 = null, test_name_prefix: ?[]const u8 = null, subsystem: ?std.Target.SubSystem = null, + /// WASI-only. Type of WASI execution model ("command" or "reactor"). + wasi_exec_model: ?WasiExecModel = null, }; fn addPackageTableToCacheHash( @@ -1340,6 +1347,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .disable_lld_caching = options.disable_lld_caching, .subsystem = options.subsystem, .is_test = options.is_test, + .wasi_exec_model = options.wasi_exec_model, }); errdefer bin_file.destroy(); comp.* = .{ @@ -1441,9 +1449,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .wasi_libc_crt_file = crt_file, }); } - // TODO add logic deciding which crt1 we want here. + const crt_file: wasi_libc.CRTFile = if (comp.bin_file.options.wasi_exec_model) |exec_model| crt_file: { + switch (exec_model) { + .command => break :crt_file wasi_libc.CRTFile.crt1_command_o, + .reactor => break :crt_file wasi_libc.CRTFile.crt1_reactor_o, + } + } else .crt1_o; comp.work_queue.writeAssumeCapacity(&[_]Job{ - .{ .wasi_libc_crt_file = .crt1_o }, + .{ .wasi_libc_crt_file = crt_file }, .{ .wasi_libc_crt_file = .libc_a }, }); } @@ -1868,7 +1881,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { for (keys[1..]) |key, i| { err_msg.notes[i] = .{ - .src_loc = key.nodeOffsetSrcLoc(values[i+1]), + .src_loc = key.nodeOffsetSrcLoc(values[i + 1]), .msg = "also here", }; } diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig index c800de3edf..be4e5c13cb 100644 --- a/src/clang_options_data.zig +++ b/src/clang_options_data.zig @@ -5257,7 +5257,14 @@ jspd1("fxray-modes="), .psl = false, }, jspd1("iwithsysroot"), -joinpd1("mexec-model="), +.{ + .name = "mexec-model=", + .syntax = .joined, + .zig_equivalent = .exec_model, + .pd1 = true, + .pd2 = false, + .psl = false, +}, joinpd1("mharden-sls="), joinpd1("mhvx-length="), jspd1("objc-isystem"), diff --git a/src/link.zig b/src/link.zig index 4072e90ca3..534b39ebbb 100644 --- a/src/link.zig +++ b/src/link.zig @@ -118,6 +118,9 @@ pub const Options = struct { version: ?std.builtin.Version, libc_installation: ?*const LibCInstallation, + /// WASI-only. Type of WASI execution model ("command" or "reactor"). + wasi_exec_model: ?Compilation.WasiExecModel = null, + pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { return if (options.use_lld) .Obj else options.output_mode; } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 21bb9d826c..bfe1902826 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -681,6 +681,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { // Put stack before globals so that stack overflow results in segfault immediately // before corrupting globals. See https://github.com/ziglang/zig/issues/4496 try argv.append("--stack-first"); + + // Reactor execution model does not have _start so lld doesn't look for it. + if (self.base.options.wasi_exec_model) |exec_model| blk: { + if (exec_model != .reactor) break :blk; + try argv.append("--no-entry"); + } } else { try argv.append("--no-entry"); // So lld doesn't look for _start. try argv.append("--export-all"); @@ -692,10 +698,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { }); if (target.os.tag == .wasi) { - if (self.base.options.link_libc and self.base.options.output_mode == .Exe) { - // TODO work out if we want standard crt, a reactor or a command - try argv.append(try comp.get_libc_crt_file(arena, "crt1.o")); - } + const crt_name = if (self.base.options.wasi_exec_model) |exec_model| + try std.fmt.allocPrint(arena, "crt1-{s}.o", .{@tagName(exec_model)}) + else + "crt1.o"; + try argv.append(try comp.get_libc_crt_file(arena, crt_name)); const is_exe_or_dyn_lib = self.base.options.output_mode == .Exe or (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic); diff --git a/src/main.zig b/src/main.zig index 0b93f97726..8b1c640cfb 100644 --- a/src/main.zig +++ b/src/main.zig @@ -613,6 +613,7 @@ fn buildOutputType( var subsystem: ?std.Target.SubSystem = null; var major_subsystem_version: ?u32 = null; var minor_subsystem_version: ?u32 = null; + var wasi_exec_model: ?Compilation.WasiExecModel = null; var system_libs = std.ArrayList([]const u8).init(gpa); defer system_libs.deinit(); @@ -1254,6 +1255,13 @@ fn buildOutputType( .framework => try frameworks.append(it.only_arg), .nostdlibinc => want_native_include_dirs = false, .strip => strip = true, + .exec_model => { + if (std.mem.eql(u8, it.only_arg, "reactor")) { + wasi_exec_model = Compilation.WasiExecModel.reactor; + } else if (std.mem.eql(u8, it.only_arg, "command")) { + wasi_exec_model = Compilation.WasiExecModel.command; + } + }, } } // Parse linker args. @@ -1969,6 +1977,7 @@ fn buildOutputType( .test_name_prefix = test_name_prefix, .disable_lld_caching = !have_enable_cache, .subsystem = subsystem, + .wasi_exec_model = wasi_exec_model, }) catch |err| { fatal("unable to create compilation: {s}", .{@errorName(err)}); }; @@ -3341,6 +3350,7 @@ pub const ClangArgIterator = struct { red_zone, no_red_zone, strip, + exec_model, }; const Args = struct { diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 95c635c09d..6f986ee6df 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -336,6 +336,10 @@ const known_options = [_]KnownOpt{ .name = "dynamiclib", .ident = "shared", }, + .{ + .name = "mexec-model", + .ident = "exec_model", + } }; const blacklisted_options = [_][]const u8{}; From 9f8de83d931f1f59ffa7010afc52a1bd54778447 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 9 Jun 2021 10:23:46 +0200 Subject: [PATCH 2/2] cc,wasi: use wasi_libc.CRTFile directly instead of WasiExecModel --- src/Compilation.zig | 15 ++------------- src/link.zig | 2 +- src/link/Wasm.zig | 12 +++++------- src/main.zig | 6 +++--- src/wasi_libc.zig | 9 +++++++++ 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index e90c635808..5c75caa598 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -603,11 +603,6 @@ pub const ClangPreprocessorMode = enum { stdout, }; -pub const WasiExecModel = enum { - command, - reactor, -}; - pub const InitOptions = struct { zig_lib_directory: Directory, local_cache_directory: Directory, @@ -731,7 +726,7 @@ pub const InitOptions = struct { test_name_prefix: ?[]const u8 = null, subsystem: ?std.Target.SubSystem = null, /// WASI-only. Type of WASI execution model ("command" or "reactor"). - wasi_exec_model: ?WasiExecModel = null, + wasi_exec_model: ?wasi_libc.CRTFile = null, }; fn addPackageTableToCacheHash( @@ -1449,14 +1444,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .wasi_libc_crt_file = crt_file, }); } - const crt_file: wasi_libc.CRTFile = if (comp.bin_file.options.wasi_exec_model) |exec_model| crt_file: { - switch (exec_model) { - .command => break :crt_file wasi_libc.CRTFile.crt1_command_o, - .reactor => break :crt_file wasi_libc.CRTFile.crt1_reactor_o, - } - } else .crt1_o; comp.work_queue.writeAssumeCapacity(&[_]Job{ - .{ .wasi_libc_crt_file = crt_file }, + .{ .wasi_libc_crt_file = comp.bin_file.options.wasi_exec_model orelse .crt1_o }, .{ .wasi_libc_crt_file = .libc_a }, }); } diff --git a/src/link.zig b/src/link.zig index 534b39ebbb..d1508c29cd 100644 --- a/src/link.zig +++ b/src/link.zig @@ -119,7 +119,7 @@ pub const Options = struct { libc_installation: ?*const LibCInstallation, /// WASI-only. Type of WASI execution model ("command" or "reactor"). - wasi_exec_model: ?Compilation.WasiExecModel = null, + wasi_exec_model: ?wasi_libc.CRTFile = null, pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { return if (options.use_lld) .Obj else options.output_mode; diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index bfe1902826..8f376e6f0d 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -684,7 +684,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { // Reactor execution model does not have _start so lld doesn't look for it. if (self.base.options.wasi_exec_model) |exec_model| blk: { - if (exec_model != .reactor) break :blk; + if (exec_model != .crt1_reactor_o) break :blk; try argv.append("--no-entry"); } } else { @@ -698,12 +698,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { }); if (target.os.tag == .wasi) { - const crt_name = if (self.base.options.wasi_exec_model) |exec_model| - try std.fmt.allocPrint(arena, "crt1-{s}.o", .{@tagName(exec_model)}) - else - "crt1.o"; - try argv.append(try comp.get_libc_crt_file(arena, crt_name)); - const is_exe_or_dyn_lib = self.base.options.output_mode == .Exe or (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic); if (is_exe_or_dyn_lib) { @@ -727,6 +721,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { } if (self.base.options.link_libc) { + try argv.append(try comp.get_libc_crt_file( + arena, + wasi_libc.crtFileFullName(self.base.options.wasi_exec_model orelse .crt1_o), + )); try argv.append(try comp.get_libc_crt_file(arena, "libc.a")); } } diff --git a/src/main.zig b/src/main.zig index 8b1c640cfb..149a94dbd0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -613,7 +613,7 @@ fn buildOutputType( var subsystem: ?std.Target.SubSystem = null; var major_subsystem_version: ?u32 = null; var minor_subsystem_version: ?u32 = null; - var wasi_exec_model: ?Compilation.WasiExecModel = null; + var wasi_exec_model: ?wasi_libc.CRTFile = null; var system_libs = std.ArrayList([]const u8).init(gpa); defer system_libs.deinit(); @@ -1257,9 +1257,9 @@ fn buildOutputType( .strip => strip = true, .exec_model => { if (std.mem.eql(u8, it.only_arg, "reactor")) { - wasi_exec_model = Compilation.WasiExecModel.reactor; + wasi_exec_model = .crt1_reactor_o; } else if (std.mem.eql(u8, it.only_arg, "command")) { - wasi_exec_model = Compilation.WasiExecModel.command; + wasi_exec_model = .crt1_command_o; } }, } diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index b61ba5091c..8f62afccba 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -45,6 +45,15 @@ pub fn emulatedLibCRFileLibName(crt_file: CRTFile) []const u8 { }; } +pub fn crtFileFullName(crt_file: CRTFile) []const u8 { + return switch (crt_file) { + .crt1_o => "crt1.o", + .crt1_reactor_o => "crt1-reactor.o", + .crt1_command_o => "crt1-command.o", + else => unreachable, + }; +} + pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions;