| author | |
| committer | |
| log | 0cfa39304b18c6a04689bd789f5dc4d035ec43b0 |
| tree | 9dc20b8bbf29909fc7f093618cccd42845aa4e41 |
| parent | b56e916fa1d3508a01a6fc0b62f3f64dd3843b85 |
Related: #78744 files changed, 120 insertions(+), 8 deletions(-)
src/Compilation.zig+10| ... | ... | @@ -468,6 +468,11 @@ pub const InitOptions = struct { |
| 468 | 468 | disable_c_depfile: bool = false, |
| 469 | 469 | linker_z_nodelete: bool = false, |
| 470 | 470 | linker_z_defs: bool = false, |
| 471 | linker_tsaware: bool = false, | |
| 472 | linker_nxcompat: bool = false, | |
| 473 | linker_dynamicbase: bool = false, | |
| 474 | major_subsystem_version: ?u32 = null, | |
| 475 | minor_subsystem_version: ?u32 = null, | |
| 471 | 476 | clang_passthrough_mode: bool = false, |
| 472 | 477 | verbose_cc: bool = false, |
| 473 | 478 | verbose_link: bool = false, |
| ... | ... | @@ -1035,6 +1040,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 1035 | 1040 | .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, |
| 1036 | 1041 | .z_nodelete = options.linker_z_nodelete, |
| 1037 | 1042 | .z_defs = options.linker_z_defs, |
| 1043 | .tsaware = options.linker_tsaware, | |
| 1044 | .nxcompat = options.linker_nxcompat, | |
| 1045 | .dynamicbase = options.linker_dynamicbase, | |
| 1046 | .major_subsystem_version = options.major_subsystem_version, | |
| 1047 | .minor_subsystem_version = options.minor_subsystem_version, | |
| 1038 | 1048 | .stack_size_override = options.stack_size_override, |
| 1039 | 1049 | .image_base_override = options.image_base_override, |
| 1040 | 1050 | .include_compiler_rt = include_compiler_rt, |
src/link.zig+5| ... | ... | @@ -69,6 +69,9 @@ pub const Options = struct { |
| 69 | 69 | rdynamic: bool, |
| 70 | 70 | z_nodelete: bool, |
| 71 | 71 | z_defs: bool, |
| 72 | tsaware: bool, | |
| 73 | nxcompat: bool, | |
| 74 | dynamicbase: bool, | |
| 72 | 75 | bind_global_refs_locally: bool, |
| 73 | 76 | is_native_os: bool, |
| 74 | 77 | is_native_abi: bool, |
| ... | ... | @@ -88,6 +91,8 @@ pub const Options = struct { |
| 88 | 91 | each_lib_rpath: bool, |
| 89 | 92 | disable_lld_caching: bool, |
| 90 | 93 | is_test: bool, |
| 94 | major_subsystem_version: ?u32, | |
| 95 | minor_subsystem_version: ?u32, | |
| 91 | 96 | gc_sections: ?bool = null, |
| 92 | 97 | allow_shlib_undefined: ?bool, |
| 93 | 98 | subsystem: ?std.Target.SubSystem, |
src/link/Coff.zig+49-8| ... | ... | @@ -877,6 +877,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 877 | 877 | man.hash.addStringSet(self.base.options.system_libs); |
| 878 | 878 | man.hash.addOptional(self.base.options.subsystem); |
| 879 | 879 | man.hash.add(self.base.options.is_test); |
| 880 | man.hash.add(self.base.options.tsaware); | |
| 881 | man.hash.add(self.base.options.nxcompat); | |
| 882 | man.hash.add(self.base.options.dynamicbase); | |
| 883 | man.hash.addOptional(self.base.options.major_subsystem_version); | |
| 884 | man.hash.addOptional(self.base.options.minor_subsystem_version); | |
| 880 | 885 | |
| 881 | 886 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 882 | 887 | _ = try man.hit(); |
| ... | ... | @@ -976,6 +981,26 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 976 | 981 | try argv.append("-DLL"); |
| 977 | 982 | } |
| 978 | 983 | |
| 984 | if (self.base.options.tsaware) { | |
| 985 | try argv.append("-tsaware"); | |
| 986 | } | |
| 987 | if (self.base.options.nxcompat) { | |
| 988 | try argv.append("-nxcompat"); | |
| 989 | } | |
| 990 | if (self.base.options.dynamicbase) { | |
| 991 | try argv.append("-dynamicbase"); | |
| 992 | } | |
| 993 | const subsystem_suffix = ss: { | |
| 994 | if (self.base.options.major_subsystem_version) |major| { | |
| 995 | if (self.base.options.minor_subsystem_version) |minor| { | |
| 996 | break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor }); | |
| 997 | } else { | |
| 998 | break :ss try allocPrint(arena, ",{d}", .{major}); | |
| 999 | } | |
| 1000 | } | |
| 1001 | break :ss ""; | |
| 1002 | }; | |
| 1003 | ||
| 979 | 1004 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 980 | 1005 | |
| 981 | 1006 | if (self.base.options.link_libc) { |
| ... | ... | @@ -1029,35 +1054,51 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1029 | 1054 | const mode: Mode = mode: { |
| 1030 | 1055 | if (resolved_subsystem) |subsystem| switch (subsystem) { |
| 1031 | 1056 | .Console => { |
| 1032 | try argv.append("-SUBSYSTEM:console"); | |
| 1057 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{ | |
| 1058 | subsystem_suffix, | |
| 1059 | })); | |
| 1033 | 1060 | break :mode .win32; |
| 1034 | 1061 | }, |
| 1035 | 1062 | .EfiApplication => { |
| 1036 | try argv.append("-SUBSYSTEM:efi_application"); | |
| 1063 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{ | |
| 1064 | subsystem_suffix, | |
| 1065 | })); | |
| 1037 | 1066 | break :mode .uefi; |
| 1038 | 1067 | }, |
| 1039 | 1068 | .EfiBootServiceDriver => { |
| 1040 | try argv.append("-SUBSYSTEM:efi_boot_service_driver"); | |
| 1069 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{ | |
| 1070 | subsystem_suffix, | |
| 1071 | })); | |
| 1041 | 1072 | break :mode .uefi; |
| 1042 | 1073 | }, |
| 1043 | 1074 | .EfiRom => { |
| 1044 | try argv.append("-SUBSYSTEM:efi_rom"); | |
| 1075 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{ | |
| 1076 | subsystem_suffix, | |
| 1077 | })); | |
| 1045 | 1078 | break :mode .uefi; |
| 1046 | 1079 | }, |
| 1047 | 1080 | .EfiRuntimeDriver => { |
| 1048 | try argv.append("-SUBSYSTEM:efi_runtime_driver"); | |
| 1081 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{ | |
| 1082 | subsystem_suffix, | |
| 1083 | })); | |
| 1049 | 1084 | break :mode .uefi; |
| 1050 | 1085 | }, |
| 1051 | 1086 | .Native => { |
| 1052 | try argv.append("-SUBSYSTEM:native"); | |
| 1087 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{ | |
| 1088 | subsystem_suffix, | |
| 1089 | })); | |
| 1053 | 1090 | break :mode .win32; |
| 1054 | 1091 | }, |
| 1055 | 1092 | .Posix => { |
| 1056 | try argv.append("-SUBSYSTEM:posix"); | |
| 1093 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{ | |
| 1094 | subsystem_suffix, | |
| 1095 | })); | |
| 1057 | 1096 | break :mode .win32; |
| 1058 | 1097 | }, |
| 1059 | 1098 | .Windows => { |
| 1060 | try argv.append("-SUBSYSTEM:windows"); | |
| 1099 | try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{ | |
| 1100 | subsystem_suffix, | |
| 1101 | })); | |
| 1061 | 1102 | break :mode .win32; |
| 1062 | 1103 | }, |
| 1063 | 1104 | } else if (target.os.tag == .uefi) { |
src/main.zig+56| ... | ... | @@ -529,6 +529,9 @@ fn buildOutputType( |
| 529 | 529 | var linker_bind_global_refs_locally: ?bool = null; |
| 530 | 530 | var linker_z_nodelete = false; |
| 531 | 531 | var linker_z_defs = false; |
| 532 | var linker_tsaware = false; | |
| 533 | var linker_nxcompat = false; | |
| 534 | var linker_dynamicbase = false; | |
| 532 | 535 | var test_evented_io = false; |
| 533 | 536 | var stack_size_override: ?u64 = null; |
| 534 | 537 | var image_base_override: ?u64 = null; |
| ... | ... | @@ -549,6 +552,8 @@ fn buildOutputType( |
| 549 | 552 | var main_pkg_path: ?[]const u8 = null; |
| 550 | 553 | var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no; |
| 551 | 554 | var subsystem: ?std.Target.SubSystem = null; |
| 555 | var major_subsystem_version: ?u32 = null; | |
| 556 | var minor_subsystem_version: ?u32 = null; | |
| 552 | 557 | |
| 553 | 558 | var system_libs = std.ArrayList([]const u8).init(gpa); |
| 554 | 559 | defer system_libs.deinit(); |
| ... | ... | @@ -1307,10 +1312,56 @@ fn buildOutputType( |
| 1307 | 1312 | image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { |
| 1308 | 1313 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); |
| 1309 | 1314 | }; |
| 1315 | } else if (mem.eql(u8, arg, "-T")) { | |
| 1316 | i += 1; | |
| 1317 | if (i >= linker_args.items.len) { | |
| 1318 | fatal("expected linker arg after '{s}'", .{arg}); | |
| 1319 | } | |
| 1320 | linker_script = linker_args.items[i]; | |
| 1310 | 1321 | } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { |
| 1311 | 1322 | link_eh_frame_hdr = true; |
| 1312 | 1323 | } else if (mem.eql(u8, arg, "--no-eh-frame-hdr")) { |
| 1313 | 1324 | link_eh_frame_hdr = false; |
| 1325 | } else if (mem.eql(u8, arg, "--tsaware")) { | |
| 1326 | linker_tsaware = true; | |
| 1327 | } else if (mem.eql(u8, arg, "--nxcompat")) { | |
| 1328 | linker_nxcompat = true; | |
| 1329 | } else if (mem.eql(u8, arg, "--dynamicbase")) { | |
| 1330 | linker_dynamicbase = true; | |
| 1331 | } else if (mem.eql(u8, arg, "--high-entropy-va")) { | |
| 1332 | // This option does not do anything. | |
| 1333 | } else if (mem.eql(u8, arg, "--export-all-symbols")) { | |
| 1334 | rdynamic = true; | |
| 1335 | } else if (mem.eql(u8, arg, "--start-group") or | |
| 1336 | mem.eql(u8, arg, "--end-group")) | |
| 1337 | { | |
| 1338 | // We don't need to care about these because these args are | |
| 1339 | // for resolving circular dependencies but our linker takes | |
| 1340 | // care of this without explicit args. | |
| 1341 | } else if (mem.startsWith(u8, arg, "--major-os-version") or | |
| 1342 | mem.startsWith(u8, arg, "--minor-os-version")) | |
| 1343 | { | |
| 1344 | // This option does not do anything. | |
| 1345 | } else if (mem.startsWith(u8, arg, "--major-subsystem-version=")) { | |
| 1346 | major_subsystem_version = std.fmt.parseUnsigned( | |
| 1347 | u32, | |
| 1348 | arg["--major-subsystem-version=".len..], | |
| 1349 | 10, | |
| 1350 | ) catch |err| { | |
| 1351 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1352 | }; | |
| 1353 | } else if (mem.startsWith(u8, arg, "--minor-subsystem-version=")) { | |
| 1354 | minor_subsystem_version = std.fmt.parseUnsigned( | |
| 1355 | u32, | |
| 1356 | arg["--minor-subsystem-version=".len..], | |
| 1357 | 10, | |
| 1358 | ) catch |err| { | |
| 1359 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1360 | }; | |
| 1361 | } else if (mem.startsWith(u8, arg, "--major-os-version=") or | |
| 1362 | mem.startsWith(u8, arg, "--minor-os-version=")) | |
| 1363 | { | |
| 1364 | // These args do nothing. | |
| 1314 | 1365 | } else { |
| 1315 | 1366 | warn("unsupported linker arg: {s}", .{arg}); |
| 1316 | 1367 | } |
| ... | ... | @@ -1800,6 +1851,11 @@ fn buildOutputType( |
| 1800 | 1851 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, |
| 1801 | 1852 | .linker_z_nodelete = linker_z_nodelete, |
| 1802 | 1853 | .linker_z_defs = linker_z_defs, |
| 1854 | .linker_tsaware = linker_tsaware, | |
| 1855 | .linker_nxcompat = linker_nxcompat, | |
| 1856 | .linker_dynamicbase = linker_dynamicbase, | |
| 1857 | .major_subsystem_version = major_subsystem_version, | |
| 1858 | .minor_subsystem_version = minor_subsystem_version, | |
| 1803 | 1859 | .link_eh_frame_hdr = link_eh_frame_hdr, |
| 1804 | 1860 | .link_emit_relocs = link_emit_relocs, |
| 1805 | 1861 | .stack_size_override = stack_size_override, |