| author | |
| committer | |
| log | 97e23896a9168132b6d36ca22ae1af10dd53d80d |
| tree | b7d25c4231838edf980b7de7eec317f0a23371ee |
| parent | 138a35df8f434115be04641b1df29514b0ef1cb8 |
| parent | dfee782d7c30e2ff84060833be375e8cdf92e3be |
| signature |
move libssp into libcompiler_rt8 files changed, 181 insertions(+), 235 deletions(-)
lib/compiler_rt.zig+1| ... | @@ -233,5 +233,6 @@ comptime { | ... | @@ -233,5 +233,6 @@ comptime { |
| 233 | _ = @import("compiler_rt/memmove.zig"); | 233 | _ = @import("compiler_rt/memmove.zig"); |
| 234 | _ = @import("compiler_rt/memcmp.zig"); | 234 | _ = @import("compiler_rt/memcmp.zig"); |
| 235 | _ = @import("compiler_rt/bcmp.zig"); | 235 | _ = @import("compiler_rt/bcmp.zig"); |
| 236 | _ = @import("compiler_rt/ssp.zig"); | ||
| 236 | } | 237 | } |
| 237 | } | 238 | } |
lib/compiler_rt/ssp.zig created+143| ... | @@ -0,0 +1,143 @@ | ||
| 1 | //! | ||
| 2 | //! Small Zig reimplementation of gcc's libssp. | ||
| 3 | //! | ||
| 4 | //! This library implements most of the builtins required by the stack smashing | ||
| 5 | //! protection as implemented by gcc&clang. | ||
| 6 | //! Missing exports: | ||
| 7 | //! - __gets_chk | ||
| 8 | //! - __mempcpy_chk | ||
| 9 | //! - __snprintf_chk | ||
| 10 | //! - __sprintf_chk | ||
| 11 | //! - __stpcpy_chk | ||
| 12 | //! - __vsnprintf_chk | ||
| 13 | //! - __vsprintf_chk | ||
| 14 | |||
| 15 | const std = @import("std"); | ||
| 16 | const common = @import("./common.zig"); | ||
| 17 | const builtin = @import("builtin"); | ||
| 18 | |||
| 19 | extern fn memset(dest: ?[*]u8, c: u8, n: usize) callconv(.C) ?[*]u8; | ||
| 20 | extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8; | ||
| 21 | extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8; | ||
| 22 | |||
| 23 | comptime { | ||
| 24 | @export(__stack_chk_fail, .{ .name = "__stack_chk_fail", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 25 | @export(__chk_fail, .{ .name = "__chk_fail", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 26 | @export(__stack_chk_guard, .{ .name = "__stack_chk_guard", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 27 | @export(__strcpy_chk, .{ .name = "__strcpy_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 28 | @export(__strncpy_chk, .{ .name = "__strncpy_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 29 | @export(__strcat_chk, .{ .name = "__strcat_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 30 | @export(__strncat_chk, .{ .name = "__strncat_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 31 | @export(__memcpy_chk, .{ .name = "__memcpy_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 32 | @export(__memmove_chk, .{ .name = "__memmove_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 33 | @export(__memset_chk, .{ .name = "__memset_chk", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 34 | } | ||
| 35 | |||
| 36 | fn __stack_chk_fail() callconv(.C) noreturn { | ||
| 37 | @panic("stack smashing detected"); | ||
| 38 | } | ||
| 39 | |||
| 40 | fn __chk_fail() callconv(.C) noreturn { | ||
| 41 | @panic("buffer overflow detected"); | ||
| 42 | } | ||
| 43 | |||
| 44 | // TODO: Initialize the canary with random data | ||
| 45 | var __stack_chk_guard: usize = blk: { | ||
| 46 | var buf = [1]u8{0} ** @sizeOf(usize); | ||
| 47 | buf[@sizeOf(usize) - 1] = 255; | ||
| 48 | buf[@sizeOf(usize) - 2] = '\n'; | ||
| 49 | break :blk @as(usize, @bitCast(buf)); | ||
| 50 | }; | ||
| 51 | |||
| 52 | fn __strcpy_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 53 | @setRuntimeSafety(false); | ||
| 54 | |||
| 55 | var i: usize = 0; | ||
| 56 | while (i < dest_n and src[i] != 0) : (i += 1) { | ||
| 57 | dest[i] = src[i]; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (i == dest_n) __chk_fail(); | ||
| 61 | |||
| 62 | dest[i] = 0; | ||
| 63 | |||
| 64 | return dest; | ||
| 65 | } | ||
| 66 | |||
| 67 | fn __strncpy_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 68 | @setRuntimeSafety(false); | ||
| 69 | if (dest_n < n) __chk_fail(); | ||
| 70 | var i: usize = 0; | ||
| 71 | while (i < n and src[i] != 0) : (i += 1) { | ||
| 72 | dest[i] = src[i]; | ||
| 73 | } | ||
| 74 | while (i < n) : (i += 1) { | ||
| 75 | dest[i] = 0; | ||
| 76 | } | ||
| 77 | return dest; | ||
| 78 | } | ||
| 79 | |||
| 80 | fn __strcat_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 81 | @setRuntimeSafety(false); | ||
| 82 | |||
| 83 | var avail = dest_n; | ||
| 84 | |||
| 85 | var dest_end: usize = 0; | ||
| 86 | while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { | ||
| 87 | avail -= 1; | ||
| 88 | } | ||
| 89 | |||
| 90 | if (avail < 1) __chk_fail(); | ||
| 91 | |||
| 92 | var i: usize = 0; | ||
| 93 | while (avail > 0 and src[i] != 0) : (i += 1) { | ||
| 94 | dest[dest_end + i] = src[i]; | ||
| 95 | avail -= 1; | ||
| 96 | } | ||
| 97 | |||
| 98 | if (avail < 1) __chk_fail(); | ||
| 99 | |||
| 100 | dest[dest_end + i] = 0; | ||
| 101 | |||
| 102 | return dest; | ||
| 103 | } | ||
| 104 | |||
| 105 | fn __strncat_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 106 | @setRuntimeSafety(false); | ||
| 107 | |||
| 108 | var avail = dest_n; | ||
| 109 | |||
| 110 | var dest_end: usize = 0; | ||
| 111 | while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { | ||
| 112 | avail -= 1; | ||
| 113 | } | ||
| 114 | |||
| 115 | if (avail < 1) __chk_fail(); | ||
| 116 | |||
| 117 | var i: usize = 0; | ||
| 118 | while (avail > 0 and i < n and src[i] != 0) : (i += 1) { | ||
| 119 | dest[dest_end + i] = src[i]; | ||
| 120 | avail -= 1; | ||
| 121 | } | ||
| 122 | |||
| 123 | if (avail < 1) __chk_fail(); | ||
| 124 | |||
| 125 | dest[dest_end + i] = 0; | ||
| 126 | |||
| 127 | return dest; | ||
| 128 | } | ||
| 129 | |||
| 130 | fn __memcpy_chk(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 131 | if (dest_n < n) __chk_fail(); | ||
| 132 | return memcpy(dest, src, n); | ||
| 133 | } | ||
| 134 | |||
| 135 | fn __memmove_chk(dest: ?[*]u8, src: ?[*]const u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 136 | if (dest_n < n) __chk_fail(); | ||
| 137 | return memmove(dest, src, n); | ||
| 138 | } | ||
| 139 | |||
| 140 | fn __memset_chk(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 141 | if (dest_n < n) __chk_fail(); | ||
| 142 | return memset(dest, c, n); | ||
| 143 | } | ||
lib/ssp.zig deleted-135| ... | @@ -1,135 +0,0 @@ | ||
| 1 | //! | ||
| 2 | //! Small Zig reimplementation of gcc's libssp. | ||
| 3 | //! | ||
| 4 | //! This library implements most of the builtins required by the stack smashing | ||
| 5 | //! protection as implemented by gcc&clang. | ||
| 6 | //! Missing exports: | ||
| 7 | //! - __gets_chk | ||
| 8 | //! - __mempcpy_chk | ||
| 9 | //! - __snprintf_chk | ||
| 10 | //! - __sprintf_chk | ||
| 11 | //! - __stpcpy_chk | ||
| 12 | //! - __vsnprintf_chk | ||
| 13 | //! - __vsprintf_chk | ||
| 14 | |||
| 15 | const std = @import("std"); | ||
| 16 | |||
| 17 | extern fn strncpy(dest: [*:0]u8, src: [*:0]const u8, n: usize) callconv(.C) [*:0]u8; | ||
| 18 | extern fn memset(dest: ?[*]u8, c: u8, n: usize) callconv(.C) ?[*]u8; | ||
| 19 | extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8; | ||
| 20 | extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8; | ||
| 21 | |||
| 22 | // Avoid dragging in the runtime safety mechanisms into this .o file. | ||
| 23 | pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn { | ||
| 24 | _ = msg; | ||
| 25 | _ = error_return_trace; | ||
| 26 | @setCold(true); | ||
| 27 | std.os.abort(); | ||
| 28 | } | ||
| 29 | |||
| 30 | export fn __stack_chk_fail() callconv(.C) noreturn { | ||
| 31 | @panic("stack smashing detected"); | ||
| 32 | } | ||
| 33 | |||
| 34 | export fn __chk_fail() callconv(.C) noreturn { | ||
| 35 | @panic("buffer overflow detected"); | ||
| 36 | } | ||
| 37 | |||
| 38 | // Emitted when targeting some architectures (eg. x86) | ||
| 39 | // XXX: This symbol should be hidden | ||
| 40 | export fn __stack_chk_fail_local() callconv(.C) noreturn { | ||
| 41 | __stack_chk_fail(); | ||
| 42 | } | ||
| 43 | |||
| 44 | // XXX: Initialize the canary with random data | ||
| 45 | export var __stack_chk_guard: usize = blk: { | ||
| 46 | var buf = [1]u8{0} ** @sizeOf(usize); | ||
| 47 | buf[@sizeOf(usize) - 1] = 255; | ||
| 48 | buf[@sizeOf(usize) - 2] = '\n'; | ||
| 49 | break :blk @as(usize, @bitCast(buf)); | ||
| 50 | }; | ||
| 51 | |||
| 52 | export fn __strcpy_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 53 | @setRuntimeSafety(false); | ||
| 54 | |||
| 55 | var i: usize = 0; | ||
| 56 | while (i < dest_n and src[i] != 0) : (i += 1) { | ||
| 57 | dest[i] = src[i]; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (i == dest_n) __chk_fail(); | ||
| 61 | |||
| 62 | dest[i] = 0; | ||
| 63 | |||
| 64 | return dest; | ||
| 65 | } | ||
| 66 | |||
| 67 | export fn __strncpy_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 68 | if (dest_n < n) __chk_fail(); | ||
| 69 | return strncpy(dest, src, n); | ||
| 70 | } | ||
| 71 | |||
| 72 | export fn __strcat_chk(dest: [*:0]u8, src: [*:0]const u8, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 73 | @setRuntimeSafety(false); | ||
| 74 | |||
| 75 | var avail = dest_n; | ||
| 76 | |||
| 77 | var dest_end: usize = 0; | ||
| 78 | while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { | ||
| 79 | avail -= 1; | ||
| 80 | } | ||
| 81 | |||
| 82 | if (avail < 1) __chk_fail(); | ||
| 83 | |||
| 84 | var i: usize = 0; | ||
| 85 | while (avail > 0 and src[i] != 0) : (i += 1) { | ||
| 86 | dest[dest_end + i] = src[i]; | ||
| 87 | avail -= 1; | ||
| 88 | } | ||
| 89 | |||
| 90 | if (avail < 1) __chk_fail(); | ||
| 91 | |||
| 92 | dest[dest_end + i] = 0; | ||
| 93 | |||
| 94 | return dest; | ||
| 95 | } | ||
| 96 | |||
| 97 | export fn __strncat_chk(dest: [*:0]u8, src: [*:0]const u8, n: usize, dest_n: usize) callconv(.C) [*:0]u8 { | ||
| 98 | @setRuntimeSafety(false); | ||
| 99 | |||
| 100 | var avail = dest_n; | ||
| 101 | |||
| 102 | var dest_end: usize = 0; | ||
| 103 | while (avail > 0 and dest[dest_end] != 0) : (dest_end += 1) { | ||
| 104 | avail -= 1; | ||
| 105 | } | ||
| 106 | |||
| 107 | if (avail < 1) __chk_fail(); | ||
| 108 | |||
| 109 | var i: usize = 0; | ||
| 110 | while (avail > 0 and i < n and src[i] != 0) : (i += 1) { | ||
| 111 | dest[dest_end + i] = src[i]; | ||
| 112 | avail -= 1; | ||
| 113 | } | ||
| 114 | |||
| 115 | if (avail < 1) __chk_fail(); | ||
| 116 | |||
| 117 | dest[dest_end + i] = 0; | ||
| 118 | |||
| 119 | return dest; | ||
| 120 | } | ||
| 121 | |||
| 122 | export fn __memcpy_chk(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 123 | if (dest_n < n) __chk_fail(); | ||
| 124 | return memcpy(dest, src, n); | ||
| 125 | } | ||
| 126 | |||
| 127 | export fn __memmove_chk(dest: ?[*]u8, src: ?[*]const u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 128 | if (dest_n < n) __chk_fail(); | ||
| 129 | return memmove(dest, src, n); | ||
| 130 | } | ||
| 131 | |||
| 132 | export fn __memset_chk(dest: ?[*]u8, c: u8, n: usize, dest_n: usize) callconv(.C) ?[*]u8 { | ||
| 133 | if (dest_n < n) __chk_fail(); | ||
| 134 | return memset(dest, c, n); | ||
| 135 | } | ||
src/Compilation.zig+24-73| ... | @@ -152,9 +152,6 @@ libunwind_static_lib: ?CRTFile = null, | ... | @@ -152,9 +152,6 @@ libunwind_static_lib: ?CRTFile = null, |
| 152 | /// Populated when we build the TSAN static library. A Job to build this is placed in the queue | 152 | /// Populated when we build the TSAN static library. A Job to build this is placed in the queue |
| 153 | /// and resolved before calling linker.flush(). | 153 | /// and resolved before calling linker.flush(). |
| 154 | tsan_static_lib: ?CRTFile = null, | 154 | tsan_static_lib: ?CRTFile = null, |
| 155 | /// Populated when we build the libssp static library. A Job to build this is placed in the queue | ||
| 156 | /// and resolved before calling linker.flush(). | ||
| 157 | libssp_static_lib: ?CRTFile = null, | ||
| 158 | /// Populated when we build the libc static library. A Job to build this is placed in the queue | 155 | /// Populated when we build the libc static library. A Job to build this is placed in the queue |
| 159 | /// and resolved before calling linker.flush(). | 156 | /// and resolved before calling linker.flush(). |
| 160 | libc_static_lib: ?CRTFile = null, | 157 | libc_static_lib: ?CRTFile = null, |
| ... | @@ -286,7 +283,6 @@ const Job = union(enum) { | ... | @@ -286,7 +283,6 @@ const Job = union(enum) { |
| 286 | libcxx: void, | 283 | libcxx: void, |
| 287 | libcxxabi: void, | 284 | libcxxabi: void, |
| 288 | libtsan: void, | 285 | libtsan: void, |
| 289 | libssp: void, | ||
| 290 | /// needed when not linking libc and using LLVM for code generation because it generates | 286 | /// needed when not linking libc and using LLVM for code generation because it generates |
| 291 | /// calls to, for example, memcpy and memset. | 287 | /// calls to, for example, memcpy and memset. |
| 292 | zig_libc: void, | 288 | zig_libc: void, |
| ... | @@ -683,7 +679,6 @@ pub const MiscTask = enum { | ... | @@ -683,7 +679,6 @@ pub const MiscTask = enum { |
| 683 | libtsan, | 679 | libtsan, |
| 684 | wasi_libc_crt_file, | 680 | wasi_libc_crt_file, |
| 685 | compiler_rt, | 681 | compiler_rt, |
| 686 | libssp, | ||
| 687 | zig_libc, | 682 | zig_libc, |
| 688 | analyze_mod, | 683 | analyze_mod, |
| 689 | 684 | ||
| ... | @@ -1072,8 +1067,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1072,8 +1067,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1072 | .Exe => true, | 1067 | .Exe => true, |
| 1073 | }; | 1068 | }; |
| 1074 | 1069 | ||
| 1075 | const needs_c_symbols = !options.skip_linker_dependencies and is_exe_or_dyn_lib; | ||
| 1076 | |||
| 1077 | // WASI-only. Resolve the optional exec-model option, defaults to command. | 1070 | // WASI-only. Resolve the optional exec-model option, defaults to command. |
| 1078 | const wasi_exec_model = if (options.target.os.tag != .wasi) undefined else options.wasi_exec_model orelse .command; | 1071 | const wasi_exec_model = if (options.target.os.tag != .wasi) undefined else options.wasi_exec_model orelse .command; |
| 1079 | 1072 | ||
| ... | @@ -1355,10 +1348,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1355,10 +1348,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1355 | if (stack_check and !target_util.supportsStackProbing(options.target)) | 1348 | if (stack_check and !target_util.supportsStackProbing(options.target)) |
| 1356 | return error.StackCheckUnsupportedByTarget; | 1349 | return error.StackCheckUnsupportedByTarget; |
| 1357 | 1350 | ||
| 1358 | const capable_of_building_ssp = canBuildLibSsp(options.target, use_llvm); | 1351 | const stack_protector: u32 = sp: { |
| 1359 | 1352 | const zig_backend = zigBackend(options.target, use_llvm); | |
| 1360 | const stack_protector: u32 = options.want_stack_protector orelse b: { | 1353 | if (!target_util.supportsStackProtector(options.target, zig_backend)) { |
| 1361 | if (!target_util.supportsStackProtector(options.target)) break :b @as(u32, 0); | 1354 | if (options.want_stack_protector) |x| { |
| 1355 | if (x > 0) return error.StackProtectorUnsupportedByTarget; | ||
| 1356 | } | ||
| 1357 | break :sp 0; | ||
| 1358 | } | ||
| 1362 | 1359 | ||
| 1363 | // This logic is checking for linking libc because otherwise our start code | 1360 | // This logic is checking for linking libc because otherwise our start code |
| 1364 | // which is trying to set up TLS (i.e. the fs/gs registers) but the stack | 1361 | // which is trying to set up TLS (i.e. the fs/gs registers) but the stack |
| ... | @@ -1367,21 +1364,20 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1367,21 +1364,20 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1367 | // as being exempt from stack protection checks, we could change this logic | 1364 | // as being exempt from stack protection checks, we could change this logic |
| 1368 | // to supporting stack protection even when not linking libc. | 1365 | // to supporting stack protection even when not linking libc. |
| 1369 | // TODO file issue about this | 1366 | // TODO file issue about this |
| 1370 | if (!link_libc) break :b 0; | 1367 | if (!link_libc) { |
| 1371 | if (!capable_of_building_ssp) break :b 0; | 1368 | if (options.want_stack_protector) |x| { |
| 1372 | if (is_safe_mode) break :b default_stack_protector_buffer_size; | 1369 | if (x > 0) return error.StackProtectorUnavailableWithoutLibC; |
| 1373 | break :b 0; | 1370 | } |
| 1371 | break :sp 0; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | if (options.want_stack_protector) |x| break :sp x; | ||
| 1375 | if (is_safe_mode) break :sp default_stack_protector_buffer_size; | ||
| 1376 | break :sp 0; | ||
| 1374 | }; | 1377 | }; |
| 1375 | if (stack_protector != 0) { | ||
| 1376 | if (!target_util.supportsStackProtector(options.target)) | ||
| 1377 | return error.StackProtectorUnsupportedByTarget; | ||
| 1378 | if (!capable_of_building_ssp) | ||
| 1379 | return error.StackProtectorUnsupportedByBackend; | ||
| 1380 | if (!link_libc) | ||
| 1381 | return error.StackProtectorUnavailableWithoutLibC; | ||
| 1382 | } | ||
| 1383 | 1378 | ||
| 1384 | const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols; | 1379 | const include_compiler_rt = options.want_compiler_rt orelse |
| 1380 | (!options.skip_linker_dependencies and is_exe_or_dyn_lib); | ||
| 1385 | 1381 | ||
| 1386 | const single_threaded = st: { | 1382 | const single_threaded = st: { |
| 1387 | if (target_util.isSingleThreaded(options.target)) { | 1383 | if (target_util.isSingleThreaded(options.target)) { |
| ... | @@ -2196,18 +2192,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -2196,18 +2192,11 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2196 | comp.job_queued_compiler_rt_obj = true; | 2192 | comp.job_queued_compiler_rt_obj = true; |
| 2197 | } | 2193 | } |
| 2198 | } | 2194 | } |
| 2199 | if (needs_c_symbols) { | ||
| 2200 | // Related: https://github.com/ziglang/zig/issues/7265. | ||
| 2201 | if (comp.bin_file.options.stack_protector != 0 and | ||
| 2202 | (!comp.bin_file.options.link_libc or | ||
| 2203 | !target_util.libcProvidesStackProtector(target))) | ||
| 2204 | { | ||
| 2205 | try comp.work_queue.writeItem(.{ .libssp = {} }); | ||
| 2206 | } | ||
| 2207 | 2195 | ||
| 2208 | if (!comp.bin_file.options.link_libc and capable_of_building_zig_libc) { | 2196 | if (!comp.bin_file.options.skip_linker_dependencies and is_exe_or_dyn_lib and |
| 2209 | try comp.work_queue.writeItem(.{ .zig_libc = {} }); | 2197 | !comp.bin_file.options.link_libc and capable_of_building_zig_libc) |
| 2210 | } | 2198 | { |
| 2199 | try comp.work_queue.writeItem(.{ .zig_libc = {} }); | ||
| 2211 | } | 2200 | } |
| 2212 | } | 2201 | } |
| 2213 | 2202 | ||
| ... | @@ -2253,9 +2242,6 @@ pub fn destroy(self: *Compilation) void { | ... | @@ -2253,9 +2242,6 @@ pub fn destroy(self: *Compilation) void { |
| 2253 | if (self.compiler_rt_obj) |*crt_file| { | 2242 | if (self.compiler_rt_obj) |*crt_file| { |
| 2254 | crt_file.deinit(gpa); | 2243 | crt_file.deinit(gpa); |
| 2255 | } | 2244 | } |
| 2256 | if (self.libssp_static_lib) |*crt_file| { | ||
| 2257 | crt_file.deinit(gpa); | ||
| 2258 | } | ||
| 2259 | if (self.libc_static_lib) |*crt_file| { | 2245 | if (self.libc_static_lib) |*crt_file| { |
| 2260 | crt_file.deinit(gpa); | 2246 | crt_file.deinit(gpa); |
| 2261 | } | 2247 | } |
| ... | @@ -4022,26 +4008,6 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v | ... | @@ -4022,26 +4008,6 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 4022 | ); | 4008 | ); |
| 4023 | }; | 4009 | }; |
| 4024 | }, | 4010 | }, |
| 4025 | .libssp => { | ||
| 4026 | const named_frame = tracy.namedFrame("libssp"); | ||
| 4027 | defer named_frame.end(); | ||
| 4028 | |||
| 4029 | comp.buildOutputFromZig( | ||
| 4030 | "ssp.zig", | ||
| 4031 | .Lib, | ||
| 4032 | &comp.libssp_static_lib, | ||
| 4033 | .libssp, | ||
| 4034 | prog_node, | ||
| 4035 | ) catch |err| switch (err) { | ||
| 4036 | error.OutOfMemory => return error.OutOfMemory, | ||
| 4037 | error.SubCompilationFailed => return, // error reported already | ||
| 4038 | else => comp.lockAndSetMiscFailure( | ||
| 4039 | .libssp, | ||
| 4040 | "unable to build libssp: {s}", | ||
| 4041 | .{@errorName(err)}, | ||
| 4042 | ), | ||
| 4043 | }; | ||
| 4044 | }, | ||
| 4045 | .zig_libc => { | 4011 | .zig_libc => { |
| 4046 | const named_frame = tracy.namedFrame("zig_libc"); | 4012 | const named_frame = tracy.namedFrame("zig_libc"); |
| 4047 | defer named_frame.end(); | 4013 | defer named_frame.end(); |
| ... | @@ -6526,21 +6492,6 @@ fn canBuildLibCompilerRt(target: std.Target, use_llvm: bool) bool { | ... | @@ -6526,21 +6492,6 @@ fn canBuildLibCompilerRt(target: std.Target, use_llvm: bool) bool { |
| 6526 | }; | 6492 | }; |
| 6527 | } | 6493 | } |
| 6528 | 6494 | ||
| 6529 | fn canBuildLibSsp(target: std.Target, use_llvm: bool) bool { | ||
| 6530 | switch (target.os.tag) { | ||
| 6531 | .plan9 => return false, | ||
| 6532 | else => {}, | ||
| 6533 | } | ||
| 6534 | switch (target.cpu.arch) { | ||
| 6535 | .spirv32, .spirv64 => return false, | ||
| 6536 | else => {}, | ||
| 6537 | } | ||
| 6538 | return switch (zigBackend(target, use_llvm)) { | ||
| 6539 | .stage2_llvm => true, | ||
| 6540 | else => build_options.have_llvm, | ||
| 6541 | }; | ||
| 6542 | } | ||
| 6543 | |||
| 6544 | /// Not to be confused with canBuildLibC, which builds musl, glibc, and similar. | 6495 | /// Not to be confused with canBuildLibC, which builds musl, glibc, and similar. |
| 6545 | /// This one builds lib/c.zig. | 6496 | /// This one builds lib/c.zig. |
| 6546 | fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool { | 6497 | fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool { |
src/link/Coff/lld.zig-6| ... | @@ -483,12 +483,6 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -483,12 +483,6 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 483 | try argv.append(lib.full_object_path); | 483 | try argv.append(lib.full_object_path); |
| 484 | } | 484 | } |
| 485 | } | 485 | } |
| 486 | // MinGW doesn't provide libssp symbols | ||
| 487 | if (target.abi.isGnu()) { | ||
| 488 | if (comp.libssp_static_lib) |lib| { | ||
| 489 | try argv.append(lib.full_object_path); | ||
| 490 | } | ||
| 491 | } | ||
| 492 | // MSVC compiler_rt is missing some stuff, so we build it unconditionally but | 486 | // MSVC compiler_rt is missing some stuff, so we build it unconditionally but |
| 493 | // and rely on weak linkage to allow MSVC compiler_rt functions to override ours. | 487 | // and rely on weak linkage to allow MSVC compiler_rt functions to override ours. |
| 494 | if (comp.compiler_rt_obj) |obj| try argv.append(obj.full_object_path); | 488 | if (comp.compiler_rt_obj) |obj| try argv.append(obj.full_object_path); |
src/link/Elf.zig-18| ... | @@ -1040,12 +1040,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1040,12 +1040,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1040 | } | 1040 | } |
| 1041 | } | 1041 | } |
| 1042 | 1042 | ||
| 1043 | // stack-protector. | ||
| 1044 | // Related: https://github.com/ziglang/zig/issues/7265 | ||
| 1045 | if (comp.libssp_static_lib) |ssp| { | ||
| 1046 | try positionals.append(.{ .path = ssp.full_object_path }); | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | for (positionals.items) |obj| { | 1043 | for (positionals.items) |obj| { |
| 1050 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; | 1044 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1051 | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| | 1045 | self.parsePositional(obj.path, obj.must_link, &parse_ctx) catch |err| |
| ... | @@ -1689,12 +1683,6 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1689,12 +1683,6 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1689 | } | 1683 | } |
| 1690 | } | 1684 | } |
| 1691 | 1685 | ||
| 1692 | // stack-protector. | ||
| 1693 | // Related: https://github.com/ziglang/zig/issues/7265 | ||
| 1694 | if (comp.libssp_static_lib) |ssp| { | ||
| 1695 | try argv.append(ssp.full_object_path); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | // Shared libraries. | 1686 | // Shared libraries. |
| 1699 | // Worst-case, we need an --as-needed argument for every lib, as well | 1687 | // Worst-case, we need an --as-needed argument for every lib, as well |
| 1700 | // as one before and one after. | 1688 | // as one before and one after. |
| ... | @@ -2729,12 +2717,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2729,12 +2717,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2729 | } | 2717 | } |
| 2730 | } | 2718 | } |
| 2731 | 2719 | ||
| 2732 | // stack-protector. | ||
| 2733 | // Related: https://github.com/ziglang/zig/issues/7265 | ||
| 2734 | if (comp.libssp_static_lib) |ssp| { | ||
| 2735 | try argv.append(ssp.full_object_path); | ||
| 2736 | } | ||
| 2737 | |||
| 2738 | // Shared libraries. | 2720 | // Shared libraries. |
| 2739 | if (is_exe_or_dyn_lib) { | 2721 | if (is_exe_or_dyn_lib) { |
| 2740 | const system_libs = self.base.options.system_libs.keys(); | 2722 | const system_libs = self.base.options.system_libs.keys(); |
src/target.zig+13-2| ... | @@ -328,8 +328,19 @@ pub fn supportsStackProbing(target: std.Target) bool { | ... | @@ -328,8 +328,19 @@ pub fn supportsStackProbing(target: std.Target) bool { |
| 328 | (target.cpu.arch == .x86 or target.cpu.arch == .x86_64); | 328 | (target.cpu.arch == .x86 or target.cpu.arch == .x86_64); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | pub fn supportsStackProtector(target: std.Target) bool { | 331 | pub fn supportsStackProtector(target: std.Target, backend: std.builtin.CompilerBackend) bool { |
| 332 | return !target.isSpirV(); | 332 | switch (target.os.tag) { |
| 333 | .plan9 => return false, | ||
| 334 | else => {}, | ||
| 335 | } | ||
| 336 | switch (target.cpu.arch) { | ||
| 337 | .spirv32, .spirv64 => return false, | ||
| 338 | else => {}, | ||
| 339 | } | ||
| 340 | return switch (backend) { | ||
| 341 | .stage2_llvm => true, | ||
| 342 | else => false, | ||
| 343 | }; | ||
| 333 | } | 344 | } |
| 334 | 345 | ||
| 335 | pub fn libcProvidesStackProtector(target: std.Target) bool { | 346 | pub fn libcProvidesStackProtector(target: std.Target) bool { |
stage1/config.zig.in-1| ... | @@ -9,7 +9,6 @@ pub const enable_logging: bool = false; | ... | @@ -9,7 +9,6 @@ pub const enable_logging: bool = false; |
| 9 | pub const enable_link_snapshots: bool = false; | 9 | pub const enable_link_snapshots: bool = false; |
| 10 | pub const enable_tracy = false; | 10 | pub const enable_tracy = false; |
| 11 | pub const value_tracing = false; | 11 | pub const value_tracing = false; |
| 12 | pub const have_stage1 = false; | ||
| 13 | pub const skip_non_native = false; | 12 | pub const skip_non_native = false; |
| 14 | pub const only_c = false; | 13 | pub const only_c = false; |
| 15 | pub const force_gpa = false; | 14 | pub const force_gpa = false; |