authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-24 14:30:05-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-24 14:30:28-07:00
log0cfa39304b18c6a04689bd789f5dc4d035ec43b0
tree9dc20b8bbf29909fc7f093618cccd42845aa4e41
parentb56e916fa1d3508a01a6fc0b62f3f64dd3843b85

zig cc: recognize more coff linker options

Related: #7874

4 files changed, 120 insertions(+), 8 deletions(-)

src/Compilation.zig+10
...@@ -468,6 +468,11 @@ pub const InitOptions = struct {...@@ -468,6 +468,11 @@ pub const InitOptions = struct {
468 disable_c_depfile: bool = false,468 disable_c_depfile: bool = false,
469 linker_z_nodelete: bool = false,469 linker_z_nodelete: bool = false,
470 linker_z_defs: bool = false,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 clang_passthrough_mode: bool = false,476 clang_passthrough_mode: bool = false,
472 verbose_cc: bool = false,477 verbose_cc: bool = false,
473 verbose_link: bool = false,478 verbose_link: bool = false,
...@@ -1035,6 +1040,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1035,6 +1040,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1035 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1040 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1036 .z_nodelete = options.linker_z_nodelete,1041 .z_nodelete = options.linker_z_nodelete,
1037 .z_defs = options.linker_z_defs,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 .stack_size_override = options.stack_size_override,1048 .stack_size_override = options.stack_size_override,
1039 .image_base_override = options.image_base_override,1049 .image_base_override = options.image_base_override,
1040 .include_compiler_rt = include_compiler_rt,1050 .include_compiler_rt = include_compiler_rt,
src/link.zig+5
...@@ -69,6 +69,9 @@ pub const Options = struct {...@@ -69,6 +69,9 @@ pub const Options = struct {
69 rdynamic: bool,69 rdynamic: bool,
70 z_nodelete: bool,70 z_nodelete: bool,
71 z_defs: bool,71 z_defs: bool,
72 tsaware: bool,
73 nxcompat: bool,
74 dynamicbase: bool,
72 bind_global_refs_locally: bool,75 bind_global_refs_locally: bool,
73 is_native_os: bool,76 is_native_os: bool,
74 is_native_abi: bool,77 is_native_abi: bool,
...@@ -88,6 +91,8 @@ pub const Options = struct {...@@ -88,6 +91,8 @@ pub const Options = struct {
88 each_lib_rpath: bool,91 each_lib_rpath: bool,
89 disable_lld_caching: bool,92 disable_lld_caching: bool,
90 is_test: bool,93 is_test: bool,
94 major_subsystem_version: ?u32,
95 minor_subsystem_version: ?u32,
91 gc_sections: ?bool = null,96 gc_sections: ?bool = null,
92 allow_shlib_undefined: ?bool,97 allow_shlib_undefined: ?bool,
93 subsystem: ?std.Target.SubSystem,98 subsystem: ?std.Target.SubSystem,
src/link/Coff.zig+49-8
...@@ -877,6 +877,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -877,6 +877,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
877 man.hash.addStringSet(self.base.options.system_libs);877 man.hash.addStringSet(self.base.options.system_libs);
878 man.hash.addOptional(self.base.options.subsystem);878 man.hash.addOptional(self.base.options.subsystem);
879 man.hash.add(self.base.options.is_test);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);
880885
881 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.886 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
882 _ = try man.hit();887 _ = try man.hit();
...@@ -976,6 +981,26 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -976,6 +981,26 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
976 try argv.append("-DLL");981 try argv.append("-DLL");
977 }982 }
978983
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 try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));1004 try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
9801005
981 if (self.base.options.link_libc) {1006 if (self.base.options.link_libc) {
...@@ -1029,35 +1054,51 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -1029,35 +1054,51 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
1029 const mode: Mode = mode: {1054 const mode: Mode = mode: {
1030 if (resolved_subsystem) |subsystem| switch (subsystem) {1055 if (resolved_subsystem) |subsystem| switch (subsystem) {
1031 .Console => {1056 .Console => {
1032 try argv.append("-SUBSYSTEM:console");1057 try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
1058 subsystem_suffix,
1059 }));
1033 break :mode .win32;1060 break :mode .win32;
1034 },1061 },
1035 .EfiApplication => {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 break :mode .uefi;1066 break :mode .uefi;
1038 },1067 },
1039 .EfiBootServiceDriver => {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 break :mode .uefi;1072 break :mode .uefi;
1042 },1073 },
1043 .EfiRom => {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 break :mode .uefi;1078 break :mode .uefi;
1046 },1079 },
1047 .EfiRuntimeDriver => {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 break :mode .uefi;1084 break :mode .uefi;
1050 },1085 },
1051 .Native => {1086 .Native => {
1052 try argv.append("-SUBSYSTEM:native");1087 try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
1088 subsystem_suffix,
1089 }));
1053 break :mode .win32;1090 break :mode .win32;
1054 },1091 },
1055 .Posix => {1092 .Posix => {
1056 try argv.append("-SUBSYSTEM:posix");1093 try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
1094 subsystem_suffix,
1095 }));
1057 break :mode .win32;1096 break :mode .win32;
1058 },1097 },
1059 .Windows => {1098 .Windows => {
1060 try argv.append("-SUBSYSTEM:windows");1099 try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
1100 subsystem_suffix,
1101 }));
1061 break :mode .win32;1102 break :mode .win32;
1062 },1103 },
1063 } else if (target.os.tag == .uefi) {1104 } else if (target.os.tag == .uefi) {
src/main.zig+56
...@@ -529,6 +529,9 @@ fn buildOutputType(...@@ -529,6 +529,9 @@ fn buildOutputType(
529 var linker_bind_global_refs_locally: ?bool = null;529 var linker_bind_global_refs_locally: ?bool = null;
530 var linker_z_nodelete = false;530 var linker_z_nodelete = false;
531 var linker_z_defs = false;531 var linker_z_defs = false;
532 var linker_tsaware = false;
533 var linker_nxcompat = false;
534 var linker_dynamicbase = false;
532 var test_evented_io = false;535 var test_evented_io = false;
533 var stack_size_override: ?u64 = null;536 var stack_size_override: ?u64 = null;
534 var image_base_override: ?u64 = null;537 var image_base_override: ?u64 = null;
...@@ -549,6 +552,8 @@ fn buildOutputType(...@@ -549,6 +552,8 @@ fn buildOutputType(
549 var main_pkg_path: ?[]const u8 = null;552 var main_pkg_path: ?[]const u8 = null;
550 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;553 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
551 var subsystem: ?std.Target.SubSystem = null;554 var subsystem: ?std.Target.SubSystem = null;
555 var major_subsystem_version: ?u32 = null;
556 var minor_subsystem_version: ?u32 = null;
552557
553 var system_libs = std.ArrayList([]const u8).init(gpa);558 var system_libs = std.ArrayList([]const u8).init(gpa);
554 defer system_libs.deinit();559 defer system_libs.deinit();
...@@ -1307,10 +1312,56 @@ fn buildOutputType(...@@ -1307,10 +1312,56 @@ fn buildOutputType(
1307 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {1312 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {
1308 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });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 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {1321 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
1311 link_eh_frame_hdr = true;1322 link_eh_frame_hdr = true;
1312 } else if (mem.eql(u8, arg, "--no-eh-frame-hdr")) {1323 } else if (mem.eql(u8, arg, "--no-eh-frame-hdr")) {
1313 link_eh_frame_hdr = false;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 } else {1365 } else {
1315 warn("unsupported linker arg: {s}", .{arg});1366 warn("unsupported linker arg: {s}", .{arg});
1316 }1367 }
...@@ -1800,6 +1851,11 @@ fn buildOutputType(...@@ -1800,6 +1851,11 @@ fn buildOutputType(
1800 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,1851 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
1801 .linker_z_nodelete = linker_z_nodelete,1852 .linker_z_nodelete = linker_z_nodelete,
1802 .linker_z_defs = linker_z_defs,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 .link_eh_frame_hdr = link_eh_frame_hdr,1859 .link_eh_frame_hdr = link_eh_frame_hdr,
1804 .link_emit_relocs = link_emit_relocs,1860 .link_emit_relocs = link_emit_relocs,
1805 .stack_size_override = stack_size_override,1861 .stack_size_override = stack_size_override,