| author | |
| committer | |
| log | 57562c8d507667b6fefcb7fbc7a305fbd610b5dd |
| tree | f0e494bdace7302f7cce8ad8c9c7d3227bd81d64 |
| parent | c9fe43679f8d8f0db6250cc881b59cc68daaf128 |
This is necessary because on COFF, the entry symbol name is not known
until the linker has looked at the set of global symbol names to
determine which of the four possible main entry points is present.11 files changed, 124 insertions(+), 99 deletions(-)
src/Compilation.zig+6-3| ... | @@ -924,7 +924,7 @@ pub const LinkObject = struct { | ... | @@ -924,7 +924,7 @@ pub const LinkObject = struct { |
| 924 | loption: bool = false, | 924 | loption: bool = false, |
| 925 | }; | 925 | }; |
| 926 | 926 | ||
| 927 | pub const InitOptions = struct { | 927 | pub const CreateOptions = struct { |
| 928 | zig_lib_directory: Directory, | 928 | zig_lib_directory: Directory, |
| 929 | local_cache_directory: Directory, | 929 | local_cache_directory: Directory, |
| 930 | global_cache_directory: Directory, | 930 | global_cache_directory: Directory, |
| ... | @@ -1054,7 +1054,7 @@ pub const InitOptions = struct { | ... | @@ -1054,7 +1054,7 @@ pub const InitOptions = struct { |
| 1054 | /// infinite recursion. | 1054 | /// infinite recursion. |
| 1055 | skip_linker_dependencies: bool = false, | 1055 | skip_linker_dependencies: bool = false, |
| 1056 | hash_style: link.File.Elf.HashStyle = .both, | 1056 | hash_style: link.File.Elf.HashStyle = .both, |
| 1057 | entry: ?[]const u8 = null, | 1057 | entry: Entry = .default, |
| 1058 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}, | 1058 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}, |
| 1059 | stack_size: ?u64 = null, | 1059 | stack_size: ?u64 = null, |
| 1060 | image_base: ?u64 = null, | 1060 | image_base: ?u64 = null, |
| ... | @@ -1089,6 +1089,8 @@ pub const InitOptions = struct { | ... | @@ -1089,6 +1089,8 @@ pub const InitOptions = struct { |
| 1089 | /// (Windows) PDB output path | 1089 | /// (Windows) PDB output path |
| 1090 | pdb_out_path: ?[]const u8 = null, | 1090 | pdb_out_path: ?[]const u8 = null, |
| 1091 | error_limit: ?Compilation.Module.ErrorInt = null, | 1091 | error_limit: ?Compilation.Module.ErrorInt = null, |
| 1092 | |||
| 1093 | pub const Entry = link.File.OpenOptions.Entry; | ||
| 1092 | }; | 1094 | }; |
| 1093 | 1095 | ||
| 1094 | fn addModuleTableToCacheHash( | 1096 | fn addModuleTableToCacheHash( |
| ... | @@ -1159,7 +1161,7 @@ fn addModuleTableToCacheHash( | ... | @@ -1159,7 +1161,7 @@ fn addModuleTableToCacheHash( |
| 1159 | } | 1161 | } |
| 1160 | } | 1162 | } |
| 1161 | 1163 | ||
| 1162 | pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | 1164 | pub fn create(gpa: Allocator, options: CreateOptions) !*Compilation { |
| 1163 | const output_mode = options.config.output_mode; | 1165 | const output_mode = options.config.output_mode; |
| 1164 | const is_dyn_lib = switch (output_mode) { | 1166 | const is_dyn_lib = switch (output_mode) { |
| 1165 | .Obj, .Exe => false, | 1167 | .Obj, .Exe => false, |
| ... | @@ -1543,6 +1545,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1543,6 +1545,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1543 | .dynamicbase = options.linker_dynamicbase, | 1545 | .dynamicbase = options.linker_dynamicbase, |
| 1544 | .major_subsystem_version = options.major_subsystem_version, | 1546 | .major_subsystem_version = options.major_subsystem_version, |
| 1545 | .minor_subsystem_version = options.minor_subsystem_version, | 1547 | .minor_subsystem_version = options.minor_subsystem_version, |
| 1548 | .entry = options.entry, | ||
| 1546 | .stack_size = options.stack_size, | 1549 | .stack_size = options.stack_size, |
| 1547 | .image_base = options.image_base, | 1550 | .image_base = options.image_base, |
| 1548 | .version_script = options.version_script, | 1551 | .version_script = options.version_script, |
src/Compilation/Config.zig-29| ... | @@ -55,7 +55,6 @@ export_memory: bool, | ... | @@ -55,7 +55,6 @@ export_memory: bool, |
| 55 | shared_memory: bool, | 55 | shared_memory: bool, |
| 56 | is_test: bool, | 56 | is_test: bool, |
| 57 | test_evented_io: bool, | 57 | test_evented_io: bool, |
| 58 | entry: ?[]const u8, | ||
| 59 | debug_format: DebugFormat, | 58 | debug_format: DebugFormat, |
| 60 | root_strip: bool, | 59 | root_strip: bool, |
| 61 | root_error_tracing: bool, | 60 | root_error_tracing: bool, |
| ... | @@ -100,12 +99,6 @@ pub const Options = struct { | ... | @@ -100,12 +99,6 @@ pub const Options = struct { |
| 100 | use_lld: ?bool = null, | 99 | use_lld: ?bool = null, |
| 101 | use_clang: ?bool = null, | 100 | use_clang: ?bool = null, |
| 102 | lto: ?bool = null, | 101 | lto: ?bool = null, |
| 103 | entry: union(enum) { | ||
| 104 | default, | ||
| 105 | disabled, | ||
| 106 | enabled, | ||
| 107 | named: []const u8, | ||
| 108 | } = .default, | ||
| 109 | /// WASI-only. Type of WASI execution model ("command" or "reactor"). | 102 | /// WASI-only. Type of WASI execution model ("command" or "reactor"). |
| 110 | wasi_exec_model: ?std.builtin.WasiExecModel = null, | 103 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| 111 | import_memory: ?bool = null, | 104 | import_memory: ?bool = null, |
| ... | @@ -123,8 +116,6 @@ pub const ResolveError = error{ | ... | @@ -123,8 +116,6 @@ pub const ResolveError = error{ |
| 123 | ObjectFilesCannotShareMemory, | 116 | ObjectFilesCannotShareMemory, |
| 124 | SharedMemoryRequiresAtomicsAndBulkMemory, | 117 | SharedMemoryRequiresAtomicsAndBulkMemory, |
| 125 | ThreadsRequireSharedMemory, | 118 | ThreadsRequireSharedMemory, |
| 126 | UnknownTargetEntryPoint, | ||
| 127 | NonExecutableEntryPoint, | ||
| 128 | EmittingLlvmModuleRequiresLlvmBackend, | 119 | EmittingLlvmModuleRequiresLlvmBackend, |
| 129 | LlvmLacksTargetSupport, | 120 | LlvmLacksTargetSupport, |
| 130 | ZigLacksTargetSupport, | 121 | ZigLacksTargetSupport, |
| ... | @@ -352,25 +343,6 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -352,25 +343,6 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 352 | break :b false; | 343 | break :b false; |
| 353 | }; | 344 | }; |
| 354 | 345 | ||
| 355 | const entry: ?[]const u8 = switch (options.entry) { | ||
| 356 | .disabled => null, | ||
| 357 | .default => b: { | ||
| 358 | if (options.output_mode != .Exe) break :b null; | ||
| 359 | |||
| 360 | // When producing C source code, the decision of entry point is made | ||
| 361 | // when compiling the C code, not when producing the C code. | ||
| 362 | if (target.ofmt == .c) break :b null; | ||
| 363 | |||
| 364 | break :b target_util.defaultEntrySymbolName(target, wasi_exec_model) orelse | ||
| 365 | return error.UnknownTargetEntryPoint; | ||
| 366 | }, | ||
| 367 | .enabled => target_util.defaultEntrySymbolName(target, wasi_exec_model) orelse | ||
| 368 | return error.UnknownTargetEntryPoint, | ||
| 369 | .named => |name| name, | ||
| 370 | }; | ||
| 371 | if (entry != null and options.output_mode != .Exe) | ||
| 372 | return error.NonExecutableEntryPoint; | ||
| 373 | |||
| 374 | const any_unwind_tables = options.any_unwind_tables or | 346 | const any_unwind_tables = options.any_unwind_tables or |
| 375 | link_libunwind or target_util.needUnwindTables(target); | 347 | link_libunwind or target_util.needUnwindTables(target); |
| 376 | 348 | ||
| ... | @@ -519,7 +491,6 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -519,7 +491,6 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 519 | .use_llvm = use_llvm, | 491 | .use_llvm = use_llvm, |
| 520 | .use_lib_llvm = use_lib_llvm, | 492 | .use_lib_llvm = use_lib_llvm, |
| 521 | .use_lld = use_lld, | 493 | .use_lld = use_lld, |
| 522 | .entry = entry, | ||
| 523 | .wasi_exec_model = wasi_exec_model, | 494 | .wasi_exec_model = wasi_exec_model, |
| 524 | .debug_format = debug_format, | 495 | .debug_format = debug_format, |
| 525 | .root_strip = root_strip, | 496 | .root_strip = root_strip, |
src/link.zig+9| ... | @@ -83,6 +83,8 @@ pub const File = struct { | ... | @@ -83,6 +83,8 @@ pub const File = struct { |
| 83 | symbol_count_hint: u64 = 32, | 83 | symbol_count_hint: u64 = 32, |
| 84 | program_code_size_hint: u64 = 256 * 1024, | 84 | program_code_size_hint: u64 = 256 * 1024, |
| 85 | 85 | ||
| 86 | /// This may depend on what symbols are found during the linking process. | ||
| 87 | entry: Entry, | ||
| 86 | /// Virtual address of the entry point procedure relative to image base. | 88 | /// Virtual address of the entry point procedure relative to image base. |
| 87 | entry_addr: ?u64, | 89 | entry_addr: ?u64, |
| 88 | stack_size: ?u64, | 90 | stack_size: ?u64, |
| ... | @@ -169,6 +171,13 @@ pub const File = struct { | ... | @@ -169,6 +171,13 @@ pub const File = struct { |
| 169 | module_definition_file: ?[]const u8, | 171 | module_definition_file: ?[]const u8, |
| 170 | 172 | ||
| 171 | wasi_emulated_libs: []const wasi_libc.CRTFile, | 173 | wasi_emulated_libs: []const wasi_libc.CRTFile, |
| 174 | |||
| 175 | pub const Entry = union(enum) { | ||
| 176 | default, | ||
| 177 | disabled, | ||
| 178 | enabled, | ||
| 179 | named: []const u8, | ||
| 180 | }; | ||
| 172 | }; | 181 | }; |
| 173 | 182 | ||
| 174 | /// Attempts incremental linking, if the file already exists. If | 183 | /// Attempts incremental linking, if the file already exists. If |
src/link/Coff.zig+20-1| ... | @@ -17,6 +17,7 @@ dynamicbase: bool, | ... | @@ -17,6 +17,7 @@ dynamicbase: bool, |
| 17 | major_subsystem_version: u16, | 17 | major_subsystem_version: u16, |
| 18 | minor_subsystem_version: u16, | 18 | minor_subsystem_version: u16, |
| 19 | lib_dirs: []const []const u8, | 19 | lib_dirs: []const []const u8, |
| 20 | entry: link.File.OpenOptions.Entry, | ||
| 20 | entry_addr: ?u32, | 21 | entry_addr: ?u32, |
| 21 | module_definition_file: ?[]const u8, | 22 | module_definition_file: ?[]const u8, |
| 22 | pdb_out_path: ?[]const u8, | 23 | pdb_out_path: ?[]const u8, |
| ... | @@ -303,7 +304,12 @@ pub fn createEmpty( | ... | @@ -303,7 +304,12 @@ pub fn createEmpty( |
| 303 | .Obj => 0, | 304 | .Obj => 0, |
| 304 | }, | 305 | }, |
| 305 | 306 | ||
| 307 | // Subsystem depends on the set of public symbol names from linked objects. | ||
| 308 | // See LinkerDriver::inferSubsystem from the LLD project for the flow chart. | ||
| 306 | .subsystem = options.subsystem, | 309 | .subsystem = options.subsystem, |
| 310 | |||
| 311 | .entry = options.entry, | ||
| 312 | |||
| 307 | .tsaware = options.tsaware, | 313 | .tsaware = options.tsaware, |
| 308 | .nxcompat = options.nxcompat, | 314 | .nxcompat = options.nxcompat, |
| 309 | .dynamicbase = options.dynamicbase, | 315 | .dynamicbase = options.dynamicbase, |
| ... | @@ -2498,7 +2504,20 @@ inline fn getSizeOfImage(self: Coff) u32 { | ... | @@ -2498,7 +2504,20 @@ inline fn getSizeOfImage(self: Coff) u32 { |
| 2498 | /// Returns symbol location corresponding to the set entrypoint (if any). | 2504 | /// Returns symbol location corresponding to the set entrypoint (if any). |
| 2499 | pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { | 2505 | pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { |
| 2500 | const comp = self.base.comp; | 2506 | const comp = self.base.comp; |
| 2501 | const entry_name = comp.config.entry orelse return null; | 2507 | |
| 2508 | // TODO This is incomplete. | ||
| 2509 | // The entry symbol name depends on the subsystem as well as the set of | ||
| 2510 | // public symbol names from linked objects. | ||
| 2511 | // See LinkerDriver::findDefaultEntry from the LLD project for the flow chart. | ||
| 2512 | const entry_name = switch (self.entry) { | ||
| 2513 | .disabled => return null, | ||
| 2514 | .default => switch (comp.config.output_mode) { | ||
| 2515 | .Exe => "wWinMainCRTStartup", | ||
| 2516 | .Obj, .Lib => return null, | ||
| 2517 | }, | ||
| 2518 | .enabled => "wWinMainCRTStartup", | ||
| 2519 | .named => |name| name, | ||
| 2520 | }; | ||
| 2502 | const global_index = self.resolver.get(entry_name) orelse return null; | 2521 | const global_index = self.resolver.get(entry_name) orelse return null; |
| 2503 | return self.globals.items[global_index]; | 2522 | return self.globals.items[global_index]; |
| 2504 | } | 2523 | } |
src/link/Coff/lld.zig+11-4| ... | @@ -52,6 +52,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -52,6 +52,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 52 | const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib; | 52 | const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib; |
| 53 | const target = comp.root_mod.resolved_target.result; | 53 | const target = comp.root_mod.resolved_target.result; |
| 54 | const optimize_mode = comp.root_mod.optimize_mode; | 54 | const optimize_mode = comp.root_mod.optimize_mode; |
| 55 | const entry_name: ?[]const u8 = switch (self.entry) { | ||
| 56 | // This logic isn't quite right for disabled or enabled. No point in fixing it | ||
| 57 | // when the goal is to eliminate dependency on LLD anyway. | ||
| 58 | // https://github.com/ziglang/zig/issues/17751 | ||
| 59 | .disabled, .default, .enabled => null, | ||
| 60 | .named => |name| name, | ||
| 61 | }; | ||
| 55 | 62 | ||
| 56 | // See link/Elf.zig for comments on how this mechanism works. | 63 | // See link/Elf.zig for comments on how this mechanism works. |
| 57 | const id_symlink_basename = "lld.id"; | 64 | const id_symlink_basename = "lld.id"; |
| ... | @@ -80,7 +87,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -80,7 +87,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 80 | } | 87 | } |
| 81 | } | 88 | } |
| 82 | try man.addOptionalFile(module_obj_path); | 89 | try man.addOptionalFile(module_obj_path); |
| 83 | man.hash.addOptionalBytes(comp.config.entry); | 90 | man.hash.addOptionalBytes(entry_name); |
| 84 | man.hash.add(self.base.stack_size); | 91 | man.hash.add(self.base.stack_size); |
| 85 | man.hash.add(self.image_base); | 92 | man.hash.add(self.image_base); |
| 86 | man.hash.addListOfBytes(self.lib_dirs); | 93 | man.hash.addListOfBytes(self.lib_dirs); |
| ... | @@ -218,8 +225,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -218,8 +225,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 218 | try argv.append("-DLL"); | 225 | try argv.append("-DLL"); |
| 219 | } | 226 | } |
| 220 | 227 | ||
| 221 | if (comp.config.entry) |entry| { | 228 | if (entry_name) |name| { |
| 222 | try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry})); | 229 | try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name})); |
| 223 | } | 230 | } |
| 224 | 231 | ||
| 225 | if (self.tsaware) { | 232 | if (self.tsaware) { |
| ... | @@ -441,7 +448,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -441,7 +448,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 441 | } | 448 | } |
| 442 | } else { | 449 | } else { |
| 443 | try argv.append("-NODEFAULTLIB"); | 450 | try argv.append("-NODEFAULTLIB"); |
| 444 | if (!is_lib and comp.config.entry == null) { | 451 | if (!is_lib and entry_name == null) { |
| 445 | if (comp.module) |module| { | 452 | if (comp.module) |module| { |
| 446 | if (module.stage1_flags.have_winmain_crt_startup) { | 453 | if (module.stage1_flags.have_winmain_crt_startup) { |
| 447 | try argv.append("-ENTRY:WinMainCRTStartup"); | 454 | try argv.append("-ENTRY:WinMainCRTStartup"); |
src/link/Elf.zig+21-8| ... | @@ -25,6 +25,7 @@ linker_script: ?[]const u8, | ... | @@ -25,6 +25,7 @@ linker_script: ?[]const u8, |
| 25 | version_script: ?[]const u8, | 25 | version_script: ?[]const u8, |
| 26 | print_icf_sections: bool, | 26 | print_icf_sections: bool, |
| 27 | print_map: bool, | 27 | print_map: bool, |
| 28 | entry_name: ?[]const u8, | ||
| 28 | 29 | ||
| 29 | ptr_width: PtrWidth, | 30 | ptr_width: PtrWidth, |
| 30 | 31 | ||
| ... | @@ -290,6 +291,13 @@ pub fn createEmpty( | ... | @@ -290,6 +291,13 @@ pub fn createEmpty( |
| 290 | .page_size = page_size, | 291 | .page_size = page_size, |
| 291 | .default_sym_version = default_sym_version, | 292 | .default_sym_version = default_sym_version, |
| 292 | 293 | ||
| 294 | .entry_name = switch (options.entry) { | ||
| 295 | .disabled => null, | ||
| 296 | .default => if (output_mode != .Exe) null else defaultEntrySymbolName(target.cpu.arch), | ||
| 297 | .enabled => defaultEntrySymbolName(target.cpu.arch), | ||
| 298 | .named => |name| name, | ||
| 299 | }, | ||
| 300 | |||
| 293 | .image_base = b: { | 301 | .image_base = b: { |
| 294 | if (is_dyn_lib) break :b 0; | 302 | if (is_dyn_lib) break :b 0; |
| 295 | if (output_mode == .Exe and comp.config.pie) break :b 0; | 303 | 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 | ... | @@ -1305,7 +1313,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1305 | 1313 | ||
| 1306 | // Look for entry address in objects if not set by the incremental compiler. | 1314 | // Look for entry address in objects if not set by the incremental compiler. |
| 1307 | if (self.entry_index == null) { | 1315 | if (self.entry_index == null) { |
| 1308 | if (comp.config.entry) |name| { | 1316 | if (self.entry_name) |name| { |
| 1309 | self.entry_index = self.globalByName(name); | 1317 | self.entry_index = self.globalByName(name); |
| 1310 | } | 1318 | } |
| 1311 | } | 1319 | } |
| ... | @@ -1679,9 +1687,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1679,9 +1687,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1679 | } | 1687 | } |
| 1680 | } | 1688 | } |
| 1681 | 1689 | ||
| 1682 | if (comp.config.entry) |entry| { | 1690 | if (self.entry_name) |name| { |
| 1683 | try argv.append("--entry"); | 1691 | try argv.appendSlice(&.{ "--entry", name }); |
| 1684 | try argv.append(entry); | ||
| 1685 | } | 1692 | } |
| 1686 | 1693 | ||
| 1687 | for (self.base.rpath_list) |rpath| { | 1694 | for (self.base.rpath_list) |rpath| { |
| ... | @@ -2427,7 +2434,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2427,7 +2434,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2427 | 2434 | ||
| 2428 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig | 2435 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 2429 | // installation sources because they are always a product of the compiler version + target information. | 2436 | // installation sources because they are always a product of the compiler version + target information. |
| 2430 | man.hash.addOptionalBytes(comp.config.entry); | 2437 | man.hash.addOptionalBytes(self.entry_name); |
| 2431 | man.hash.add(self.image_base); | 2438 | man.hash.add(self.image_base); |
| 2432 | man.hash.add(self.base.gc_sections); | 2439 | man.hash.add(self.base.gc_sections); |
| 2433 | man.hash.addOptional(self.sort_section); | 2440 | man.hash.addOptional(self.sort_section); |
| ... | @@ -2563,9 +2570,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2563,9 +2570,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2563 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), | 2570 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), |
| 2564 | } | 2571 | } |
| 2565 | 2572 | ||
| 2566 | if (comp.config.entry) |entry| { | 2573 | if (self.entry_name) |name| { |
| 2567 | try argv.append("--entry"); | 2574 | try argv.appendSlice(&.{ "--entry", name }); |
| 2568 | try argv.append(entry); | ||
| 2569 | } | 2575 | } |
| 2570 | 2576 | ||
| 2571 | for (self.base.force_undefined_symbols.keys()) |sym| { | 2577 | for (self.base.force_undefined_symbols.keys()) |sym| { |
| ... | @@ -6512,6 +6518,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); | ... | @@ -6512,6 +6518,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); |
| 6512 | pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1; | 6518 | pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1; |
| 6513 | pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2; | 6519 | pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2; |
| 6514 | 6520 | ||
| 6521 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { | ||
| 6522 | return switch (cpu_arch) { | ||
| 6523 | .mips, .mipsel, .mips64, .mips64el => "__start", | ||
| 6524 | else => "_start", | ||
| 6525 | }; | ||
| 6526 | } | ||
| 6527 | |||
| 6515 | const std = @import("std"); | 6528 | const std = @import("std"); |
| 6516 | const build_options = @import("build_options"); | 6529 | const build_options = @import("build_options"); |
| 6517 | const builtin = @import("builtin"); | 6530 | const builtin = @import("builtin"); |
src/link/MachO.zig+13-4| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | base: File, | 1 | base: File, |
| 2 | entry_name: ?[]const u8, | ||
| 2 | 3 | ||
| 3 | /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. | 4 | /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. |
| 4 | llvm_object: ?*LlvmObject = null, | 5 | llvm_object: ?*LlvmObject = null, |
| ... | @@ -231,6 +232,12 @@ pub fn createEmpty( | ... | @@ -231,6 +232,12 @@ pub fn createEmpty( |
| 231 | .install_name = options.install_name, | 232 | .install_name = options.install_name, |
| 232 | .entitlements = options.entitlements, | 233 | .entitlements = options.entitlements, |
| 233 | .compatibility_version = options.compatibility_version, | 234 | .compatibility_version = options.compatibility_version, |
| 235 | .entry_name = switch (options.entry) { | ||
| 236 | .disabled => null, | ||
| 237 | .default => if (output_mode != .Exe) null else default_entry_symbol_name, | ||
| 238 | .enabled => default_entry_symbol_name, | ||
| 239 | .named => |name| name, | ||
| 240 | }, | ||
| 234 | }; | 241 | }; |
| 235 | if (use_llvm and comp.config.have_zcu) { | 242 | if (use_llvm and comp.config.have_zcu) { |
| 236 | self.llvm_object = try LlvmObject.create(arena, comp); | 243 | self.llvm_object = try LlvmObject.create(arena, comp); |
| ... | @@ -1629,8 +1636,9 @@ pub fn resolveSymbols(self: *MachO) !void { | ... | @@ -1629,8 +1636,9 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1629 | // we search for it in libraries should there be no object files specified | 1636 | // we search for it in libraries should there be no object files specified |
| 1630 | // on the linker line. | 1637 | // on the linker line. |
| 1631 | if (output_mode == .Exe) { | 1638 | if (output_mode == .Exe) { |
| 1632 | const entry_name = comp.config.entry.?; | 1639 | if (self.entry_name) |entry_name| { |
| 1633 | _ = try self.addUndefined(entry_name, .{}); | 1640 | _ = try self.addUndefined(entry_name, .{}); |
| 1641 | } | ||
| 1634 | } | 1642 | } |
| 1635 | 1643 | ||
| 1636 | // Force resolution of any symbols requested by the user. | 1644 | // Force resolution of any symbols requested by the user. |
| ... | @@ -5085,8 +5093,7 @@ pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { | ... | @@ -5085,8 +5093,7 @@ pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5085 | /// Returns symbol location corresponding to the set entrypoint if any. | 5093 | /// Returns symbol location corresponding to the set entrypoint if any. |
| 5086 | /// Asserts output mode is executable. | 5094 | /// Asserts output mode is executable. |
| 5087 | pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { | 5095 | pub fn getEntryPoint(self: MachO) ?SymbolWithLoc { |
| 5088 | const comp = self.base.comp; | 5096 | const entry_name = self.entry_name orelse return null; |
| 5089 | const entry_name = comp.config.entry orelse return null; | ||
| 5090 | const global = self.getGlobal(entry_name) orelse return null; | 5097 | const global = self.getGlobal(entry_name) orelse return null; |
| 5091 | return global; | 5098 | return global; |
| 5092 | } | 5099 | } |
| ... | @@ -5645,6 +5652,8 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index, logger: anytype) void { | ... | @@ -5645,6 +5652,8 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index, logger: anytype) void { |
| 5645 | } | 5652 | } |
| 5646 | } | 5653 | } |
| 5647 | 5654 | ||
| 5655 | const default_entry_symbol_name = "_main"; | ||
| 5656 | |||
| 5648 | pub const base_tag: File.Tag = File.Tag.macho; | 5657 | pub const base_tag: File.Tag = File.Tag.macho; |
| 5649 | pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1))); | 5658 | pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1))); |
| 5650 | pub const N_BOUNDARY: u16 = @as(u16, @bitCast(@as(i16, -2))); | 5659 | pub const N_BOUNDARY: u16 = @as(u16, @bitCast(@as(i16, -2))); |
src/link/MachO/zld.zig+2-3| ... | @@ -276,9 +276,8 @@ pub fn linkWithZld( | ... | @@ -276,9 +276,8 @@ pub fn linkWithZld( |
| 276 | try argv.append("-dead_strip_dylibs"); | 276 | try argv.append("-dead_strip_dylibs"); |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | if (comp.config.entry) |entry| { | 279 | if (macho_file.entry_name) |entry_name| { |
| 280 | try argv.append("-e"); | 280 | try argv.appendSlice(&.{ "-e", entry_name }); |
| 281 | try argv.append(entry); | ||
| 282 | } | 281 | } |
| 283 | 282 | ||
| 284 | for (objects) |obj| { | 283 | for (objects) |obj| { |
src/link/Wasm.zig+33-18| ... | @@ -37,6 +37,7 @@ pub const Relocation = types.Relocation; | ... | @@ -37,6 +37,7 @@ pub const Relocation = types.Relocation; |
| 37 | pub const base_tag: link.File.Tag = .wasm; | 37 | pub const base_tag: link.File.Tag = .wasm; |
| 38 | 38 | ||
| 39 | base: link.File, | 39 | base: link.File, |
| 40 | entry_name: ?[]const u8, | ||
| 40 | import_symbols: bool, | 41 | import_symbols: bool, |
| 41 | export_symbol_names: []const []const u8, | 42 | export_symbol_names: []const []const u8, |
| 42 | global_base: ?u64, | 43 | global_base: ?u64, |
| ... | @@ -397,6 +398,7 @@ pub fn createEmpty( | ... | @@ -397,6 +398,7 @@ pub fn createEmpty( |
| 397 | const use_llvm = comp.config.use_llvm; | 398 | const use_llvm = comp.config.use_llvm; |
| 398 | const output_mode = comp.config.output_mode; | 399 | const output_mode = comp.config.output_mode; |
| 399 | const shared_memory = comp.config.shared_memory; | 400 | const shared_memory = comp.config.shared_memory; |
| 401 | const wasi_exec_model = comp.config.wasi_exec_model; | ||
| 400 | 402 | ||
| 401 | // If using LLD to link, this code should produce an object file so that it | 403 | // If using LLD to link, this code should produce an object file so that it |
| 402 | // can be passed to LLD. | 404 | // can be passed to LLD. |
| ... | @@ -434,6 +436,13 @@ pub fn createEmpty( | ... | @@ -434,6 +436,13 @@ pub fn createEmpty( |
| 434 | .initial_memory = options.initial_memory, | 436 | .initial_memory = options.initial_memory, |
| 435 | .max_memory = options.max_memory, | 437 | .max_memory = options.max_memory, |
| 436 | .wasi_emulated_libs = options.wasi_emulated_libs, | 438 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 439 | |||
| 440 | .entry_name = switch (options.entry) { | ||
| 441 | .disabled => null, | ||
| 442 | .default => if (output_mode != .Exe) null else defaultEntrySymbolName(wasi_exec_model), | ||
| 443 | .enabled => defaultEntrySymbolName(wasi_exec_model), | ||
| 444 | .named => |name| name, | ||
| 445 | }, | ||
| 437 | }; | 446 | }; |
| 438 | if (use_llvm and comp.config.have_zcu) { | 447 | if (use_llvm and comp.config.have_zcu) { |
| 439 | wasm.llvm_object = try LlvmObject.create(arena, comp); | 448 | wasm.llvm_object = try LlvmObject.create(arena, comp); |
| ... | @@ -3042,7 +3051,7 @@ fn setupExports(wasm: *Wasm) !void { | ... | @@ -3042,7 +3051,7 @@ fn setupExports(wasm: *Wasm) !void { |
| 3042 | fn setupStart(wasm: *Wasm) !void { | 3051 | fn setupStart(wasm: *Wasm) !void { |
| 3043 | const comp = wasm.base.comp; | 3052 | const comp = wasm.base.comp; |
| 3044 | // do not export entry point if user set none or no default was set. | 3053 | // do not export entry point if user set none or no default was set. |
| 3045 | const entry_name = comp.config.entry orelse return; | 3054 | const entry_name = wasm.entry_name orelse return; |
| 3046 | 3055 | ||
| 3047 | const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { | 3056 | const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { |
| 3048 | log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); | 3057 | log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); |
| ... | @@ -3475,8 +3484,8 @@ fn resetState(wasm: *Wasm) void { | ... | @@ -3475,8 +3484,8 @@ fn resetState(wasm: *Wasm) void { |
| 3475 | } | 3484 | } |
| 3476 | 3485 | ||
| 3477 | pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | 3486 | pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| 3478 | const use_lld = build_options.have_llvm and wasm.base.comp.config.use_lld; | 3487 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 3479 | const use_llvm = wasm.base.comp.config.use_llvm; | 3488 | const use_llvm = comp.config.use_llvm; |
| 3480 | 3489 | ||
| 3481 | if (use_lld) { | 3490 | if (use_lld) { |
| 3482 | return wasm.linkWithLLD(comp, prog_node); | 3491 | return wasm.linkWithLLD(comp, prog_node); |
| ... | @@ -3492,7 +3501,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3492,7 +3501,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3492 | const tracy = trace(@src()); | 3501 | const tracy = trace(@src()); |
| 3493 | defer tracy.end(); | 3502 | defer tracy.end(); |
| 3494 | 3503 | ||
| 3495 | const gpa = wasm.base.comp.gpa; | 3504 | const gpa = comp.gpa; |
| 3496 | const shared_memory = comp.config.shared_memory; | 3505 | const shared_memory = comp.config.shared_memory; |
| 3497 | const import_memory = comp.config.import_memory; | 3506 | const import_memory = comp.config.import_memory; |
| 3498 | 3507 | ||
| ... | @@ -3503,8 +3512,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3503,8 +3512,8 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3503 | 3512 | ||
| 3504 | const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type. | 3513 | const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type. |
| 3505 | const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path}); | 3514 | const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path}); |
| 3506 | const opt_zcu = wasm.base.comp.module; | 3515 | const opt_zcu = comp.module; |
| 3507 | const use_llvm = wasm.base.comp.config.use_llvm; | 3516 | const use_llvm = comp.config.use_llvm; |
| 3508 | 3517 | ||
| 3509 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 3518 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 3510 | // will not be part of the linker line anyway. | 3519 | // 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 | ... | @@ -3535,7 +3544,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3535 | defer if (!wasm.base.disable_lld_caching) man.deinit(); | 3544 | defer if (!wasm.base.disable_lld_caching) man.deinit(); |
| 3536 | var digest: [Cache.hex_digest_len]u8 = undefined; | 3545 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 3537 | 3546 | ||
| 3538 | const objects = wasm.base.comp.objects; | 3547 | const objects = comp.objects; |
| 3539 | 3548 | ||
| 3540 | // NOTE: The following section must be maintained to be equal | 3549 | // NOTE: The following section must be maintained to be equal |
| 3541 | // as the section defined in `linkWithLLD` | 3550 | // as the section defined in `linkWithLLD` |
| ... | @@ -3556,7 +3565,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3556,7 +3565,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3556 | } | 3565 | } |
| 3557 | try man.addOptionalFile(module_obj_path); | 3566 | try man.addOptionalFile(module_obj_path); |
| 3558 | try man.addOptionalFile(compiler_rt_path); | 3567 | try man.addOptionalFile(compiler_rt_path); |
| 3559 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); | 3568 | man.hash.addOptionalBytes(wasm.entry_name); |
| 3560 | man.hash.add(wasm.base.stack_size); | 3569 | man.hash.add(wasm.base.stack_size); |
| 3561 | man.hash.add(wasm.base.build_id); | 3570 | man.hash.add(wasm.base.build_id); |
| 3562 | man.hash.add(import_memory); | 3571 | man.hash.add(import_memory); |
| ... | @@ -3605,12 +3614,12 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l | ... | @@ -3605,12 +3614,12 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3605 | var positionals = std.ArrayList([]const u8).init(arena); | 3614 | var positionals = std.ArrayList([]const u8).init(arena); |
| 3606 | try positionals.ensureUnusedCapacity(objects.len); | 3615 | try positionals.ensureUnusedCapacity(objects.len); |
| 3607 | 3616 | ||
| 3608 | const target = wasm.base.comp.root_mod.resolved_target.result; | 3617 | const target = comp.root_mod.resolved_target.result; |
| 3609 | const output_mode = wasm.base.comp.config.output_mode; | 3618 | const output_mode = comp.config.output_mode; |
| 3610 | const link_mode = wasm.base.comp.config.link_mode; | 3619 | const link_mode = comp.config.link_mode; |
| 3611 | const link_libc = wasm.base.comp.config.link_libc; | 3620 | const link_libc = comp.config.link_libc; |
| 3612 | const link_libcpp = wasm.base.comp.config.link_libcpp; | 3621 | const link_libcpp = comp.config.link_libcpp; |
| 3613 | const wasi_exec_model = wasm.base.comp.config.wasi_exec_model; | 3622 | const wasi_exec_model = comp.config.wasi_exec_model; |
| 3614 | 3623 | ||
| 3615 | // When the target os is WASI, we allow linking with WASI-LIBC | 3624 | // When the target os is WASI, we allow linking with WASI-LIBC |
| 3616 | if (target.os.tag == .wasi) { | 3625 | if (target.os.tag == .wasi) { |
| ... | @@ -4648,7 +4657,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4648,7 +4657,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4648 | } | 4657 | } |
| 4649 | try man.addOptionalFile(module_obj_path); | 4658 | try man.addOptionalFile(module_obj_path); |
| 4650 | try man.addOptionalFile(compiler_rt_path); | 4659 | try man.addOptionalFile(compiler_rt_path); |
| 4651 | man.hash.addOptionalBytes(wasm.base.comp.config.entry); | 4660 | man.hash.addOptionalBytes(wasm.entry_name); |
| 4652 | man.hash.add(wasm.base.stack_size); | 4661 | man.hash.add(wasm.base.stack_size); |
| 4653 | man.hash.add(wasm.base.build_id); | 4662 | man.hash.add(wasm.base.build_id); |
| 4654 | man.hash.add(import_memory); | 4663 | man.hash.add(import_memory); |
| ... | @@ -4799,9 +4808,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! | ... | @@ -4799,9 +4808,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4799 | try argv.append("--export-dynamic"); | 4808 | try argv.append("--export-dynamic"); |
| 4800 | } | 4809 | } |
| 4801 | 4810 | ||
| 4802 | if (comp.config.entry) |entry| { | 4811 | if (wasm.entry_name) |entry_name| { |
| 4803 | try argv.append("--entry"); | 4812 | try argv.appendSlice(&.{ "--entry", entry_name }); |
| 4804 | try argv.append(entry); | ||
| 4805 | } else { | 4813 | } else { |
| 4806 | try argv.append("--no-entry"); | 4814 | try argv.append("--no-entry"); |
| 4807 | } | 4815 | } |
| ... | @@ -5347,3 +5355,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { | ... | @@ -5347,3 +5355,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { |
| 5347 | try wasm.mark(target_loc.finalLoc(wasm)); | 5355 | try wasm.mark(target_loc.finalLoc(wasm)); |
| 5348 | } | 5356 | } |
| 5349 | } | 5357 | } |
| 5358 | |||
| 5359 | fn defaultEntrySymbolName(wasi_exec_model: std.builtin.WasiExecModel) []const u8 { | ||
| 5360 | return switch (wasi_exec_model) { | ||
| 5361 | .reactor => "_initialize", | ||
| 5362 | .command => "_start", | ||
| 5363 | }; | ||
| 5364 | } |
src/main.zig+9-9| ... | @@ -857,6 +857,7 @@ fn buildOutputType( | ... | @@ -857,6 +857,7 @@ fn buildOutputType( |
| 857 | var linker_optimization: ?[]const u8 = null; | 857 | var linker_optimization: ?[]const u8 = null; |
| 858 | var linker_module_definition_file: ?[]const u8 = null; | 858 | var linker_module_definition_file: ?[]const u8 = null; |
| 859 | var test_no_exec = false; | 859 | var test_no_exec = false; |
| 860 | var entry: Compilation.CreateOptions.Entry = .default; | ||
| 860 | var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; | 861 | var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; |
| 861 | var stack_size: ?u64 = null; | 862 | var stack_size: ?u64 = null; |
| 862 | var image_base: ?u64 = null; | 863 | var image_base: ?u64 = null; |
| ... | @@ -1129,7 +1130,7 @@ fn buildOutputType( | ... | @@ -1129,7 +1130,7 @@ fn buildOutputType( |
| 1129 | } else if (mem.eql(u8, arg, "-O")) { | 1130 | } else if (mem.eql(u8, arg, "-O")) { |
| 1130 | mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal()); | 1131 | mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal()); |
| 1131 | } else if (mem.startsWith(u8, arg, "-fentry=")) { | 1132 | } else if (mem.startsWith(u8, arg, "-fentry=")) { |
| 1132 | create_module.opts.entry = .{ .named = arg["-fentry=".len..] }; | 1133 | entry = .{ .named = arg["-fentry=".len..] }; |
| 1133 | } else if (mem.eql(u8, arg, "--force_undefined")) { | 1134 | } else if (mem.eql(u8, arg, "--force_undefined")) { |
| 1134 | try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {}); | 1135 | try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {}); |
| 1135 | } else if (mem.eql(u8, arg, "--stack")) { | 1136 | } else if (mem.eql(u8, arg, "--stack")) { |
| ... | @@ -1556,12 +1557,12 @@ fn buildOutputType( | ... | @@ -1556,12 +1557,12 @@ fn buildOutputType( |
| 1556 | } else if (mem.eql(u8, arg, "--import-memory")) { | 1557 | } else if (mem.eql(u8, arg, "--import-memory")) { |
| 1557 | create_module.opts.import_memory = true; | 1558 | create_module.opts.import_memory = true; |
| 1558 | } else if (mem.eql(u8, arg, "-fentry")) { | 1559 | } else if (mem.eql(u8, arg, "-fentry")) { |
| 1559 | switch (create_module.opts.entry) { | 1560 | switch (entry) { |
| 1560 | .default, .disabled => create_module.opts.entry = .enabled, | 1561 | .default, .disabled => entry = .enabled, |
| 1561 | .enabled, .named => {}, | 1562 | .enabled, .named => {}, |
| 1562 | } | 1563 | } |
| 1563 | } else if (mem.eql(u8, arg, "-fno-entry")) { | 1564 | } else if (mem.eql(u8, arg, "-fno-entry")) { |
| 1564 | create_module.opts.entry = .disabled; | 1565 | entry = .disabled; |
| 1565 | } else if (mem.eql(u8, arg, "--export-memory")) { | 1566 | } else if (mem.eql(u8, arg, "--export-memory")) { |
| 1566 | create_module.opts.export_memory = true; | 1567 | create_module.opts.export_memory = true; |
| 1567 | } else if (mem.eql(u8, arg, "--import-symbols")) { | 1568 | } else if (mem.eql(u8, arg, "--import-symbols")) { |
| ... | @@ -2065,7 +2066,7 @@ fn buildOutputType( | ... | @@ -2065,7 +2066,7 @@ fn buildOutputType( |
| 2065 | create_module.sysroot = it.only_arg; | 2066 | create_module.sysroot = it.only_arg; |
| 2066 | }, | 2067 | }, |
| 2067 | .entry => { | 2068 | .entry => { |
| 2068 | create_module.opts.entry = .{ .named = it.only_arg }; | 2069 | entry = .{ .named = it.only_arg }; |
| 2069 | }, | 2070 | }, |
| 2070 | .force_undefined_symbol => { | 2071 | .force_undefined_symbol => { |
| 2071 | try force_undefined_symbols.put(arena, it.only_arg, {}); | 2072 | try force_undefined_symbols.put(arena, it.only_arg, {}); |
| ... | @@ -2210,7 +2211,7 @@ fn buildOutputType( | ... | @@ -2210,7 +2211,7 @@ fn buildOutputType( |
| 2210 | } else if (mem.eql(u8, arg, "--export-table")) { | 2211 | } else if (mem.eql(u8, arg, "--export-table")) { |
| 2211 | linker_export_table = true; | 2212 | linker_export_table = true; |
| 2212 | } else if (mem.eql(u8, arg, "--no-entry")) { | 2213 | } else if (mem.eql(u8, arg, "--no-entry")) { |
| 2213 | create_module.opts.entry = .disabled; | 2214 | entry = .disabled; |
| 2214 | } else if (mem.eql(u8, arg, "--initial-memory")) { | 2215 | } else if (mem.eql(u8, arg, "--initial-memory")) { |
| 2215 | const next_arg = linker_args_it.nextOrFatal(); | 2216 | const next_arg = linker_args_it.nextOrFatal(); |
| 2216 | linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { | 2217 | linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| ... | @@ -2284,7 +2285,7 @@ fn buildOutputType( | ... | @@ -2284,7 +2285,7 @@ fn buildOutputType( |
| 2284 | }; | 2285 | }; |
| 2285 | have_version = true; | 2286 | have_version = true; |
| 2286 | } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { | 2287 | } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { |
| 2287 | create_module.opts.entry = .{ .named = linker_args_it.nextOrFatal() }; | 2288 | entry = .{ .named = linker_args_it.nextOrFatal() }; |
| 2288 | } else if (mem.eql(u8, arg, "-u")) { | 2289 | } else if (mem.eql(u8, arg, "-u")) { |
| 2289 | try force_undefined_symbols.put(arena, linker_args_it.nextOrFatal(), {}); | 2290 | try force_undefined_symbols.put(arena, linker_args_it.nextOrFatal(), {}); |
| 2290 | } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { | 2291 | } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { |
| ... | @@ -3200,6 +3201,7 @@ fn buildOutputType( | ... | @@ -3200,6 +3201,7 @@ fn buildOutputType( |
| 3200 | .minor_subsystem_version = minor_subsystem_version, | 3201 | .minor_subsystem_version = minor_subsystem_version, |
| 3201 | .link_eh_frame_hdr = link_eh_frame_hdr, | 3202 | .link_eh_frame_hdr = link_eh_frame_hdr, |
| 3202 | .link_emit_relocs = link_emit_relocs, | 3203 | .link_emit_relocs = link_emit_relocs, |
| 3204 | .entry = entry, | ||
| 3203 | .force_undefined_symbols = force_undefined_symbols, | 3205 | .force_undefined_symbols = force_undefined_symbols, |
| 3204 | .stack_size = stack_size, | 3206 | .stack_size = stack_size, |
| 3205 | .image_base = image_base, | 3207 | .image_base = image_base, |
| ... | @@ -3845,8 +3847,6 @@ fn createModule( | ... | @@ -3845,8 +3847,6 @@ fn createModule( |
| 3845 | error.ObjectFilesCannotShareMemory => fatal("object files cannot share memory", .{}), | 3847 | error.ObjectFilesCannotShareMemory => fatal("object files cannot share memory", .{}), |
| 3846 | error.SharedMemoryRequiresAtomicsAndBulkMemory => fatal("shared memory requires atomics and bulk_memory CPU features", .{}), | 3848 | error.SharedMemoryRequiresAtomicsAndBulkMemory => fatal("shared memory requires atomics and bulk_memory CPU features", .{}), |
| 3847 | error.ThreadsRequireSharedMemory => fatal("threads require shared memory", .{}), | 3849 | error.ThreadsRequireSharedMemory => fatal("threads require shared memory", .{}), |
| 3848 | error.UnknownTargetEntryPoint => fatal("unknown target entry point", .{}), | ||
| 3849 | error.NonExecutableEntryPoint => fatal("entry points only allowed for executables", .{}), | ||
| 3850 | error.EmittingLlvmModuleRequiresLlvmBackend => fatal("emitting an LLVM module requires using the LLVM backend", .{}), | 3850 | error.EmittingLlvmModuleRequiresLlvmBackend => fatal("emitting an LLVM module requires using the LLVM backend", .{}), |
| 3851 | error.LlvmLacksTargetSupport => fatal("LLVM lacks support for the specified target", .{}), | 3851 | error.LlvmLacksTargetSupport => fatal("LLVM lacks support for the specified target", .{}), |
| 3852 | error.ZigLacksTargetSupport => fatal("compiler backend unavailable for the specified target", .{}), | 3852 | error.ZigLacksTargetSupport => fatal("compiler backend unavailable for the specified target", .{}), |
src/target.zig-20| ... | @@ -683,23 +683,3 @@ pub fn backendSupportsFeature( | ... | @@ -683,23 +683,3 @@ pub fn backendSupportsFeature( |
| 683 | .safety_checked_instructions => use_llvm, | 683 | .safety_checked_instructions => use_llvm, |
| 684 | }; | 684 | }; |
| 685 | } | 685 | } |
| 686 | |||
| 687 | pub fn defaultEntrySymbolName( | ||
| 688 | target: std.Target, | ||
| 689 | /// May be `undefined` when `target` is not WASI. | ||
| 690 | wasi_exec_model: std.builtin.WasiExecModel, | ||
| 691 | ) ?[]const u8 { | ||
| 692 | return switch (target.ofmt) { | ||
| 693 | .coff => "wWinMainCRTStartup", | ||
| 694 | .macho => "_main", | ||
| 695 | .elf, .plan9 => switch (target.cpu.arch) { | ||
| 696 | .mips, .mipsel, .mips64, .mips64el => "__start", | ||
| 697 | else => "_start", | ||
| 698 | }, | ||
| 699 | .wasm => switch (wasi_exec_model) { | ||
| 700 | .reactor => "_initialize", | ||
| 701 | .command => "_start", | ||
| 702 | }, | ||
| 703 | else => null, | ||
| 704 | }; | ||
| 705 | } |