authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 22:07:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 22:07:47-07:00
log0edde40c25c033aec67f235365593ee26ff52740
treedfdd8caf259e2d03ba89d4c0211d9cafb45c6064
parent56c03881ebd8617e6506bfad01bf9cfdd4d3df7e
parent5b2a79848ced20db80f3f4ce46b3ef7f4a051d53

Merge 'Add support for no red zone'

Merges #7511

16 files changed, 118 insertions(+), 30 deletions(-)

lib/std/build.zig+9
......@@ -1332,6 +1332,8 @@ pub const LibExeObjStep = struct {
13321332 /// Position Independent Executable
13331333 pie: ?bool = null,
13341334
1335 red_zone: ?bool = null,
1336
13351337 subsystem: ?builtin.SubSystem = null,
13361338
13371339 /// Overrides the default stack size
......@@ -2260,6 +2262,13 @@ pub const LibExeObjStep = struct {
22602262 if (self.disable_stack_probing) {
22612263 try zig_args.append("-fno-stack-check");
22622264 }
2265 if (self.red_zone) |red_zone| {
2266 if (red_zone) {
2267 try zig_args.append("-mred-zone");
2268 } else {
2269 try zig_args.append("-mno-red-zone");
2270 }
2271 }
22632272 if (self.disable_sanitize_c) {
22642273 try zig_args.append("-fno-sanitize-c");
22652274 }
src/Compilation.zig+13
......@@ -392,6 +392,7 @@ pub const InitOptions = struct {
392392 want_pie: ?bool = null,
393393 want_sanitize_c: ?bool = null,
394394 want_stack_check: ?bool = null,
395 want_red_zone: ?bool = null,
395396 want_valgrind: ?bool = null,
396397 want_tsan: ?bool = null,
397398 want_compiler_rt: ?bool = null,
......@@ -743,6 +744,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
743744 } else null;
744745
745746 const strip = options.strip or !target_util.hasDebugInfo(options.target);
747 const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target);
746748
747749 // We put everything into the cache hash that *cannot be modified during an incremental update*.
748750 // For example, one cannot change the target between updates, but one can change source files,
......@@ -773,6 +775,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
773775 cache.hash.add(pie);
774776 cache.hash.add(tsan);
775777 cache.hash.add(stack_check);
778 cache.hash.add(red_zone);
776779 cache.hash.add(link_mode);
777780 cache.hash.add(options.function_sections);
778781 cache.hash.add(strip);
......@@ -982,6 +985,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
982985 .valgrind = valgrind,
983986 .tsan = tsan,
984987 .stack_check = stack_check,
988 .red_zone = red_zone,
985989 .single_threaded = single_threaded,
986990 .verbose_link = options.verbose_link,
987991 .machine_code_model = options.machine_code_model,
......@@ -2256,6 +2260,12 @@ pub fn addCCArgs(
22562260 try argv.append("-fsanitize=thread");
22572261 }
22582262
2263 if (comp.bin_file.options.red_zone) {
2264 try argv.append("-mred-zone");
2265 } else if (target_util.hasRedZone(target)) {
2266 try argv.append("-mno-red-zone");
2267 }
2268
22592269 switch (comp.bin_file.options.optimize_mode) {
22602270 .Debug => {
22612271 // windows c runtime requires -D_DEBUG if using debug libraries
......@@ -2960,6 +2970,7 @@ fn buildOutputFromZig(
29602970 .function_sections = true,
29612971 .want_sanitize_c = false,
29622972 .want_stack_check = false,
2973 .want_red_zone = comp.bin_file.options.red_zone,
29632974 .want_valgrind = false,
29642975 .want_tsan = false,
29652976 .want_pic = comp.bin_file.options.pic,
......@@ -3198,6 +3209,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
31983209 .tsan_enabled = comp.bin_file.options.tsan,
31993210 .function_sections = comp.bin_file.options.function_sections,
32003211 .enable_stack_probing = comp.bin_file.options.stack_check,
3212 .red_zone = comp.bin_file.options.red_zone,
32013213 .enable_time_report = comp.time_report,
32023214 .enable_stack_report = comp.stack_report,
32033215 .test_is_evented = comp.test_evented_io,
......@@ -3342,6 +3354,7 @@ pub fn build_crt_file(
33423354 .optimize_mode = comp.compilerRtOptMode(),
33433355 .want_sanitize_c = false,
33443356 .want_stack_check = false,
3357 .want_red_zone = comp.bin_file.options.red_zone,
33453358 .want_valgrind = false,
33463359 .want_tsan = false,
33473360 .want_pic = comp.bin_file.options.pic,
src/clang_options_data.zig+16-2
......@@ -3803,7 +3803,14 @@ flagpd1("mno-qpx"),
38033803flagpd1("mno-rdpid"),
38043804flagpd1("mno-rdrnd"),
38053805flagpd1("mno-rdseed"),
3806flagpd1("mno-red-zone"),
3806.{
3807 .name = "mno-red-zone",
3808 .syntax = .flag,
3809 .zig_equivalent = .no_red_zone,
3810 .pd1 = true,
3811 .pd2 = false,
3812 .psl = false,
3813},
38073814flagpd1("mno-reference-types"),
38083815flagpd1("mno-relax"),
38093816flagpd1("mno-relax-all"),
......@@ -3901,7 +3908,14 @@ flagpd1("mrdseed"),
39013908flagpd1("mreassociate"),
39023909flagpd1("mrecip"),
39033910flagpd1("mrecord-mcount"),
3904flagpd1("mred-zone"),
3911.{
3912 .name = "mred-zone",
3913 .syntax = .flag,
3914 .zig_equivalent = .red_zone,
3915 .pd1 = true,
3916 .pd2 = false,
3917 .psl = false,
3918},
39053919flagpd1("mreference-types"),
39063920sepd1("mregparm"),
39073921flagpd1("mrelax"),
src/glibc.zig+1
......@@ -934,6 +934,7 @@ fn buildSharedLib(
934934 .optimize_mode = comp.compilerRtOptMode(),
935935 .want_sanitize_c = false,
936936 .want_stack_check = false,
937 .want_red_zone = comp.bin_file.options.red_zone,
937938 .want_valgrind = false,
938939 .want_tsan = false,
939940 .emit_h = null,
src/libcxx.zig+2
......@@ -167,6 +167,7 @@ pub fn buildLibCXX(comp: *Compilation) !void {
167167 .link_mode = link_mode,
168168 .want_sanitize_c = false,
169169 .want_stack_check = false,
170 .want_red_zone = comp.bin_file.options.red_zone,
170171 .want_valgrind = false,
171172 .want_tsan = comp.bin_file.options.tsan,
172173 .want_pic = comp.bin_file.options.pic,
......@@ -284,6 +285,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
284285 .link_mode = link_mode,
285286 .want_sanitize_c = false,
286287 .want_stack_check = false,
288 .want_red_zone = comp.bin_file.options.red_zone,
287289 .want_valgrind = false,
288290 .want_tsan = comp.bin_file.options.tsan,
289291 .want_pic = comp.bin_file.options.pic,
src/libunwind.zig+1
......@@ -108,6 +108,7 @@ pub fn buildStaticLib(comp: *Compilation) !void {
108108 .link_mode = link_mode,
109109 .want_sanitize_c = false,
110110 .want_stack_check = false,
111 .want_red_zone = comp.bin_file.options.red_zone,
111112 .want_valgrind = false,
112113 .want_tsan = false,
113114 .want_pic = comp.bin_file.options.pic,
src/link.zig+1
......@@ -77,6 +77,7 @@ pub const Options = struct {
7777 valgrind: bool,
7878 tsan: bool,
7979 stack_check: bool,
80 red_zone: bool,
8081 single_threaded: bool,
8182 verbose_link: bool,
8283 dll_export_fns: bool,
src/main.zig+12
......@@ -267,6 +267,8 @@ const usage_build_generic =
267267 \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses
268268 \\ small|kernel|
269269 \\ medium|large]
270 \\ -mred-zone Force-enable the "red-zone"
271 \\ -mno-red-zone Force-disable the "red-zone"
270272 \\ --name [name] Override root name (not a file path)
271273 \\ -O [mode] Choose what to optimize for
272274 \\ Debug (default) Optimizations off, safety on
......@@ -505,6 +507,7 @@ fn buildOutputType(
505507 var want_pie: ?bool = null;
506508 var want_sanitize_c: ?bool = null;
507509 var want_stack_check: ?bool = null;
510 var want_red_zone: ?bool = null;
508511 var want_valgrind: ?bool = null;
509512 var want_tsan: ?bool = null;
510513 var want_compiler_rt: ?bool = null;
......@@ -843,6 +846,10 @@ fn buildOutputType(
843846 want_stack_check = true;
844847 } else if (mem.eql(u8, arg, "-fno-stack-check")) {
845848 want_stack_check = false;
849 } else if (mem.eql(u8, arg, "-mred-zone")) {
850 want_red_zone = true;
851 } else if (mem.eql(u8, arg, "-mno-red-zone")) {
852 want_red_zone = false;
846853 } else if (mem.eql(u8, arg, "-fsanitize-c")) {
847854 want_sanitize_c = true;
848855 } else if (mem.eql(u8, arg, "-fno-sanitize-c")) {
......@@ -1068,6 +1075,8 @@ fn buildOutputType(
10681075 .no_pic => want_pic = false,
10691076 .pie => want_pie = true,
10701077 .no_pie => want_pie = false,
1078 .red_zone => want_red_zone = true,
1079 .no_red_zone => want_red_zone = false,
10711080 .nostdlib => ensure_libc_on_non_freestanding = false,
10721081 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
10731082 .shared => {
......@@ -1760,6 +1769,7 @@ fn buildOutputType(
17601769 .want_pie = want_pie,
17611770 .want_sanitize_c = want_sanitize_c,
17621771 .want_stack_check = want_stack_check,
1772 .want_red_zone = want_red_zone,
17631773 .want_valgrind = want_valgrind,
17641774 .want_tsan = want_tsan,
17651775 .want_compiler_rt = want_compiler_rt,
......@@ -2969,6 +2979,8 @@ pub const ClangArgIterator = struct {
29692979 framework_dir,
29702980 framework,
29712981 nostdlibinc,
2982 red_zone,
2983 no_red_zone,
29722984 };
29732985
29742986 const Args = struct {
src/musl.zig+1
......@@ -206,6 +206,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
206206 .optimize_mode = comp.compilerRtOptMode(),
207207 .want_sanitize_c = false,
208208 .want_stack_check = false,
209 .want_red_zone = comp.bin_file.options.red_zone,
209210 .want_valgrind = false,
210211 .want_tsan = false,
211212 .emit_h = null,
src/stage1.zig+1
......@@ -119,6 +119,7 @@ pub const Module = extern struct {
119119 tsan_enabled: bool,
120120 function_sections: bool,
121121 enable_stack_probing: bool,
122 red_zone: bool,
122123 enable_time_report: bool,
123124 enable_stack_report: bool,
124125 test_is_evented: bool,
src/stage1/all_types.hpp+1
......@@ -2195,6 +2195,7 @@ struct CodeGen {
21952195 bool link_mode_dynamic;
21962196 bool dll_export_fns;
21972197 bool have_stack_probing;
2198 bool red_zone;
21982199 bool function_sections;
21992200 bool test_is_evented;
22002201 bool valgrind_enabled;
src/stage1/codegen.cpp+4
......@@ -514,6 +514,10 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
514514 maybe_import_dll(g, llvm_fn, linkage);
515515 }
516516
517 if (!g->red_zone) {
518 addLLVMFnAttr(llvm_fn, "noredzone");
519 }
520
517521 if (fn->alignstack_value != 0) {
518522 addLLVMFnAttrInt(llvm_fn, "alignstack", fn->alignstack_value);
519523 }
src/stage1/stage1.cpp+1
......@@ -91,6 +91,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) {
9191 g->have_pic = stage1->pic;
9292 g->have_pie = stage1->pie;
9393 g->have_stack_probing = stage1->enable_stack_probing;
94 g->red_zone = stage1->red_zone;
9495 g->is_single_threaded = stage1->is_single_threaded;
9596 g->valgrind_enabled = stage1->valgrind_enabled;
9697 g->tsan_enabled = stage1->tsan_enabled;
src/stage1/stage1.h+1
......@@ -188,6 +188,7 @@ struct ZigStage1 {
188188 bool tsan_enabled;
189189 bool function_sections;
190190 bool enable_stack_probing;
191 bool red_zone;
191192 bool enable_time_report;
192193 bool enable_stack_report;
193194 bool test_is_evented;
src/target.zig+18
......@@ -349,3 +349,21 @@ pub fn defaultCompilerRtOptimizeMode(target: std.Target) std.builtin.Mode {
349349 return .ReleaseFast;
350350 }
351351}
352
353pub fn hasRedZone(target: std.Target) bool {
354 return switch (target.cpu.arch) {
355 .x86_64,
356 .i386,
357 .wasm32,
358 .wasm64,
359 .powerpc,
360 .powerpc64,
361 .powerpc64le,
362 .aarch64,
363 .aarch64_be,
364 .aarch64_32,
365 => true,
366
367 else => false,
368 };
369}
tools/update_clang_options.zig+36-28
......@@ -248,6 +248,14 @@ const known_options = [_]KnownOpt{
248248 .name = "mtune",
249249 .ident = "mcpu",
250250 },
251 .{
252 .name = "mred-zone",
253 .ident = "red_zone",
254 },
255 .{
256 .name = "mno-red-zone",
257 .ident = "no_red_zone",
258 },
251259 .{
252260 .name = "MD",
253261 .ident = "dep_file",
......@@ -340,9 +348,9 @@ pub fn main() anyerror!void {
340348 const child_args = [_][]const u8{
341349 llvm_tblgen_exe,
342350 "--dump-json",
343 try std.fmt.allocPrint(allocator, "{}/clang/include/clang/Driver/Options.td", .{llvm_src_root}),
344 try std.fmt.allocPrint(allocator, "-I={}/llvm/include", .{llvm_src_root}),
345 try std.fmt.allocPrint(allocator, "-I={}/clang/include/clang/Driver", .{llvm_src_root}),
351 try std.fmt.allocPrint(allocator, "{s}/clang/include/clang/Driver/Options.td", .{llvm_src_root}),
352 try std.fmt.allocPrint(allocator, "-I={s}/llvm/include", .{llvm_src_root}),
353 try std.fmt.allocPrint(allocator, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}),
346354 };
347355
348356 const child_result = try std.ChildProcess.exec(.{
......@@ -351,11 +359,11 @@ pub fn main() anyerror!void {
351359 .max_output_bytes = 100 * 1024 * 1024,
352360 });
353361
354 std.debug.warn("{}\n", .{child_result.stderr});
362 std.debug.warn("{s}\n", .{child_result.stderr});
355363
356364 const json_text = switch (child_result.term) {
357365 .Exited => |code| if (code == 0) child_result.stdout else {
358 std.debug.warn("llvm-tblgen exited with code {}\n", .{code});
366 std.debug.warn("llvm-tblgen exited with code {d}\n", .{code});
359367 std.process.exit(1);
360368 },
361369 else => {
......@@ -412,7 +420,7 @@ pub fn main() anyerror!void {
412420 } else if (std.mem.eql(u8, prefix, "/")) {
413421 pslash = true;
414422 } else {
415 std.debug.warn("{} has unrecognized prefix '{}'\n", .{ name, prefix });
423 std.debug.warn("{s} has unrecognized prefix '{s}'\n", .{ name, prefix });
416424 std.process.exit(1);
417425 }
418426 }
......@@ -422,7 +430,7 @@ pub fn main() anyerror!void {
422430 // `-MT foo` is ambiguous because there is also an -MT flag
423431 // The canonical way to specify the flag is with `/MT` and so we make this
424432 // the only way.
425 try stdout.print("flagpsl(\"{}\"),\n", .{name});
433 try stdout.print("flagpsl(\"{s}\"),\n", .{name});
426434 } else if (knownOption(name)) |ident| {
427435
428436 // Workaround the fact that in 'Options.td' -Ofast is listed as 'joined'
......@@ -430,34 +438,34 @@ pub fn main() anyerror!void {
430438
431439 try stdout.print(
432440 \\.{{
433 \\ .name = "{}",
434 \\ .syntax = {},
435 \\ .zig_equivalent = .{},
436 \\ .pd1 = {},
437 \\ .pd2 = {},
438 \\ .psl = {},
441 \\ .name = "{s}",
442 \\ .syntax = {s},
443 \\ .zig_equivalent = .{s},
444 \\ .pd1 = {s},
445 \\ .pd2 = {s},
446 \\ .psl = {s},
439447 \\}},
440448 \\
441449 , .{ name, final_syntax, ident, pd1, pd2, pslash });
442450 } else if (pd1 and !pd2 and !pslash and syntax == .flag) {
443 try stdout.print("flagpd1(\"{}\"),\n", .{name});
451 try stdout.print("flagpd1(\"{s}\"),\n", .{name});
444452 } else if (!pd1 and !pd2 and pslash and syntax == .flag) {
445 try stdout.print("flagpsl(\"{}\"),\n", .{name});
453 try stdout.print("flagpsl(\"{s}\"),\n", .{name});
446454 } else if (pd1 and !pd2 and !pslash and syntax == .joined) {
447 try stdout.print("joinpd1(\"{}\"),\n", .{name});
455 try stdout.print("joinpd1(\"{s}\"),\n", .{name});
448456 } else if (pd1 and !pd2 and !pslash and syntax == .joined_or_separate) {
449 try stdout.print("jspd1(\"{}\"),\n", .{name});
457 try stdout.print("jspd1(\"{s}\"),\n", .{name});
450458 } else if (pd1 and !pd2 and !pslash and syntax == .separate) {
451 try stdout.print("sepd1(\"{}\"),\n", .{name});
459 try stdout.print("sepd1(\"{s}\"),\n", .{name});
452460 } else {
453461 try stdout.print(
454462 \\.{{
455 \\ .name = "{}",
456 \\ .syntax = {},
463 \\ .name = "{s}",
464 \\ .syntax = {s},
457465 \\ .zig_equivalent = .other,
458 \\ .pd1 = {},
459 \\ .pd2 = {},
460 \\ .psl = {},
466 \\ .pd1 = {s},
467 \\ .pd2 = {s},
468 \\ .psl = {s},
461469 \\}},
462470 \\
463471 , .{ name, syntax, pd1, pd2, pslash });
......@@ -506,8 +514,8 @@ const Syntax = union(enum) {
506514 out_stream: anytype,
507515 ) !void {
508516 switch (self) {
509 .multi_arg => |n| return out_stream.print(".{{.{}={}}}", .{ @tagName(self), n }),
510 else => return out_stream.print(".{}", .{@tagName(self)}),
517 .multi_arg => |n| return out_stream.print(".{{.{s}={}}}", .{ @tagName(self), n }),
518 else => return out_stream.print(".{s}", .{@tagName(self)}),
511519 }
512520 }
513521};
......@@ -559,9 +567,9 @@ fn objSyntax(obj: *json.ObjectMap) Syntax {
559567 return .flag;
560568 }
561569 const key = obj.get("!name").?.String;
562 std.debug.warn("{} (key {}) has unrecognized superclasses:\n", .{ name, key });
570 std.debug.warn("{s} (key {s}) has unrecognized superclasses:\n", .{ name, key });
563571 for (obj.get("!superclasses").?.Array.items) |superclass_json| {
564 std.debug.warn(" {}\n", .{superclass_json.String});
572 std.debug.warn(" {s}\n", .{superclass_json.String});
565573 }
566574 std.process.exit(1);
567575}
......@@ -612,7 +620,7 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
612620
613621fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn {
614622 file.writer().print(
615 \\Usage: {} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
623 \\Usage: {s} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
616624 \\Alternative Usage: zig run /path/to/git/zig/tools/update_clang_options.zig -- /path/to/llvm-tblgen /path/to/git/llvm/llvm-project
617625 \\
618626 \\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig.