diff --git a/src/Compilation.zig b/src/Compilation.zig index d8c59f4f1b..9029d8ecbc 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -924,7 +924,7 @@ pub const LinkObject = struct { loption: bool = false, }; -pub const InitOptions = struct { +pub const CreateOptions = struct { zig_lib_directory: Directory, local_cache_directory: Directory, global_cache_directory: Directory, @@ -1054,7 +1054,7 @@ pub const InitOptions = struct { /// infinite recursion. skip_linker_dependencies: bool = false, hash_style: link.File.Elf.HashStyle = .both, - entry: ?[]const u8 = null, + entry: Entry = .default, force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}, stack_size: ?u64 = null, image_base: ?u64 = null, @@ -1089,6 +1089,8 @@ pub const InitOptions = struct { /// (Windows) PDB output path pdb_out_path: ?[]const u8 = null, error_limit: ?Compilation.Module.ErrorInt = null, + + pub const Entry = link.File.OpenOptions.Entry; }; fn addModuleTableToCacheHash( @@ -1159,7 +1161,7 @@ fn addModuleTableToCacheHash( } } -pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { +pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { const output_mode = options.config.output_mode; const is_dyn_lib = switch (output_mode) { .Obj, .Exe => false, @@ -1543,6 +1545,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .dynamicbase = options.linker_dynamicbase, .major_subsystem_version = options.major_subsystem_version, .minor_subsystem_version = options.minor_subsystem_version, + .entry = options.entry, .stack_size = options.stack_size, .image_base = options.image_base, .version_script = options.version_script, diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index d5f3b2ef95..4abf3e88d4 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -55,7 +55,6 @@ export_memory: bool, shared_memory: bool, is_test: bool, test_evented_io: bool, -entry: ?[]const u8, debug_format: DebugFormat, root_strip: bool, root_error_tracing: bool, @@ -100,12 +99,6 @@ pub const Options = struct { use_lld: ?bool = null, use_clang: ?bool = null, lto: ?bool = null, - entry: union(enum) { - default, - disabled, - enabled, - named: []const u8, - } = .default, /// WASI-only. Type of WASI execution model ("command" or "reactor"). wasi_exec_model: ?std.builtin.WasiExecModel = null, import_memory: ?bool = null, @@ -123,8 +116,6 @@ pub const ResolveError = error{ ObjectFilesCannotShareMemory, SharedMemoryRequiresAtomicsAndBulkMemory, ThreadsRequireSharedMemory, - UnknownTargetEntryPoint, - NonExecutableEntryPoint, EmittingLlvmModuleRequiresLlvmBackend, LlvmLacksTargetSupport, ZigLacksTargetSupport, @@ -352,25 +343,6 @@ pub fn resolve(options: Options) ResolveError!Config { break :b false; }; - const entry: ?[]const u8 = switch (options.entry) { - .disabled => null, - .default => b: { - if (options.output_mode != .Exe) break :b null; - - // When producing C source code, the decision of entry point is made - // when compiling the C code, not when producing the C code. - if (target.ofmt == .c) break :b null; - - break :b target_util.defaultEntrySymbolName(target, wasi_exec_model) orelse - return error.UnknownTargetEntryPoint; - }, - .enabled => target_util.defaultEntrySymbolName(target, wasi_exec_model) orelse - return error.UnknownTargetEntryPoint, - .named => |name| name, - }; - if (entry != null and options.output_mode != .Exe) - return error.NonExecutableEntryPoint; - const any_unwind_tables = options.any_unwind_tables or link_libunwind or target_util.needUnwindTables(target); @@ -519,7 +491,6 @@ pub fn resolve(options: Options) ResolveError!Config { .use_llvm = use_llvm, .use_lib_llvm = use_lib_llvm, .use_lld = use_lld, - .entry = entry, .wasi_exec_model = wasi_exec_model, .debug_format = debug_format, .root_strip = root_strip, diff --git a/src/link.zig b/src/link.zig index 8fc1e8cc91..a051d27b12 100644 --- a/src/link.zig +++ b/src/link.zig @@ -83,6 +83,8 @@ pub const File = struct { symbol_count_hint: u64 = 32, program_code_size_hint: u64 = 256 * 1024, + /// This may depend on what symbols are found during the linking process. + entry: Entry, /// Virtual address of the entry point procedure relative to image base. entry_addr: ?u64, stack_size: ?u64, @@ -169,6 +171,13 @@ pub const File = struct { module_definition_file: ?[]const u8, wasi_emulated_libs: []const wasi_libc.CRTFile, + + pub const Entry = union(enum) { + default, + disabled, + enabled, + named: []const u8, + }; }; /// Attempts incremental linking, if the file already exists. If diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 861ec030b3..53f999b965 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -17,6 +17,7 @@ dynamicbase: bool, major_subsystem_version: u16, minor_subsystem_version: u16, lib_dirs: []const []const u8, +entry: link.File.OpenOptions.Entry, entry_addr: ?u32, module_definition_file: ?[]const u8, pdb_out_path: ?[]const u8, @@ -303,7 +304,12 @@ pub fn createEmpty( .Obj => 0, }, + // Subsystem depends on the set of public symbol names from linked objects. + // See LinkerDriver::inferSubsystem from the LLD project for the flow chart. .subsystem = options.subsystem, + + .entry = options.entry, + .tsaware = options.tsaware, .nxcompat = options.nxcompat, .dynamicbase = options.dynamicbase, @@ -2498,7 +2504,20 @@ inline fn getSizeOfImage(self: Coff) u32 { /// Returns symbol location corresponding to the set entrypoint (if any). pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { const comp = self.base.comp; - const entry_name = comp.config.entry orelse return null; + + // TODO This is incomplete. + // The entry symbol name depends on the subsystem as well as the set of + // public symbol names from linked objects. + // See LinkerDriver::findDefaultEntry from the LLD project for the flow chart. + const entry_name = switch (self.entry) { + .disabled => return null, + .default => switch (comp.config.output_mode) { + .Exe => "wWinMainCRTStartup", + .Obj, .Lib => return null, + }, + .enabled => "wWinMainCRTStartup", + .named => |name| name, + }; const global_index = self.resolver.get(entry_name) orelse return null; return self.globals.items[global_index]; } diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index 5b01f63645..6afe741f66 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -52,6 +52,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib; const target = comp.root_mod.resolved_target.result; const optimize_mode = comp.root_mod.optimize_mode; + const entry_name: ?[]const u8 = switch (self.entry) { + // This logic isn't quite right for disabled or enabled. No point in fixing it + // when the goal is to eliminate dependency on LLD anyway. + // https://github.com/ziglang/zig/issues/17751 + .disabled, .default, .enabled => null, + .named => |name| name, + }; // See link/Elf.zig for comments on how this mechanism works. const id_symlink_basename = "lld.id"; @@ -80,7 +87,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod } } try man.addOptionalFile(module_obj_path); - man.hash.addOptionalBytes(comp.config.entry); + man.hash.addOptionalBytes(entry_name); man.hash.add(self.base.stack_size); man.hash.add(self.image_base); man.hash.addListOfBytes(self.lib_dirs); @@ -218,8 +225,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod try argv.append("-DLL"); } - if (comp.config.entry) |entry| { - try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry})); + if (entry_name) |name| { + try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name})); } if (self.tsaware) { @@ -441,7 +448,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod } } else { try argv.append("-NODEFAULTLIB"); - if (!is_lib and comp.config.entry == null) { + if (!is_lib and entry_name == null) { if (comp.module) |module| { if (module.stage1_flags.have_winmain_crt_startup) { try argv.append("-ENTRY:WinMainCRTStartup"); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ea8454490c..65fc0ff5a3 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -25,6 +25,7 @@ linker_script: ?[]const u8, version_script: ?[]const u8, print_icf_sections: bool, print_map: bool, +entry_name: ?[]const u8, ptr_width: PtrWidth, @@ -290,6 +291,13 @@ pub fn createEmpty( .page_size = page_size, .default_sym_version = default_sym_version, + .entry_name = switch (options.entry) { + .disabled => null, + .default => if (output_mode != .Exe) null else defaultEntrySymbolName(target.cpu.arch), + .enabled => defaultEntrySymbolName(target.cpu.arch), + .named => |name| name, + }, + .image_base = b: { if (is_dyn_lib) break :b 0; if (output_mode == .Exe and comp.config.pie) break :b 0; @@ -1305,7 +1313,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node // Look for entry address in objects if not set by the incremental compiler. if (self.entry_index == null) { - if (comp.config.entry) |name| { + if (self.entry_name) |name| { self.entry_index = self.globalByName(name); } } @@ -1679,9 +1687,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { } } - if (comp.config.entry) |entry| { - try argv.append("--entry"); - try argv.append(entry); + if (self.entry_name) |name| { + try argv.appendSlice(&.{ "--entry", name }); } for (self.base.rpath_list) |rpath| { @@ -2427,7 +2434,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v // We can skip hashing libc and libc++ components that we are in charge of building from Zig // installation sources because they are always a product of the compiler version + target information. - man.hash.addOptionalBytes(comp.config.entry); + man.hash.addOptionalBytes(self.entry_name); man.hash.add(self.image_base); man.hash.add(self.base.gc_sections); man.hash.addOptional(self.sort_section); @@ -2563,9 +2570,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), } - if (comp.config.entry) |entry| { - try argv.append("--entry"); - try argv.append(entry); + if (self.entry_name) |name| { + try argv.appendSlice(&.{ "--entry", name }); } for (self.base.force_undefined_symbols.keys()) |sym| { @@ -6512,6 +6518,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1; pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2; +fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { + return switch (cpu_arch) { + .mips, .mipsel, .mips64, .mips64el => "__start", + else => "_start", + }; +} + const std = @import("std"); const build_options = @import("build_options"); const builtin = @import("builtin"); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index d8fc71c0f0..8c0874e3cb 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1,4 +1,5 @@ base: File, +entry_name: ?[]const u8, /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. llvm_object: ?*LlvmObject = null, @@ -231,6 +232,12 @@ pub fn createEmpty( .install_name = options.install_name, .entitlements = options.entitlements, .compatibility_version = options.compatibility_version, + .entry_name = switch (options.entry) { + .disabled => null, + .default => if (output_mode != .Exe) null else default_entry_symbol_name, + .enabled => default_entry_symbol_name, + .named => |name| name, + }, }; if (use_llvm and comp.config.have_zcu) { self.llvm_object = try LlvmObject.create(arena, comp); @@ -1629,8 +1636,9 @@ pub fn resolveSymbols(self: *MachO) !void { // we search for it in libraries should there be no object files specified // on the linker line. if (output_mode == .Exe) { - const entry_name = comp.config.entry.?; - _ = try self.addUndefined(entry_name, .{}); + if (self.entry_name) |entry_name| { + _ = try self.addUndefined(entry_name, .{}); + } } // Force resolution of any symbols requested by the user. @@ -5085,8 +5093,7 @@ pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { /// Returns symbol location corresponding to the set entrypoint if any. /// Asserts output mode is executable. pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { - const comp = self.base.comp; - const entry_name = comp.config.entry orelse return null; + const entry_name = self.entry_name orelse return null; const global = self.getGlobal(entry_name) orelse return null; return global; } @@ -5645,6 +5652,8 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index, logger: anytype) void { } } +const default_entry_symbol_name = "_main"; + pub const base_tag: File.Tag = File.Tag.macho; pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1))); pub const N_BOUNDARY: u16 = @as(u16, @bitCast(@as(i16, -2))); diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index fa6aa152e4..05fa8e671a 100644 --- a/src/link/MachO/zld.zig +++ b/src/link/MachO/zld.zig @@ -276,9 +276,8 @@ pub fn linkWithZld( try argv.append("-dead_strip_dylibs"); } - if (comp.config.entry) |entry| { - try argv.append("-e"); - try argv.append(entry); + if (macho_file.entry_name) |entry_name| { + try argv.appendSlice(&.{ "-e", entry_name }); } for (objects) |obj| { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index b4b0f16d4a..91653ce641 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -37,6 +37,7 @@ pub const Relocation = types.Relocation; pub const base_tag: link.File.Tag = .wasm; base: link.File, +entry_name: ?[]const u8, import_symbols: bool, export_symbol_names: []const []const u8, global_base: ?u64, @@ -397,6 +398,7 @@ pub fn createEmpty( const use_llvm = comp.config.use_llvm; const output_mode = comp.config.output_mode; const shared_memory = comp.config.shared_memory; + const wasi_exec_model = comp.config.wasi_exec_model; // If using LLD to link, this code should produce an object file so that it // can be passed to LLD. @@ -434,6 +436,13 @@ pub fn createEmpty( .initial_memory = options.initial_memory, .max_memory = options.max_memory, .wasi_emulated_libs = options.wasi_emulated_libs, + + .entry_name = switch (options.entry) { + .disabled => null, + .default => if (output_mode != .Exe) null else defaultEntrySymbolName(wasi_exec_model), + .enabled => defaultEntrySymbolName(wasi_exec_model), + .named => |name| name, + }, }; if (use_llvm and comp.config.have_zcu) { wasm.llvm_object = try LlvmObject.create(arena, comp); @@ -3042,7 +3051,7 @@ fn setupExports(wasm: *Wasm) !void { fn setupStart(wasm: *Wasm) !void { const comp = wasm.base.comp; // do not export entry point if user set none or no default was set. - const entry_name = comp.config.entry orelse return; + const entry_name = wasm.entry_name orelse return; const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); @@ -3475,8 +3484,8 @@ fn resetState(wasm: *Wasm) void { } pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { - const use_lld = build_options.have_llvm and wasm.base.comp.config.use_lld; - const use_llvm = wasm.base.comp.config.use_llvm; + const use_lld = build_options.have_llvm and comp.config.use_lld; + const use_llvm = comp.config.use_llvm; if (use_lld) { return wasm.linkWithLLD(comp, prog_node); @@ -3492,7 +3501,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l const tracy = trace(@src()); defer tracy.end(); - const gpa = wasm.base.comp.gpa; + const gpa = comp.gpa; const shared_memory = comp.config.shared_memory; const import_memory = comp.config.import_memory; @@ -3503,8 +3512,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type. const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path}); - const opt_zcu = wasm.base.comp.module; - const use_llvm = wasm.base.comp.config.use_llvm; + const opt_zcu = comp.module; + const use_llvm = comp.config.use_llvm; // If there is no Zig code to compile, then we should skip flushing the output file because it // will not be part of the linker line anyway. @@ -3535,7 +3544,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l defer if (!wasm.base.disable_lld_caching) man.deinit(); var digest: [Cache.hex_digest_len]u8 = undefined; - const objects = wasm.base.comp.objects; + const objects = comp.objects; // NOTE: The following section must be maintained to be equal // as the section defined in `linkWithLLD` @@ -3556,7 +3565,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l } try man.addOptionalFile(module_obj_path); try man.addOptionalFile(compiler_rt_path); - man.hash.addOptionalBytes(wasm.base.comp.config.entry); + man.hash.addOptionalBytes(wasm.entry_name); man.hash.add(wasm.base.stack_size); man.hash.add(wasm.base.build_id); man.hash.add(import_memory); @@ -3605,12 +3614,12 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l var positionals = std.ArrayList([]const u8).init(arena); try positionals.ensureUnusedCapacity(objects.len); - const target = wasm.base.comp.root_mod.resolved_target.result; - const output_mode = wasm.base.comp.config.output_mode; - const link_mode = wasm.base.comp.config.link_mode; - const link_libc = wasm.base.comp.config.link_libc; - const link_libcpp = wasm.base.comp.config.link_libcpp; - const wasi_exec_model = wasm.base.comp.config.wasi_exec_model; + const target = comp.root_mod.resolved_target.result; + const output_mode = comp.config.output_mode; + const link_mode = comp.config.link_mode; + const link_libc = comp.config.link_libc; + const link_libcpp = comp.config.link_libcpp; + const wasi_exec_model = comp.config.wasi_exec_model; // When the target os is WASI, we allow linking with WASI-LIBC if (target.os.tag == .wasi) { @@ -4648,7 +4657,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! } try man.addOptionalFile(module_obj_path); try man.addOptionalFile(compiler_rt_path); - man.hash.addOptionalBytes(wasm.base.comp.config.entry); + man.hash.addOptionalBytes(wasm.entry_name); man.hash.add(wasm.base.stack_size); man.hash.add(wasm.base.build_id); man.hash.add(import_memory); @@ -4799,9 +4808,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! try argv.append("--export-dynamic"); } - if (comp.config.entry) |entry| { - try argv.append("--entry"); - try argv.append(entry); + if (wasm.entry_name) |entry_name| { + try argv.appendSlice(&.{ "--entry", entry_name }); } else { try argv.append("--no-entry"); } @@ -5347,3 +5355,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { try wasm.mark(target_loc.finalLoc(wasm)); } } + +fn defaultEntrySymbolName(wasi_exec_model: std.builtin.WasiExecModel) []const u8 { + return switch (wasi_exec_model) { + .reactor => "_initialize", + .command => "_start", + }; +} diff --git a/src/main.zig b/src/main.zig index 0822557158..54db7eb37d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -857,6 +857,7 @@ fn buildOutputType( var linker_optimization: ?[]const u8 = null; var linker_module_definition_file: ?[]const u8 = null; var test_no_exec = false; + var entry: Compilation.CreateOptions.Entry = .default; var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; var stack_size: ?u64 = null; var image_base: ?u64 = null; @@ -1129,7 +1130,7 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "-O")) { mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal()); } else if (mem.startsWith(u8, arg, "-fentry=")) { - create_module.opts.entry = .{ .named = arg["-fentry=".len..] }; + entry = .{ .named = arg["-fentry=".len..] }; } else if (mem.eql(u8, arg, "--force_undefined")) { try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {}); } else if (mem.eql(u8, arg, "--stack")) { @@ -1556,12 +1557,12 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--import-memory")) { create_module.opts.import_memory = true; } else if (mem.eql(u8, arg, "-fentry")) { - switch (create_module.opts.entry) { - .default, .disabled => create_module.opts.entry = .enabled, + switch (entry) { + .default, .disabled => entry = .enabled, .enabled, .named => {}, } } else if (mem.eql(u8, arg, "-fno-entry")) { - create_module.opts.entry = .disabled; + entry = .disabled; } else if (mem.eql(u8, arg, "--export-memory")) { create_module.opts.export_memory = true; } else if (mem.eql(u8, arg, "--import-symbols")) { @@ -2065,7 +2066,7 @@ fn buildOutputType( create_module.sysroot = it.only_arg; }, .entry => { - create_module.opts.entry = .{ .named = it.only_arg }; + entry = .{ .named = it.only_arg }; }, .force_undefined_symbol => { try force_undefined_symbols.put(arena, it.only_arg, {}); @@ -2210,7 +2211,7 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--export-table")) { linker_export_table = true; } else if (mem.eql(u8, arg, "--no-entry")) { - create_module.opts.entry = .disabled; + entry = .disabled; } 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| { @@ -2284,7 +2285,7 @@ fn buildOutputType( }; have_version = true; } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { - create_module.opts.entry = .{ .named = linker_args_it.nextOrFatal() }; + entry = .{ .named = linker_args_it.nextOrFatal() }; } else if (mem.eql(u8, arg, "-u")) { try force_undefined_symbols.put(arena, linker_args_it.nextOrFatal(), {}); } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { @@ -3200,6 +3201,7 @@ fn buildOutputType( .minor_subsystem_version = minor_subsystem_version, .link_eh_frame_hdr = link_eh_frame_hdr, .link_emit_relocs = link_emit_relocs, + .entry = entry, .force_undefined_symbols = force_undefined_symbols, .stack_size = stack_size, .image_base = image_base, @@ -3845,8 +3847,6 @@ fn createModule( error.ObjectFilesCannotShareMemory => fatal("object files cannot share memory", .{}), error.SharedMemoryRequiresAtomicsAndBulkMemory => fatal("shared memory requires atomics and bulk_memory CPU features", .{}), error.ThreadsRequireSharedMemory => fatal("threads require shared memory", .{}), - error.UnknownTargetEntryPoint => fatal("unknown target entry point", .{}), - error.NonExecutableEntryPoint => fatal("entry points only allowed for executables", .{}), error.EmittingLlvmModuleRequiresLlvmBackend => fatal("emitting an LLVM module requires using the LLVM backend", .{}), error.LlvmLacksTargetSupport => fatal("LLVM lacks support for the specified target", .{}), error.ZigLacksTargetSupport => fatal("compiler backend unavailable for the specified target", .{}), diff --git a/src/target.zig b/src/target.zig index d1a98601cf..262632b373 100644 --- a/src/target.zig +++ b/src/target.zig @@ -683,23 +683,3 @@ pub fn backendSupportsFeature( .safety_checked_instructions => use_llvm, }; } - -pub fn defaultEntrySymbolName( - target: std.Target, - /// May be `undefined` when `target` is not WASI. - wasi_exec_model: std.builtin.WasiExecModel, -) ?[]const u8 { - return switch (target.ofmt) { - .coff => "wWinMainCRTStartup", - .macho => "_main", - .elf, .plan9 => switch (target.cpu.arch) { - .mips, .mipsel, .mips64, .mips64el => "__start", - else => "_start", - }, - .wasm => switch (wasi_exec_model) { - .reactor => "_initialize", - .command => "_start", - }, - else => null, - }; -}