| author | |
| committer | |
| log | be2bd5848a880765f4bc7e2363ef201a0930a04b |
| tree | 868694d734e82cb93b52b6c0c155d932f5f65f8f |
| parent | 2ccaa5414b904edb2f4af293291f5401d106f277 |
| parent | fdb934a157230ae6d3f11dee8d0d62013d5b919e |
| signature |
stage2: implement stack protectors15 files changed, 193 insertions(+), 61 deletions(-)
src/Compilation.zig+76-45| ... | @@ -173,6 +173,7 @@ astgen_wait_group: WaitGroup = .{}, | ... | @@ -173,6 +173,7 @@ astgen_wait_group: WaitGroup = .{}, |
| 173 | /// TODO: Remove this when Stage2 becomes the default compiler as it will already have this information. | 173 | /// TODO: Remove this when Stage2 becomes the default compiler as it will already have this information. |
| 174 | export_symbol_names: std.ArrayListUnmanaged([]const u8) = .{}, | 174 | export_symbol_names: std.ArrayListUnmanaged([]const u8) = .{}, |
| 175 | 175 | ||
| 176 | pub const default_stack_protector_buffer_size = 4; | ||
| 176 | pub const SemaError = Module.SemaError; | 177 | pub const SemaError = Module.SemaError; |
| 177 | 178 | ||
| 178 | pub const CRTFile = struct { | 179 | pub const CRTFile = struct { |
| ... | @@ -837,6 +838,10 @@ pub const InitOptions = struct { | ... | @@ -837,6 +838,10 @@ pub const InitOptions = struct { |
| 837 | want_pie: ?bool = null, | 838 | want_pie: ?bool = null, |
| 838 | want_sanitize_c: ?bool = null, | 839 | want_sanitize_c: ?bool = null, |
| 839 | want_stack_check: ?bool = null, | 840 | want_stack_check: ?bool = null, |
| 841 | /// null means default. | ||
| 842 | /// 0 means no stack protector. | ||
| 843 | /// other number means stack protection with that buffer size. | ||
| 844 | want_stack_protector: ?u32 = null, | ||
| 840 | want_red_zone: ?bool = null, | 845 | want_red_zone: ?bool = null, |
| 841 | omit_frame_pointer: ?bool = null, | 846 | omit_frame_pointer: ?bool = null, |
| 842 | want_valgrind: ?bool = null, | 847 | want_valgrind: ?bool = null, |
| ... | @@ -1014,6 +1019,15 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1014,6 +1019,15 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1014 | return error.ExportTableAndImportTableConflict; | 1019 | return error.ExportTableAndImportTableConflict; |
| 1015 | } | 1020 | } |
| 1016 | 1021 | ||
| 1022 | // The `have_llvm` condition is here only because native backends cannot yet build compiler-rt. | ||
| 1023 | // Once they are capable this condition could be removed. When removing this condition, | ||
| 1024 | // also test the use case of `build-obj -fcompiler-rt` with the native backends | ||
| 1025 | // and make sure the compiler-rt symbols are emitted. | ||
| 1026 | const capable_of_building_compiler_rt = build_options.have_llvm; | ||
| 1027 | |||
| 1028 | const capable_of_building_zig_libc = build_options.have_llvm; | ||
| 1029 | const capable_of_building_ssp = build_options.have_llvm; | ||
| 1030 | |||
| 1017 | const comp: *Compilation = comp: { | 1031 | const comp: *Compilation = comp: { |
| 1018 | // For allocations that have the same lifetime as Compilation. This arena is used only during this | 1032 | // For allocations that have the same lifetime as Compilation. This arena is used only during this |
| 1019 | // initialization and then is freed in deinit(). | 1033 | // initialization and then is freed in deinit(). |
| ... | @@ -1289,11 +1303,36 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1289,11 +1303,36 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1289 | 1303 | ||
| 1290 | const sanitize_c = options.want_sanitize_c orelse is_safe_mode; | 1304 | const sanitize_c = options.want_sanitize_c orelse is_safe_mode; |
| 1291 | 1305 | ||
| 1292 | const stack_check: bool = b: { | 1306 | const stack_check: bool = options.want_stack_check orelse b: { |
| 1293 | if (!target_util.supportsStackProbing(options.target)) | 1307 | if (!target_util.supportsStackProbing(options.target)) break :b false; |
| 1294 | break :b false; | 1308 | break :b is_safe_mode; |
| 1295 | break :b options.want_stack_check orelse is_safe_mode; | ||
| 1296 | }; | 1309 | }; |
| 1310 | if (stack_check and !target_util.supportsStackProbing(options.target)) | ||
| 1311 | return error.StackCheckUnsupportedByTarget; | ||
| 1312 | |||
| 1313 | const stack_protector: u32 = options.want_stack_protector orelse b: { | ||
| 1314 | if (!target_util.supportsStackProtector(options.target)) break :b @as(u32, 0); | ||
| 1315 | |||
| 1316 | // This logic is checking for linking libc because otherwise our start code | ||
| 1317 | // which is trying to set up TLS (i.e. the fs/gs registers) but the stack | ||
| 1318 | // protection code depends on fs/gs registers being already set up. | ||
| 1319 | // If we were able to annotate start code, or perhaps the entire std lib, | ||
| 1320 | // as being exempt from stack protection checks, we could change this logic | ||
| 1321 | // to supporting stack protection even when not linking libc. | ||
| 1322 | // TODO file issue about this | ||
| 1323 | if (!link_libc) break :b 0; | ||
| 1324 | if (!capable_of_building_ssp) break :b 0; | ||
| 1325 | if (is_safe_mode) break :b default_stack_protector_buffer_size; | ||
| 1326 | break :b 0; | ||
| 1327 | }; | ||
| 1328 | if (stack_protector != 0) { | ||
| 1329 | if (!target_util.supportsStackProtector(options.target)) | ||
| 1330 | return error.StackProtectorUnsupportedByTarget; | ||
| 1331 | if (!capable_of_building_ssp) | ||
| 1332 | return error.StackProtectorUnsupportedByBackend; | ||
| 1333 | if (!link_libc) | ||
| 1334 | return error.StackProtectorUnavailableWithoutLibC; | ||
| 1335 | } | ||
| 1297 | 1336 | ||
| 1298 | const valgrind: bool = b: { | 1337 | const valgrind: bool = b: { |
| 1299 | if (!target_util.hasValgrindSupport(options.target)) | 1338 | if (!target_util.hasValgrindSupport(options.target)) |
| ... | @@ -1378,6 +1417,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1378,6 +1417,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1378 | cache.hash.add(unwind_tables); | 1417 | cache.hash.add(unwind_tables); |
| 1379 | cache.hash.add(tsan); | 1418 | cache.hash.add(tsan); |
| 1380 | cache.hash.add(stack_check); | 1419 | cache.hash.add(stack_check); |
| 1420 | cache.hash.add(stack_protector); | ||
| 1381 | cache.hash.add(red_zone); | 1421 | cache.hash.add(red_zone); |
| 1382 | cache.hash.add(omit_frame_pointer); | 1422 | cache.hash.add(omit_frame_pointer); |
| 1383 | cache.hash.add(link_mode); | 1423 | cache.hash.add(link_mode); |
| ... | @@ -1741,6 +1781,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1741,6 +1781,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1741 | .valgrind = valgrind, | 1781 | .valgrind = valgrind, |
| 1742 | .tsan = tsan, | 1782 | .tsan = tsan, |
| 1743 | .stack_check = stack_check, | 1783 | .stack_check = stack_check, |
| 1784 | .stack_protector = stack_protector, | ||
| 1744 | .red_zone = red_zone, | 1785 | .red_zone = red_zone, |
| 1745 | .omit_frame_pointer = omit_frame_pointer, | 1786 | .omit_frame_pointer = omit_frame_pointer, |
| 1746 | .single_threaded = single_threaded, | 1787 | .single_threaded = single_threaded, |
| ... | @@ -1822,6 +1863,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1822,6 +1863,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1822 | }; | 1863 | }; |
| 1823 | errdefer comp.destroy(); | 1864 | errdefer comp.destroy(); |
| 1824 | 1865 | ||
| 1866 | const target = comp.getTarget(); | ||
| 1867 | |||
| 1825 | // Add a `CObject` for each `c_source_files`. | 1868 | // Add a `CObject` for each `c_source_files`. |
| 1826 | try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len); | 1869 | try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len); |
| 1827 | for (options.c_source_files) |c_source_file| { | 1870 | for (options.c_source_files) |c_source_file| { |
| ... | @@ -1837,11 +1880,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1837,11 +1880,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1837 | 1880 | ||
| 1838 | const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null; | 1881 | const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null; |
| 1839 | 1882 | ||
| 1840 | if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and | 1883 | if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and target.ofmt != .c) { |
| 1841 | options.target.ofmt != .c) | 1884 | if (target.isDarwin()) { |
| 1842 | { | 1885 | switch (target.abi) { |
| 1843 | if (comp.getTarget().isDarwin()) { | ||
| 1844 | switch (comp.getTarget().abi) { | ||
| 1845 | .none, | 1886 | .none, |
| 1846 | .simulator, | 1887 | .simulator, |
| 1847 | .macabi, | 1888 | .macabi, |
| ... | @@ -1852,9 +1893,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1852,9 +1893,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1852 | // If we need to build glibc for the target, add work items for it. | 1893 | // If we need to build glibc for the target, add work items for it. |
| 1853 | // We go through the work queue so that building can be done in parallel. | 1894 | // We go through the work queue so that building can be done in parallel. |
| 1854 | if (comp.wantBuildGLibCFromSource()) { | 1895 | if (comp.wantBuildGLibCFromSource()) { |
| 1855 | if (!target_util.canBuildLibC(comp.getTarget())) return error.LibCUnavailable; | 1896 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1856 | 1897 | ||
| 1857 | if (glibc.needsCrtiCrtn(comp.getTarget())) { | 1898 | if (glibc.needsCrtiCrtn(target)) { |
| 1858 | try comp.work_queue.write(&[_]Job{ | 1899 | try comp.work_queue.write(&[_]Job{ |
| 1859 | .{ .glibc_crt_file = .crti_o }, | 1900 | .{ .glibc_crt_file = .crti_o }, |
| 1860 | .{ .glibc_crt_file = .crtn_o }, | 1901 | .{ .glibc_crt_file = .crtn_o }, |
| ... | @@ -1867,10 +1908,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1867,10 +1908,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1867 | }); | 1908 | }); |
| 1868 | } | 1909 | } |
| 1869 | if (comp.wantBuildMuslFromSource()) { | 1910 | if (comp.wantBuildMuslFromSource()) { |
| 1870 | if (!target_util.canBuildLibC(comp.getTarget())) return error.LibCUnavailable; | 1911 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1871 | 1912 | ||
| 1872 | try comp.work_queue.ensureUnusedCapacity(6); | 1913 | try comp.work_queue.ensureUnusedCapacity(6); |
| 1873 | if (musl.needsCrtiCrtn(comp.getTarget())) { | 1914 | if (musl.needsCrtiCrtn(target)) { |
| 1874 | comp.work_queue.writeAssumeCapacity(&[_]Job{ | 1915 | comp.work_queue.writeAssumeCapacity(&[_]Job{ |
| 1875 | .{ .musl_crt_file = .crti_o }, | 1916 | .{ .musl_crt_file = .crti_o }, |
| 1876 | .{ .musl_crt_file = .crtn_o }, | 1917 | .{ .musl_crt_file = .crtn_o }, |
| ... | @@ -1887,7 +1928,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1887,7 +1928,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1887 | }); | 1928 | }); |
| 1888 | } | 1929 | } |
| 1889 | if (comp.wantBuildWasiLibcFromSource()) { | 1930 | if (comp.wantBuildWasiLibcFromSource()) { |
| 1890 | if (!target_util.canBuildLibC(comp.getTarget())) return error.LibCUnavailable; | 1931 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1891 | 1932 | ||
| 1892 | const wasi_emulated_libs = comp.bin_file.options.wasi_emulated_libs; | 1933 | const wasi_emulated_libs = comp.bin_file.options.wasi_emulated_libs; |
| 1893 | try comp.work_queue.ensureUnusedCapacity(wasi_emulated_libs.len + 2); // worst-case we need all components | 1934 | try comp.work_queue.ensureUnusedCapacity(wasi_emulated_libs.len + 2); // worst-case we need all components |
| ... | @@ -1902,7 +1943,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1902,7 +1943,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1902 | }); | 1943 | }); |
| 1903 | } | 1944 | } |
| 1904 | if (comp.wantBuildMinGWFromSource()) { | 1945 | if (comp.wantBuildMinGWFromSource()) { |
| 1905 | if (!target_util.canBuildLibC(comp.getTarget())) return error.LibCUnavailable; | 1946 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 1906 | 1947 | ||
| 1907 | const static_lib_jobs = [_]Job{ | 1948 | const static_lib_jobs = [_]Job{ |
| 1908 | .{ .mingw_crt_file = .mingw32_lib }, | 1949 | .{ .mingw_crt_file = .mingw32_lib }, |
| ... | @@ -1921,7 +1962,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1921,7 +1962,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1921 | } | 1962 | } |
| 1922 | } | 1963 | } |
| 1923 | // Generate Windows import libs. | 1964 | // Generate Windows import libs. |
| 1924 | if (comp.getTarget().os.tag == .windows) { | 1965 | if (target.os.tag == .windows) { |
| 1925 | const count = comp.bin_file.options.system_libs.count(); | 1966 | const count = comp.bin_file.options.system_libs.count(); |
| 1926 | try comp.work_queue.ensureUnusedCapacity(count); | 1967 | try comp.work_queue.ensureUnusedCapacity(count); |
| 1927 | var i: usize = 0; | 1968 | var i: usize = 0; |
| ... | @@ -1940,15 +1981,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1940,15 +1981,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1940 | try comp.work_queue.writeItem(.libtsan); | 1981 | try comp.work_queue.writeItem(.libtsan); |
| 1941 | } | 1982 | } |
| 1942 | 1983 | ||
| 1943 | // The `have_llvm` condition is here only because native backends cannot yet build compiler-rt. | ||
| 1944 | // Once they are capable this condition could be removed. When removing this condition, | ||
| 1945 | // also test the use case of `build-obj -fcompiler-rt` with the native backends | ||
| 1946 | // and make sure the compiler-rt symbols are emitted. | ||
| 1947 | const capable_of_building_compiler_rt = build_options.have_llvm; | ||
| 1948 | |||
| 1949 | const capable_of_building_zig_libc = build_options.have_llvm; | ||
| 1950 | const capable_of_building_ssp = comp.bin_file.options.use_stage1; | ||
| 1951 | |||
| 1952 | if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) { | 1984 | if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) { |
| 1953 | if (is_exe_or_dyn_lib) { | 1985 | if (is_exe_or_dyn_lib) { |
| 1954 | log.debug("queuing a job to build compiler_rt_lib", .{}); | 1986 | log.debug("queuing a job to build compiler_rt_lib", .{}); |
| ... | @@ -1962,8 +1994,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1962,8 +1994,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1962 | } | 1994 | } |
| 1963 | } | 1995 | } |
| 1964 | if (needs_c_symbols) { | 1996 | if (needs_c_symbols) { |
| 1965 | // MinGW provides no libssp, use our own implementation. | 1997 | // Related: https://github.com/ziglang/zig/issues/7265. |
| 1966 | if (comp.getTarget().isMinGW() and capable_of_building_ssp) { | 1998 | if (comp.bin_file.options.stack_protector != 0 and |
| 1999 | (!comp.bin_file.options.link_libc or | ||
| 2000 | !target_util.libcProvidesStackProtector(target))) | ||
| 2001 | { | ||
| 1967 | try comp.work_queue.writeItem(.{ .libssp = {} }); | 2002 | try comp.work_queue.writeItem(.{ .libssp = {} }); |
| 1968 | } | 2003 | } |
| 1969 | 2004 | ||
| ... | @@ -4123,6 +4158,17 @@ pub fn addCCArgs( | ... | @@ -4123,6 +4158,17 @@ pub fn addCCArgs( |
| 4123 | try argv.append("-fno-omit-frame-pointer"); | 4158 | try argv.append("-fno-omit-frame-pointer"); |
| 4124 | } | 4159 | } |
| 4125 | 4160 | ||
| 4161 | const ssp_buf_size = comp.bin_file.options.stack_protector; | ||
| 4162 | if (ssp_buf_size != 0) { | ||
| 4163 | try argv.appendSlice(&[_][]const u8{ | ||
| 4164 | "-fstack-protector-strong", | ||
| 4165 | "--param", | ||
| 4166 | try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}), | ||
| 4167 | }); | ||
| 4168 | } else { | ||
| 4169 | try argv.append("-fno-stack-protector"); | ||
| 4170 | } | ||
| 4171 | |||
| 4126 | switch (comp.bin_file.options.optimize_mode) { | 4172 | switch (comp.bin_file.options.optimize_mode) { |
| 4127 | .Debug => { | 4173 | .Debug => { |
| 4128 | // windows c runtime requires -D_DEBUG if using debug libraries | 4174 | // windows c runtime requires -D_DEBUG if using debug libraries |
| ... | @@ -4131,27 +4177,12 @@ pub fn addCCArgs( | ... | @@ -4131,27 +4177,12 @@ pub fn addCCArgs( |
| 4131 | // to -O1. Besides potentially impairing debugging, -O1/-Og significantly | 4177 | // to -O1. Besides potentially impairing debugging, -O1/-Og significantly |
| 4132 | // increases compile times. | 4178 | // increases compile times. |
| 4133 | try argv.append("-O0"); | 4179 | try argv.append("-O0"); |
| 4134 | |||
| 4135 | if (comp.bin_file.options.link_libc and target.os.tag != .wasi) { | ||
| 4136 | try argv.append("-fstack-protector-strong"); | ||
| 4137 | try argv.append("--param"); | ||
| 4138 | try argv.append("ssp-buffer-size=4"); | ||
| 4139 | } else { | ||
| 4140 | try argv.append("-fno-stack-protector"); | ||
| 4141 | } | ||
| 4142 | }, | 4180 | }, |
| 4143 | .ReleaseSafe => { | 4181 | .ReleaseSafe => { |
| 4144 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather | 4182 | // See the comment in the BuildModeFastRelease case for why we pass -O2 rather |
| 4145 | // than -O3 here. | 4183 | // than -O3 here. |
| 4146 | try argv.append("-O2"); | 4184 | try argv.append("-O2"); |
| 4147 | if (comp.bin_file.options.link_libc and target.os.tag != .wasi) { | 4185 | try argv.append("-D_FORTIFY_SOURCE=2"); |
| 4148 | try argv.append("-D_FORTIFY_SOURCE=2"); | ||
| 4149 | try argv.append("-fstack-protector-strong"); | ||
| 4150 | try argv.append("--param"); | ||
| 4151 | try argv.append("ssp-buffer-size=4"); | ||
| 4152 | } else { | ||
| 4153 | try argv.append("-fno-stack-protector"); | ||
| 4154 | } | ||
| 4155 | }, | 4186 | }, |
| 4156 | .ReleaseFast => { | 4187 | .ReleaseFast => { |
| 4157 | try argv.append("-DNDEBUG"); | 4188 | try argv.append("-DNDEBUG"); |
| ... | @@ -4161,12 +4192,10 @@ pub fn addCCArgs( | ... | @@ -4161,12 +4192,10 @@ pub fn addCCArgs( |
| 4161 | // Zig code than it is for C code. Also, C programmers are used to their code | 4192 | // Zig code than it is for C code. Also, C programmers are used to their code |
| 4162 | // running in -O2 and thus the -O3 path has been tested less. | 4193 | // running in -O2 and thus the -O3 path has been tested less. |
| 4163 | try argv.append("-O2"); | 4194 | try argv.append("-O2"); |
| 4164 | try argv.append("-fno-stack-protector"); | ||
| 4165 | }, | 4195 | }, |
| 4166 | .ReleaseSmall => { | 4196 | .ReleaseSmall => { |
| 4167 | try argv.append("-DNDEBUG"); | 4197 | try argv.append("-DNDEBUG"); |
| 4168 | try argv.append("-Os"); | 4198 | try argv.append("-Os"); |
| 4169 | try argv.append("-fno-stack-protector"); | ||
| 4170 | }, | 4199 | }, |
| 4171 | } | 4200 | } |
| 4172 | 4201 | ||
| ... | @@ -5031,6 +5060,7 @@ fn buildOutputFromZig( | ... | @@ -5031,6 +5060,7 @@ fn buildOutputFromZig( |
| 5031 | .use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1, | 5060 | .use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1, |
| 5032 | .want_sanitize_c = false, | 5061 | .want_sanitize_c = false, |
| 5033 | .want_stack_check = false, | 5062 | .want_stack_check = false, |
| 5063 | .want_stack_protector = 0, | ||
| 5034 | .want_red_zone = comp.bin_file.options.red_zone, | 5064 | .want_red_zone = comp.bin_file.options.red_zone, |
| 5035 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 5065 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 5036 | .want_valgrind = false, | 5066 | .want_valgrind = false, |
| ... | @@ -5311,6 +5341,7 @@ pub fn build_crt_file( | ... | @@ -5311,6 +5341,7 @@ pub fn build_crt_file( |
| 5311 | .optimize_mode = comp.compilerRtOptMode(), | 5341 | .optimize_mode = comp.compilerRtOptMode(), |
| 5312 | .want_sanitize_c = false, | 5342 | .want_sanitize_c = false, |
| 5313 | .want_stack_check = false, | 5343 | .want_stack_check = false, |
| 5344 | .want_stack_protector = 0, | ||
| 5314 | .want_red_zone = comp.bin_file.options.red_zone, | 5345 | .want_red_zone = comp.bin_file.options.red_zone, |
| 5315 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 5346 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 5316 | .want_valgrind = false, | 5347 | .want_valgrind = false, |
src/Sema.zig+8-7| ... | @@ -7567,10 +7567,11 @@ fn handleExternLibName( | ... | @@ -7567,10 +7567,11 @@ fn handleExternLibName( |
| 7567 | ) CompileError![:0]u8 { | 7567 | ) CompileError![:0]u8 { |
| 7568 | blk: { | 7568 | blk: { |
| 7569 | const mod = sema.mod; | 7569 | const mod = sema.mod; |
| 7570 | const comp = mod.comp; | ||
| 7570 | const target = mod.getTarget(); | 7571 | const target = mod.getTarget(); |
| 7571 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); | 7572 | log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); |
| 7572 | if (target_util.is_libc_lib_name(target, lib_name)) { | 7573 | if (target_util.is_libc_lib_name(target, lib_name)) { |
| 7573 | if (!mod.comp.bin_file.options.link_libc) { | 7574 | if (!comp.bin_file.options.link_libc and !comp.bin_file.options.parent_compilation_link_libc) { |
| 7574 | return sema.fail( | 7575 | return sema.fail( |
| 7575 | block, | 7576 | block, |
| 7576 | src_loc, | 7577 | src_loc, |
| ... | @@ -7578,11 +7579,11 @@ fn handleExternLibName( | ... | @@ -7578,11 +7579,11 @@ fn handleExternLibName( |
| 7578 | .{}, | 7579 | .{}, |
| 7579 | ); | 7580 | ); |
| 7580 | } | 7581 | } |
| 7581 | mod.comp.bin_file.options.link_libc = true; | 7582 | comp.bin_file.options.link_libc = true; |
| 7582 | break :blk; | 7583 | break :blk; |
| 7583 | } | 7584 | } |
| 7584 | if (target_util.is_libcpp_lib_name(target, lib_name)) { | 7585 | if (target_util.is_libcpp_lib_name(target, lib_name)) { |
| 7585 | if (!mod.comp.bin_file.options.link_libcpp) { | 7586 | if (!comp.bin_file.options.link_libcpp) { |
| 7586 | return sema.fail( | 7587 | return sema.fail( |
| 7587 | block, | 7588 | block, |
| 7588 | src_loc, | 7589 | src_loc, |
| ... | @@ -7590,14 +7591,14 @@ fn handleExternLibName( | ... | @@ -7590,14 +7591,14 @@ fn handleExternLibName( |
| 7590 | .{}, | 7591 | .{}, |
| 7591 | ); | 7592 | ); |
| 7592 | } | 7593 | } |
| 7593 | mod.comp.bin_file.options.link_libcpp = true; | 7594 | comp.bin_file.options.link_libcpp = true; |
| 7594 | break :blk; | 7595 | break :blk; |
| 7595 | } | 7596 | } |
| 7596 | if (mem.eql(u8, lib_name, "unwind")) { | 7597 | if (mem.eql(u8, lib_name, "unwind")) { |
| 7597 | mod.comp.bin_file.options.link_libunwind = true; | 7598 | comp.bin_file.options.link_libunwind = true; |
| 7598 | break :blk; | 7599 | break :blk; |
| 7599 | } | 7600 | } |
| 7600 | if (!target.isWasm() and !mod.comp.bin_file.options.pic) { | 7601 | if (!target.isWasm() and !comp.bin_file.options.pic) { |
| 7601 | return sema.fail( | 7602 | return sema.fail( |
| 7602 | block, | 7603 | block, |
| 7603 | src_loc, | 7604 | src_loc, |
| ... | @@ -7605,7 +7606,7 @@ fn handleExternLibName( | ... | @@ -7605,7 +7606,7 @@ fn handleExternLibName( |
| 7605 | .{ lib_name, lib_name }, | 7606 | .{ lib_name, lib_name }, |
| 7606 | ); | 7607 | ); |
| 7607 | } | 7608 | } |
| 7608 | mod.comp.stage1AddLinkLib(lib_name) catch |err| { | 7609 | comp.stage1AddLinkLib(lib_name) catch |err| { |
| 7609 | return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{ | 7610 | return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{ |
| 7610 | lib_name, @errorName(err), | 7611 | lib_name, @errorName(err), |
| 7611 | }); | 7612 | }); |
src/clang_options_data.zig+40-5| ... | @@ -3290,7 +3290,14 @@ flagpd1("fno-stack-arrays"), | ... | @@ -3290,7 +3290,14 @@ flagpd1("fno-stack-arrays"), |
| 3290 | .psl = false, | 3290 | .psl = false, |
| 3291 | }, | 3291 | }, |
| 3292 | flagpd1("fno-stack-clash-protection"), | 3292 | flagpd1("fno-stack-clash-protection"), |
| 3293 | flagpd1("fno-stack-protector"), | 3293 | .{ |
| 3294 | .name = "fno-stack-protector", | ||
| 3295 | .syntax = .flag, | ||
| 3296 | .zig_equivalent = .no_stack_protector, | ||
| 3297 | .pd1 = true, | ||
| 3298 | .pd2 = false, | ||
| 3299 | .psl = false, | ||
| 3300 | }, | ||
| 3294 | flagpd1("fno-stack-size-section"), | 3301 | flagpd1("fno-stack-size-section"), |
| 3295 | flagpd1("fno-standalone-debug"), | 3302 | flagpd1("fno-standalone-debug"), |
| 3296 | flagpd1("fno-strength-reduce"), | 3303 | flagpd1("fno-strength-reduce"), |
| ... | @@ -3588,9 +3595,30 @@ flagpd1("fstack-arrays"), | ... | @@ -3588,9 +3595,30 @@ flagpd1("fstack-arrays"), |
| 3588 | .psl = false, | 3595 | .psl = false, |
| 3589 | }, | 3596 | }, |
| 3590 | flagpd1("fstack-clash-protection"), | 3597 | flagpd1("fstack-clash-protection"), |
| 3591 | flagpd1("fstack-protector"), | 3598 | .{ |
| 3592 | flagpd1("fstack-protector-all"), | 3599 | .name = "fstack-protector", |
| 3593 | flagpd1("fstack-protector-strong"), | 3600 | .syntax = .flag, |
| 3601 | .zig_equivalent = .stack_protector, | ||
| 3602 | .pd1 = true, | ||
| 3603 | .pd2 = false, | ||
| 3604 | .psl = false, | ||
| 3605 | }, | ||
| 3606 | .{ | ||
| 3607 | .name = "fstack-protector-all", | ||
| 3608 | .syntax = .flag, | ||
| 3609 | .zig_equivalent = .stack_protector, | ||
| 3610 | .pd1 = true, | ||
| 3611 | .pd2 = false, | ||
| 3612 | .psl = false, | ||
| 3613 | }, | ||
| 3614 | .{ | ||
| 3615 | .name = "fstack-protector-strong", | ||
| 3616 | .syntax = .flag, | ||
| 3617 | .zig_equivalent = .stack_protector, | ||
| 3618 | .pd1 = true, | ||
| 3619 | .pd2 = false, | ||
| 3620 | .psl = false, | ||
| 3621 | }, | ||
| 3594 | flagpd1("fstack-size-section"), | 3622 | flagpd1("fstack-size-section"), |
| 3595 | flagpd1("fstack-usage"), | 3623 | flagpd1("fstack-usage"), |
| 3596 | flagpd1("fstandalone-debug"), | 3624 | flagpd1("fstandalone-debug"), |
| ... | @@ -4809,7 +4837,14 @@ flagpd1("single_module"), | ... | @@ -4809,7 +4837,14 @@ flagpd1("single_module"), |
| 4809 | }, | 4837 | }, |
| 4810 | sepd1("split-dwarf-file"), | 4838 | sepd1("split-dwarf-file"), |
| 4811 | sepd1("split-dwarf-output"), | 4839 | sepd1("split-dwarf-output"), |
| 4812 | sepd1("stack-protector"), | 4840 | .{ |
| 4841 | .name = "stack-protector", | ||
| 4842 | .syntax = .separate, | ||
| 4843 | .zig_equivalent = .stack_protector, | ||
| 4844 | .pd1 = true, | ||
| 4845 | .pd2 = false, | ||
| 4846 | .psl = false, | ||
| 4847 | }, | ||
| 4813 | sepd1("stack-protector-buffer-size"), | 4848 | sepd1("stack-protector-buffer-size"), |
| 4814 | sepd1("stack-usage-file"), | 4849 | sepd1("stack-usage-file"), |
| 4815 | .{ | 4850 | .{ |
src/codegen/llvm.zig+8-3| ... | @@ -711,9 +711,14 @@ pub const Object = struct { | ... | @@ -711,9 +711,14 @@ pub const Object = struct { |
| 711 | DeclGen.removeFnAttr(llvm_func, "noinline"); | 711 | DeclGen.removeFnAttr(llvm_func, "noinline"); |
| 712 | } | 712 | } |
| 713 | 713 | ||
| 714 | // TODO: port these over from stage1 | 714 | // TODO: disable this if safety is off for the function scope |
| 715 | // addLLVMFnAttr(llvm_fn, "sspstrong"); | 715 | const ssp_buf_size = module.comp.bin_file.options.stack_protector; |
| 716 | // addLLVMFnAttrStr(llvm_fn, "stack-protector-buffer-size", "4"); | 716 | if (ssp_buf_size != 0) { |
| 717 | var buf: [12]u8 = undefined; | ||
| 718 | const arg = std.fmt.bufPrintZ(&buf, "{d}", .{ssp_buf_size}) catch unreachable; | ||
| 719 | dg.addFnAttr(llvm_func, "sspstrong"); | ||
| 720 | dg.addFnAttrString(llvm_func, "stack-protector-buffer-size", arg); | ||
| 721 | } | ||
| 717 | 722 | ||
| 718 | // TODO: disable this if safety is off for the function scope | 723 | // TODO: disable this if safety is off for the function scope |
| 719 | if (module.comp.bin_file.options.stack_check) { | 724 | if (module.comp.bin_file.options.stack_check) { |
src/glibc.zig+1| ... | @@ -1111,6 +1111,7 @@ fn buildSharedLib( | ... | @@ -1111,6 +1111,7 @@ fn buildSharedLib( |
| 1111 | .optimize_mode = comp.compilerRtOptMode(), | 1111 | .optimize_mode = comp.compilerRtOptMode(), |
| 1112 | .want_sanitize_c = false, | 1112 | .want_sanitize_c = false, |
| 1113 | .want_stack_check = false, | 1113 | .want_stack_check = false, |
| 1114 | .want_stack_protector = 0, | ||
| 1114 | .want_red_zone = comp.bin_file.options.red_zone, | 1115 | .want_red_zone = comp.bin_file.options.red_zone, |
| 1115 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 1116 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 1116 | .want_valgrind = false, | 1117 | .want_valgrind = false, |
src/libcxx.zig+2| ... | @@ -206,6 +206,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { | ... | @@ -206,6 +206,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { |
| 206 | .link_mode = link_mode, | 206 | .link_mode = link_mode, |
| 207 | .want_sanitize_c = false, | 207 | .want_sanitize_c = false, |
| 208 | .want_stack_check = false, | 208 | .want_stack_check = false, |
| 209 | .want_stack_protector = 0, | ||
| 209 | .want_red_zone = comp.bin_file.options.red_zone, | 210 | .want_red_zone = comp.bin_file.options.red_zone, |
| 210 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 211 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 211 | .want_valgrind = false, | 212 | .want_valgrind = false, |
| ... | @@ -349,6 +350,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { | ... | @@ -349,6 +350,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { |
| 349 | .link_mode = link_mode, | 350 | .link_mode = link_mode, |
| 350 | .want_sanitize_c = false, | 351 | .want_sanitize_c = false, |
| 351 | .want_stack_check = false, | 352 | .want_stack_check = false, |
| 353 | .want_stack_protector = 0, | ||
| 352 | .want_red_zone = comp.bin_file.options.red_zone, | 354 | .want_red_zone = comp.bin_file.options.red_zone, |
| 353 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 355 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 354 | .want_valgrind = false, | 356 | .want_valgrind = false, |
src/libtsan.zig+1| ... | @@ -211,6 +211,7 @@ pub fn buildTsan(comp: *Compilation) !void { | ... | @@ -211,6 +211,7 @@ pub fn buildTsan(comp: *Compilation) !void { |
| 211 | .link_mode = link_mode, | 211 | .link_mode = link_mode, |
| 212 | .want_sanitize_c = false, | 212 | .want_sanitize_c = false, |
| 213 | .want_stack_check = false, | 213 | .want_stack_check = false, |
| 214 | .want_stack_protector = 0, | ||
| 214 | .want_valgrind = false, | 215 | .want_valgrind = false, |
| 215 | .want_tsan = false, | 216 | .want_tsan = false, |
| 216 | .want_pic = true, | 217 | .want_pic = true, |
src/libunwind.zig+1| ... | @@ -113,6 +113,7 @@ pub fn buildStaticLib(comp: *Compilation) !void { | ... | @@ -113,6 +113,7 @@ pub fn buildStaticLib(comp: *Compilation) !void { |
| 113 | .link_mode = link_mode, | 113 | .link_mode = link_mode, |
| 114 | .want_sanitize_c = false, | 114 | .want_sanitize_c = false, |
| 115 | .want_stack_check = false, | 115 | .want_stack_check = false, |
| 116 | .want_stack_protector = 0, | ||
| 116 | .want_red_zone = comp.bin_file.options.red_zone, | 117 | .want_red_zone = comp.bin_file.options.red_zone, |
| 117 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 118 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 118 | .want_valgrind = false, | 119 | .want_valgrind = false, |
src/link.zig+3| ... | @@ -90,6 +90,9 @@ pub const Options = struct { | ... | @@ -90,6 +90,9 @@ pub const Options = struct { |
| 90 | entry: ?[]const u8, | 90 | entry: ?[]const u8, |
| 91 | stack_size_override: ?u64, | 91 | stack_size_override: ?u64, |
| 92 | image_base_override: ?u64, | 92 | image_base_override: ?u64, |
| 93 | /// 0 means no stack protector | ||
| 94 | /// other value means stack protector with that buffer size. | ||
| 95 | stack_protector: u32, | ||
| 93 | cache_mode: CacheMode, | 96 | cache_mode: CacheMode, |
| 94 | include_compiler_rt: bool, | 97 | include_compiler_rt: bool, |
| 95 | /// Set to `true` to omit debug info. | 98 | /// Set to `true` to omit debug info. |
src/link/Elf.zig+6| ... | @@ -1673,6 +1673,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1673,6 +1673,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1673 | } | 1673 | } |
| 1674 | } | 1674 | } |
| 1675 | 1675 | ||
| 1676 | // stack-protector. | ||
| 1677 | // Related: https://github.com/ziglang/zig/issues/7265 | ||
| 1678 | if (comp.libssp_static_lib) |ssp| { | ||
| 1679 | try argv.append(ssp.full_object_path); | ||
| 1680 | } | ||
| 1681 | |||
| 1676 | // compiler-rt | 1682 | // compiler-rt |
| 1677 | if (compiler_rt_path) |p| { | 1683 | if (compiler_rt_path) |p| { |
| 1678 | try argv.append(p); | 1684 | try argv.append(p); |
src/main.zig+16| ... | @@ -378,6 +378,8 @@ const usage_build_generic = | ... | @@ -378,6 +378,8 @@ const usage_build_generic = |
| 378 | \\ -fno-lto Force-disable Link Time Optimization | 378 | \\ -fno-lto Force-disable Link Time Optimization |
| 379 | \\ -fstack-check Enable stack probing in unsafe builds | 379 | \\ -fstack-check Enable stack probing in unsafe builds |
| 380 | \\ -fno-stack-check Disable stack probing in safe builds | 380 | \\ -fno-stack-check Disable stack probing in safe builds |
| 381 | \\ -fstack-protector Enable stack protection in unsafe builds | ||
| 382 | \\ -fno-stack-protector Disable stack protection in safe builds | ||
| 381 | \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds | 383 | \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds |
| 382 | \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds | 384 | \\ -fno-sanitize-c Disable C undefined behavior detection in safe builds |
| 383 | \\ -fvalgrind Include valgrind client requests in release builds | 385 | \\ -fvalgrind Include valgrind client requests in release builds |
| ... | @@ -668,6 +670,7 @@ fn buildOutputType( | ... | @@ -668,6 +670,7 @@ fn buildOutputType( |
| 668 | var want_unwind_tables: ?bool = null; | 670 | var want_unwind_tables: ?bool = null; |
| 669 | var want_sanitize_c: ?bool = null; | 671 | var want_sanitize_c: ?bool = null; |
| 670 | var want_stack_check: ?bool = null; | 672 | var want_stack_check: ?bool = null; |
| 673 | var want_stack_protector: ?u32 = null; | ||
| 671 | var want_red_zone: ?bool = null; | 674 | var want_red_zone: ?bool = null; |
| 672 | var omit_frame_pointer: ?bool = null; | 675 | var omit_frame_pointer: ?bool = null; |
| 673 | var want_valgrind: ?bool = null; | 676 | var want_valgrind: ?bool = null; |
| ... | @@ -1168,6 +1171,10 @@ fn buildOutputType( | ... | @@ -1168,6 +1171,10 @@ fn buildOutputType( |
| 1168 | want_stack_check = true; | 1171 | want_stack_check = true; |
| 1169 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { | 1172 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { |
| 1170 | want_stack_check = false; | 1173 | want_stack_check = false; |
| 1174 | } else if (mem.eql(u8, arg, "-fstack-protector")) { | ||
| 1175 | want_stack_protector = Compilation.default_stack_protector_buffer_size; | ||
| 1176 | } else if (mem.eql(u8, arg, "-fno-stack-protector")) { | ||
| 1177 | want_stack_protector = 0; | ||
| 1171 | } else if (mem.eql(u8, arg, "-mred-zone")) { | 1178 | } else if (mem.eql(u8, arg, "-mred-zone")) { |
| 1172 | want_red_zone = true; | 1179 | want_red_zone = true; |
| 1173 | } else if (mem.eql(u8, arg, "-mno-red-zone")) { | 1180 | } else if (mem.eql(u8, arg, "-mno-red-zone")) { |
| ... | @@ -1521,6 +1528,12 @@ fn buildOutputType( | ... | @@ -1521,6 +1528,12 @@ fn buildOutputType( |
| 1521 | .no_color_diagnostics => color = .off, | 1528 | .no_color_diagnostics => color = .off, |
| 1522 | .stack_check => want_stack_check = true, | 1529 | .stack_check => want_stack_check = true, |
| 1523 | .no_stack_check => want_stack_check = false, | 1530 | .no_stack_check => want_stack_check = false, |
| 1531 | .stack_protector => { | ||
| 1532 | if (want_stack_protector == null) { | ||
| 1533 | want_stack_protector = Compilation.default_stack_protector_buffer_size; | ||
| 1534 | } | ||
| 1535 | }, | ||
| 1536 | .no_stack_protector => want_stack_protector = 0, | ||
| 1524 | .unwind_tables => want_unwind_tables = true, | 1537 | .unwind_tables => want_unwind_tables = true, |
| 1525 | .no_unwind_tables => want_unwind_tables = false, | 1538 | .no_unwind_tables => want_unwind_tables = false, |
| 1526 | .nostdlib => ensure_libc_on_non_freestanding = false, | 1539 | .nostdlib => ensure_libc_on_non_freestanding = false, |
| ... | @@ -2859,6 +2872,7 @@ fn buildOutputType( | ... | @@ -2859,6 +2872,7 @@ fn buildOutputType( |
| 2859 | .want_unwind_tables = want_unwind_tables, | 2872 | .want_unwind_tables = want_unwind_tables, |
| 2860 | .want_sanitize_c = want_sanitize_c, | 2873 | .want_sanitize_c = want_sanitize_c, |
| 2861 | .want_stack_check = want_stack_check, | 2874 | .want_stack_check = want_stack_check, |
| 2875 | .want_stack_protector = want_stack_protector, | ||
| 2862 | .want_red_zone = want_red_zone, | 2876 | .want_red_zone = want_red_zone, |
| 2863 | .omit_frame_pointer = omit_frame_pointer, | 2877 | .omit_frame_pointer = omit_frame_pointer, |
| 2864 | .want_valgrind = want_valgrind, | 2878 | .want_valgrind = want_valgrind, |
| ... | @@ -4663,6 +4677,8 @@ pub const ClangArgIterator = struct { | ... | @@ -4663,6 +4677,8 @@ pub const ClangArgIterator = struct { |
| 4663 | no_color_diagnostics, | 4677 | no_color_diagnostics, |
| 4664 | stack_check, | 4678 | stack_check, |
| 4665 | no_stack_check, | 4679 | no_stack_check, |
| 4680 | stack_protector, | ||
| 4681 | no_stack_protector, | ||
| 4666 | strip, | 4682 | strip, |
| 4667 | exec_model, | 4683 | exec_model, |
| 4668 | emit_llvm, | 4684 | emit_llvm, |
src/musl.zig+1| ... | @@ -215,6 +215,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { | ... | @@ -215,6 +215,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { |
| 215 | .optimize_mode = comp.compilerRtOptMode(), | 215 | .optimize_mode = comp.compilerRtOptMode(), |
| 216 | .want_sanitize_c = false, | 216 | .want_sanitize_c = false, |
| 217 | .want_stack_check = false, | 217 | .want_stack_check = false, |
| 218 | .want_stack_protector = 0, | ||
| 218 | .want_red_zone = comp.bin_file.options.red_zone, | 219 | .want_red_zone = comp.bin_file.options.red_zone, |
| 219 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, | 220 | .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, |
| 220 | .want_valgrind = false, | 221 | .want_valgrind = false, |
src/stage1.zig+1-1| ... | @@ -416,7 +416,7 @@ export fn stage2_add_link_lib( | ... | @@ -416,7 +416,7 @@ export fn stage2_add_link_lib( |
| 416 | const target = comp.getTarget(); | 416 | const target = comp.getTarget(); |
| 417 | const is_libc = target_util.is_libc_lib_name(target, lib_name); | 417 | const is_libc = target_util.is_libc_lib_name(target, lib_name); |
| 418 | if (is_libc) { | 418 | if (is_libc) { |
| 419 | if (!comp.bin_file.options.link_libc) { | 419 | if (!comp.bin_file.options.link_libc and !comp.bin_file.options.parent_compilation_link_libc) { |
| 420 | return "dependency on libc must be explicitly specified in the build command"; | 420 | return "dependency on libc must be explicitly specified in the build command"; |
| 421 | } | 421 | } |
| 422 | return null; | 422 | return null; |
src/target.zig+9| ... | @@ -300,6 +300,15 @@ pub fn supportsStackProbing(target: std.Target) bool { | ... | @@ -300,6 +300,15 @@ pub fn supportsStackProbing(target: std.Target) bool { |
| 300 | (target.cpu.arch == .i386 or target.cpu.arch == .x86_64); | 300 | (target.cpu.arch == .i386 or target.cpu.arch == .x86_64); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | pub fn supportsStackProtector(target: std.Target) bool { | ||
| 304 | // TODO: investigate whether stack-protector works on wasm | ||
| 305 | return !target.isWasm(); | ||
| 306 | } | ||
| 307 | |||
| 308 | pub fn libcProvidesStackProtector(target: std.Target) bool { | ||
| 309 | return !target.isMinGW() and target.os.tag != .wasi; | ||
| 310 | } | ||
| 311 | |||
| 303 | pub fn supportsReturnAddress(target: std.Target) bool { | 312 | pub fn supportsReturnAddress(target: std.Target) bool { |
| 304 | return switch (target.cpu.arch) { | 313 | return switch (target.cpu.arch) { |
| 305 | .wasm32, .wasm64 => target.os.tag == .emscripten, | 314 | .wasm32, .wasm64 => target.os.tag == .emscripten, |
tools/update_clang_options.zig+20| ... | @@ -352,6 +352,26 @@ const known_options = [_]KnownOpt{ | ... | @@ -352,6 +352,26 @@ const known_options = [_]KnownOpt{ |
| 352 | .name = "fno-stack-check", | 352 | .name = "fno-stack-check", |
| 353 | .ident = "no_stack_check", | 353 | .ident = "no_stack_check", |
| 354 | }, | 354 | }, |
| 355 | .{ | ||
| 356 | .name = "stack-protector", | ||
| 357 | .ident = "stack_protector", | ||
| 358 | }, | ||
| 359 | .{ | ||
| 360 | .name = "fstack-protector", | ||
| 361 | .ident = "stack_protector", | ||
| 362 | }, | ||
| 363 | .{ | ||
| 364 | .name = "fno-stack-protector", | ||
| 365 | .ident = "no_stack_protector", | ||
| 366 | }, | ||
| 367 | .{ | ||
| 368 | .name = "fstack-protector-strong", | ||
| 369 | .ident = "stack_protector", | ||
| 370 | }, | ||
| 371 | .{ | ||
| 372 | .name = "fstack-protector-all", | ||
| 373 | .ident = "stack_protector", | ||
| 374 | }, | ||
| 355 | .{ | 375 | .{ |
| 356 | .name = "MD", | 376 | .name = "MD", |
| 357 | .ident = "dep_file", | 377 | .ident = "dep_file", |