From 8932c2d7456fc86b9e92c7976cedcce798caef1a Mon Sep 17 00:00:00 2001 From: Lee Cannon Date: Sun, 20 Dec 2020 21:41:00 +0000 Subject: [PATCH] Added support for no red zone --- lib/std/build.zig | 4 ++++ src/Compilation.zig | 12 +++++++++++- src/glibc.zig | 1 + src/libcxx.zig | 2 ++ src/libunwind.zig | 1 + src/link.zig | 1 + src/main.zig | 8 ++++++++ src/musl.zig | 1 + src/stage1.zig | 1 + src/stage1/all_types.hpp | 1 + src/stage1/codegen.cpp | 4 ++++ src/stage1/stage1.cpp | 1 + src/stage1/stage1.h | 1 + 13 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/std/build.zig b/lib/std/build.zig index 5fd64cad0b..869671c785 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1262,6 +1262,7 @@ pub const LibExeObjStep = struct { disable_stack_probing: bool, disable_sanitize_c: bool, sanitize_thread: bool, + no_red_zone: bool = false, rdynamic: bool, c_std: Builder.CStd, override_lib_dir: ?[]const u8, @@ -2260,6 +2261,9 @@ pub const LibExeObjStep = struct { if (self.disable_stack_probing) { try zig_args.append("-fno-stack-check"); } + if (self.no_red_zone) { + try zig_args.append("-fno-red-zone"); + } if (self.disable_sanitize_c) { try zig_args.append("-fno-sanitize-c"); } diff --git a/src/Compilation.zig b/src/Compilation.zig index b017dde8c8..1588544010 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -392,6 +392,7 @@ pub const InitOptions = struct { want_pie: ?bool = null, want_sanitize_c: ?bool = null, want_stack_check: ?bool = null, + no_red_zone: bool = false, want_valgrind: ?bool = null, want_tsan: ?bool = null, want_compiler_rt: ?bool = null, @@ -773,6 +774,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { cache.hash.add(pie); cache.hash.add(tsan); cache.hash.add(stack_check); + cache.hash.add(options.no_red_zone); cache.hash.add(link_mode); cache.hash.add(options.function_sections); cache.hash.add(strip); @@ -982,6 +984,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .valgrind = valgrind, .tsan = tsan, .stack_check = stack_check, + .no_red_zone = options.no_red_zone, .single_threaded = single_threaded, .verbose_link = options.verbose_link, .machine_code_model = options.machine_code_model, @@ -2255,7 +2258,11 @@ pub fn addCCArgs( } else if (!comp.sanitize_c and comp.bin_file.options.tsan) { try argv.append("-fsanitize=thread"); } - + + if (comp.bin_file.options.no_red_zone) { + try argv.append("-mno-red-zone"); + } + switch (comp.bin_file.options.optimize_mode) { .Debug => { // windows c runtime requires -D_DEBUG if using debug libraries @@ -2960,6 +2967,7 @@ fn buildOutputFromZig( .function_sections = true, .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, @@ -3198,6 +3206,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node .tsan_enabled = comp.bin_file.options.tsan, .function_sections = comp.bin_file.options.function_sections, .enable_stack_probing = comp.bin_file.options.stack_check, + .no_red_zone = comp.bin_file.options.no_red_zone, .enable_time_report = comp.time_report, .enable_stack_report = comp.stack_report, .test_is_evented = comp.test_evented_io, @@ -3342,6 +3351,7 @@ pub fn build_crt_file( .optimize_mode = comp.compilerRtOptMode(), .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, diff --git a/src/glibc.zig b/src/glibc.zig index e7b7b1b1cf..28ed31f7bb 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -934,6 +934,7 @@ fn buildSharedLib( .optimize_mode = comp.compilerRtOptMode(), .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = false, .emit_h = null, diff --git a/src/libcxx.zig b/src/libcxx.zig index e79a0106e9..dc9fdc15e7 100644 --- a/src/libcxx.zig +++ b/src/libcxx.zig @@ -167,6 +167,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { .link_mode = link_mode, .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = comp.bin_file.options.tsan, .want_pic = comp.bin_file.options.pic, @@ -284,6 +285,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { .link_mode = link_mode, .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = comp.bin_file.options.tsan, .want_pic = comp.bin_file.options.pic, diff --git a/src/libunwind.zig b/src/libunwind.zig index 7710b1aa77..cfc0cb00aa 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -108,6 +108,7 @@ pub fn buildStaticLib(comp: *Compilation) !void { .link_mode = link_mode, .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, diff --git a/src/link.zig b/src/link.zig index ffb69adee9..04cfce99ab 100644 --- a/src/link.zig +++ b/src/link.zig @@ -77,6 +77,7 @@ pub const Options = struct { valgrind: bool, tsan: bool, stack_check: bool, + no_red_zone: bool, single_threaded: bool, verbose_link: bool, dll_export_fns: bool, diff --git a/src/main.zig b/src/main.zig index b50f89e5c2..a7a23c2b2d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -282,6 +282,8 @@ const usage_build_generic = \\ -fno-PIE Force-disable Position Independent Executable \\ -fstack-check Enable stack probing in unsafe builds \\ -fno-stack-check Disable stack probing in safe builds + \\ -fred-zone Enable the "red-zone" + \\ -fno-red-zone Disable the "red-zone" \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds \\ -fvalgrind Include valgrind client requests in release builds @@ -505,6 +507,7 @@ fn buildOutputType( var want_pie: ?bool = null; var want_sanitize_c: ?bool = null; var want_stack_check: ?bool = null; + var no_red_zone: bool = false; var want_valgrind: ?bool = null; var want_tsan: ?bool = null; var want_compiler_rt: ?bool = null; @@ -843,6 +846,10 @@ fn buildOutputType( want_stack_check = true; } else if (mem.eql(u8, arg, "-fno-stack-check")) { want_stack_check = false; + } else if (mem.eql(u8, arg, "-fred-zone")) { + no_red_zone = false; + } else if (mem.eql(u8, arg, "-fno-red-zone")) { + no_red_zone = true; } else if (mem.eql(u8, arg, "-fsanitize-c")) { want_sanitize_c = true; } else if (mem.eql(u8, arg, "-fno-sanitize-c")) { @@ -1760,6 +1767,7 @@ fn buildOutputType( .want_pie = want_pie, .want_sanitize_c = want_sanitize_c, .want_stack_check = want_stack_check, + .no_red_zone = no_red_zone, .want_valgrind = want_valgrind, .want_tsan = want_tsan, .want_compiler_rt = want_compiler_rt, diff --git a/src/musl.zig b/src/musl.zig index a865e78623..d9060307d0 100644 --- a/src/musl.zig +++ b/src/musl.zig @@ -206,6 +206,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { .optimize_mode = comp.compilerRtOptMode(), .want_sanitize_c = false, .want_stack_check = false, + .no_red_zone = comp.bin_file.options.no_red_zone, .want_valgrind = false, .want_tsan = false, .emit_h = null, diff --git a/src/stage1.zig b/src/stage1.zig index cf3a252ce8..721ab93fcd 100644 --- a/src/stage1.zig +++ b/src/stage1.zig @@ -119,6 +119,7 @@ pub const Module = extern struct { tsan_enabled: bool, function_sections: bool, enable_stack_probing: bool, + no_red_zone: bool, enable_time_report: bool, enable_stack_report: bool, test_is_evented: bool, diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index 24b54ad794..af8305d4b0 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -2195,6 +2195,7 @@ struct CodeGen { bool link_mode_dynamic; bool dll_export_fns; bool have_stack_probing; + bool no_red_zone; bool function_sections; bool test_is_evented; bool valgrind_enabled; diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 386bc43086..fbc13f2638 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -513,6 +513,10 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } else { maybe_import_dll(g, llvm_fn, linkage); } + + if (g->no_red_zone) { + addLLVMFnAttr(llvm_fn, "noredzone"); + } if (fn->alignstack_value != 0) { addLLVMFnAttrInt(llvm_fn, "alignstack", fn->alignstack_value); diff --git a/src/stage1/stage1.cpp b/src/stage1/stage1.cpp index 1195a83931..7cf34c9a47 100644 --- a/src/stage1/stage1.cpp +++ b/src/stage1/stage1.cpp @@ -91,6 +91,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { g->have_pic = stage1->pic; g->have_pie = stage1->pie; g->have_stack_probing = stage1->enable_stack_probing; + g->no_red_zone = stage1->no_red_zone; g->is_single_threaded = stage1->is_single_threaded; g->valgrind_enabled = stage1->valgrind_enabled; g->tsan_enabled = stage1->tsan_enabled; diff --git a/src/stage1/stage1.h b/src/stage1/stage1.h index dbf6491699..66e0effbf6 100644 --- a/src/stage1/stage1.h +++ b/src/stage1/stage1.h @@ -188,6 +188,7 @@ struct ZigStage1 { bool tsan_enabled; bool function_sections; bool enable_stack_probing; + bool no_red_zone; bool enable_time_report; bool enable_stack_report; bool test_is_evented;