authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-12 13:00:13-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:19-07:00
log43720be04af8ddb8334b210ff936a834fb8871a7
tree884a175200dc948e2a1bb40fb10472f356f2a9af
parent5a6a1f8a8ad1475d328c998824981c7b310987d2

frontend: fix stack protector option logic

Commit 97e23896a9168132b6d36ca22ae1af10dd53d80d regressed this behavior because it made target_util.supportsStackProtector *correctly* notice which zig backend is being used to generate code, while the logic calling that function *incorrectly assumed* that .zig code is being compiled, when in reality it might be only C code being compiled. This commit adjusts the option resolution logic for stack protector so that it takes into account the zig backend only if there is a zig compilation unit. A separate piece of logic checks whether clang supports stack protector for a given target. closes #18009 closes #18114 closes #18254

4 files changed, 25 insertions(+), 5 deletions(-)

src/Compilation/Config.zig+4-2
...@@ -31,6 +31,7 @@ shared_memory: bool,...@@ -31,6 +31,7 @@ shared_memory: bool,
31is_test: bool,31is_test: bool,
32test_evented_io: bool,32test_evented_io: bool,
33entry: ?[]const u8,33entry: ?[]const u8,
34any_c_source_files: bool,
3435
35pub const CFrontend = enum { clang, aro };36pub const CFrontend = enum { clang, aro };
3637
...@@ -48,7 +49,7 @@ pub const Options = struct {...@@ -48,7 +49,7 @@ pub const Options = struct {
48 any_sanitize_thread: bool = false,49 any_sanitize_thread: bool = false,
49 any_unwind_tables: bool = false,50 any_unwind_tables: bool = false,
50 any_dyn_libs: bool = false,51 any_dyn_libs: bool = false,
51 c_source_files_len: usize = 0,52 any_c_source_files: bool = false,
52 emit_llvm_ir: bool = false,53 emit_llvm_ir: bool = false,
53 emit_llvm_bc: bool = false,54 emit_llvm_bc: bool = false,
54 link_libc: ?bool = null,55 link_libc: ?bool = null,
...@@ -231,7 +232,7 @@ pub fn resolve(options: Options) !Config {...@@ -231,7 +232,7 @@ pub fn resolve(options: Options) !Config {
231 }232 }
232233
233 if (options.lto) |x| break :b x;234 if (options.lto) |x| break :b x;
234 if (options.c_source_files_len == 0) break :b false;235 if (!options.any_c_source_files) break :b false;
235236
236 if (target.cpu.arch.isRISCV()) {237 if (target.cpu.arch.isRISCV()) {
237 // Clang and LLVM currently don't support RISC-V target-abi for LTO.238 // Clang and LLVM currently don't support RISC-V target-abi for LTO.
...@@ -384,6 +385,7 @@ pub fn resolve(options: Options) !Config {...@@ -384,6 +385,7 @@ pub fn resolve(options: Options) !Config {
384 .use_lld = use_lld,385 .use_lld = use_lld,
385 .entry = entry,386 .entry = entry,
386 .wasi_exec_model = wasi_exec_model,387 .wasi_exec_model = wasi_exec_model,
388 .any_c_source_files = options.any_c_source_files,
387 };389 };
388}390}
389391
src/Package/Module.zig+12-1
...@@ -229,7 +229,18 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -229,7 +229,18 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
229 };229 };
230230
231 const stack_protector: u32 = sp: {231 const stack_protector: u32 = sp: {
232 if (!target_util.supportsStackProtector(target, zig_backend)) {232 const use_zig_backend = options.global.have_zcu or
233 (options.global.any_c_source_files and options.global.c_frontend == .aro);
234 if (use_zig_backend and !target_util.supportsStackProtector(target, zig_backend)) {
235 if (options.inherited.stack_protector) |x| {
236 if (x > 0) return error.StackProtectorUnsupportedByTarget;
237 }
238 break :sp 0;
239 }
240
241 if (options.global.any_c_source_files and options.global.c_frontend == .clang and
242 !target_util.clangSupportsStackProtector(target))
243 {
233 if (options.inherited.stack_protector) |x| {244 if (options.inherited.stack_protector) |x| {
234 if (x > 0) return error.StackProtectorUnsupportedByTarget;245 if (x > 0) return error.StackProtectorUnsupportedByTarget;
235 }246 }
src/main.zig+2-2
...@@ -949,7 +949,7 @@ fn buildOutputType(...@@ -949,7 +949,7 @@ fn buildOutputType(
949 // Populated just before the call to `createModule`.949 // Populated just before the call to `createModule`.
950 .emit_bin = undefined,950 .emit_bin = undefined,
951 // Populated just before the call to `createModule`.951 // Populated just before the call to `createModule`.
952 .c_source_files_len = undefined,952 .any_c_source_files = undefined,
953 },953 },
954 // Populated in the call to `createModule` for the root module.954 // Populated in the call to `createModule` for the root module.
955 .resolved_options = undefined,955 .resolved_options = undefined,
...@@ -2635,7 +2635,7 @@ fn buildOutputType(...@@ -2635,7 +2635,7 @@ fn buildOutputType(
2635 create_module.opts.emit_llvm_ir = emit_llvm_ir != .no;2635 create_module.opts.emit_llvm_ir = emit_llvm_ir != .no;
2636 create_module.opts.emit_llvm_bc = emit_llvm_bc != .no;2636 create_module.opts.emit_llvm_bc = emit_llvm_bc != .no;
2637 create_module.opts.emit_bin = emit_bin != .no;2637 create_module.opts.emit_bin = emit_bin != .no;
2638 create_module.opts.c_source_files_len = create_module.c_source_files.items.len;2638 create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0;
26392639
2640 const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory);2640 const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory);
2641 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {2641 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {
src/target.zig+7
...@@ -360,6 +360,13 @@ pub fn supportsStackProtector(target: std.Target, backend: std.builtin.CompilerB...@@ -360,6 +360,13 @@ pub fn supportsStackProtector(target: std.Target, backend: std.builtin.CompilerB
360 };360 };
361}361}
362362
363pub fn clangSupportsStackProtector(target: std.Target) bool {
364 return switch (target.cpu.arch) {
365 .spirv32, .spirv64 => return false,
366 else => true,
367 };
368}
369
363pub fn libcProvidesStackProtector(target: std.Target) bool {370pub fn libcProvidesStackProtector(target: std.Target) bool {
364 return !target.isMinGW() and target.os.tag != .wasi and !target.isSpirV();371 return !target.isMinGW() and target.os.tag != .wasi and !target.isSpirV();
365}372}